一些知识点
- 在深度学习训练后,需要计算每个epoch得到的模型的训练效果的时候,一般会用到**Tensor.**detach() item() cpu() numpy()等函数。
摘录自pytorch detach() item() cpu() numpy()理解
-
item()返回的是tensor中的值,且只能返回单个值(标量),不能返回向量,使用返回loss等。
-
detach阻断反向传播,返回值仍为tensor。
-
cpu()将变量放在cpu上,仍为tensor。注意cuda上面的变量类型只能是tensor,不能是其他。
-
numpy()将tensor转换为numpy。
-
用plt画图时,要将Tensor转换为numpy。即用
Tensor.numpy()
转换。 -
TensorFlow使用静态图,PyTroch使用动态图,所以PyTroch可以随时看到结果。
-
torch.unsqueeze() 的作用是将一维变二维,torch只能处理二维的数据。
-
BN批量归一化 nn.BatchNorm1d(num_features=16)
- BN是对隐藏层的标准化处理,它与输入的标准化处理Normalizing Inputs是有区别的。
- Normalizing Inputs是使所有输入的均值为0,方差为1。而Batch Normalization可使各隐藏层输入的均值和方差为任意值。
- BN应作用在非线性映射前,即对x=Wu+b做规范化时,在每一个全连接和激励函数之间。
- 收敛速度很慢,或梯度爆炸等无法训练。加快训练速度,提高模型精度。
- 激活函数
- 输入维度与输出维度是一样的。
- 激活函数的输入维度一般包括批量数N,即输入数据的维度一般是4维,如(N,C,W,H)。
- 搭建比较深的神经网络时,一般使用relu激活函数(LeakyReLu)。
- softmax常用于多分类神经网络输出层。
- 损失函数
- 损失函数对每个参数的偏导数就是梯度下降中提到的梯度,防止过拟合时添加的正则化项也是加在损失函数后面。
- 在机器学习中常用的损失函数有两种:
- 分类问题 —— 交叉熵(Cross Entropy)。反应的两个概率分布的距离(不是欧氏距离)。
- 又称对数似然损失、对数损失(Log-likelihood Loss)
- 二分类时还可称之为逻辑回归损失(Logistic Loss)。
- 因为交叉熵描述了两个概率分布的差异,然而神经网络输出的是向量,并不是概率分布的形式。所以需要softmax激活函数将一个向量进行“归一化”成概率分布的形式,再采用交叉熵损失函数计算loss。
- 在多分类任务中,经常采用
softmax激活函数+交叉熵损失函数
。 loss = nn.CrossEntropyLoss()
- 回归问题 —— 均方误差(Mean squared error,MSE)。回归问题预测的不是类别,而是一个任意实数。在神经网络中一般只有一个输出节点,该输出值就是预测值。反应的预测值与实际值之间的距离可以用欧氏距离来表示。
loss = nn.MSELoss(reduction='mean')
# reduction=‘mean’(default)、‘sum’、‘none’。如果取’sum’,则 只是差平方的和,但不会除以n。
- 优化器
- RMSprop、Adadelta和Adam被认为是自适应优化算法,因为它们会自动更新学习率。而使用SGD时,必须手动选择学习率和动量参数,通常会随着时间的推移而降低学习率。
- 可以考虑综合使用这些优化算法。
Adam + (SGD+动量优化)
- 先使用Adam优化算法来进行训练,这将大大地节省训练时间,且不必担心初始化和参数调整;
- 一旦用Adam训练获得较好的参数后,就可以切换到SGD+动量优化,以达到最佳性能。
卷积神经网络CNN
由卷积层(nn.Conv2d)、池化层(nn.MaxPool2d)和全连接层(nn.Linear)等叠加而成。
- nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1) # 步长默认为1
- nn.MaxPool2d(kernel_size=2, stride=2) # 当之传入一个参数时,stride默认等于kernel_size
- nn.Linear(in_dim=1296, out_dim=128)
卷积核 kernel
- 卷积核(kernel)又称权重过滤器,简称为过滤器(filter),是整个卷积过程的核心。
- 卷积核一般是奇数阶矩阵
- 比较简单的卷积核或过滤器有:
- Horizontalfilter:检测图像的水平边缘。其特点是有值的是第1行和第3行,第2行为0。
- Verticalfilter:检测图像的垂直边缘。其特点是有值的是第1列和第3列,第2列为0。
- Sobel Filter:增强图像中心区域权重。
- 过滤器如何确定呢?
过滤器类似于标准神经网络中的权重矩阵W,W需要通过梯度下降算法反复迭代求得。同样,在深度学习学习中,过滤器也是需要通过模型训练来得到的。卷积神经网络主要目的就是计算出这些filter的数值。确定得到了这些filter后,卷积神经网络的浅层网络也就实现了对图像所有边缘特征的检测。 - 参数共享。卷积核的值在整个过程中都是共享的,所以又把卷积核的值称为共享变量。卷积神经网络采用参数共享的方法大大降低了参数的数量。
步长 strides
- 卷积核在窗口中每次移动的格数(无论是自左向右移动,或自上向下移动)称为步幅(strides)。
- 在用PyTorch具体实现时,strides参数格式为单个整数或两个整数的元组。
填充 Padding
-
当输入图片与卷积核不匹配时或卷积核超过图片边界时,可以采用边界填充(Padding)的方法。根据是否扩展Padding又分为Same、Valid:
-
采用Same方式时,对图片扩展并补0;
-
采用Valid方式时,不对图片进行扩展。
-
那如何选择呢?在实际训练过程中,一般选择Same方式,使用Same不会丢失信息。
-
设补0的圈数为p,输入数据大小为n,过滤器大小为f,步幅大小为s,则有:
-
$ p=\frac{f-1}{2} $ (可能有这些规则:1.如果不能整除,就取整数。2.当设为valid时,p=0)
-
卷积后的大小为:$ \frac{n-f+2p}{s}+1 $
激活函数 nn.ReLU()
常用的激活函数有:nn.Sigmoid、nn.ReLU、nn.LeakyReLU、nn.Tanh
卷积函数 nn.Conv2d()
- nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1, padding=0) # 步长默认为1,填充默认为0.
- 输入、输出(注意:第一个维度是批量大小,卷积过程中不会改变)
- Input:( N N N, C i n C_{in} Cin, H i n H_{in} Hin, W i n W_{in} Win )
- Output:( N N N, C o u t C_{out} Cout, H o u t H_{out} Hout, W o u t W_{out} Wout )
转置卷积函数 nn.ConvTranspose2d()
- 转置卷积(Transposed Convolution)在一些文献中也称为反卷积(Deconvolution)或部分跨越卷积(Fractionally-Strided Convolution)。
- 通过卷积的正向传播的图像一般越来越小,记为下采样(Downsampled)。
- 卷积的反向传播实际上就是一种转置卷积,它是上采样(Up-Sampling)。(图像就会越来越大)
- torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0)
池化 Pooling
-
池化(Pooling)又称下采样。降采样:保留显著特征、降低特征维度、增大感受野、减小尺寸。
-
最大池化比其他池化方法更常用。
-
常用的3种池化方式
-
最大池化
nn.MaxPool2d(kernel_size, strides)
:选择Pooling窗口中的最大值作为采样值。 -
均值池化
nn.AvgPool2d(kernel_size, strides)
:将Pooling窗口中的所有值相加取平均,以平均值作为采样值。 -
全局最大(或均值)池化:与平常最大或最小池化相对而言,全局池化是对整个特征图(feature map)的池化而不是在移动窗口范围内的池化。PyTorch虽然没有对应名称的池化层,但可以使用PyTorch中的自适应池化层来分别实现全局平均池化、全局最大池化。
- 全局平均池化(Global Average Pooling,GAP),不以窗口的形式取均值,而是以特征图为单位进行均值化,即一个特征图输出一个值。
- 使用全局平均池化代替CNN中传统的全连接层。目前卷积网络中最后几个全连接层,大都用GAP替换。
nn.AdaptiveAvgPool2d(1)
- 全局最大池化
AdaptiveMaxPool2d(1)
- 全局平均池化(Global Average Pooling,GAP),不以窗口的形式取均值,而是以特征图为单位进行均值化,即一个特征图输出一个值。