<1> increase_resolution()函数中修改resnet18步长的问题:
def increase_resolution(self):
"""论文第6页提到:为了更精确的定位,ResNet的最后两个块的步长被降低到一个像素,提供更高的输出分辨率。"""
global OUT_HEIGHT, OUT_WIDTH
# 为什么传入的是一个tuple(1,1)
# 对于Conv2d()中的stride而言,传入int类型的1意为在h和w两个维度上的步长都为1
# 传入tuple类型的(2,1)意为在h维度上的步长为2,w维度上的步长为1
self.basemodel.layer3[0].conv1.stride = (1,1)
self.basemodel.layer3[0].downsample[0].stride=(1,1)
self.basemodel.layer4[0].conv1.stride = (1,1)
self.basemodel.layer4[0].downsample[0].stride=(1,1)
OUT_HEIGHT *= 4
OUT_WIDTH *= 4
# 打印结果应当为:32×56
print("using high resolution output ({}x{})".format(OUT_HEIGHT,OUT_WIDTH))
<2>warnings库
import warnings
warnings.warn('Something you want to say.')
<3>卷积输出特征图算出来是小数
输入图像为224×224×3,送入3×3卷积层,padding=1,stride=2,按照计算公式可以发现输出特征图的高和宽都不是整数,这种情况下,我们对商进行上下取整,即输出特征图的尺寸为112×112。这种思路其实就是当卷积核在特征图上滑动时,若滑动覆盖区域(即感受野)不全位于特征图内时,不再进行卷积操作。
<4>nn.Module中parameters()方法和named_parameters()方法
前者返回的仅仅是一个参数迭代器;后者返回的是一个tuple,既包含网络层的名称也包含网络层参数迭代器。parameter()返回的其实是named_parameters()返回的一部分,即仅仅是参数迭代器部分。
import torchvision.models as models
model = models.resnet18().cuda()
for param in model.named_parameters():
print(type(param))
print(type(param[0]))
print(type(param[1]))
print('-'*20)
# 运行结果
# <class tuple>
# <class 'str'>
# <class 'torch.nn.parameter.Parameter'>
个人理解是,model.named_parameters()返回的是一个大元组,里面包含很多小元组,param每次遍历的就是每个小元组,即((name1,para1), (name2,para2), (name3,para3),.......)。