Переписать модель PyTorch как модель Keras и перенести веса с неправильной формой?

#tensorflow #machine-learning #keras #pytorch #transfer-learning

#tensorflow #машинное обучение #keras #pytorch #перенос-обучение

Вопрос:

У меня есть модель PyTorch, которую я пытаюсь переписать в Keras, с которой у меня минимальный опыт. Это модель PyTorch

 class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.hidden_x1 = nn.Sequential(
            nn.Conv1d(in_channels=2, out_channels=8, kernel_size=7),
            nn.SELU(),
            nn.Conv1d(in_channels=8, out_channels=6, kernel_size=7),
            nn.SELU(),
            nn.Conv1d(in_channels=6, out_channels=4, kernel_size=5),
            nn.SELU(),
        )
        self.hidden_xfc = nn.Sequential(
            nn.Linear(256, 20),
            nn.SELU(),
            nn.Linear(20, 20),
            nn.SELU(),
        )
        self.hidden_x2 = nn.Sequential(
            nn.MaxPool1d(kernel_size=2),
            nn.Conv1d(in_channels=2, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.Conv1d(in_channels=4, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.Conv1d(in_channels=4, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.Conv1d(in_channels=4, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.Conv1d(in_channels=4, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.Conv1d(in_channels=4, out_channels=4, kernel_size=5),
            nn.SELU(),
            nn.AvgPool1d(kernel_size=2),
            nn.Conv1d(in_channels=4, out_channels=2, kernel_size=3),
            nn.SELU(),
            nn.AvgPool1d(kernel_size=2),
            nn.Conv1d(in_channels=2, out_channels=2, kernel_size=3),
            nn.SELU(),
            nn.AvgPool1d(kernel_size=2),
        )
        self.hidden_encoded_1 = nn.Flatten()
        self.hidden_embedding = nn.Sequential(
            nn.Linear(26, 16),
            nn.SELU(),
            nn.Linear(16, 8),
            nn.SELU(),
            nn.Linear(8, 4),
        )
        
    def forward(self, x, n=-1):
      x = torch.transpose(x, 1, 2)
      x = self.hidden_x1(x)
      xfc = torch.reshape(x, (n, 256))
      xfc = self.hidden_xfc(xfc)
      x = torch.reshape(x, (n, 2, 128))
      x = self.hidden_x2(x)
      encoded = self.hidden_encoded_1(x)
      encoded = torch.cat((encoded, xfc), 1)
      embedding = self.hidden_embedding(encoded)

      return embedding
 

Это переведенная модель Keras, в которой я не уверен, верна она или нет на данный момент.

 class sho_Model(tf.keras.Model):
    def __init__(self):
        super(sho_Model, self).__init__()
        self.hidden_x1 = keras.models.Sequential(layers=[
            
            Conv1D(filters=8, kernel_size=7, activation=selu, input_shape=(1, 80, 2)),
            Conv1D(filters=6, kernel_size=7, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu)                              
        ])

        self.hidden_xfc = keras.models.Sequential(layers=[
            Dense(20, activation=selu),
            Dense(20, activation=selu)
        ])

        self.hidden_x2 = keras.models.Sequential(layers=[
            
            MaxPool1D(pool_size=2),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            Conv1D(filters=4, kernel_size=5, activation=selu),
            AveragePooling1D(pool_size=2),
            Conv1D(filters=2, kernel_size=3, activation=selu),
            AveragePooling1D(pool_size=2),
            Conv1D(filters=2, kernel_size=3, activation=selu),
            AveragePooling1D(pool_size=2)
        ])

        self.hidden_encoded = Flatten()
        
        self.hidden_embedding = keras.models.Sequential(layers=[
            Dense(16, activation=selu),
            Dense(8, activation=selu),
            Dense(4)
        ])

    def call(self, inputs, n=-1):
        x = K.permute_dimensions(inputs, (2, 1))
        x = self.hidden_x1(x)
        xfc = K.reshape(x, (n, 256))
        xfc = self.hidden_xfc(xfc)
        x = K.reshape(x, (n, 2, 128))
        x = self.hidden_x2(x)
        encoded = self.hidden_encoded(x)
        encoded = K.concatenate((encoded, xfc), 1)
        embedding = self.hidden_embedding(encoded)
        return embedding
 

Чтобы перенести веса из модели PyTorch в модель Keras, я использую

 curr_layer = 0
for layer in keras_model.layers:
    layer.set_weights(list(pytorch_model.parameters())[curr_layer].data.cpu().numpy())
    curr_layer =1
 

Но это выдает ошибку

 ValueError: You called `set_weights(weights)` on layer "sequential" with a weight list of length 8, but the layer was expecting 6 weights. Provided weights: [[[ 0.0098705   0.04642887 -0.02304325 -0.15255862...
 

Когда я перечисляю слои в модели keras с

 for layer in keras_model.layers:
    print(layer.name)
 

Я просто получаю шесть слоев, как я могу вызвать каждый отдельный слой для передачи веса?

 sequential
sequential_1
sequential_2
flatten
sequential_3
 

Комментарии:

1. когда вы запускаете цикл переноса веса, не могли бы вы распечатать, на каком слое он находится?

2. Это было на первом слое «последовательный»