1、卷积层
1.1 Convolution
1.1.1 卷积操作
- 卷积运算:卷积核在输入信号(图像)上滑动,相应位置上进行乘加
- 卷积核:又称为滤波器、过滤器,可认为是某种模式、某种特征
1.1.2 卷积维度
一般情况下,卷积核在几个维度上滑动就是几维卷积
- 一维卷积
- 二维卷积
- 三维卷积
1.2 nn.Conv2d
# nn.Conv2d(
# in_channels,
# out_channels,
# kernel_size,
# stride=1,
# padding=0,
# dilation=1,
# groups=1,
# bias=True,
# padding_mode='zeros'
# )
1.2.1 基本介绍
功能:对多个二维信号进行二维卷积
主要参数:
in_channels
:输入通道数out_channels
:输出通道数,等价于卷积核个数kernel_size
:卷积核尺寸stride
:步长padding
:填充个数dilation
:空洞卷积大小groups
:分组卷积设置,默认为1,即不分组bias
:是否使用偏置
尺寸计算:
H o u t = ⌊ H i n + 2 × p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 s t r i d e [ 0 ] + 1 ⌋ H_{out} = \lfloor \frac{H_{in} + 2 \times padding[0] - dilation[0] \times (kernel\_size[0] - 1) - 1}{stride[0]} + 1 \rfloor Hout=⌊stride[0]Hin+2×padding[0]−dilation[0]×(kernel_size[0]−1)−1+1⌋
1.2.2 代码框架
conv_layer = nn.Conv2d(3, 1, 3) # input:(i, o, size) weights:(o, i , h, w)
nn.init.xavier_normal_(conv_layer.weight.data)
img_conv = conv_layer(img_tensor)
1.3 nn.ConvTranspose
# nn.ConvTranspose(
# in_channels,
# out_channels,
# kernel_size,
# stride=1,
# padding=0,
# output_padding=0,
# groups=1,
# bias=True,
# dilation=1,
# padding_mode='zeros'
# )
1.3.1 基本介绍
功能:用于对图像进行上采样
对比:
- 正常卷积:假设图像尺寸为4×4,卷积核为3×3,padding=0,stride=1,
则图像: I 16 ∗ 1 I_{16*1} I16∗1,卷积核: K 4 ∗ 16 K_{4*16} K4∗16,输出: O 4 ∗ 1 = K 4 ∗ 16 × I 16 ∗ 1 O_{4*1}=K_{4*16}×I_{16*1} O4∗1=K4∗16×I16∗1 - 转置卷积:假设图像尺寸为2×2,卷积核为3×3,padding=0,stride=1,
则图像: I 4 ∗ 1 I_{4*1} I4∗1,卷积核: K 16 ∗ 4 K_{16*4} K16∗4,输出: O 16 ∗ 1 = K 16 ∗ 4 × I 4 ∗ 1 O_{16*1}=K_{16*4}×I_{4*1} O16∗1=K16∗4×I4∗1
主要参数:
in_channels
:输入通道数out_channels
:输出通道数kernel_size
:卷积核大小stride
:步长padding
:填充dilation
:空洞卷积大小groups
:分组卷积bias
:是否使用偏置
尺寸计算: H o u t = ( H i n − 1 ) × s t r i d e [ 0 ] − 2 × p a d d i n g [ 0 ] + d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) + o u t p u t _ p a d d i n g [ 0 ] + 1 H_{out} = (H_{in} - 1) \times stride[0] - 2 \times padding[0] + dilation[0] \times (kernel\_size[0] - 1) + output\_padding[0] + 1 Hout=(Hin−1)×stride[0]−2×padding[0]+dilation[0]×(kernel_size[0]−1)+output_padding[0]+1
1.3.2 代码框架
conv_layer = nn.ConvTranspose2d(3, 1, 3, stride=2) # input:(i, o, size)
nn.init.xavier_normal_(conv_layer.weight.data)
img_conv = conv_layer(img_tensor)
2、池化层
2.1 概念
对信息进行收集并总结,类似水池收集水资源,因而得名池化层
- 收集:多变少
- 总结:最大值/平均值
2.2 nn.MaxPool2d
# nn.MaxPool2d(
# kernel_size,
# stride=None,
# padding=0,
# dilation=1,
# return_indices=False,
# ceil_mode=False,
# )
2.2.1 基本介绍
功能:对二维信号(图像)进行最大值池化
主要参数:
kernel_size
:池化核大小stride
:步长padding
:填充dilation
:池化核间隔大小return_indices
:是否返回最大值索引ceil_mode
:是否向上取整
2.2.2 代码框架
MaxPool2d
maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2)) # input:(i, o, size) weights:(o, i , h, w)
img_pool = maxpool_layer(img_tensor)
MaxPool2d
unpool
# pooling
img_tensor = torch.randint(high=5, size=(1, 1, 4, 4), dtype=torch.float)
maxpool_layer = nn.MaxPool2d((2, 2), stride=(2, 2), return_indices=True)
img_pool, indices = maxpool_layer(img_tensor)
# unpooling
img_reconstruct = torch.randn_like(img_pool, dtype=torch.float)
maxunpool_layer = nn.MaxUnpool2d((2, 2), stride=(2, 2))
img_unpool = maxunpool_layer(img_reconstruct, indices)
2.3 nn.AvgPool2d
# nn.AvgPool2d(
# kernel_size,
# stride=None,
# padding=0,
# ceil_mode=False,
# count_include_pad=True,
# divisor_override=None
# )
2.3.1 基本介绍
功能:对二维信号(图像)进行平均值池化
主要参数:
kernel_size
:池化核大小stride
:步长padding
:填充ceil_mode
:是否向上取整count_include_pad
:是否包含填充的像素divisor_override
:除数重写
2.3.2 代码框架
AvgPool2d
avgpoollayer = nn.AvgPool2d((2, 2), stride=(2, 2)) # input:(i, o, size) weights:(o, i , h, w)
img_pool = avgpoollayer(img_tensor)
AvgPool2d
divisor_override
img_tensor = torch.ones((1, 1, 4, 4))
avgpool_layer = nn.AvgPool2d((2, 2), stride=(2, 2), divisor_override=3)
img_pool = avgpool_layer(img_tensor)
3、线性层
3.1 概念
又称全连接层,其每个神经元与上一层所有神经元相连实现对前一层的线性组合、线性变换
3.2 nn.Linear
# nn.Linear(
# in_features,
# out_features,
# bias=True
# )
3.2.1 基本介绍
功能:对一维信号(向量)进行线性组合
主要参数:
in_features
:输入结点数out_features
:输出结点数bias
:是否使用偏置
计算公式: y = x W T + b i a s y = xW^T + bias y=xWT+bias
3.2.2 代码框架
inputs = torch.tensor([[1., 2, 3]])
linear_layer = nn.Linear(3, 4)
linear_layer.weight.data = torch.tensor([[1., 1., 1.],
[2., 2., 2.],
[3., 3., 3.],
[4., 4., 4.]])
linear_layer.bias.data.fill_(0.5)
output = linear_layer(inputs)
4、激活函数层
4.1 nn.Sigmoid
计算公式: y = 1 1 + e − x y = \frac{1}{1 + e^{-x}} y=1+e−x1
梯度公式: y ‘ = y × ( 1 − y ) y^{`} = y \times (1 - y) y‘=y×(1−y)
特性:
- 输出值在(0, 1),符合概率
- 导数范围是[0, 0.25],易导致梯度消失
- 输出为非0,破坏数据分布
4.2 nn.tanh
计算公式: y = s i n x c o s x = e x − e − x e − + e − x = 2 1 + e − 2 x + 1 y = \frac{sinx}{cosx} = \frac{e^x - e^{-x}}{e^{-} + e^{-x}} = \frac{2}{1 + e^{-2x}} + 1 y=cosxsinx=e−+e−xex−e−x=1+e−2x2+1
梯度公式: y ‘ = 1 − y 2 y^{`} = 1 - y^2 y‘=1−y2
特性:
- 输出值在(-1, 1),数据符合0均值
- 导数范围是(0, 1),易导致梯度消失
4.3 nn.ReLU
计算公式: y = m a x ( 0 , x ) y = max(0, x) y=max(0,x)
梯度公式:
y ′ = { 1 , x > 0 undefined , x = 0 0 , x < 0 y' = \begin{cases} 1, & x > 0 \\ \text{undefined}, & x = 0 \\ 0, & x < 0 \end{cases} y′=⎩
⎨
⎧1,undefined,0,x>0x=0x<0
特性:
- 输出值均为正数,负半轴导致死神经元
- 导数是1,缓解梯度消失,但易引发梯度爆炸
4.3.1 nn.LeakuReLU
negative_slope
: 负斜率的值,默认为0.01,即负斜率
4.3.2 nn.PReLU
init
:可学习斜率
4.3.3 nn.RReLU
lower
:均匀分布下限upper
:均匀分布上限
微语录:黑暗中有人擎花而来,惊动火焰,燃烧万千蝴蝶迷了眼。