Как создать автоэнкодер, в котором веса кодера / декодера отражаются (транспонируются) - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь построить свою первую нейросеть Autoencoder, используя TensorFlow. Размеры слоев в кодере и декодере одинаковы, только в обратном порядке. Автоэнкодер учится сжимать и восстанавливать данные изображения до приемлемого стандарта, но я хотел бы попытаться улучшить его производительность, вместо этого используя декодер в качестве точной транспонирования кодера.

Я заблудился, как это сделать в TensorFlow.

Вот фрагмент конструкции моей сети:

imgW, imgH = 28, 28
encoderDims = [
    imgW * imgH,
    (imgW // 2) * (imgH // 2),
    (imgW // 3) * (imgH // 3),
    (imgW // 4) * (imgH // 4)
]
decoderDims = list(reversed(encoderDims))

encoderWeights, encoderBiases = [], []
decoderWeights, decoderBiases = [], []
for layer in range(len(encoderDims) - 1):
    encoderWeights.append(
        tf.Variable(tf.random_normal([encoderDims[layer], encoderDims[layer + 1]]))
    )
    encoderBiases.append(
        tf.Variable(tf.random_normal([encoderDims[layer + 1]]))
    )
    decoderWeights.append(
        tf.Variable(tf.random_normal([decoderDims[layer], decoderDims[layer + 1]]))
    )
    decoderBiases.append(
        tf.Variable(tf.random_normal([decoderDims[layer + 1]]))
    )

input = tf.placeholder(tf.float32, [None, imgW * imgH])
encoded = input
for layer in range(len(encoderDims) - 1):
    encoded = tf.add(tf.matmul(encoded, encoderWeights[layer]), encoderBiases[layer])
    encoded = tf.nn.sigmoid(encoded)

decoded = encoded
for layer in range(len(decoderDims) - 1):
    decoded = tf.add(tf.matmul(decoded, decoderWeights[layer]), decoderBiases[layer])
    if layer != len(decoderDims) - 2:
        decoded = tf.nn.sigmoid(decoded)

loss = tf.losses.mean_squared_error(labels=input, predictions=decoded)
train = tf.train.AdamOptimizer(learningRate).minimize(loss)

Две проблемы, которые я не знаю, как преодолеть:

  1. Как мне настроить только параметры энкодера во время тренировки относительно потери?
  2. Как я могу создать веса и смещения декодера таким образом, чтобы после каждой итерации обучения параметров кодера они устанавливались как транспонирование вновь настроенных параметров кодера?

1 Ответ

0 голосов
/ 05 июля 2018

Я сомневаюсь, что это превзойдет обычные автоэнкодеры. Но если вы хотите получить удивительно хорошие результаты, сообщите об этом сообществу. По вашим вопросам:

1.) Поскольку необходимо использовать некоторую ошибку восстановления между входом и выходом, единственный вариант - тренироваться со всей сетью (например, кодером и декодером в целом). Но вы можете установить флаг для переменных декодера, который предотвращает их изменение алгоритмом после инициализации. Установите их на trainable=False. После подготовки к эпохе вы можете вручную установить для них вес транспонированного энкодера.

2.) Здесь я не уверен, как вы интерпретируете «транспонирование». Если вы имеете в виду, что веса уровня 1 кодера должны соответствовать весам последнего уровня декодера, вы можете попробовать это:

for layer in range(len(encoderWeights)):
    decoderWeights[-layer-1] = tf.transpose(encoderWeights[layer])

Если вы хотите транспонировать матрицы слоев по отдельности, вы можете использовать сказанное tf.tranpose(). С математической точки зрения правильной обратной операцией умножения матриц будет обратная матрица, если она определена. TensorFlow предоставляет tf.matrix_inverse() для этого. Однако будьте очень осторожны при использовании этого, поскольку разумный результат не гарантирован.

...