软工大一学生,9月升大二,在暑假期间申报项目,7月份开始学习,学习的项目关于到神经网络和注意力机制
首先通过廖雪峰老师的网站自学了python
配置开发环境
Anaconda3
python3.7&3.8
pycharm 2020.2版本
pytorch 1.6
下载pytorch:可以通过先下载anaconda,在此环境下进行下载pytorch,使用清华镜像源,利用Re:从零开始的Pytorch官方入门新手教程!!进行大概的下载学习,后来发现pytorch没有下载成功,就进行再次下载在win10终端下载一分钟pytorch
下载pycharm 直接把破解包拖入pycharm中即可使用
通过大神的视频自学(霹雳吧啦Wz这位神仙up主的原创讲解视频)
卷积神经网络基础
卷积神经网络基础补充
BP算法包括信号的前向传播和误差的反向传播
计算误差是按输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。
输入层:输出层:
三个问题:
如果卷积核1的偏移量为-1 则1 3 1 1就变成0 2 0 0
加上激活函数该如何计算?
激活函数的作用:引入非线性因素,使得具备解决非线性问题的能力
Sigmoid激活函数
缺点:当函数饱和时梯度值非常小,故网络层数较深时易出现梯度消失的情况
Relu激活函数
缺点:当反向传播过程中有一个非常大的梯度经过时,反向传播更新后可能导致权重分布中心小于零,导致该处的倒数始终为0,反向传播无法更新权重,即进入失活状态(所以一开始不要用太大的学习率进行学习,要不然导致很多神经元失活)
使用padding的方式进行补0
N=(W - F + 2*P )/S+1
1.图片大小W X W
2.Filter 大小 卷积核大小 滤波器大小(这里是3X3)
3.步长
4.Padding的像素数p(这里p=1)
例如这张图卷积后输出的矩阵尺寸的大小计算公式为:( 4 - 3 + 1)/ 2 + 1 =2
MaxPooling下采样层(得到每个的最大值)
目的对特征图进行稀疏处理,减少数据运算量
AveragePooling下采样层(得到每一个的平均值)
特点:
输入层X1,X2
中间是隐层设置三个结点:w
代表权重
代表激活函数
y1与y2的计算同样是上一层隐层的输出运算类似,同样是上一层输出的值 * 权重w + 偏置b
但是没有用到激活函数
因为y1 y2 的输出概率分布,所以使用softmax激活函数使其拥有概率分布的特点
在这里按照实示例得到o1和o2的函数
经过softmax处理后的所有输出节点概率和为1
用什么公式计算交叉熵就是看激活函数是什么
注意softmax和sigmoid函数各自的特点!
两者之间的差别:
输出概率和为1
示例:Softmax的输出是属于是不是狗狗(输出只归于一个类别)
每个输出节点互不相干
示例:Signmoid输出是人类和男人(可能同时属于同一个类别)
以w11为例,讲解如何进行误差的反向传播
已经得到Loss 、o1,o2,y1,y2
Loss对w11求偏导
具体计算过程:a1是指
具体计算:
代入Loss对w11的求偏导的公式中:
相当于我们把我们所得到的误差传播到了每一个结点,得到了每个结点的损失梯度
这个方向还不是减少损失最快的方向、最优的方向
理想中
现实:常用的卷积(Conv2d)在pytorch中对应的函数是:
做法:
重点是分批次,不能一次性将数据载入,分批次的话,每一次都是实现局部最优
希望网络可以更快的收敛
会用到优化器optimazer
1.SGD优化器
2.SGD+Momentum优化器
3.Adagrad优化器
4.RMSProp优化器(自适应学习率)
5.Adam优化器(自适应学习率)
**易受噪声影响:**如果有些样本标注是错误的,那就求得
的梯度方向可能与我们理想中的方向相悖
多了动量部分(除了加入自身的动量还会考虑上次的动量,一般动量系数取0.9
例如:
通常选择(SGD + Momentum +Adam)
主要还是看情况
学习大神的博客:pytorch中的卷积操作详解
pytorch中的Tensor通道排列顺序是:[batch, channel, height, width]
batch 训练样本的个数
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
in_channels参数代表输入特征矩阵的深度即channel,比如输入一张RGB彩色图像,那in_channels=3
out_channels参数代表卷积核的个数,使用n个卷积核输出的特征矩阵深度即channel就是n
kernel_size参数代表卷积核的尺寸,输入可以是int类型如3 代表卷积核的height=width=3,也可以是tuple类型如(3, 5)代表卷积核的height=3,width=5
stride参数代表卷积核的步距默认为1,和kernel_size一样输入可以是int类型,也可以是tuple类型
padding参数代表在输入特征矩阵四周补零的情况默认为0,同样输入可以为int型如1 代表上下方向各补一行0元素,左右方向各补一列0像素(即补一圈0),如果输入为tuple型如(2, 1) 代表在上方补两行下方补一行,左边补两列,右边补一列。
bias参数表示是否使用偏置默认使用
矩阵经卷积操作后的尺寸
N = (W − F + 2P ) / S + 1
入图片大小 W×W
Filter大小 F×F
步长 S
padding的像素数 P
则删除多余的行和列来保证卷积的输出尺寸为整数。
示例:
(1)首先使用torch中的随机函数生成一个batch_size为1,channel为1,高和宽都等于5的矩阵
(2)接着我们定义一个卷积核,input_size=1, output_size=1, kernel_size=2, stride=2, padding=1
(3)然后我们使用该卷积核对我们生成的随机矩阵进行卷积操作
(4)打印各参数的数值
import torch.nn as nn
import torch
im = torch.randn(1, 1, 5, 5)
c = nn.Conv2d(1, 1, kernel_size=2, stride=2, padding=1)
output = c(im)
print(im)
print(output)
print(list(c.parameters()))
计算得矩阵尺寸应该为N =(5 - 2 + 2*1)/ 2 +1 = 3.5
实际的打印信息如下: :
# im
tensor([[[[-0.2146, 0.3375, 2.7877, 0.2052, -0.4651],
[-0.2261, 0.0116, -0.6255, 1.2523, -1.0565],
[-1.9227, -0.2575, -0.7725, 0.5658, 0.0717],
[ 0.8153, -1.3656, -0.1844, 0.1573, -0.2235],
[ 0.0184, -0.0475, 0.2359, 0.0127, 2.0665]]]])
# output
tensor([[[[-0.0467, -1.1766, -0.0450],
[ 0.5063, 0.1971, -1.0401],
[-0.0748, 0.4769, -0.8986]]]], grad_fn=<ThnnConv2DBackward>)
# conv2d:parameters
[Parameter containing:
tensor([[[[-0.4872, 0.0604],
[-0.3968, -0.3317]]]], requires_grad=True), Parameter containing:
tensor([-0.1179], requires_grad=True)]
真正的输出矩阵尺寸是3x3
内部操作:
(1)首先进行padding的填充,size:7 x 7
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, -0.2146, 0.3375, 2.7877, 0.2052, -0.4651, 0.0000],
[0.0000, -0.2261, 0.0116, -0.6255, 1.2523, -1.0565, 0.0000],
[0.0000, -1.9227, -0.2575, -0.7725, 0.5658, 0.0717, 0.0000],
[0.0000, 0.8153, -1.3656, -0.1844, 0.1573, -0.2235, 0.0000],
[0.0000, 0.0184, -0.0475, 0.2359, 0.0127, 2.0665, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]
(2)通过计算发现输出为非整数,为了得到整数,将最后一行以及最后一列删除掉,size:6 x 6
[0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, -0.2146, 0.3375, 2.7877, 0.2052, -0.4651],
[0.0000, -0.2261, 0.0116, -0.6255, 1.2523, -1.0565],
[0.0000, -1.9227, -0.2575, -0.7725, 0.5658, 0.0717],
[0.0000, 0.8153, -1.3656, -0.1844, 0.1573, -0.2235],
[0.0000, 0.0184, -0.0475, 0.2359, 0.0127, 2.0665]
(3)接着使用卷积核进行卷积操作,就能得到我们的输出矩阵,需要注意的是pytorch中的卷积默认是带有bias的,所以计算卷积后需要加上bias偏量。例如输出的第一个值的计算过程如下:
[0.0000, 0.0000], [-0.4872, 0.0604],
卷积 加上 [-0.1179]
[0.0000, -0.2146] [-0.3968, -0.3317]
# 即
(0*(-0.4872)+ 0*(0.0604)+ 0*(-0.3968)+(-0.2146)*(-0.3317))+(-0.1179)= -0.0467
我们的计算结果与pytorch的输出相同,我们只计算了其中一个值,其他的值也一样:
# output
tensor([[[[-0.0467, -1.1766, -0.0450],
[ 0.5063, 0.1971, -1.0401],
[-0.0748, 0.4769, -0.8986]]]], grad_fn=<ThnnConv2DBackward>)
在pytorch的卷积过程中,当通过N = (W − F + 2P ) / S + 1计算式得到的输出尺寸非整数时,会通过删除多余的行和列来保证卷积的输出尺寸为整数。