АвтоЭнкодер форма - PullRequest
       7

АвтоЭнкодер форма

0 голосов
/ 01 ноября 2018

Я пытаюсь создать автоэнкодер в 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. Я думаю, что это происходит из значения инициализации фильтра и смещения. Как я могу справиться с этим?

1 Ответ

0 голосов
/ 02 ноября 2018

Вы забыли предвзятость и активацию. Таким образом, ваша сеть слабее, чем PCA. Я предлагаю вам использовать tf.layers вместо. Если вы хотите использовать tf.nn, тогда, пожалуйста, используйте tf.get_variable. Кроме того, вы должны добавить: tf.nn.bias_add tf.nn.relu (или любая другая активация)

Если вы хотите знать, работает ли код, просто протестируйте его:

sess = tf.Session()
sess.run(tf.tf.global_variables_initializer())
test_output = sess.run(xo, feed_dict={ae_inputs : np.random.random((1, 32, 32, 1))}
print(test_output)

EDIT Итак, код, который вы разместили, использует в основном API tf.layers, в который включены смещение и активация. API tf.nn является более базовым и применяется только для свертки, но без активации или смещения.

Основываясь на ваших изменениях, я думаю, что вы хотите реализовать CAE в nn API. Типичный уровень кодера будет следующим:

conv = tf.nn.conv2d(
                     nput=input_tensor,
                     filter=tf.get_variable("conv_weight_name", shape=[height,
                                                                width,
                                                                number_input_feature_maps,
                                                                number_output_feature_maps]),
                     strides=[1, 1, 1, 1],
                     padding="SAME")
bias = tf.nn.bias_add(conv, tf.get_variable("name_bias",
                                            [number_output_feature_maps]))
layer_out = tf.nn.relu(bias)

Вот типичный слой для транспонированной свертки.

conv_transpose = tf.nn.conv2d_transpose(value=input_tensor,
                       filter=tf.get_variable("deconnv_weight_name", shape=[height,
                                                                     width,
                                                                     number_output_feature_maps,
                                                                     number_input_feature_maps]),
                       output_shape=[batc_size, height_output, width_ouput, feature_maps_output],
                       strides=[1, 1, 1, 1])
bias = tf.nn.bias_add(conv_transpose, tf.get_variable("name_bias", shape=[number_output_feature_maps]))

layer_out = tf.nn.relu(bias)
           `

Если у вас есть вопросы по поводу имен, просто задайте их в сети.

...