我加载了一个自定义的PyTorch模型,我想找出它的输入形状。就像这样:
model.input_shape
能否获取这些信息?
更新: print()
和 summary()
不显示此模型的输入形状,因此它们不是我要找的内容。
我加载了一个自定义的PyTorch模型,我想找出它的输入形状。就像这样:
model.input_shape
能否获取这些信息?
更新: print()
和 summary()
不显示此模型的输入形状,因此它们不是我要找的内容。
PyTorch模型非常灵活,甚至不强制或通常不期望数据具有固定的输入形状。
如果您有某些层,则可能会存在约束条件,例如:
但正如您所看到的,这两者都没有强制执行数据的 总体 形状。
我们现在可能还没有意识到,但在更复杂的模型中,正确设置第一个线性层的大小有时会引起沮丧。我们听说过著名从业者输入任意数字,然后依靠PyTorch的错误消息来回溯其线性层的正确大小。没错,它是完全合法的!
如果您的模型的第一层是全连接层,则print(model)
中的第一层将详细说明单个样本的期望维度。
然而,如果它是卷积层,则由于这些层是动态的,并且会像输入允许的那样跨越,因此没有简单的方法从模型本身检索此信息。1 这种灵活性意味着对于许多体系结构,所有多个兼容的输入大小2都可以被网络接受。
这是PyTorch的动态计算图的一个特性。
您需要做的是调查网络架构,并一旦找到可解释的层(例如全连接层)便可以“向后工作”,确定先前的层(例如池化和卷积)如何压缩/修改其尺寸。
例如,在来自使用PyTorch进行深度学习(8.5.1)的以下模型中:
class NetWidth(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 16, kernel_size=3, padding=1)
self.fc1 = nn.Linear(16 * 8 * 8, 32)
self.fc2 = nn.Linear(32, 2)
def forward(self, x):
out = F.max_pool2d(torch.tanh(self.conv1(x)), 2)
out = F.max_pool2d(torch.tanh(self.conv2(out)), 2)
out = out.view(-1, 16 * 8 * 8)
out = torch.tanh(self.fc1(out))
out = self.fc2(out)
return out
我们可以看到该模型接收一个具有 3 个通道的输入 2.d. 图像,并进行以下处理:
Conv2d
-> 将其发送到具有 32 个通道的相同大小的图像max_pool2d(,2)
-> 每个维度将图像的大小减半Conv2d
-> 将其发送到具有 16 个通道的相同大小的图像max_pool2d(,2)
-> 每个维度将图像的大小减半view
-> 重新塑造图像Linear
-> 接收大小为 16 * 8 * 8
的张量并将其发送到大小为 32
因此,倒推回去,我们得到:
16 * 8 * 8
的张量view
所看到的图像形状为 (channels, 8,8),当前形状为 (channels, 16,16)2因此,假设内核大小和填充足够使卷积本身保持图像尺寸,则输入图像的形状可能是(3,32,32),即 RGB 32x32 像素正方形图像。
注意事项:
即使是外部包pytorch-summary
也需要您提供输入形状才能显示每个层的输出形状。
然而,它可以是任何两个数字,其乘积等于 8*8,例如 (64,1),(32,2),(16,4) 等。但由于代码写作为 8*8,因此作者很可能使用了实际的维度。
print(model)
将为您提供模型摘要,您可以看到每个层的形状。
您还可以使用pytorch-summary包。
如果您的网络以FC作为第一层,则可以轻松找出其输入形状。如果前面有卷积层和全连接层,则该网络仅会针对一个特定的输入大小产生输出。建议使用不同的形状,即提供某些形状的玩具批次,然后检查在FC层之前的Conv层的输出结果。
由于这取决于第一个FC层之前网络的架构(卷积层数、内核等),因此我无法为正确输入提供确切的公式。正如所提到的,您必须通过尝试各种输入形状并观察第一个FC层之前的网络输出来找到正确的输入形状。几乎总是有一种用代码解决问题的方法,但我现在想不到其他的方法。
input_shape
的。 - yakhyoclass CustomNet(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(1568, 256)
self.fc2 = nn.Linear(256, 256)
self.fc3 = nn.Linear(256, 20)
def forward(self, x):
out = self.fc1(x)
out = F.relu(out)
out = self.fc2(out)
out = F.relu(out)
out = self.fc3(out)
return out
model = CustomNet()
< p > 所以 model.parameters()
方法返回一个迭代器,该迭代器是 torch.Tensor 类的模块参数。查看文档 https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module.parameters < /p>
< p > 而第一个参数是输入张量。< /p>
first_parameter = next(model.parameters())
input_shape = first_parameter.size()
first_parameter = next(module.parameters())
中有一个 typo。它应该是 --> model.parameters()
。2. 如果网络以 FC 层开头似乎可以工作。 - Volkov Maxim