Как сохранить вес модели керас для каждой эпохи? - PullRequest
1 голос
/ 05 апреля 2020

Я хочу сохранить модель кераса и сохранить веса каждой эпохи, чтобы иметь лучшие веса. Как мне это сделать?

Любая помощь будет оценена.

код :

def createModel():
    input_shape=(1, 22, 5, 3844)
    model = Sequential()
    #C1
    model.add(Conv3D(16, (22, 5, 5), strides=(1, 2, 2), padding='same',activation='relu',data_format= "channels_first", input_shape=input_shape))
    model.add(keras.layers.MaxPooling3D(pool_size=(1, 2, 2),data_format= "channels_first",  padding='same'))
    model.add(BatchNormalization())
    #C2
    model.add(Conv3D(32, (1, 3, 3), strides=(1, 1,1), padding='same',data_format= "channels_first",  activation='relu'))#incertezza se togliere padding
    model.add(keras.layers.MaxPooling3D(pool_size=(1,2, 2),data_format= "channels_first", ))
    model.add(BatchNormalization())

     #C3
    model.add(Conv3D(64, (1,3, 3), strides=(1, 1,1), padding='same',data_format= "channels_first",  activation='relu'))#incertezza se togliere padding
    model.add(keras.layers.MaxPooling3D(pool_size=(1,2, 2),data_format= "channels_first",padding='same' ))
    model.add(Dense(64, input_dim=64, kernel_regularizer=regularizers.l2(0.01), activity_regularizer=regularizers.l1(0.01)))
    model.add(BatchNormalization())

    model.add(Flatten())
    model.add(Dropout(0.5))
    model.add(Dense(256, activation='sigmoid'))
    model.add(Dropout(0.5))
    model.add(Dense(2, activation='softmax'))

    opt_adam = keras.optimizers.Adam(lr=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
    model.compile(loss='categorical_crossentropy', optimizer=opt_adam, metrics=['accuracy'])

    return model

Ответы [ 4 ]

2 голосов
/ 05 апреля 2020

model.get_weights () вернет тензор в виде массива numpy. Вы можете сохранить эти веса в файле с расширением .npy, используя np.save ().

Чтобы сохранять веса каждую эпоху, вы можете использовать в Keras то, что называется обратными вызовами.

from keras.callbacks import ModelCheckpoint

перед выполнением model.fit определите контрольную точку, как показано ниже

checkpoint = ModelCheckpoint(.....), присвойте аргумент 'period' как 1, который назначает периодичность эпох. Это должно сделать это.

1 голос
/ 06 апреля 2020

Вы можете написать обратный вызов ModelCheckpoint, используя tf.keras.callbacks.ModelCheckpoint для сохранения весов в каждую эпоху. Если вы используете недавний Tensorflow, например TF2.1 или новее, то вам нужно использовать save_freq='epoch' для сохранения весов в каждую эпоху вместо использования period=1 в качестве другого упомянутого ответа. Пожалуйста, проверьте весь пример здесь

обратный вызов выглядит следующим образом

checkpoint_path = "./training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(
   checkpoint_path, verbose=1, save_weights_only=True,
   # Save weights, every epoch.
   save_freq='epoch')

вызов модели обучения

# Create a basic model instance
model=create_model()
model.save_weights(checkpoint_path.format(epoch=0))
model.fit(x_train, y_train,
         epochs = 50, callbacks = [cp_callback],
         validation_data = (x_test,y_test),
         verbose=0)

Надеюсь, это поможет. Спасибо!

1 голос
/ 05 апреля 2020

Вы должны использовать model.get_weights () и функцию LambdaCallback вместе:

  1. model.get_weights () : Возвращает список всех весовых тензоров в модели , как Numpy массивов.

    model = Sequential()
    weights = model.get_weights()
    
  2. LambdaCallback : Этот обратный вызов создан с анонимными функциями, которые будут вызываться в соответствующее время

    import json
    json_log = open('loss_log.json', mode='wt', buffering=1)
    json_logging_callback = LambdaCallback(
                on_epoch_end=lambda epoch, logs: json_log.write(
                    json.dumps({'epoch': epoch, 'loss': logs['loss']}) + '\n'),
                on_train_end=lambda logs: json_log.close()
    )
    
    model.fit(...,
              callbacks=[json_logging_callback])
    

Когда ваш код рассматривается, вы должны написать функцию обратного вызова и добавить к вашей модель :

import json
from keras.callbacks import LambdaCallback

json_log = open('loss_log.json', mode='wt', buffering=1)
json_logging_callback = LambdaCallback(
            on_epoch_end=lambda epoch, logs: json_log.write(
                json.dumps({'epoch': epoch, 
                            'loss': logs['loss'],
                            'weights': model.get_weights()}) + '\n'),
            on_train_end=lambda logs: json_log.close()
)

model.compile(loss='categorical_crossentropy',
              optimizer=opt_adam, 
              metrics=['accuracy'])

model.fit_generator(..., callbacks=[json_logging_callback])

Этот код запишите все веса во всех слоях в файл json. Если вы хотите сохранить веса в указанном слое c, просто измените код с помощью

model.layers[0].get_weights()
1 голос
/ 05 апреля 2020

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

Например.

checkpoint = ModelCheckpoint("best_model.hdf5", monitor='loss', verbose=1,
    save_best_only=True, mode='auto', period=1)

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test),
          callbacks=[checkpoint])

source = https://medium.com/@italojs / сберегательный ваш-папье-за-каждый-эпохальный keras обратных вызовов-b494d9648202

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