Сохранение модели и её весов в Keras

Добрый день, уважаемые читатели. Мы уже разобрали кучу приёмов, связанных с библиотекой Keras, Sklearn и т.д. Однако мы ещё не разбирали сохранение весов модели Keras и самой модели в отдельный файл (да, была статья про консервацию модели, но это немного другое).

Сегодня мы разберём этот аспект, используя такой инструмент, как callback, а также такие форматы файлов как json и h5.

Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!

Импорты и загрузка данных

Тут всё просто. В моих статьях неоднократно совершался этот шаг, так что все читатели уже в курсе делов :)

In[1]:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

from tensorflow.keras.models import Sequential, model_from_json
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.callbacks import ModelCheckpoint

In[2]:
dataset = load_breast_cancer()
X = dataset.data
y = dataset.target
del dataset

X.shape, y.shape

Out[2]:
((569, 30), (569,))
In[3]:
X_train, X_test, y_train, y_test = train_test_split(X,
                          y,
                          test_size=0.1)

X_train.shape, y_train.shape

Out[3]:
((512, 30), (512,))

Построение модели

Теперь построим модель. Создадим функцию, которая возвращает скомпилированную модель:

In[4]:
def build_model():
   
  model = Sequential()
   
  model.add(Dense(16, activation='relu'))
  model.add(Dropout(0.2))
  model.add(Dense(16, activation='relu'))
  model.add(Dense(1, activation='sigmoid'))
   
  model.compile(optimizer='rmsprop',
                loss='binary_crossentropy',
                metrics=['accuracy'])
   
  return model

А здесь начинается самое интересное. Мы передадим в метод fit() дополнительный аргумент callbacks.

Наш «отклик» будет сохранять лучшую вариацию весов в отдельный файл на этапе обучения.

Обучим модель, применив отклик:

In[5]:
model = build_model()

weights_file = 'weights.h5'
callback = ModelCheckpoint(weights_file,
              monitor='acc',
              mode='max',
              save_best_only=True)

model.fit(X_train, 
     y_train, 
     validation_data=[X_test, y_test],
     epochs=10,
     batch_size=8,
     callbacks=[callback])

acc = accuracy_score(y_test, model.predict(X_test).flat)
acc

Out[5]:
0.7017543859649122

Для сохранения самой модели мы воспользуемся файлом с форматом JSON. У моделей Keras существует метод to_json(), который возвращает представление модели в виде словаря. Запишем этот словарь в файл.

In[6]:
json_file = 'model.json'
model_json = model.to_json()

with open(json_file, 'w') as f:
  f.write(model_json)

Теперь загрузим модель из файла и присвоим ей веса из файла .h5.

In[7]:
with open(json_file, 'r') as f:
  loaded_model = model_from_json(f.read())
   
loaded_model.load_weights('weights.h5')
loaded_acc = accuracy_score(y_test, loaded_model.predict(X_test).flat)

loaded_acc == acc

Out[7]:
True

Таким образом, мы полностью возобновили модель из двух файлов.

Заключение

Таким образом, мы научились выполнять сохранение модели и её веса, а потом загружать её обратно. Программный интерфейс — очень прост. Также вы можете сохранять модель в YAML-файл, для этого просто «json» замените на «yaml» во всей программе :)

Документ .ipynb, который вы можете просмотреть и изменить по своему усмотрению, находится по ссылке.

Также рекомендую прочитать статью Функциональный API библиотеки Keras. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.