如何在 Pytorch 训练期间添加额外的输出节点?

社会演员多 pytorch 186

原文标题How to add an additional output node during training for Pytorch?

我正在制作一个类增量学习多标签分类器。在这里,模型首先使用 7 个标签进行训练。训练后,会出现另一个数据集,其中包含相同的标签,但多了一个。我想自动向经过训练的网络添加一个额外的节点,并继续在这个新数据集上进行训练。我怎样才能做到这一点?

class FeedForewardNN(nn.Module):
    def __init__(self, input_size, h1_size = 264, h2_size = 128, num_services=8):
        super().__init__()
        self.input_size = input_size
        self.lin1 = nn.Linear(input_size, h1_size)
        self.lin2 = nn.Linear(h1_size, h2_size)
        self.lin3 = nn.Linear(h2_size, num_services)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.lin1(x)
        x = self.relu(x)
        x = self.lin2(x)
        x = self.relu(x)
        x = self.lin3(x)
        x = self.sigmoid(x)
        return x

这是前馈神经网络的架构。然后我首先在只有 7 个类的数据集上进行训练。

#Create NN
input_size = len(x_columns)
net1 = FeedForewardNN(input_size, num_services=7)
alpha= 0.001

#Define optimizer
optimizer = optim.Adam(net.parameters(), lr=alpha)
criterion = nn.BCELoss()
running_loss = 0

#Training Loop
loss_list = []
auc_list = []

for i in range(len(train_data_x)):
    optimizer.zero_grad()

    outputs = net1(train_data_x[i])
    loss = criterion(outputs, train_data_y[i])
    loss.backward()
    optimizer.step()

但是,我想添加一个额外的输出节点,定义新的权重但保持旧的训练权重,并在这个新数据集上进行训练。

原文链接:https://stackoverflow.com//questions/71410194/how-to-add-an-additional-output-node-during-training-for-pytorch

回复

我来回复
  • Alexey Birukov的头像
    Alexey Birukov 评论

    我建议用具有所需形状的新图层替换图层,然后将其参数值部分分配为旧参数值,如下所示:

    def increaseClassifier( m: torch.nn.Linear ):
        w = m.weight
        b = m.bias
        old_shape = m.weight.shape
    
        m2 = nn.Linear( old_shape[1], old_shape[0] +1 )
        m2.weight = nn.parameter.Parameter( torch.cat( (m.weight, m2.weight[0:1]) ) )
        m2.bias = nn.parameter.Parameter( torch.cat( (m.bias, m2.bias[0:1]) ) )
        return m2
    
    class FeedForewardNN(nn.Module):
        ...
        def incrHere(self):
            self.lin3 = increaseClassifier( self.lin3 )
    

    升级版:

    你能解释一下,这个新输出节点附带的这些额外权重是如何初始化的?

    新通道的初始权重来自于新层的创建,层构造函数通过一些随机初始化来生成新参数,然后我们用训练好的权重替换部分,剩下的部分准备好进行新的训练。

    m2.weight = nn.parameter.Parameter( torch.cat( (m.weight,m2.weight[0:1]) ) )

    2年前 0条评论