共同训练模型:传递给模型的Numpy数组列表不是模型预期的大小

时间:2020-11-05 20:07:46

标签: python arrays numpy tensorflow keras

我正在尝试训练以下模型。在这里,我同时运行三个模型,并与主要模型共同承担损失。但是,我遇到了一些错误。

def categorical_crossentropy_base(coeffs, num_class):

    def categorical_crossentropy(y_true, y_pred, from_logits=False, label_smoothing=0):
        """Computes the categorical crossentropy loss.
      Args:
        y_true: tensor of true targets.
        y_pred: tensor of predicted targets.
        from_logits: Whether `y_pred` is expected to be a logits tensor. By default,
          we assume that `y_pred` encodes a probability distribution.
        label_smoothing: Float in [0, 1]. If > `0` then smooth the labels.
      Returns:
        Categorical crossentropy loss value.
      """
        y_pred1 = y_pred[:, :num_class]  # the 1st prediction
        y_pred2 = y_pred[:, num_class:2*num_class]  # the 2nd prediction
        y_pred3 = y_pred[:, 2*num_class:]  # the 3rd prediction

        # you should adapt the ground truth to contain all 3 ground truth of course
        y_true1 = y_true[:, :num_class]  # the 1st gt
        y_true2 = y_true[:, num_class:2*num_class]  # the 2nd gt
        y_true3 = y_true[:, 2*num_class:]  # the 3rd gt

        loss1 = K.categorical_crossentropy(y_true1, y_pred1, from_logits=from_logits)
        loss2 = K.categorical_crossentropy(y_true2, y_pred2, from_logits=from_logits)
        loss3 = K.categorical_crossentropy(y_true3, y_pred3, from_logits=from_logits)
        
        #l2 difference computation 
        l13 = l2(loss3, loss2)
        
        l23 = l2(loss3, loss1)
        
        # combine the losses the way you like it
        total_loss = coeffs[0]*loss3 + coeffs[1]*l13 + coeffs[2]*l23
        return total_loss

    return categorical_crossentropy

def l2(v1, v2):
    
    # take square of differences and sum them
    l2 = np.sum(np.power((v2-v1),2))
    
    return l2
in1 = Input((6373,))
enc1 = Dense(num_nodes)(in1)
enc1 = Dropout(0.3)(enc1)
enc1 = Dense(num_nodes, activation='relu')(enc1)
enc1 = Dropout(0.3)(enc1)
enc1 = Dense(num_nodes, activation='relu')(enc1)
out1 = Dense(units=nclass, activation='softmax')(enc1)

in2 = Input((512,))
enc2 = Dense(num_nodes, activation='relu')(in2)
enc2 = Dense(num_nodes, activation='relu')(enc2)
out2 = Dense(units=nclass, activation='softmax')(enc2)

in3 = Input((768,))
enc3 = Dense(num_nodes, activation='relu')(in3)
enc3 = Dense(num_nodes, activation='relu')(enc3)
out3 = Dense(units=nclass, activation='softmax')(enc3)

adam = Adam(lr=0.0001)

total_out = Concatenate(axis=1)([out1, out2, out3])
model = Model(inputs=[in1, in2, in3], outputs=[total_out])

coeffs = [w1, w2, w3]
#model.compile(loss=categorical_crossentropy_base(coeffs=coeffs, num_class=nclass),  optimizer='adam', metrics=['accuracy'])
model.compile(loss=categorical_crossentropy_base(coeffs=coeffs, num_class=nclass),  optimizer='adam')

我不确定在尝试拟合模型时是否正确发送了输入。 这就是我的做法:

    model.fit(x=[X_Train1, X_Train2, X_Train3], 
              y=[Y_Train_Class1, Y_Train_Class2, Y_Train_Class3], 
              batch_size=batch_size, 
              epochs=epochs,
              validation_data=[(X_Valid1, Y_Valid_Class1),
                               (X_Valid2, Y_Valid_Class2),
                               (X_Valid3, Y_Valid_Class3)],
              verbose=1,
              callbacks=callbacks_list)

其中X_Train1.shape = (3330, 6373)X_Train2.shape = (3329, 512)X_Train3.shape = (3329, 768),但是当我尝试拟合模型时,我不断遇到以下错误:


ValueError: Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 1 array(s), but instead got the following list of 3 arrays: [array([[1, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 0, 0, 0, 1],
       ...,
       [0, 1, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1]]), array([[1, 0, 0, 0, 0],
       [0, 1, 0, ...

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

  1. 选中X_Train1.shape = (3330, 6373)。看起来应该是X_Train1.shape = (3329, 6373)
  2. ,您将发送三个标签数组:y=[Y_Train_Class1, Y_Train_Class2, Y_Train_Class3]。您的模型需要一个输出(一个数组)