Pytorch神经网络设计技巧-如何得到各层的input shape

当设计神经网络时,常常被每层的input shape所烦恼,计算也很恼人。
在使用pytorch设计的时候,有两种方法能够协助你进行输入维度的设置。

方法一:懒加载(nn.Lazy**)

Pytorch 提供了各个常用层的Lazy版本,类似于懒加载的思想
这些层有懒初始化(lazy initialization)的机制,在使用时不用显示指定input shape
它们会在第一次前向传播的时候获取输入数据的shape来初始化自己的input shape
省去人工计算input shape的操作。
在这里插入图片描述

方法二:利用前向传播调试

懒初始化是Pytorch比较新的特性,官方也提示后续会对懒初始化机制进行不断地完善。
如果坚持使用不带lazy的层,可以在设计的时候给一个输入数据
让数据在网络中进行一次前向传播,打印每个层输出的shape:

# 生成1幅单通道的224*224大小的随机图像
X = torch.randn(1, 1, 224, 224)
# 这里的net是nn.Sequential类型,里面包含了各个layer,它是可迭代的结构。
net = nn.Sequential(
    nn.Conv2d(in_channels=1, out_channels=96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, padding=2), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Flatten(),
    nn.Linear(in_features=6400, out_features=4096) , nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(in_features=4096, out_features=4096) , nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(in_features=4096, out_features=10)
)
for layer in net:
    X=layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)

此外,如果你的net是继承自nn.Module的类实例,可以设置一个类型为nn.Sequential的成员变量封装各个layer,然后for循环来遍历这个成员变量,本质是一样的:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(in_channels=1, out_channels=96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(in_channels=96, out_channels=256, kernel_size=5, padding=2), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(in_channels=256, out_channels=384, kernel_size=3, padding=1), nn.ReLU(),
            nn.Conv2d(in_channels=384, out_channels=384, kernel_size=3, padding=1), nn.ReLU(),
            nn.Conv2d(in_channels=384, out_channels=256, kernel_size=3, padding=1), nn.ReLU(),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Flatten(),
            nn.Linear(in_features=6400, out_features=4096), nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(in_features=4096, out_features=4096), nn.ReLU(),
            nn.Dropout(p=0.5),
            nn.Linear(in_features=4096, out_features=10)
        )
    def forward(self, x):
        return self.layers(x)
net = Net()
X = torch.randn(1, 1, 224, 224)
for layer in net.layers:
    X = layer(X)
    print(layer.__class__.__name__, 'output shape:\t', X.shape)

最终输出是一样的(输出有点长,这里就放部分的截图):
在这里插入图片描述
这样就可以根据输出的shape来设计和添加合适的层了。

参考:

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值