pytorch中根据神经网络结构确定输入图片尺寸(根据图片尺寸修改神经网络结构)

在学习pytorch的过程中,看到一些代码的解释中会说这个网络的期望输入大小为32x32(也可能是其他数字),请将输入图片调整为32x32。 开始的时候有一些不解,仔细看代码后明白,为代码条理清晰,一些神经网络结构事先被定义好,当卷积神经网络中包含有全连接层时,由于全连接层被设置为是固定尺寸的输入输出,全连接层的输入与输入图像尺寸息息相关,故定义好网络结构后,输入图像尺寸亦随之确定。 所以在用pytorch编写神经网络结构时,尤其是卷积神经网络,要特别注意输入图像的尺寸,如果想套用某个网络结构,需要先通过网络结构计算出输入图像尺寸,将自己的图像调整为所需要的尺寸;当然还可以根据自己的图像尺寸适当调整网络结构。以下是具体操作方法。

分析神经网络结构

示例:

class ConvNet(nn.Module):
    def __init__(self):
        super().__init__()
        # 1,28x28
        self.conv1=nn.Conv2d(1,10,5) # 24x24
        self.pool = nn.MaxPool2d(2,2) # 12x12
        self.conv2=nn.Conv2d(10,20,3) # 10x10
        self.fc1 = nn.Linear(20*10*10,500)
        self.fc2 = nn.Linear(500,10)
    def forward(self,x):
        in_size = x.size(0)
        out = self.conv1(x) #24
        out = F.relu(out)
        out = self.pool(out)  #12
        out = self.conv2(out) #10
        out = F.relu(out)
        out = out.view(in_size,-1)
        out = self.fc1(out)
        out = F.relu(out)
        out = self.fc2(out)
        out = F.log_softmax(out,dim=1)
        return out

在写代码时,尽量将每一层的输入输出尺寸标注出来,以便后续阅读。
首先介绍Conv2d、max_pool2d的参数:
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, 
dilation=1, groups=1, bias=True)

in_channels:输入通道数
out_channels:输出通道数(卷积核的个数)
kernel_size:卷积核的尺寸
stride:卷积步长(默认值为1)
padding:输入在每一条边补充0的层数(默认不补充)
dilation:卷积核元素之间的间距(默认值为1)
groups:从输入通道到输出通道的阻塞连接数(默认值是1)
bias:是否添加偏置(默认是True)

torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)


kernel_size:池化的窗口大小
stride:窗口移动的步长,默认值是kernel_size
padding:输入的每一条边补充0的层数
dilation:一个控制窗口中元素步幅的参数
return_indices:如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
ceil_mode:如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作
接下来通过网络结构分析每层输出尺寸大小:
重要公式:边长为n的图像,经过卷积核尺寸大小为k,步长为s的卷积,得到边长为1+(n-k)/s的图像

举例说明:
分析一下代码的输出尺寸:

class ConvNet(nn.Module):
    def __init__(self):
        super().__init__()
        # 1,28x28
        self.conv1=nn.Conv2d(1,10,5) # 24x24
        self.pool = nn.MaxPool2d(2,2) # 12x12
        self.conv2=nn.Conv2d(10,20,3) # 10x10
        self.fc1 = nn.Linear(20*10*10,500)
        self.fc2 = nn.Linear(500,10)
   def forward(self,x):
        in_size = x.size(0)
        out = self.conv1(x) #24
        out = F.relu(out)
        out = self.pool(out)  #12
        out = self.conv2(out) #10
        out = F.relu(out)
        out = out.view(in_size,-1)
        out = self.fc1(out)
        out = F.relu(out)
        out = self.fc2(out)
        out = F.log_softmax(out,dim=1)
        return out

为了清晰分析,在编写神经网络结构的代码时,最好将会使输入输出改变的结构(例如本例的卷积层和池化层),在前面定义出来。 如果读别人已写好的代码时,一定要结合前向传播的结构来分析,不能只看代码的上面部分,因为神经网络的结构中,可能还含有其他能改变图像尺寸的结构。在上述代码中,只有以下代码部分会改变输出图像尺寸大小。

        # 1,28x28
        self.conv1=nn.Conv2d(1,10,5) # 24x24
        self.pool = nn.MaxPool2d(2,2) # 12x12
        self.conv2=nn.Conv2d(10,20,3) # 10x10
        self.fc1 = nn.Linear(20*10*10,500)
        self.fc2 = nn.Linear(500,10)

假设输入图像尺寸为28x28
第一层卷积卷积核尺寸大小为5x5,步长为1。所以输出图像尺寸:1+(28-5)/1=24
即代码第二行注释标注:经过第一层卷积层后,输出图像尺寸变为24x24
同理,在池化层,池化窗口大小为2x2,移动步长为2,所以经过池化层后,输出图像尺寸变为12x12
第二层卷积尺寸大小为3x3,步长为1,所以输出图像尺寸:1+(12-3)/1=10
经过第二层卷积后,输出图像尺寸为10x10,输出维度为20,所以全连接层的输入固定为201010
所以此网络只接受输入图像尺寸为28x28。
如果,不想改变输入图像的尺寸,可以通过以上步骤,计算出全连接层的输入,适当改变神经网络结构,已达到理想的效果。
现在很多卷积神经网络模型,都用卷积层替代全连接层,就是因为这个原因。因为全连接层的参数的尺寸与输入图像的尺寸有关,故输入图像尺寸改变,模型参数初始化尺寸亦改变。若采用卷积层替代全连接层,则输入图像尺寸改变,模型不用做任何改变。
————————————————
转载自:https://blog.csdn.net/weixin_43423455/article/details/99096580

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值