1.视频和论文学习
MobileNet
MobileNet 所创建的目的是为了让深度学习网络在移动式或嵌入式设备中运行,其中MobileNet分为MobileNetV1、MobileNetV2、MobileNetV3,其中MobileNetV1的特点如下:
- 传统卷积:卷积核channel=输入特征矩阵channel;输出特征矩阵channel=卷积核个数
- DW卷积:卷积核channel=1;输入特征矩阵channel=卷积核个数=输出特殊矩阵chennl
所以经过dw卷积特征矩阵深度不会变化
Depthwise Separable conv深度可分卷积由DW卷积与PW卷积构成
PW卷积本质上是普通卷积,但卷积核为1
- 增加了两个超参数 α:控制卷积层卷积核个数 β:控制输入图像大小
- V1网络结构:
MobileNetV2特点:准确率更高模型更小
- Inverted Residuals 倒残差结构
- 结构相反和传统卷积比,这个先降维再升维
- Linear bottlenecks:针对倒残差结构的最后一个1x1卷积层用了线性激活函数,避免信息损失(relu在低维信息损失比较多)
- 更改了激活函数为 RELU6=min(max(x,0),6)
- stride =1且输入输出特征矩阵shape相同时,才有shortcut连接
MobileNetV3特点
- 更新block(benck)
- 使用NAS搜索参数
- 重新设计耗时层结构
ShuffleNet
ShuffleNet Unit中全是GConv和DWConv
在左侧的网络结构中:对于输入特征矩阵,有串行的GConv1和GConv2,对于普通的组卷积的计算,只针对该组内的channel的信息进行计算。组卷积虽然能够减少参数和计算量,但是组卷积中不同组之间的信息没有交流。为了解决这个问题,论文中提出了Channel Shuffle的概念。
对于右侧而言:将输入特征矩阵先通过GConv,得到对应的特征矩阵,然后对于GConv1假设采用3个组,即g=3,对于得到的特征矩阵继续划分,每个组序号相同的再分到一个组,就可以得到通过Channel Shuffle后的特征矩阵,再通过GConv2,得到输出特征矩阵。
ShuffleNet的性能指标:
ShuffleNet 0.5x版本虽然错误率与AlexNet差不多,但是它的推理时间较AlexNet少了很多。
而且ShuffleNet 2x版本与1.0 MobileNet-224推理时间相差不大,但是错误率更低。
由于1×1的卷积占用了绝大部分的计算量,ShuffleNetV1将其转换为GConv(a代表传统结构,b代表步长为1的结构,c代表步长为2的结构)
SENet
SENet通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征,特点如下:
SE 模块的示意图如下:
- Squeeze每个通道压成一个标量,一般可以用下采样
- 再做一个Excitation操作,可以用Fc层来完成
- 在乘到featuremap,作为这层的输出,传给下一层
上左图是将SE模块嵌入到Inception结构的一个示例。方框旁边的维度信息代表该层的输出。
用global average pooling 作为Squeeze 操作。紧接着两个Fully Connected 层组成一个Bottleneck结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的1/16 ,然后经过ReLu激活后再通过一个Fully Connected 层升回到原来的维度。 这样做比直接用一个Fully Connected 层的好处在于:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)极大地减少了参数量和计算量。然后通过一个Sigmoid的门获得0~1之间归一化的权重,最后通过一个Scale的操作来将归一化后的权重加权到每个通道的特征上。
除此之外,SE 模块还可以嵌入到含有skip-connections 的模块中。上右图是将SE 嵌入到ResNet模块中的一个例子,操作过程基本和SE-Inception一样,只不过是在Addition前对分支上Residual的特征进行了特征重标定。如果对Addition后主支上的特征进行重标定,由于在主干上存在0~1的scale操作,在网络较深BP优化时就会在靠近输入层容易出现梯度消散的情况,导致模型难以优化。
2.代码作业
HybridSN 高光谱分类
S. K. Roy, G. Krishna, S. R. Dubey, B. B. Chaudhuri HybridSN: Exploring 3-D–2-D CNN Feature Hierarchy for Hyperspectral Image Classification, IEEE GRSL 2020
这篇论文构建了一个 混合网络 解决高光谱图像分类问题,首先用 3D卷积,然后使用 2D卷积,代码相对简单,下面是代码的解析。
首先取得数据并规定具体python和wget版本号:
引入基本函数库:
1. 定义 HybridSN 类
三维卷积部分:
- conv1:(1, 30, 25, 25), 8个 7x3x3 的卷积核 ==>(8, 24, 23, 23)
- conv2:(8, 24, 23, 23), 16个 5x3x3 的卷积核 ==>(16, 20, 21, 21)
- conv3:(16, 20, 21, 21),32个 3x3x3 的卷积核 ==>(32, 18, 19, 19)
接下来要进行二维卷积,因此把前面的 32*18 reshape 一下,得到 (576, 19, 19)
二维卷积:(576, 19, 19) 64个 3x3 的卷积核,得到 (64, 17, 17)
接下来是一个 flatten 操作,变为 18496 维的向量,
接下来依次为256,128节点的全连接层,都使用比例为0.4的 Dropout,
最后输出为 16 个节点,是最终的分类类别数。
下面是 HybridSN 类的代码:
2. 创建数据集
首先对高光谱数据实施PCA降维;然后创建 keras 方便处理的数据格式;然后随机抽取 10% 数据做为训练集,剩余的做为测试集。
首先定义基本函数:
下面读取并创建数据集:
3. 开始训练
训练结果为下图所示:
4.模型测试
3.思考题
- 训练HybridSN,然后多测试几次,会发现每次分类的结果都不一样,请思考为什么?
nn.dropout()是为了防止或减轻过拟合而使用的函数,它一般用在全连接层 Dropout就是在不同的训练过程中随机扔掉一部分神经元。也就是让某个神经元的激活值以一定的概率p,让其停止工作,这次训练过程中不更新权值,也不参加神经网络的计算,它的随机性导致了每次结果不一样
- 如果想要进一步提升高光谱图像的分类性能,可以如何改进?
使用注意力机制来处理特征,进而提升高光谱图像的分类性能
- depth-wise conv 和 分组卷积有什么区别与联系?
分组卷积的参数量是常规卷积(Convolution)参数量的1/g, 其中g是分组数
DW卷积的参数量是常规卷积(Convolution)参数量的1/n, 其中n是卷积核个数
当分组卷积中的g=C_in, n=C_in时,DW==分组卷积
- 在 ShuffleNet 中,通道的 shuffle 如何用代码实现?
import torch
import torch.nn as nn
from torchstat import stat # 查看网络参数
def channel_shuffle(x, groups):
# 获取输入特征图的shape=[b,c,h,w]
batch_size, num_channels, height, width = x.size()
# 均分通道,获得每个组对应的通道数
channels_per_group = num_channels // groups
# 特征图shape调整 [b,c,h,w]==>[b,g,c_g,h,w]
x = x.view(batch_size, groups, channels_per_group, height, width)
# 维度调整 [b,g,c_g,h,w]==>[b,c_g,g,h,w];# 将调整后的tensor以连续值的形式保存在内存中
x = torch.transpose(x,1,2).contiguous()
# 将调整后的通道拼接回去 [b,c_g,g,h,w]==>[b,c,h,w]
x = x.view(batch_size, -1, height, width)
# 完成通道重排
return x