我有一个PyTorch的3dResNet模型。我还注释掉了resnet.py源代码中的flatten行,所以我的输出不应该是1D。
下面是我的代码:
class VideoModel(nn.Module):
def __init__(self,num_channels=3):
super(VideoModel, self).__init__()
self.r2plus1d = models.video.r2plus1d_18(pretrained=True)
self.r2plus1d.fc = Identity()
for layer in self.r2plus1d.children():
layer.requires_grad_ = False
def forward(self, x):
print(x.shape)
x = self.r2plus1d(x)
print(x.shape)
return x
我的身份类的存在只是为了忽略一个层:
class Identity(nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
return x
当我运行torch.randn(1, 3, 8, 112, 112)
作为输入时,我得到以下输出:
torch.Size([1, 3, 8, 112, 112])
torch.Size([1, 512, 1, 1, 1])
为什么我有一个1D输出,即使我删除了fc层和平坦操作?有没有更好的方法来去除扁平化手术?
原因是压平步骤前的AdaptiveAvgPool3d
层。它以参数output_size=(1,1,1)
调用,因此将最后三个维度池到(1,1,1)
,而不管它们的原始维度。
在您的示例中,平均池后的输出形状为(1,512,1,1,1)
, flatten后的输出形状为(1,512)
, fc层后的输出形状为(1,400)
。
所以扁平化操作不负责,禁用平均池和所有后续步骤以获得所需的结果。