如何改变densenet121模型的out_features ?



如何更改densenet121模型中的out_features?

我使用下面的代码来训练模型:

from torch.nn.modules.dropout import Dropout

class Densnet121(nn.Module):
def __init__(self):
super(Densnet121, self).__init__() 
self.cnn1 = nn.Conv2d(in_channels=3 , out_channels=64 , kernel_size=3 , stride=1 )
self.Densenet_121 = models.densenet121(pretrained=True)
self.gap = AvgPool2d(kernel_size=2, stride=1, padding=1)
self.bn1 = nn.BatchNorm2d(1024)
self.do1 = nn.Dropout(0.25)
self.linear = nn.Linear(256,256)
self.bn2 = nn.BatchNorm2d(256)
self.do2 = nn.Dropout(0.25)
self.output = nn.Linear(64 * 64 * 64,2)
self.act = nn.ReLU()

def densenet(self):
for param in self.Densenet_121.parameters():
param.requires_grad = False
self.Densenet_121.classifier = nn.Linear(1024, 1024)
return self.Densenet_121

def forward(self, x):
img = self.act(self.cnn1(x))
img = self.densenet(img)      

img = self.gap(img)
img = self.bn1(img)
img = self.do1(img)
img = self.linear(img)
img = self.bn2(img)
img = self.do2(img)
img = torch.flatten(img, 1)
img = self.output(img)

return img

在训练这个模型时,我遇到了以下错误:

RuntimeError: Given groups=1, weight of size [64, 3, 7, 7], expected input[64, 64, 62, 62] to have 3 channels, but got 64 channels instead

您的第一个转换层输出形状为(b, 64, h, w)的张量,而下一层,密集模型期望3个通道。因此引发了错误:

"预期输入[…]有3个通道,但得到64通道,而不是">

不幸的是,这个值在Densenet类的源代码中是硬编码的,参见参考资料。

然而,一种解决方法是在初始化密集网络后覆盖第一个卷积层。像这样的代码应该可以工作:
# First gather the conv layer specs
conv = self.Densenet_121.features.conv0
kwargs = {k: getattr(conv, k) for k in 
('out_channels', 'stride', 'kernel_size', 'padding', 'bias')}
# overwrite with identical specs with new in_channels
model.features.conv0 = nn.Conv2d(in_channels=64, **kwargs)    

或者你可以这样做:

w = model.features.conv0.weight
w.data = torch.rand(len(w), 64, *w.shape[:2])

替换底层卷积层权重而不影响其元数据(例如:conv.in_channels仍然等于3),这可能有副作用。因此,我建议采用第一种方法。

相关内容

  • 没有找到相关文章

最新更新