Создание автоэнкодера, в котором вход является частью полной модели - PullRequest
0 голосов
/ 07 июня 2019

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

Это подзадача другого вопроса, который я написал: Как создать автоэнкодер, где каждый слой кодера должен представлять собой слой декодера . В этом вопросе я попытался создать автоэнкодер, в котором каждая пара соответствующих слоев также обучается как автоэнкодер. К сожалению, пользовательский слой регуляризации, который использовался для определения суб-авто-кодеров, не прекращает обратное распространение в начале суб-авто-кодера.

from keras.layers import Dense
from keras.datasets import mnist
from keras.models import Model
from keras.layers import Input
import keras
import numpy as np

# Define shape of the network, layers, some hyperparameters and training data
sizes = [784, 400, 200, 100, 50]
up_layers = []
down_layers = []
for i in range(1, len(sizes)):
    layer = Dense(units=sizes[i], activation='sigmoid', input_dim=sizes[i-1])
    up_layers.append(layer)
for i in range(len(sizes)-2, -1, -1):
    layer = Dense(units=sizes[i], activation='sigmoid', input_dim=sizes[i+1])
    down_layers.append(layer)

batch_size = 128
num_classes = 10
epochs = 1
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
x_train = x_train.reshape([x_train.shape[0], 28*28])
x_test = x_test.reshape([x_test.shape[0], 28*28])


y_train = x_train
y_test = x_test

optimizer = keras.optimizers.Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)



output = input = Input(shape=(sizes[0],))
#define first layer and set not to propagate the gradients to it
output_to_train = up_layers[0](output)
output = keras.layers.Lambda(lambda x: keras.backend.stop_gradient(x))(output_to_train)
for i in range(1, len(up_layers)):
    output = up_layers[i](output)
for i in range(0, len(down_layers)-1):
    output = down_layers[i](output)
crs = [output]
losses = [keras.losses.mean_squared_error]

network = Model([input], crs)
network.compile(loss=losses, optimizer=optimizer)

training_data = [output_to_train(y_train)] #should contain the output of the first layer for the training data, but dynamic
test_data = [output_to_train(y_test)] #should contain the output of the first layer for the test data, but dynamic


# Save the weights of first layer before training (those should remain unchanged)
weights_before = up_layers[0].get_weights()[0]

network.fit(x_train, training_data, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, test_data))

# Compare weights to weights after training (the sum of the difference has to be zero)
weights_after = up_layers[0].get_weights()[0]
print('\nSum of difference:', np.sum(weights_before-weights_after))

В показанном коде я просто анализирую тренировочные данные через первый слой и использую этот результат в качестве желаемого результата. Это не динамично, а создается один раз перед тренировкой. Поскольку я хочу научить первый слой другому методу наряду с остальной частью показанной модели, это не точное представление.

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