【问题标题】:Sharing parameters between certain layers of different instances of the same pytorch model在同一 pytorch 模型的不同实例的某些层之间共享参数
【发布时间】:2019-02-07 08:31:15
【问题描述】:

我有一个看起来像这样的多层 pytorch 模型

class CNN(nn.Module):
    def __init__(self):
        super(CNN).__init__()
        self.layer1 = nn.Conv2d(#parameters)
        self.layer2 = nn.Conv2d(#different_parameters)
        self.layer3 = nn.Conv2d(#other_parameters)
        self.layer4 = nn.Conv2d(#final_parameters)

    def forward(self, x):
        out1 = self.layer2(F.relu(self.layer1(x)))
        out2 = self.layer4(F.relu(self.layer3(x)))
        return torch.cat((out1, out2), 0)

然后我想实例化这个类(cnn1, cnn2)的多个实例,并在实例之间共享第一个路径(layer1, layer2)的参数,同时保持其他参数分开。

是否有最佳/受支持的方法来做到这一点?

【问题讨论】:

  • 你为什么沿第一个维度(批量)而不是 dim=1 通道维度进行 torch.cat?

标签: python deep-learning pytorch


【解决方案1】:

只需将layer1layer2 收集为独立模块即可。

一个例子: model1mode2 有私有的全连接层,但共享 conv2d 层,即特征提取器

feature_ex = nn.Sequential(OrderedDict([('conv1', nn.Conv2d(1, 6, 5)),
                                        ('relu1', nn.ReLU()),
                                        ('maxpool1', nn.MaxPool2d((2, 2))),
                                        ('conv2', nn.Conv2d(6, 16, 5)),
                                        ('relu2', nn.ReLU()),
                                        ('maxpool2', nn.MaxPool2d(2))
                                        ]))


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # an affine operation: y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = feature_ex(x)   # [1]
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)     # [2]

        return x

    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:       # Get the products
            num_features *= s
        return num_features


model1 = Net()
model2 = Net()

img = torch.randn(10, 1, 32, 32)
out1 = model1.forward(img)
out2 = model2.forward(img)

# [1]
# print(np.allclose(out1.detach().numpy(), out2.detach().numpy()))
# output: True

# [2]
print(np.allclose(out1.detach().numpy(), out2.detach().numpy()))
# output: False

【讨论】:

    猜你喜欢
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 2019-01-30
    • 2020-03-25
    相关资源
    最近更新 更多