Я пытаюсь создать автоэнкодер в Tensorflow без использования contriib.
Вот оригинальный код
https://github.com/Machinelearninguru/Deep_Learning/blob/master/TensorFlow/neural_networks/autoencoder/simple_autoencoder.py
Вот программа, которую я изменяю:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
ae_inputs = tf.placeholder(tf.float32, (None, 32, 32, 1)) # input to the network (MNIST images)
xi = tf.nn.conv2d(ae_inputs,
filter=tf.Variable(tf.random_normal([5,5,1,32])),
strides=[1,2,2,1],
padding='SAME')
print("xi {0}".format(xi))
xi = tf.nn.conv2d(xi,
filter=tf.Variable(tf.random_normal([5,5,32,16])),
strides=[1,2,2,32],
padding='SAME')
print("xi {0}".format(xi))
xi = tf.nn.conv2d(xi,
filter=tf.Variable(tf.random_normal([5,5,16,8])),
strides=[1,4,4,16],
padding='SAME')
print("xi {0}".format(xi))
xo = tf.nn.conv2d_transpose(xi,
filter=tf.Variable(tf.random_normal([5,5,16,8])),
output_shape=[1, 8, 8, 16],
strides=[1,4,4,1],
padding='SAME')
print("xo {0}".format(xo))
xo = tf.nn.conv2d_transpose(xo,
filter=tf.Variable(tf.random_normal([5,5,32,16])),
output_shape=[1, 16, 16, 32],
strides=[1,2,2,1],
padding='SAME')
print("xo {0}".format(xo))
xo = tf.nn.conv2d_transpose(xo,
filter=tf.Variable(tf.random_normal([5,5,1,32])),
output_shape=[1, 32, 32, 1],
strides=[1,2,2,1],
padding='SAME')
print("xo {0}".format(xo))
И результат печати таков:
xi Tensor («Conv2D: 0», shape = (?, 16, 16, 32), dtype = float32)
xi Tensor («Conv2D_1: 0», shape = (?, 8, 8, 16), dtype = float32)
xi Tensor («Conv2D_2: 0», shape = (?, 2, 2, 8), dtype = float32)
xo Tensor ("conv2d_transpose: 0", shape = (1, 8, 8, 16), dtype = float32)
xo Tensor ("conv2d_transpose_1: 0", shape = (1, 16, 16, 32), dtype = float32)
xo Tensor («conv2d_transpose_2: 0», shape = (1, 32, 32, 1), dtype = float32)
Кажется, что вывод имеет хорошую форму, но я не совсем уверен во всех параметрах conv2 и conv2_transpose.
Может ли кто-нибудь исправить мой код, если это необходимо
редактирование:
@Lau Я добавляю функцию relu, как вы говорите, но я не знаю, куда добавить смещение:
xi = tf.nn.conv2d(ae_inputs,
filter=tf.Variable(tf.random_normal([5,5,1,32])),
strides=[1,2,2,1],
padding='SAME')
xi = tf.nn.relu(xi)
# xi = max_pool(xi,2)
print("xi {0}".format(xi))
xi = tf.nn.conv2d(xi,
filter=tf.Variable(tf.random_normal([5,5,32,16])),
strides=[1,2,2,1],
padding='SAME')
xi = tf.nn.relu(xi)
# xi = max_pool(xi,2)
print("xi {0}".format(xi))
xi = tf.nn.conv2d(xi,
filter=tf.Variable(tf.random_normal([5,5,16,8])),
strides=[1,4,4,1],
padding='SAME')
xi = tf.nn.relu(xi)
# xi = max_pool(xi,4)
print("xi {0}".format(xi))
xo = tf.nn.conv2d_transpose(xi,
filter=tf.Variable(tf.random_normal([5,5,16,8])),
output_shape=[tf.shape(xi)[0], 8, 8, 16],
strides=[1,4,4,1],
padding='SAME')
xo = tf.nn.relu(xo)
print("xo {0}".format(xo))
xo = tf.nn.conv2d_transpose(xo,
filter=tf.Variable(tf.random_normal([5,5,32,16])),
output_shape=[tf.shape(xo)[0], 16, 16, 32],
strides=[1,2,2,1],
padding='SAME')
xo = tf.nn.relu(xo)
print("xo {0}".format(xo))
xo = tf.nn.conv2d_transpose(xo,
filter=tf.Variable(tf.random_normal([5,5,1,32])),
output_shape=[tf.shape(xo)[0], 32, 32, 1],
strides=[1,2,2,1],
padding='SAME')
xo = tf.nn.tanh(xo)
print("xo {0}".format(xo))
return xo
Я не понимаю, в чем разница с исходным кодом:
# encoder
# 32 x 32 x 1 -> 16 x 16 x 32
# 16 x 16 x 32 -> 8 x 8 x 16
# 8 x 8 x 16 -> 2 x 2 x 8
print('inputs {0}'.format(inputs))
net = lays.conv2d(inputs, 32, [5, 5], stride=2, padding='SAME')
print('net {0}'.format(net))
net = lays.conv2d(net, 16, [5, 5], stride=2, padding='SAME')
print('net {0}'.format(net))
net = lays.conv2d(net, 8, [5, 5], stride=4, padding='SAME')
print('net {0}'.format(net))
# decoder
# 2 x 2 x 8 -> 8 x 8 x 16
# 8 x 8 x 16 -> 16 x 16 x 32
# 16 x 16 x 32 -> 32 x 32 x 1
net = lays.conv2d_transpose(net, 16, [5, 5], stride=4, padding='SAME')
print('net {0}'.format(net))
net = lays.conv2d_transpose(net, 32, [5, 5], stride=2, padding='SAME')
print('net {0}'.format(net))
net = lays.conv2d_transpose(net, 1, [5, 5], stride=2, padding='SAME', activation_fn=tf.nn.tanh)
print('net {0}'.format(net))
return net
Редактировать2:
@ Лау Я делаю новую версию автоэнкодера с вашими модификациями:
mean = 0
stdvev = 0.1
with tf.name_scope('L0'):
xi = tf.nn.conv2d(ae_inputs,
filter=tf.truncated_normal([5,5,1,32], mean = mean, stddev=stdvev),
strides=[1,1,1,1],
padding='SAME')
xi = tf.nn.bias_add(xi, bias_variable([32]))
xi = max_pool(xi,2)
print("xi {0}".format(xi))
with tf.name_scope('L1'):
xi = tf.nn.conv2d(xi,
filter=tf.truncated_normal([5,5,32,16], mean = mean, stddev=stdvev),
strides=[1,1,1,1],
padding='SAME')
xi = tf.nn.bias_add(xi, bias_variable([16]))
xi = max_pool(xi,2)
print("xi {0}".format(xi))
with tf.name_scope('L2'):
xi = tf.nn.conv2d(xi,
filter=tf.truncated_normal([5,5,16,8], mean = mean, stddev=stdvev),
strides=[1,1,1,1],
padding='SAME')
xi = tf.nn.bias_add(xi, bias_variable([8]))
xi = max_pool(xi,4)
print("xi {0}".format(xi))
with tf.name_scope('L3'):
xo = tf.nn.conv2d_transpose(xi,
filter=tf.truncated_normal([5,5,16,8], mean = mean, stddev=stdvev),
output_shape=[tf.shape(xi)[0], 8, 8, 16],
strides=[1,4,4,1],
padding='SAME')
xo = tf.nn.bias_add(xo, bias_variable([16]))
print("xo {0}".format(xo))
with tf.name_scope('L4'):
xo = tf.nn.conv2d_transpose(xo,
filter=tf.truncated_normal([5,5,32,16], mean = mean, stddev=stdvev),
output_shape=[tf.shape(xo)[0], 16, 16, 32],
strides=[1,2,2,1],
padding='SAME')
xo = tf.nn.bias_add(xo, bias_variable([32]))
print("xo {0}".format(xo))
with tf.name_scope('L5'):
xo = tf.nn.conv2d_transpose(xo,
filter=tf.truncated_normal([5,5,1,32], mean = mean, stddev=stdvev),
output_shape=[tf.shape(xo)[0], 32, 32, 1],
strides=[1,2,2,1],
padding='SAME')
xo = tf.nn.bias_add(xo, bias_variable([1]))
xo = tf.nn.tanh(xo)
print("xo {0}".format(xo))
Но результат один и тот же, декодированные значения не совпадают.
Edit3:
Я изменяю определение фильтра с
filter=tf.truncated_normal([5,5,16,8], mean = mean, stddev=stdvev),
до
filter= tf.get_variable('filter2',[5,5,16,8]),
Результат, кажется, сходится к лучшему результату, но все же сходится к другому значению. В оригинальном коде (0.006) и моей версии 0.015. Я думаю, что это происходит из значения инициализации фильтра и смещения. Как я могу справиться с этим?