Google Colab keras Sequential 模型返回一个空的 history.history 对象“”

Posted

技术标签:

【中文标题】Google Colab keras Sequential 模型返回一个空的 history.history 对象“”【英文标题】:Google Colab keras Sequential model returns an empty history.history object ""Google Colab keras Sequential 模型返回一个空的 history.history 对象“” 【发布时间】:2020-10-28 13:44:03 【问题描述】:

我在使用 google colab 和我训练的 Keras 模型时遇到了困难。我正在使用各种魔术技巧,例如 Tensorboard、HParams、回调等。

最初,请原谅我只发布代码和屏幕截图,而不是数据。由于发布的代码在我的本地机器上成功运行,而不是在 colab 上,我猜这不是由于数据错误,而是代码错误。

我的本​​地机器TF版本:2.1.0

Colab 的 TF 版本:2.2.0

下面是我的代码。

import tensorflow as tf
import tensorflow_addons as tfa
import tensorflow_docs as tfdocs #!pip install git+https://github.com/tensorflow/docs
import tensorflow_docs.plots as tfplots
import tensorflow_docs.modeling as tfmodel

from tensorflow.keras import layers, regularizers, models
from tensorflow.keras import models
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.utils import model_to_dot, plot_model
from tensorflow.keras.models import load_model, model_from_json

%load_ext tensorboard
from tensorboard.plugins.hparams import api as hp

import keras.backend as K
from tensorflow import keras

回调

def callback(folder_path, saved_model_name, logdir, hparams):
    
    # Initialize parameters
    monitor_metric = 'val_loss'
    minimum_delta = 0.1
    patience_limit = 1
    verbose_value = 1
    mode_value = 'min'
    weights_fname = os.path.join(os.getcwd(), '0/1.h5'.format(folder_path, saved_model_name))
    print(weights_fname)
    
    # Initialize callbacks
    callbacks = [
        
        EarlyStopping(monitor=monitor_metric,
                      min_delta=minimum_delta,
                      patience=patience_limit,
                      verbose=verbose_value,
                      mode=mode_value,
                      restore_best_weights=True),

        ModelCheckpoint(filepath=weights_fname,
                        monitor=monitor_metric,
                        verbose=verbose_value,
                        save_best_only=True,
                        save_weights_only=True),

        tf.keras.callbacks.TensorBoard(logdir),
        
        hp.KerasCallback(logdir, hparams)
    ]
    
    return callbacks

超参数

HP_HIDDEN_UNITS = hp.HParam('batch_size', hp.Discrete([32, 64, 128]))
HP_EMBEDDING_DIM = hp.HParam('embedding_dim', hp.Discrete([100, 200, 300]))
HP_LEARNING_RATE = hp.HParam('learning_rate', hp.Discrete([0.001, 0.01, 0.1])) # Adam default: 0.001, SGD default: 0.01, RMSprop default: 0.001
HP_DECAY_STEPS_MULTIPLIER = hp.HParam('decay_steps_multiplier', hp.Discrete([100, 1000]))

METRIC_ACCURACY = 'accuracy'

创建和拟合模型函数

def create_fit_keras_model(hparams,
                           version_data_control,
                           optimizer_name,
                           validation_method,
                           callbacks,
                           folder_path,
                           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)
    
    model = keras.Sequential(name='MultyInput_Keras_Classification_model_0dim_1batchsize_2lr_3decaymultiplier_4'.format(hparams[HP_EMBEDDING_DIM], hparams[HP_HIDDEN_UNITS],
                                                                                                                                  hparams[HP_LEARNING_RATE], 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')
    
    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.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.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.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.GlobalMaxPooling1D(name="globalmaxpooling_user_reviews_layer")(emb4)
    
    merged = layers.concatenate([encoded_layer1, encoded_layer2, encoded_layer3, encoded_layer4], 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(y_train.shape[1], 
                                activation=neural_network_parameters['output_activation'],
                                name='output_layer')(dense_layer_1)

    model = keras.Model(inputs=[actors, plot, features, reviews], outputs=output_layer, name='MultyInput_Keras_Classification_model_0dim_1batchsize_2lr_3decaymultiplier_4'.format(hparams[HP_EMBEDDING_DIM], 
                                                                                                                                                                                             hparams[HP_HIDDEN_UNITS],
                                                                                                                                                                                             hparams[HP_LEARNING_RATE], 
                                                                                                                                                                                             hparams[HP_DECAY_STEPS_MULTIPLIER],
                                                                                                                                                                                             version_data_control))
    print(model.summary())
    
    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=[neural_network_parameters['model_metric']])
    
    plot_model(model, to_file=os.path.join(os.getcwd(), 'model_one/network_structure_multy_input_keras_model_0.png'.format(version_data_control)))
    
    start_time = time.time()
    
    if validation_method=="validation_split":
        
        model.fit([X_train_seq_actors, X_train_seq_plot, X_train_seq_features, X_train_seq_reviews],
                  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_split=fit_parameters['validation_data_ratio'],
                  callbacks=callbacks)
        
    elif validation_method=="validation_data":
        
        model.fit([X_train_seq_actors, X_train_seq_plot, X_train_seq_features, X_train_seq_reviews], 
                  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], y_test),
                  callbacks=callbacks)
    
    #save the model
    save_model(model, folder_path, "multi_input_keras_model_0dim_1batchsize_2lr_3decaymultiplier_4".format(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)))
    
    _, accuracy = model.evaluate([X_test_seq_actors, X_test_seq_plot, X_test_seq_features, X_test_seq_reviews], y_test, batch_size=hparams[HP_HIDDEN_UNITS], verbose=2)

    return accuracy, model

