Как определить набор проверки в Keras с настраиваемой функцией потерь - PullRequest
1 голос
/ 02 февраля 2020

Я пробую пример https://github.com/yaringal/multi-task-learning-example/blob/master/multi-task-learning-example.ipynb.

Только я пытаюсь добавить несколько входов и больше выходов. Для предотвращения переоснащения я использую EarlyStopping. Поскольку у меня есть набор данных временных рядов, я хочу использовать набор тестов в качестве набора проверки. Однако я получаю сообщение об ошибке не могу решить.

Это моя архитектура:

from keras.layers import Input, Dense, Lambda, Layer
from keras.initializers import Constant
from keras.models import Model
from keras import backend as K

# Custom loss layer
class CustomMultiLossLayer(Layer):
    def __init__(self, nb_outputs=6, **kwargs):
        self.nb_outputs = 6
        self.is_placeholder = True
        super(CustomMultiLossLayer, self).__init__(**kwargs)

    def build(self, input_shape=None):
        # initialise log_vars
        self.log_vars = []
        for i in range(self.nb_outputs):
            self.log_vars += [self.add_weight(name='log_var' + str(i), shape=(1,),
                                              initializer=Constant(0.), trainable=True)]
        super(CustomMultiLossLayer, self).build(input_shape)

    def multi_loss(self, ys_true, ys_pred):
        assert len(ys_true) == self.nb_outputs and len(ys_pred) == self.nb_outputs
        loss = 0
        for y_true, y_pred, log_var in zip(ys_true, ys_pred, self.log_vars):
            precision = K.exp(-log_var[0])
            loss += K.sum(precision * (y_true - y_pred)**2. + log_var[0], -1)
        return K.mean(loss)

    def call(self, inputs):
        ys_true = inputs[:self.nb_outputs]
        ys_pred = inputs[self.nb_outputs:]
        loss = self.multi_loss(ys_true, ys_pred)
        self.add_loss(loss, inputs=inputs)
        # We won't actually use the output.
        return K.concatenate(inputs, -1)

def get_prediction_model():

    # NN structure

    # Dense layer after numerical input
    dense_num = Dense(128, kernel_initializer="he_normal", activation="relu")(numerical_features_in)


    # Concatenate embedding layer with numerical features
    main = Concatenate()([emb_1, emb_2,
                          emb_2, emb_4,
                          dense_num
                         ]
                        )

    # Stack a deep densely-connected network on top
    dense2 = Dense(512, kernel_initializer="he_normal", activation="relu", kernel_regularizer=regularizers.l2(0.01))(main)
    dropout1 = Dropout(0.5)(dense2)
    x = Dense(256, kernel_initializer="he_normal", activation="relu", kernel_regularizer=regularizers.l2(0.01))(dropout1)


    x1 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y1_pred = Dense(D1, kernel_initializer="he_normal", activation="relu")(x1)

    x2 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y2_pred = Dense(D2, kernel_initializer="he_normal", activation="relu")(x2)

    x3 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y3_pred = Dense(D3, kernel_initializer="he_normal", activation="relu")(x3)

    x4 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y4_pred = Dense(D4, kernel_initializer="he_normal", activation="relu")(x4)

    x5 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y5_pred = Dense(D5, kernel_initializer="he_normal", activation="relu")(x5)

    x6 = Dense(64, kernel_initializer="he_normal", activation="relu")(x)
    y6_pred = Dense(D6, kernel_initializer="he_normal", activation="relu")(x6)
    #y7_pred = Dense(D7)(x)
    #y8_pred = Dense(D8)(x)

    return Model(inputs=[emb_1_in, emb_2_in, 
                emb_3_in, arrival_4_in,
                numerical_features_in], outputs=[y1_pred, y2_pred, y3_pred, y4_pred, y5_pred, y6_pred])

def get_trainable_model(prediction_model):

    y1_pred, y2_pred, y3_pred, y4_pred, y5_pred, y6_pred = prediction_model(inputs=[emb_1_in, emb_2_in, 
                emb_3_in, emb_4_in,
                numerical_features_in])

    y1_true = Input(shape=(D1,), name='y1_true')
    y2_true = Input(shape=(D2,), name='y2_true')
    y3_true = Input(shape=(D3,), name='y3_true')
    y4_true = Input(shape=(D4,), name='y4_true')
    y5_true = Input(shape=(D5,), name='y5_true')
    y6_true = Input(shape=(D6,), name='y6_true')
    #y7_true = Input(shape=(D7,), name='y7_true')
    #y8_true = Input(shape=(D8,), name='y8_true')
    out = CustomMultiLossLayer(nb_outputs=6)([y1_true, y2_true, y3_true, y4_true, y5_true, y6_true, 
                                              y1_pred, y2_pred, y3_pred, y4_pred, y5_pred, y6_pred])
    return Model([emb_1_in, emb_2_in, 
                emb_3_in, emb_4_in,
                numerical_features_in, y1_true, y2_true, y3_true, y4_true, y5_true, y6_true], out)

prediction_model = get_prediction_model()
trainable_model = get_trainable_model(prediction_model)
trainable_model.compile(optimizer='adam', loss=None)
assert len(trainable_model.layers[-1].trainable_weights) == 6  
assert len(trainable_model.losses) == 1

# Define callbacks earlystopping
earlystopping = EarlyStopping(monitor='val_loss',
                              min_delta=0,
                              patience=5,
                              verbose=0, 
                              mode='auto'
                              )

# Define validation set
validationset = (
    [    
    test['feature1'], test['feature2'],
        test['feature3'], test['feature4'], 
        test[numerical_features], 


    test['target1'], test['target2'], 
    test['target3'], test['target4'],
    test['target5'], test['target6']
    ],

    [test['target1'], test['target2'], 
    test['target3'], test['target4'],
    test['target5'], test['target6']]
)

# Fit the model
hist = trainable_model.fit(
    [
        train['feature1'], train['feature2'],
        train['feature3'], train['feature4'], 
        train[numerical_features], 

    train['target1'], train['target2'], 
    train['target3'], train['target4'],
    train['target5'], train['target6']
    ],

          epochs=100,
          verbose=True,
          validation_data = validationset,
          batch_size=1024,
          callbacks=[earlystopping]
)

Но теперь я получаю сообщение об ошибке:

ValueError: ('Ошибка при проверке целевого объекта модели: не ожидал данных, но получил:', [411 84,0 415 187,0 410 714,0 412 1261,0 413 80,0 ... 62496 27,0 62576 14,0 62584 552,0 62510 337,0 62571 221,0

Может кто-нибудь помочь мне разобраться, как установить правильность проверки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...