文章目录
- 1 DownSample下采样部分
- 1.1 两种实现方式
- 1.2 代码实现
- 2 UpSample上采样部分
- 2.1 代码实现
1 DownSample下采样部分
1.1 两种实现方式
下采样,即改变特征图的尺寸
下采样的话源码实现了两种方式
- 方式一:是通过卷积实现下采样,我们知道卷积操作天然就有改变特征图的效果
- 方式二:是通过平均池化层实现下采样
方式一的话会增加参数
方式二的话是没有参数的
这两种是可以选择的
一般情况下
- 如果我们感觉模型的能力不强,可以用带参数的卷积的方式做下采样
- 如果我们感觉模型的能力比较强,可以用不带参数的池化做下采样,防止过拟合
上采样也是同样的道理
1.2 代码实现
这里注意一点,我们在实现过程中,用了非对称的填充
class Downsample(nn.Module):def __init__(self, in_channels, with_conv):super().__init__()self.with_conv = with_convif self.with_conv:# 非对称填充,必须我们自己来做self.conv = torch.nn.Conv2d(in_channels,in_channels,kernel_size=3,stride=2,padding=0)def forward(self, x):if self.with_conv:pad = (0,1,0,1)x = torch.nn.functional.pad(x, pad, mode="constant", value=0)#进行填充,填充的值为0x = self.conv(x)else:x = torch.nn.functional.avg_pool2d(x, kernel_size=2, stride=2)return x
即第15,16行
这是因为这个网络在设计的过程中,尽量维持卷积核尺寸大小统一且是奇数(这里是3),所以假设我们直接用卷积核自带的填充,则默认是对称填充,则会导致不能整除而出错
举例如下假设输入尺寸图大小128*128,则对称填充后,会变为130
最后输出尺寸大小为(公式 $ \frac{特征图长或宽+2*填充尺寸-卷积核尺寸}{步长}+1$)
130 − 3 2 + 1 \frac{130-3}{2}+1 2130−3+1 有没有发现左边不能整除
这时候我们只需要填充一侧(非对称填充)填充完后,尺寸大小是129
129 − 3 2 + 1 = 64 \frac{129-3}{2}+1=64 2129−3+1=64
2 UpSample上采样部分
上采样即改变特征图大小为原本的2倍
用插值(最近邻)的方式实现上采样
2.1 代码实现
class Upsample(nn.Module):def __init__(self, in_channels, with_conv):super().__init__()self.with_conv = with_convif self.with_conv:self.conv = torch.nn.Conv2d(in_channels,in_channels,kernel_size=3,stride=1,padding=1)def forward(self, x):x = torch.nn.functional.interpolate(x, scale_factor=2.0, mode="nearest")if self.with_conv:x = self.conv(x)return x
这里的上采样方式比较简单,通过插值实现的
而之前有些工作是通过转置卷积实现的