Python
类的继承问题
CSDN: python中super().init ()
关键字:assert、raise、yield
CSDN: python中assert的用法(简洁明了)
8. 错误和异常¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- StopAsyncIteration +-- ArithmeticError | +-- FloatingPointError | +-- OverflowError | +-- ZeroDivisionError +-- AssertionError +-- AttributeError +-- BufferError +-- EOFError +-- ImportError | +-- ModuleNotFoundError +-- LookupError | +-- IndexError | +-- KeyError +-- MemoryError +-- NameError | +-- UnboundLocalError +-- OSError | +-- BlockingIOError | +-- ChildProcessError | +-- ConnectionError | | +-- BrokenPipeError | | +-- ConnectionAbortedError | | +-- ConnectionRefusedError | | +-- ConnectionResetError | +-- FileExistsError | +-- FileNotFoundError | +-- InterruptedError | +-- IsADirectoryError | +-- NotADirectoryError | +-- PermissionError | +-- ProcessLookupError | +-- TimeoutError +-- ReferenceError +-- RuntimeError | +-- NotImplementedError | +-- RecursionError +-- SyntaxError | +-- IndentationError | +-- TabError +-- SystemError +-- TypeError +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning +-- ResourceWarning
C语言中文网: Python raise用法(超级详细,看了无师自通)
python中yield的用法详解——最简单,最清晰的解释
关于copy
CSDN: python中的copy.copy和copy.deepcopy
CSDN: 系统学习Python——字典(dict):copy()函数
关于train和eval
CSDN: 【Pytorch】model.train() 和 model.eval() 原理与用法
CSDN: python之*的用法
关于detach和detach_方法
详解.detach()、 .data和.detach_()
pytorch:.detach()、.detach_()的作用和区别
Pytorch中inplace操作
pytorch中的ReLU与inplace原地操作的一些注意点
detach复制一个原变量,但是requires_grad = False,因此对新变量的backward操作会报错。此后如果新变量不改变,则原变量的梯度仍为True,相关的梯度相关操作仍正常进行。新变量一旦改变,原变量由于内存共享,值发生改变,梯度False。这里新变量的改变,需得是那种in-place级别的改变。
这种控制是通过auto_grad控制的,因此如果detach的是原变量.data,即使新变量改变了,原变量仍可以做相关求导操作,只不过返回的梯度值是错误的。
detach_就是in-place升级版,直接把原变量的梯度也给设置成False了。
交叉熵误差
二分类交叉熵,多分类交叉熵,focal loss
假设网络输出为out,真实标签为y,预测标签为y_hat.
(1)对于二分类问题,计算公式为l o s s = − y ∗ l o g ( y ^ ) − ( 1 − y ) ∗ l o g ( 1 − y ^ ) loss = -y*log(\hat{y})-(1-y)*log(1-\hat{y}) l oss = − y ∗ l o g ( y ^ ) − ( 1 − y ) ∗ l o g ( 1 − y ^ )
out,y,y_hat的形状均一致,可谓任意形状张量
1 2 3 4 criterion1 = nn.BCEWithLogitsLoss() criterion2 = nn.BCEWithLoss() loss1 = criterion1(out ,y) loss2 = criterion2(y_hat,y)
(2)对于多分类交叉熵,计算公式为l o s s = − 1 n ∑ i = 1 n ∑ j = 1 k y i j ∗ l o g ( y ^ i j ) loss = -\frac{1}{n}\sum_{i=1}^{n}\sum_{j=1}^{k}y_{ij}*log(\hat{y}_{ij}) l oss = − n 1 ∑ i = 1 n ∑ j = 1 k y ij ∗ l o g ( y ^ ij ) ,class表示分类的个数,n表示序列长度
1 2 criterion = nn.CrossEntropyLoss() criterion(out,y)
①out,y,y_hat的形状分别为(batch,class),(batch),(batch,class)
内部运算时,会将out–softmax–exp–>y_hat,将y–>y.long(),根据y给出的位置信息,在y_hat中找到对应位置的元素,把batch个相加之后求平均。
②out,y,y_hat的形状分别为(batch,class,n),(batch,n),(batch,class,n)
内部运算时,会将out–softmax–exp–>y_hat,将y–>y.long(),根据y给出的位置信息,在y_hat中找到对应位置的元素,把batch个相加之后求平均。注意softmax是在class维度进行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 out = [[[0.4100 , 0.2784 , 0.8864 , 0.2563 , 0.6145 , 0.1003 , 0.2250 ], [0.8236 , 0.3911 , 0.7626 , 0.4091 , 0.5717 , 0.1733 , 0.7634 ], [0.6580 , 0.9722 , 0.0596 , 0.5479 , 0.9591 , 0.5731 , 0.7304 ]], [[7.4100 , 0.2784 , 0.8864 , 0.2563 , 2.6145 , 0.1003 , 0.2250 ], [0.8236 , 2.3911 , 0.7626 , 0.4091 , 0.5717 , 4.1733 , 0.7634 ], [0.6580 , 0.9722 , 0.0596 , 6.5479 , 0.9591 , 0.5731 , 2.7304 ]]] y = [[0.4966 ,2.4566 ,0.1086 , 1.6627 ,0.3579 ,2.6607 ,0.3494 ], [1.4966 ,0.4566 ,0.1086 , 1.6627 ,1.3579 ,0.6607 ,1.3494 ]] out = torch.Tensor(out) y = torch.Tensor(y).long() criterion = nn.CrossEntropyLoss() print (criterion(out,y)) y_hat = out.log_softmax(dim=1 ) sum = 0 for batch in range (y.shape[0 ]): for i in range (y.shape[1 ]): sum = sum -y_hat[batch, y[batch,i] ,i] sum /len (y.flatten())
③对于out,y,y_hat的形状分别为(batch,class,rows,cols),(batch,rows,cols),(batch,class,rows,cols),思路上和②同理。
训练rnn的心得
训练rnn时一定要注意各个变量的形状和组织结构,下面给出一段代码做具体注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 import torchfrom torch import nnfrom torch.nn import functional as Ffrom d2l import torch as d2lclass RNNModel (nn.Module ): def __init__ (self,rnn_net,vocab_size ) : super (RNNModel,self).__init__() self.net = rnn_net self.vocab_size = vocab_size self.linear = nn.Linear(self.net.hidden_size,self.vocab_size) def forward (self,inputs,state ): X = F.one_hot(inputs.T,self.vocab_size) X = X.to(torch.float32) Y, state_new = self.net(X, state) outputs = self.linear(Y.reshape((-1 ,self.net.hidden_size))) return outputs, state_new def begin_state (self,batch_size ): return torch.zeros(1 ,batch_size,self.net.hidden_size) def predict_clancy (prefix,num_steps,net,vocab ): state = rnn.begin_state(batch_size=1 ) for c in prefix[:-1 ]: _, state = net(torch.tensor(vocab.token_to_idx[c]).reshape((1 ,1 )),state) for _ in range (num_steps): c, state = rnn(torch.tensor(vocab.token_to_idx[prefix[-1 ]]).reshape((1 ,1 )) ,state) prefix = prefix + vocab.idx_to_token[torch.argmax(c,dim=1 )] return prefix def grad_clipping (net, theta ): """裁剪梯度""" if isinstance (net, nn.Module): params = [p for p in net.parameters() if p.requires_grad] else : params = net.params norm = torch.tensor([torch.sum ((p.grad ** 2 )) for p in params]) norm = torch.sqrt(torch.sum (norm)) if norm > theta: for param in params: param.grad[:] *= theta / norm batch_size = 16 num_steps = 35 num_epochs = 500 lr = 1 train_iter, vocab = d2l.load_data_time_machine(batch_size,num_steps) rnn = RNNModel(nn.RNN(input_size = len (vocab),hidden_size = 256 ,nonlinearity='tanh' ),len (vocab)) state = rnn.begin_state(batch_size) loss = nn.CrossEntropyLoss() updater = torch.optim.SGD(rnn.parameters(),lr) scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(updater, T_max=num_epochs) ppl = [] for epoch in range (num_epochs): ppl_epoch = [0 ,0 ] for X, Y in train_iter: state.detach_() updater.zero_grad() Y_new, state = rnn(X, state) l = loss(Y_new.reshape(num_steps,batch_size,-1 ).permute(0 ,2 ,1 ),Y.T.long()) l.backward() grad_clipping(rnn, 1 ) updater.step() scheduler.step() ppl_epoch[0 ] += l * Y.numel() ppl_epoch[1 ] += Y.numel() if (epoch)%20 ==0 : print (epoch,l) ppl.append(math.exp(ppl_epoch[0 ] / ppl_epoch[1 ])) predict_clancy('time machine ' ,60 , rnn, vocab) from matplotlib import pyplot as pltplt.plot(range (num_epochs),ppl)
从文本读入后,在for X, Y in train_iter中,X:(batch,steps),Y:(batch,steps)
X进入rnn的forward后,会先转置再做one_hot,形状变为X:(steps,batch,len(vocab))
在nn.RNN中,会以steps为循环一步一步地预测,因此Y_hat是由一个个(batch,len(vocab))拼接起来的,最终形状为(steps*batch,len(vocab))
如若想计算交叉熵,有两种方式:
把Y转置
后再拉平,变为(steps*batch),转为long型后再和Y_hat一起进入nn.CrossEntropy,即loss(Y_new, Y.T.flatten().long()).mean()
把Y_hat换为三维后变为(steps,batch,len(vocab)),再换轴变为(steps,len(vocab),batch),再和转置转整型后的Y一起进入nn.CrossEntropy,即loss(Y_new.reshape(num_steps,batch_size,-1).permute(0,2,1),Y.T.long())。
此段请务必配合上一节一同理解,很重要。分类的类数目class一定要放中间。
numel()函数
pytorch中的numel函数用法说明
注意力机制的理解
用数学语言描述,假设有一个查询
q ∈ R q \mathbf{q} \in \mathbb{R}^q q ∈ R q 和m m m 个“键-值”对
( k 1 , v 1 ) , … , ( k m , v m ) (\mathbf{k}_1, \mathbf{v}_1), \ldots, (\mathbf{k}_m, \mathbf{v}_m) ( k 1 , v 1 ) , … , ( k m , v m ) ,
其中k i ∈ R k \mathbf{k}_i \in \mathbb{R}^k k i ∈ R k ,v i ∈ R v \mathbf{v}_i \in \mathbb{R}^v v i ∈ R v 。
注意力汇聚函数f f f 就被表示成值的加权和:
f ( q , ( k 1 , v 1 ) , … , ( k m , v m ) ) = ∑ i = 1 m α ( q , k i ) v i ∈ R v , f(\mathbf{q}, (\mathbf{k}_1, \mathbf{v}_1), \ldots, (\mathbf{k}_m, \mathbf{v}_m)) = \sum_{i=1}^m \alpha(\mathbf{q}, \mathbf{k}_i) \mathbf{v}_i \in \mathbb{R}^v,
f ( q , ( k 1 , v 1 ) , … , ( k m , v m )) = i = 1 ∑ m α ( q , k i ) v i ∈ R v ,
其中查询q \mathbf{q} q 和键k i \mathbf{k}_i k i 的注意力权重(标量)是通过注意力评分函数a a a 将两个向量映射成标量,再经过softmax运算得到的:
α ( q , k i ) = s o f t m a x ( a ( q , k i ) ) = exp ( a ( q , k i ) ) ∑ j = 1 m exp ( a ( q , k j ) ) ∈ R . \alpha(\mathbf{q}, \mathbf{k}_i) = \mathrm{softmax}(a(\mathbf{q}, \mathbf{k}_i)) = \frac{\exp(a(\mathbf{q}, \mathbf{k}_i))}{\sum_{j=1}^m \exp(a(\mathbf{q}, \mathbf{k}_j))} \in \mathbb{R}.
α ( q , k i ) = softmax ( a ( q , k i )) = ∑ j = 1 m exp ( a ( q , k j )) exp ( a ( q , k i )) ∈ R .
综上,本来的损失函数是q和y直接求,现在变成了y_hat(q,y)和y求,那么理论上说模型的输出在无形中加入了和标签直接相关的信息,也就是注意力机制。
但是实际情况中,似乎values并不一定是y,也可能是其他任何人为设定的东西。总之keys和values是不变的,至于注意力往哪集中是注意力层通过修正权重参数来实现的。
tensor.contiguous()和tensor.view()
tensor.contiguous
[…,0,0]和[:,0,0]
【Python】[…,0,0]和[:,0,0]是什么意思呢
torch.repeat_interleave()与tensor.repeat()
torch.repeat_interleave()与tensor.repeat()——数组的重复
反射
【Python】反射
**kwargs
训练加速指南
『PyTorch』PyTorch深度学习模型训练加速指南
syn_bn
torch.nn.SyncBatchNorm.convert_sync_batchnorm
html
学习资料
本人跟学的bilibili的加百利先生的视频:
https://www.bilibili.com/video/BV1kb411n7NJ?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click
我已经学完了,将我自己编的文件发布在了github中:
https://github.com/ClancyCC/html-css-js
Q1:关于目录的读取
./是当前目录
…/是父级目录
/是根目录
根目录指逻辑驱动器的最上一级目录,它是相对子目录来说的。打开“我的电脑”,双击C盘就进入C盘的根目录,双击D盘就进入D盘的根目录。其它类推。根目录在文件系统建立时即已被创建,其目的就是存储子目录(也称为文件夹)或文件的目录项。
但有时调用我发现./和/的应用是不太一样的。有时候不一定哪个是对的。
Q2:关于img前后伪元素伪类的特殊情况
网络解释:
个人发现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <style > *{ margin : 0 ; padding : 0 ; } .box { background-repeat : no-repeat; width : 250px ; height : 250px ; overflow : hidden; margin : 5px ; float : left; position : relative; } .box > *{ position : absolute; } .box img { transform : translateX (0 ) translateY (0 ); } .box img ::after { content : "hjhghjg" ; left : 0px ; top : 0px ; position : absolute; background : transparent; height : 250px ; width : 250px ; } .box :hover img ::after { background : rgb (255 , 255 , 255 ,0.3 ); } </style > <div class ="box" > <img src ="xxxx.png" alt ="" > <img src ="" alt ="" > </div > 、
Q3:需要理解伪元素中的content属性有什么特殊意义
暂未解决
Q4:关于在VS code中注释代码语句
1 2 3 注释语句:ctrl+/或者ctrl+K+ctrl+C 取消注释:ctrl+/或者ctrl+K+ctrl+U 块注释,多行注释:选中代码+alt+shift+A
linux
CSDN:
CSDN:
CSDN: