基础不牢,地动山摇
这句话真的是至理名言。入门的时候入的不好,疯狂的踩坑以及遇到很多很多的问题。有很多理论知识和实战的知识都是欠缺的。于是就有了这个合集,去记录遇到的大大小小的问题和不断地做知识补充。就算是遇到了解决肯定还会再忘的,那就本地存个档把这些东西都记录下来。由于个人水平不够,本合集势必是又乱又蠢的了,希望各位读者见谅。
在这里要郑重感谢我的入门领路人兼好好好朋友tan 90°同学。每一次都会被tan 90°的奇思妙想和他强大的学习能力、动手能力深深折服,橙色橘猫头像同学是我永远的老师。
损失函数
CrossEntropyLoss(交叉熵)
分类任务里常用的损失函数。
Negative log likelihood loss(负对数似然损失)
同样的,也是分类任务里常用的损失函数。
两者都在torch.nn里,支持直接调用,调用的用法是:
1 | loss_fc = torch.nn.CrossEntropyLoss() #torch.nn.NLLLoss() |
CrossEntropyLoss和nll_loss的主要区别是:
利用网络的output和真实标签target计算softmax+交叉熵损失的过程为: (1)sm=softmax(output); 计算softmax (2)logsm=log(sm); 取对数 (3)loss=-logsm.*target 取负后与onehot标签对应相乘完成交叉熵计算
CrossEntropyLoss执行上述三步,而NLLLoss相当于只执行(3)
原文链接:https://blog.csdn.net/qq_33727302/article/details/110174224
因此,在实际训练中,如果做的是分类任务,且使用CrossEntropyLoss作为损失函数的话,神经网络的部分就没必要加入nn.Softmax或者nn.LogSoftmax等之类的,因为在CrossEntropyLoss已经内置了该功能
手撕交叉熵:交叉熵损失函数(Cross Entropy Loss)_crossentropyloss-CSDN博客
对抗样本
解决对一个对象多次BP更新时造成的RuntimeError: you can only change requires_grad flags of leaf variables.问题
在生成对抗样本的情境中,常常需要对一个对象(比如对抗扰动)进行多次的反向传播更新。
报错原因:攻击函数返回值是同一个对象perturbation,该对象在一开始计算时被设置requires_grad = True,在以上函数运行完一遍之后,计算图变成:perturbation -> adv -> pred -> loss -> perturbation. 也就是说,完成一遍更新之后,perturbation不再是叶子节点了,因此报错。
解决办法:每轮更新得到的对抗样本或扰动在输入模型得到输出时,不要把这个对像作为模型输入,而是复制成一个新的张量,并且这个张量脱离计算图。这样在下一次重新进入函数开始新一轮计算时就不会对计算图造成混乱。
1 | return perturbation.detach() |
卷积层和池化层
做卷积可以直接调用pytorch的内置函数。分两种
1.构建卷积网络 -- nn.Conv2d()
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)
in_channels:输入通道数
out_channels:卷积核个数
kernel_size:卷积核的shape,如果输入x是int,那么就是(x,x)
stride:卷积核移动的步长
padding:填充,(行数、列数)
Padding即所谓的图像填充,后面的int型常数代表填充的多少(行数、列数),默认为0。需要注意的是这里的填充包括图像的上下左右,以padding = 1为例,若原始图像大小为32x32,那么padding后的图像大小就变成了34x34,而不是33x33。 Pytorch不同于Tensorflow的地方在于,Tensorflow提供的是padding的模式,比如same、valid,且不同模式对应了不同的输出图像尺寸计算公式。而Pytorch则需要手动输入padding的数量。
dilation:这个参数决定了是否采用空洞卷积,默认为1(不采用)
若dilation=2:https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md
bias:是否加偏置
padding_mode:padding模式,默认是0填充
zero:零填充(在矩阵的高、宽两个维度上用0进行填充,填充时将在一个维度的两边都进行填充)
reflect:镜像填充(以矩阵边缘为对称轴,将矩阵中的元素对称的填充到最外围)
replicate:重复填充(直接用边缘的像素值来填充)
circular:循环填充
参考链接:https://blog.csdn.net/sazass/article/details/116790155
2.调用卷积函数
常用链接:
1.image标签名称对应表: ImageNet图像库1000个类别名称(中文注释不断更新)_imagenet类别_有石为玉的博客-CSDN博客
一些常用的python处理函数
我有健忘症(
pytorch张量拷贝
# Operation | New/Shared memory | Still in computation graph |
---|---|---|
tensor.clone() | New | Yes |
tensor.detach() | Shared | No |
clone()函数可以返回一个完全相同的tensor,新的tensor开辟新的内存,但是仍然留在计算图中
detach()函数可以返回一个完全相同的tensor,新的tensor开辟与旧的tensor共享内存,新的tensor会脱离计算图,不会牵扯梯度计算。此外,一些原地操作(in-place, such as resize_ / resize_as_ / set_ / transpose_) 在两者任意一个执行都会引发错误。
tensor转图片
因此,在将tensor恢复成图片时,我们常用的是detach()函数。
代码如下:
1 | img_tensor = tensor.detach() |
tensor与ndarray互转
1 | #ndarry转tensor |
注意:
torch.from_numpy()会指向相同的内存地址。修改原array变量ten也会变!!!
torch.tensor()不会指向相同的内存地址,是深度copy。
1 | # 如果一个tensor的device是GPU,先使用如下命令转为CPU |
注意: GPU上的tensor不能和numpy直接转换。必须先转换为CPU上的tensor
latex公式语法
latex公式写法参考链接:
【精选】【latex技巧】常用公式汇总(精简:))_latex公式_six_gods的博客-CSDN博客