Керас: неконтролируемая предварительная тренировка убивает производительность - PullRequest
0 голосов
/ 24 февраля 2019

Я пытаюсь обучить глубокому классификатору в Керасе как с предварительной подготовкой скрытых слоев, так и без нее, с помощью сложенных автоэнкодеров.Моя проблема в том, что предварительная подготовка, по-видимому, резко снижает производительность (т. Е. Если pretrain установлен в False в коде ниже, ошибка обучения на уровне окончательной классификации сходится гораздо быстрее).Это кажется мне совершенно возмутительным, учитывая, что предварительная подготовка должна только инициализировать веса скрытых слоев, и я не понимаю, как это может полностью убить производительность моделей, даже если эта инициализация работает не очень хорошо.Я не могу включить конкретный набор данных, который я использовал, но эффект должен произойти для любого подходящего набора данных (например, minist).Что здесь происходит и как я могу это исправить?

РЕДАКТИРОВАТЬ: код теперь воспроизводим с данными MNIST, отпечатки конечных строк изменяются в функции потерь, которая значительно ниже приповышение квалификации.Я также немного изменил код и добавил примеры кривых обучения ниже:

enter image description here

from functools import partial

import matplotlib.pyplot as plt
from keras.datasets import mnist
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import SGD
from keras.regularizers import l2
from keras.utils import to_categorical

(inputs_train, targets_train), _ = mnist.load_data()

inputs_train = inputs_train[:1000].reshape(1000, 784)
targets_train = to_categorical(targets_train[:1000])

hidden_nodes = [256] * 4
learning_rate = 0.01
regularization = 1e-6
epochs = 30

def train_model(pretrain):
    model = Sequential()

    layer = partial(Dense,
                    activation='sigmoid',
                    kernel_initializer='random_normal',
                    kernel_regularizer=l2(regularization))

    for i, hn in enumerate(hidden_nodes):
        kwargs = dict(units=hn, name='hidden_{}'.format(i + 1))

        if i == 0:
            kwargs['input_dim'] = inputs_train.shape[1]

        model.add(layer(**kwargs))

    if pretrain:
        # train autoencoders
        inputs_train_ = inputs_train.copy()

        for i, hn in enumerate(hidden_nodes):
            autoencoder = Sequential()

            autoencoder.add(layer(units=hn,
                                  input_dim=inputs_train_.shape[1],
                                  name='hidden'))

            autoencoder.add(layer(units=inputs_train_.shape[1],
                                  name='decode'))

            autoencoder.compile(optimizer=SGD(lr=learning_rate, momentum=0.9),
                                loss='binary_crossentropy')

            autoencoder.fit(
                inputs_train_,
                inputs_train_,
                batch_size=32,
                epochs=epochs,
                verbose=0)

            autoencoder.pop()

            model.layers[i].set_weights(autoencoder.layers[0].get_weights())

            inputs_train_ = autoencoder.predict(inputs_train_)

    num_classes = targets_train.shape[1]

    model.add(Dense(units=num_classes,
                    activation='softmax',
                    name='classify'))

    model.compile(optimizer=SGD(lr=learning_rate, momentum=0.9),
                  loss='categorical_crossentropy')

    h = model.fit(
        inputs_train,
        targets_train,
        batch_size=32,
        epochs=epochs,
        verbose=0)

    return h.history['loss']

plt.plot(train_model(pretrain=False), label="Without Pre-Training")
plt.plot(train_model(pretrain=True), label="With Pre-Training")

plt.xlabel("Epoch")
plt.ylabel("Cross-Entropy")

plt.legend()

plt.show()
...