Получение ошибки при попытке вернуть значения нескольких метрик из режима нейронной сети Keras. - PullRequest
1 голос
/ 14 июля 2020

У меня есть нейронная сеть, которая успешно обучается по трем метрикам. Метрики:

  • потеря по Хэммингу (mode = "multi-label")
  • оценка F1 (средняя) микро
  • оценка F1 (средняя = нет)

Полный код моего приложения вы можете проверить на этом colab ссылка

Вкратце, структура моей нейронной сети:

def create_fit_keras_model(hparams,
                           version_data_control,
                           optimizer_name,
                           validation_method,
                           callbacks,
                           optimizer_version = None):

    sentenceLength_actors = X_train_seq_actors.shape[1]
    vocab_size_frequent_words_actors = len(actors_tokenizer.word_index)

    sentenceLength_plot = X_train_seq_plot.shape[1]
    vocab_size_frequent_words_plot = len(plot_tokenizer.word_index)

    sentenceLength_features = X_train_seq_features.shape[1]
    vocab_size_frequent_words_features = len(features_tokenizer.word_index)

    sentenceLength_reviews = X_train_seq_reviews.shape[1]
    vocab_size_frequent_words_reviews = len(reviews_tokenizer.word_index)

    sentenceLength_title = X_train_seq_title.shape[1]
    vocab_size_frequent_words_title = len(title_tokenizer.word_index)

    model = keras.Sequential(name='{0}_{1}dim_{2}batchsize_{3}lr_{4}decaymultiplier_{5}'.format(sequential_model_name, 
                                                                                                str(hparams[HP_EMBEDDING_DIM]), 
                                                                                                str(hparams[HP_HIDDEN_UNITS]),
                                                                                                str(hparams[HP_LEARNING_RATE]), 
                                                                                                str(hparams[HP_DECAY_STEPS_MULTIPLIER]),
                                                                                                version_data_control))
    actors = keras.Input(shape=(sentenceLength_actors,), name='actors_input')
    plot = keras.Input(shape=(sentenceLength_plot,), name='plot_input')
    features = keras.Input(shape=(sentenceLength_features,), name='features_input')
    reviews = keras.Input(shape=(sentenceLength_reviews,), name='reviews_input')
    title = keras.Input(shape=(sentenceLength_title,), name='title_input')

    emb1 = layers.Embedding(input_dim = vocab_size_frequent_words_actors + 2,
                            output_dim = hparams[HP_EMBEDDING_DIM],
                            embeddings_initializer = 'uniform',
                            mask_zero = True,
                            input_length = sentenceLength_actors,
                            name="actors_embedding_layer")(actors)
    
    # encoded_layer1 = layers.GlobalAveragePooling1D(name="globalaveragepooling_actors_layer")(emb1)
    encoded_layer1 = layers.GlobalMaxPooling1D(name="globalmaxpooling_actors_layer")(emb1)
    
    emb2 = layers.Embedding(input_dim = vocab_size_frequent_words_plot + 2,
                            output_dim = hparams[HP_EMBEDDING_DIM],
                            embeddings_initializer = 'uniform',
                            mask_zero = True,
                            input_length = sentenceLength_plot,
                            name="plot_embedding_layer")(plot)
    
    # encoded_layer2 = layers.GlobalAveragePooling1D(name="globalaveragepooling_plot_summary_Layer")(emb2)
    encoded_layer2 = layers.GlobalMaxPooling1D(name="globalmaxpooling_plot_summary_Layer")(emb2)

    emb3 = layers.Embedding(input_dim = vocab_size_frequent_words_features + 2,
                            output_dim = hparams[HP_EMBEDDING_DIM],
                            embeddings_initializer = 'uniform',
                            mask_zero = True,
                            input_length = sentenceLength_features,
                            name="features_embedding_layer")(features)
    
    # encoded_layer3 = layers.GlobalAveragePooling1D(name="globalaveragepooling_movie_features_layer")(emb3)
    encoded_layer3 = layers.GlobalMaxPooling1D(name="globalmaxpooling_movie_features_layer")(emb3)
    
    emb4 = layers.Embedding(input_dim = vocab_size_frequent_words_reviews + 2,
                            output_dim = hparams[HP_EMBEDDING_DIM],
                            embeddings_initializer = 'uniform',
                            mask_zero = True,
                            input_length = sentenceLength_reviews,
                            name="reviews_embedding_layer")(reviews)
    
    # encoded_layer4 = layers.GlobalAveragePooling1D(name="globalaveragepooling_user_reviews_layer")(emb4)
    encoded_layer4 = layers.GlobalMaxPooling1D(name="globalmaxpooling_user_reviews_layer")(emb4)

    emb5 = layers.Embedding(input_dim = vocab_size_frequent_words_title + 2,
                            output_dim = hparams[HP_EMBEDDING_DIM],
                            embeddings_initializer = 'uniform',
                            mask_zero = True,
                            input_length = sentenceLength_title,
                            name="title_embedding_layer")(title)
    
    # encoded_layer5 = layers.GlobalAveragePooling1D(name="globalaveragepooling_movie_title_layer")(emb5)
    encoded_layer5 = layers.GlobalMaxPooling1D(name="globalmaxpooling_movie_title_layer")(emb5)

    merged = layers.concatenate([encoded_layer1, encoded_layer2, encoded_layer3, encoded_layer4, encoded_layer5], axis=-1)

    dense_layer_1 = layers.Dense(hparams[HP_HIDDEN_UNITS],
                                 kernel_regularizer=regularizers.l2(neural_network_parameters['l2_regularization']),
                                 activation=neural_network_parameters['dense_activation'],
                                 name="1st_dense_hidden_layer_concatenated_inputs")(merged)
    
    layers.Dropout(neural_network_parameters['dropout_rate'])(dense_layer_1)
    
    output_layer = layers.Dense(neural_network_parameters['number_target_variables'],
                                activation=neural_network_parameters['output_activation'],
                                name='output_layer')(dense_layer_1)

    model = keras.Model(inputs=[actors, plot, features, reviews, title], outputs=output_layer, name='{0}_{1}dim_{2}batchsize_{3}lr_{4}decaymultiplier_{5}'.format(sequential_model_name, 
                                                                                                                                                                  str(hparams[HP_EMBEDDING_DIM]), 
                                                                                                                                                                  str(hparams[HP_HIDDEN_UNITS]),
                                                                                                                                                                  str(hparams[HP_LEARNING_RATE]), 
                                                                                                                                                                  str(hparams[HP_DECAY_STEPS_MULTIPLIER]),
                                                                                                                                                                  version_data_control))
    print(model.summary())
    
