一位深度学习小萌新的学渣笔记(一)神经网络原理理解+pytorch框架理解

软工大二学生,在暑假期间申报项目,7月份开始学习,学习的项目关系到神经网络和注意力机制

自学python

首先通过廖雪峰老师的网站自学了python


简单了解神经网络

学习所需知识
知识

配置开发环境
Anaconda3
python3.7&3.8
pycharm 2020.2版本
pytorch 1.6

下载pytorch :可以通过先下载anaconda,在此环境下进行下载pytorch,使用清华镜像源,利用Re:从零开始的Pytorch官方入门新手教程!!进行大概的下载学习,后来发现pytorch没有下载成功,就进行再次下载在win10终端下载一分钟pytorch
下载pycharm 直接把破解包拖入pycharm中即可使用

通过大神的视频自学
卷积神经网络基础

卷积神经网络基础补充

1.全连接层

在这里插入图片描述
BP算法包括信号的前向传播和误差的反向传播
计算误差是按输入到输出的方向进行,而调整权值和阈值则从输出到输入的方向进行。


输入层:输出层:

2.卷积层

在这里插入图片描述
特点:

  • 局部感知机制
  • 权值共享

    值得注意:
  • 卷积核的channel(深度)与输入特征层的channel相同
  • 输出的特证矩阵channel与卷积核个数相同

三个问题:

加上偏移量bias该如何计算?

如果卷积核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

3.池化层

目的:对特征图进行稀疏处理,减少数据运算量
MaxPooling下采样层(得到每个的最大值)
在这里插入图片描述
AveragePooling下采样层(得到每一个的平均值)
特点:
没有任何的训练参数
只改变特征矩阵的高度和宽度,不改变深度
一般poolsize(池化核大小)和stride(步长)相同

4.误差的计算

以三个层的BP神经网络实例:

输入层X1,X2
中间是隐层设置三个结点:w
代表权重

在这里插入图片描述

代表激活函数

隐层的输出:

用激活函数
在这里插入图片描述

y1和y2的输出公式:


y1与y2的计算同样是上一层隐层的输出运算类似,同样是上一层输出的值 * 权重w + 偏置b
但是没有用到激活函数

softmax的激活函数

因为y1 y2 的输出概率分布,所以使用softmax激活函数使其拥有概率分布的特点
在这里插入图片描述
在这里插入图片描述
在这里按照实示例得到o1和o2的函数在这里插入图片描述
经过softmax处理后的所有输出节点概率和为1

Cross entrop loss交叉熵损失

在这里插入图片描述

用什么公式计算交叉熵就是看激活函数是什么

注意softmax和sigmoid函数各自的特点!

两者之间的差别:

Softmax:

输出概率和为1
示例:Softmax的输出是属于是不是狗狗(输出只归于一个类别)

Signmoid:

每个输出节点互不相干
示例:Signmoid输出是人类和男人(可能同时属于同一个类别)

本示例中Loss的计算

5.误差的反向传播

以w11为例,讲解如何进行误差的反向传播

LOSS求偏导

已经得到Loss 、o1,o2,y1,y2
Loss对w11求偏导在这里插入图片描述
具体计算过程:a1是指在这里插入图片描述
具体计算:
在这里插入图片描述
代入Loss对w11的求偏导的公式中:
在这里插入图片描述
相当于我们把我们所得到的误差传播到了每一个结点,得到了每个结点的损失梯度

6.权重的更新

更新权重的公式1

learning(是自己设置的学习率)*损失梯度
在这里插入图片描述

这个方向还不是减少损失最快的方向、最优的方向

理想中在这里插入图片描述
现实:常用的卷积(Conv2d)在pytorch中对应的函数是:在这里插入图片描述
做法:在这里插入图片描述
重点是分批次,不能一次性将数据载入,分批次的话,每一次都是实现局部最优

更新权重的工具-优化器

希望网络可以更快的收敛
会用到优化器optimazer
1.SGD优化器
2.SGD+Momentum优化器
3.Adagrad优化器
4.RMSProp优化器(自适应学习率)
5.Adam优化器(自适应学习率)

1. SGD优化器

**易受噪声影响:**如果有些样本标注是错误的,那就求得
的梯度方向可能与我们理想中的方向相悖

**局部最优解:**如果方向错误 就可能得到局部最优解在这里插入图片描述

2.SGD+Momentum优化器

在这里插入图片描述
多了动量部分(除了加入自身的动量还会考虑上次的动量,一般动量系数取0.9
例如:在这里插入图片描述

3.Adagrad优化器(自适应学习率)

在这里插入图片描述

4.RMSProp优化器(自适应学习率)

在这里插入图片描述

5.Adam优化器(自适应学习率)

在这里插入图片描述

优化器之间的对比
  • SGD(慢 最有解)
  • Momentum (偏 找的回正确路径)
  • Adagrad(快且正确)
  • Rmsprop(快且正确)
最优组合

通常选择(SGD + Momentum +Adam)
主要还是看情况

pytorch中的卷积操作详解

学习大神的博客:pytorch中的卷积操作详解

池化层:

Tensor通道

pytorch中的Tensor通道排列顺序是:[batch, channel, height, width]
batch 训练样本的个数

卷积层:

Conv2d函数

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')
  • 1

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

如果N出现非整数的情况

删除多余的行和列来保证卷积的输出尺寸为整数。

示例:
(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)]
``
计算得矩阵尺寸应该为N =(5 - 2 + 2*1)/ 2 +1 = 3.5
实际的打印信息如下:

真正的输出矩阵尺寸是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=)

在pytorch的卷积过程中,当通过N = (W − F + 2P ) / S + 1计算式得到的输出尺寸非整数时,会通过删除多余的行和列来保证卷积的输出尺寸为整数。
2赞
粤 ICP 备 2020080455 号