运行一切 - 函数 -> 基本上这是我调用来训练我的模型的函数。

def run(run_dir, hparams, version_data_control, optimizer_name, validation_method, callbacks, folder_path):
    with tf.summary.create_file_writer(run_dir).as_default():
        hp.hparams(hparams)  # record the values used in this trial
        accuracy, model = create_fit_keras_model(hparams, version_data_control, optimizer_name, validation_method, callbacks, folder_path)
        print(model.history.history)
        tf.summary.scalar(METRIC_ACCURACY, accuracy, step=1)

    return model

训练过程 -> 在我的本地机器上成功运行,但在 Google Colab 中却没有。

session_num = 1

for batch_size in HP_HIDDEN_UNITS.domain.values:
    for embedding_dim in HP_EMBEDDING_DIM.domain.values:
        for learning_rate in HP_LEARNING_RATE.domain.values:
            for decay_steps_multiplier in HP_DECAY_STEPS_MULTIPLIER.domain.values:
                hparams = 
                    HP_HIDDEN_UNITS: batch_size,
                    HP_EMBEDDING_DIM: embedding_dim,
                    HP_LEARNING_RATE: learning_rate,
                    HP_DECAY_STEPS_MULTIPLIER: decay_steps_multiplier
                  
                run_name = "run-id 0/1".format(session_num, (len(HP_HIDDEN_UNITS.domain.values)*len(HP_EMBEDDING_DIM.domain.values)*len(HP_LEARNING_RATE.domain.values)*len(HP_DECAY_STEPS_MULTIPLIER.domain.values)))
                print('--- Starting trial: %s/n' % run_name)
                print(h.name: hparams[h] for h in hparams, "/n")
                
                model_history=run('./logs/hparam_tuning/' + run_name, hparams, version_data_control, "adam", "validation_split",
                                  callback("model_one/adam_v2_07072020", 
                                           "multi_input_keras_model_0dim_1batchsize_2lr_3decaymultiplier_4".format(str(embedding_dim), str(batch_size), str(learning_rate), str(decay_steps_multiplier), version_data_control),
                                           "./logs/hparam_tuning/"+datetime.now().strftime("%Y%m%d-%H%M%S"), 
                                           hparams),
                                  "model_one/adam_v2_07072020")
                
                hist = pd.DataFrame(model_history.history.history)
                hist['epoch'] = model_history.history.epoch

根据下面的屏幕截图,一切运行良好。虽然从 run() 函数返回的历史模型是完全空的。此外,即使日志位于 logdir 目录中,Tensorboard 上也不会打印任何内容。另外,我想补充一点,上面发布的代码在我的本地机器上完美运行,包括 Tensorboard 和回调,以及模型历史。但由于缺乏资源,我想在 colab 上运行 100 个 epoch,而不是像本例(演示)中那样运行 1 个。

我得到的错误

我的文件

提前感谢您的任何 cmets 和帮助。如果您可能想查看包含数据的完整代码,我可以与您分享我的 colab 笔记本。只需在 cmets 中发布您的 Gmail 帐户,我会与您分享!

【问题讨论】:

【参考方案1】:

我通过将 model.fit() 方法分配给不同的对象解决了这个问题,如下所示:

fitted_model = model.fit([X_train_seq_actors, X_train_seq_plot, X_train_seq_features, X_train_seq_reviews],
                  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_split=fit_parameters['validation_data_ratio'],
                  callbacks=callbacks)

然后通过返回fitted_model 对象我可以成功运行这个hist = pd.DataFrame(model_history.history)

输出:

+----+----------+------------+------------+----------------+---------+
|    |     loss |   accuracy |   val_loss |   val_accuracy |   epoch |
|----+----------+------------+------------+----------------+---------|
|  1 | 0.295619 |   0.452375 |   0.186601 |        0.64396 |       1 |
+----+----------+------------+------------+----------------+---------+

希望这也能帮助其他用户。如果在同一问题上给出了类似的答案,请随意将其分配为 [重复] 问题。

【讨论】:

这是一个非常奇怪的。今天当我打电话给model.history.history返回空字典时,我突然遇到了类似的问题。所以我需要像你建议的那样分配单独的变量,它可以工作。 @kitokid 很高兴我帮助了你:)

以上是关于Google Colab keras Sequential 模型返回一个空的 history.history 对象“”的主要内容,如果未能解决你的问题,请参考以下文章

使用 Keras 在 Google colab 上运行 3D CNN 的问题

Google Colab keras Sequential 模型返回一个空的 history.history 对象“”

使用 TPU 运行时在 Google Colab 上训练 Keras 模型时出错

Google Colab 上的 Keras YoloV3,AttributeError: module 'keras.backend' has no attribute 'control_flow_o

我在 google colab 上训练了一个 keras 模型。现在无法在我的系统上本地加载它。

使用大数据集在 Google Colab TPU 上训练 seq2seq 模型 - Keras