У меня есть код, в котором я в функции создаю модель нейронной сети с заданными параметрами (количество слоёв и нейронов в них и подобное). Использую эту функцию для перебора моделей с целью найти лучшую модель (такое небольшое исследование). Например, начинаю с 2 слоёв по 11 нейронов, 2 слоя 12 нейронов, ... , 3 слоя 11 нейронов ... и так далее.
При этом, после обучения каждой модели, строю график изменения функции потерь и показателя качества модели по эпохам. Казалось бы мне остаётся посмотреть на сгенерированные при переборе графики и выбрать наилучшую модель, которая лучше обучилась за минимальное количество эпох. Но! Когда я выбираю лучшую модель из перебираемых и вызываю туже функцию только уже с заданными параметрами выбранной модели, получаю другой (не тот, что видел на графике при переборе) результат! И понятия не имею почему.
При переборе использую метод model.summary(), который выводит характеристики модели: имяСлоя_номер ---- размер входа/выхода и подобное...
Так вот, когда в цикле функция создания модели вызывается первый раз, то model.summary() выводит имена слоёв с номер, начиная с 1 и, допустим, последним с номером 5. То при втором вызове этой функции в цикле с другими параметрами, model.summary() выводит название первого слоя с номером, начиная с 6. Будто они как-то связаны, хотя при выходе из функции все созданные объекты должны теряться (удаляться).
Общая картина: последовательный перебор модели, начиная с некоторой модели x1 и заканчивая моделью xN, и отдельно создать и обучить сеть с параметрами как у xN, то результаты разные, а именно у модели, к которой мы пришли перебором, показатели на графике лучше. Кажется, что Keras при построении следующей модели использует предыдущее обучение, то есть она как бы предобучена, и с каждым разом показывает результат всё лучше. Почему так происходит?
def plot_res(result, n_epoch, n_hidden, c_hidden, batch_size):
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))
ax[0].set_ylim(ymin=-0.05, ymax=1.05)
ax[0].plot(range(1, n_epoch + 1), result.history['val_loss'],
linestyle='--', color='g', label='validation')
ax[0].plot(range(1, n_epoch + 1), result.history['loss'], color='y', label='train')
ax[0].set_xlabel('Эпохи')
ax[0].set_ylabel('Функция потерь')
ax[0].legend(loc='best')
ax[0].set_title('Изменение функции потерь')
ax[1].set_ylim(ymin=-0.05, ymax=1.05)
ax[1].plot(range(1, n_epoch + 1), result.history['val_acc'],
linestyle='--', color='g', label='validation')
ax[1].plot(range(1, n_epoch + 1), result.history['acc'], color='y', label='train')
ax[1].set_xlabel('Эпохи')
ax[1].set_ylabel('Показатель качества')
ax[1].legend(loc='best')
ax[1].set_title('Изменение показателя качества')
# fig.show()
fig.savefig('NN_eph{}_c_hd{}_n_hd{}_btch{}.png'.format(n_epoch, c_hidden, n_hidden, batch_size), dpi=300)
# Для тестирования
def neural_network(n_epoch=10,
batch_size=64,
verbose=0,
n_classes=2,
optimizer=Adam(),
n_hidden=38,
validation_split=0.2,
reshaped=11,
c_hidden=2):
x_train, x_test, y_train, y_test = prepare_data_base(n_classes, "DATA_BASE.csv")
model = Sequential()
model.add(Dense(n_hidden, input_shape=(reshaped,)))
model.add(Activation('relu'))
for _ in range(c_hidden):
model.add(Dense(n_hidden))
model.add(Activation('relu'))
model.add(Dense(n_classes))
model.add(Activation('softmax'))
model.summary()
model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=["accuracy"])
result = model.fit(x_train, y_train, batch_size=batch_size, epochs=n_epoch,
verbose=verbose, validation_split=validation_split)
score = model.evaluate(x_test, y_test, verbose=verbose)
print("Test score: ", score[0])
print("Test accuracy: ", score[1])
plot_res(result, n_epoch, n_hidden, c_hidden, batch_size)
model.save("model_eph{}_c_hd{}_n_hd{}_btch{}.json".format(n_epoch, c_hidden, n_hidden, batch_size))