#     pruning_schedule = tfmot.sparsity.keras.PolynomialDecay(initial_sparsity=0.0,
#                                                             final_sparsity=0.4,
#                                                             begin_step=600,
#                                                             end_step=1000)
    
#     model_for_pruning = tfmot.sparsity.keras.prune_low_magnitude(model, pruning_schedule=pruning_schedule)
    
    if optimizer_name=="adam" and optimizer_version is None:
        
        optimizer = optimizer_adam_v2(hparams[HP_LEARNING_RATE], hparams[HP_DECAY_STEPS_MULTIPLIER], X_train_seq_actors.shape[0], optimizer_parameters['validation_split_ratio'], hparams[HP_HIDDEN_UNITS])
        
    elif optimizer_name=="sgd" and optimizer_version is None:
        
        optimizer = optimizer_sgd_v1(hparams[HP_LEARNING_RATE])
        
    elif optimizer_name=="rmsprop" and optimizer_version is None:
        
        optimizer = optimizer_rmsprop_v1(hparams[HP_LEARNING_RATE])

    model.compile(optimizer=optimizer,
                  loss=neural_network_parameters['model_loss'],
                  metrics=[tfa.metrics.HammingLoss(mode="multilabel", name="hamming_loss"), 
                           tfa.metrics.F1Score(y_train[0].shape[-1], average="micro", name="f1_score_micro"), 
                           tfa.metrics.F1Score(y_train[0].shape[-1], average=None, name="f1_score_none")], )
    
    #plot model's structure
    plot_model(model, to_file=os.path.join(os.getcwd(), '{0}/{1}_{2}batchsize_{3}lr_{4}decaymultiplier_{5}.png'.format(folder_path_model_saved, 
                                                                                                                       network_structure_file_name,
                                                                                                                       str(hparams[HP_EMBEDDING_DIM]), 
                                                                                                                       str(hparams[HP_HIDDEN_UNITS]),
                                                                                                                       str(hparams[HP_LEARNING_RATE]), 
                                                                                                                       str(hparams[HP_DECAY_STEPS_MULTIPLIER]),
                                                                                                                       version_data_control)))
    start_time = time.time()
    
    steps_per_epoch=int(np.ceil((X_train_seq_actors.shape[0]*optimizer_parameters['validation_split_ratio'])//hparams[HP_HIDDEN_UNITS]))
    
    print("\nSteps per epoch on current run: {0}".format(steps_per_epoch))
    
    if validation_method=="validation_split":

        fitted_model=model.fit([X_train_seq_actors, X_train_seq_plot, X_train_seq_features, X_train_seq_reviews, X_train_seq_title],
                                y_train,
                                steps_per_epoch=int(np.ceil((X_train_seq_actors.shape[0]*optimizer_parameters['validation_split_ratio'])//hparams[HP_HIDDEN_UNITS])),
                                epochs=fit_parameters["epoch"],
                                batch_size=hparams[HP_HIDDEN_UNITS],
                                validation_split=fit_parameters['validation_data_ratio'],
                                callbacks=callbacks,
                                use_multiprocessing=True,
                                # sample_weight=class_weights_sample
                              )

    elif validation_method=="validation_data":
        
        fitted_model=model.fit([X_train_seq_actors, X_train_seq_plot, X_train_seq_features, X_train_seq_reviews, X_train_seq_title], 
                               y_train,
                               steps_per_epoch=int(np.ceil((X_train_seq_actors.shape[0]*optimizer_parameters['validation_split_ratio'])//hparams[HP_HIDDEN_UNITS])),
                               epochs=fit_parameters["epoch"],
                               verbose=fit_parameters["verbose_fit"],
                               batch_size=hparams[HP_HIDDEN_UNITS],
                               validation_data=([X_test_seq_actors, X_test_seq_plot, X_test_seq_features, X_test_seq_reviews, X_test_seq_title],
                                                y_test),
                               callbacks=callbacks,
                              )
    #save the model
    save_model(model,
               folder_path_model_saved,
               "{0}_{1}dim_{2}batchsize_{3}lr_{4}decaymultiplier_{5}".format(saved_model_name,
                                                                             str(hparams[HP_EMBEDDING_DIM]), 
                                                                             str(hparams[HP_HIDDEN_UNITS]), 
                                                                             str(hparams[HP_LEARNING_RATE]), 
                                                                             str(hparams[HP_DECAY_STEPS_MULTIPLIER]), 
                                                                             version_data_control))

    elapsed_time = time.time() - start_time
    
    print("\nTraining time of the multi-input keras model has finished. Duration {} secs".format(format_timespan(elapsed_time)))
    
# I get an error here!
    _, model_metric = model.evaluate([X_test_seq_actors, X_test_seq_plot, X_test_seq_features, X_test_seq_reviews, X_test_seq_title], y_test, batch_size=hparams[HP_HIDDEN_UNITS], verbose=2)

    print('Results of model_metrics on test data: {0}'.format(model_metric))

    return model_metric, model, fitted_model

Вкл. на последнем этапе я вызвал model.evaluate () и получил следующую ошибку: python ValueError: too many values to unpack (expected 2)

И я полагаю, это потому, что я использовал 3 метрики одновременно. Как я могу решить эту проблему и вернуть значения всех показателей в списке или словаре?

1 Ответ

1 голос
/ 14 июля 2020

model.evaluate возвращает список потерь и показателей соответственно

В вашем случае у вас есть один результат и 3 показателя, поэтому model.evaluate возвращает список из 4 чисел в этой последовательности [loss, metric1, metric2 , metric3]

вы просто переопределите проблему следующим образом:

evalution = model.evaluate([X_test_seq_actors, X_test_seq_plot, X_test_seq_features, X_test_seq_reviews, X_test_seq_title], 
                           y_test, batch_size=hparams[HP_HIDDEN_UNITS], verbose=2)

loss = evalution[0] # single number
model_metric = evalution[1:] # is a list of 3 elements
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...