Задать вопрос
@Sanderses
student

Почему при последовательном создании моделей в Keras они каким-то образом между собой зависят, хотя, наверное, не должны?

У меня есть код, в котором я в функции создаю модель нейронной сети с заданными параметрами (количество слоёв и нейронов в них и подобное). Использую эту функцию для перебора моделей с целью найти лучшую модель (такое небольшое исследование). Например, начинаю с 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))
  • Вопрос задан
  • 184 просмотра
Подписаться 2 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ivodopyanov
NLP, python, numpy, tensorflow
Возможно, глобальный инкремент в номерах слоев может быть связан с тем, что сессия Tensorflow хранится в Keras глобально в tensorflow_backend.py и названия переменных по умолчанию должны быть уникальны в рамках сессий. Это если бэкенд - TF.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы