Tensorflow Autoencoder с пользовательскими примерами обучения из двоичного файла

Я пытаюсь адаптировать код Tensorflow Autoencoder, найденный здесь (https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/autoencoder.py), чтобы использовать мои собственные обучающие примеры. Мои обучающие примеры представляют собой одноканальные изображения 29 * 29 (уровень серого), постоянно сохраняемые как значения UINT8 в двоичном файле. Я создал модуль, который создает data_batches, который будет направлять обучение. Это модуль:

import tensorflow as tf

# various initialization variables
BATCH_SIZE = 128
N_FEATURES = 9

def batch_generator(filenames, record_bytes):
""" filenames is the list of files you want to read from. 
In this case, it contains only heart.csv
"""

record_bytes = 29**2 # 29x29 images per record
filename_queue = tf.train.string_input_producer(filenames)
reader = tf.FixedLengthRecordReader(record_bytes=record_bytes) # skip the first line in the file
_, value = reader.read(filename_queue)
print(value)

# record_defaults are the default values in case some of our columns are empty
# This is also to tell tensorflow the format of our data (the type of the decode result)
# for this dataset, out of 9 feature columns, 
# 8 of them are floats (some are integers, but to make our features homogenous, 
# we consider them floats), and 1 is string (at position 5)
# the last column corresponds to the lable is an integer

#record_defaults = [[1.0] for _ in range(N_FEATURES)]
#record_defaults[4] = ['']
#record_defaults.append([1])

# read in the 10 columns of data
content = tf.decode_raw(value, out_type=tf.uint8) 
#print(content)

# convert the 5th column (present/absent) to the binary value 0 and 1
#condition = tf.equal(content[4], tf.constant('Present'))
#content[4] = tf.where(condition, tf.constant(1.0), tf.constant(0.0))

# pack all UINT8 values into a tensor
features = tf.stack(content)
#print(features)

# assign the last column to label
#label = content[-1]

# The bytes read  represent the image, which we reshape
# from [depth * height * width] to [depth, height, width].
depth_major = tf.reshape(
  tf.strided_slice(content, [0],
                   [record_bytes]),
  [1, 29, 29])

# Convert from [depth, height, width] to [height, width, depth].
uint8image = tf.transpose(depth_major, [1, 2, 0])

# minimum number elements in the queue after a dequeue, used to ensure 
# that the samples are sufficiently mixed
# I think 10 times the BATCH_SIZE is sufficient
min_after_dequeue = 10 * BATCH_SIZE

# the maximum number of elements in the queue
capacity = 20 * BATCH_SIZE

# shuffle the data to generate BATCH_SIZE sample pairs
data_batch = tf.train.shuffle_batch([uint8image], batch_size=BATCH_SIZE, 
                                    capacity=capacity, min_after_dequeue=min_after_dequeue)

return data_batch

Затем я адаптирую код Autoencoder для загрузки batch_xs из моего входного кода пакетной подачи:

from __future__ import division, print_function, absolute_import

# Various initialization variables
DATA_PATH1 = 'data/building_extract_train.bin'

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# custom imports
import data_reader

# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)

# Parameters
learning_rate = 0.01
training_epochs = 20
batch_size = 256
display_step = 1
examples_to_show = 10

# Network Parameters
n_hidden_1 = 256 # 1st layer num features
n_hidden_2 = 128 # 2nd layer num features
#n_input = 784 # edge-data input (img shape: 28*28)
n_input = 841 # edge-data input (img shape: 29*29)

# tf Graph input (only pictures)
X = tf.placeholder("float", [None, n_input])

# create the data batches (queue)
# Accepts two parameters. The tensor containing the binary files and the    size of a record
data_batch = data_reader.batch_generator([DATA_PATH1],29**2)

weights = {
 'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
 'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
 'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])),
 'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])),
}
biases = {
 'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
 'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])),
 'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])),
 'decoder_b2': tf.Variable(tf.random_normal([n_input])),
}

# Building the encoder
def encoder(x):
 # Encoder Hidden layer with sigmoid activation #1
 layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
                               biases['encoder_b1']))
 # Decoder Hidden layer with sigmoid activation #2
 layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1,   weights['encoder_h2']),
                               biases['encoder_b2']))
 return layer_2


# Building the decoder
def decoder(x):
 # Encoder Hidden layer with sigmoid activation #1
 layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
                               biases['decoder_b1']))
 # Decoder Hidden layer with sigmoid activation #2
 layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1,       weights['decoder_h2']),
                               biases['decoder_b2']))
return layer_2

# Construct model
encoder_op = encoder(X)
decoder_op = decoder(encoder_op)

# Prediction
y_pred = decoder_op
# Targets (Labels) are the input data.
y_true = X

# Define loss and optimizer, minimize the squared error
cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
optimizer = tf.train.RMSPropOptimizer(learning_rate).minimize(cost)

# Initializing the variables
init = tf.global_variables_initializer()

# Launch the graph
with tf.Session() as sess:
 coord = tf.train.Coordinator()
 threads = tf.train.start_queue_runners(coord=coord)
 sess.run(init)
 total_batch = int(mnist.train.num_examples/batch_size)
 # Training cycle
 for epoch in range(training_epochs):
    # Loop over all batches
    for i in range(total_batch):
        #batch_xs, batch_ys = mnist.train.next_batch(batch_size)
        batch_xs = sess.run([data_batch])
        #print(batch_xs)
        #batch_xs = tf.reshape(batch_xs, [-1, n_input])
        # Run optimization op (backprop) and cost op (to get loss value)
        _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
    # Display logs per epoch step
    if epoch % display_step == 0:
        print("Epoch:", '%04d' % (epoch+1),
              "cost=", "{:.9f}".format(c))
 coord.request_stop()
 coord.join(threads)
 print("Optimization Finished!")

К сожалению, при запуске кода я получаю эту ошибку: ValueError: невозможно передать значение shape (1, 128, 29, 29, 1) для Tensor 'Placeholder: 0', которое имеет shape '(?, 841)'

Мой первый вопрос: почему у меня есть Тензоры формы (1, 128, 29, 29, 1), когда я ожидал (128,29,29,1)? Я что-то упустил?

Я также не понимаю следующий код и как его изменить, чтобы сравнить с моим набором данных:

 # Applying encode and decode over test set
 encode_decode = sess.run(
   y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})

Насколько я понимаю, этот код выполняет часть y_pred графика и передает первые 10 тестовых изображений ранее определенному заполнителю X. Если бы я использовал вторую очередь данных для моих тестовых изображений (29x29), как бы я ввел их в приведенный выше словарь?

Например, используя свой код, я мог бы определить data_batch_eval следующим образом:

data_batch_eval = data_reader.batch_generator([DATA_PATH_EVAL],29**2)   # eval set

Тем не менее, как мне извлечь первые 10 тестовых изображений для загрузки в словарь?


person divined    schedule 15.07.2017    source источник
comment
Какова цель вашей переменной features? Кажется, вы ее создали, но не используете.   -  person Anis    schedule 15.07.2017
comment
Я просто забыл это прокомментировать. Его нужно удалить.   -  person divined    schedule 17.07.2017


Ответы (1)


Мой первый вопрос: почему у меня есть Тензоры формы (1, 128, 29, 29, 1), когда я ожидал (128,29,29,1)? Я что-то упустил?

Вам нужно снять скобку в sessions.run:

 batch_xs = sess.run(data_batch)

К сожалению, при запуске кода я получаю эту ошибку: ValueError: невозможно передать значение shape (1, 128, 29, 29, 1) для Tensor 'Placeholder: 0', которое имеет shape '(?, 841)'

Вы объявили свой заполнитель X как [None, 841] и вводите вход [128, 29, 29, 1]:

 X = tf.placeholder("float", [None, n_input])

Измените либо ввод фида, либо заполнитель, чтобы оба имели одинаковый размер.

Примечание: ваша обработка очередей неэффективна, вы напрямую передаете data_batch в качестве входных данных в ваш network, а не через механизм feed in.

person vijay m    schedule 15.07.2017
comment
Спасибо за ответ. Он работал, удалив скобки и изменив форму на [29 ** 2]. К сожалению, для такой простой сети это очень медленно. Кажется, мне нужно использовать механизм feed_in. - person divined; 16.07.2017
comment
Да, как я уже сказал в своей заметке, вы неправильно обрабатываете очереди. Передайте свой data_batch прямо в encoder_op = encoder (data_batch). если вы хотите использовать обе очереди, а также feed_dict (во время вывода), вы можете использовать tf.placeholder_with_default(). В любом случае, это совсем другая проблема, откройте новую проблему, если у вас все еще есть проблемы, я решу их. - person vijay m; 16.07.2017