Реализация RBM с тензорным потоком

Я пытаюсь реализовать RBM с tenorflow, вот код:

rbm.py

""" An rbm implementation for TensorFlow, based closely on the one in Theano """
import tensorflow as tf
import math
def sample_prob(probs):
    return tf.nn.relu(
        tf.sign(
            probs - tf.random_uniform(probs.get_shape())))
class RBM(object):
    def __init__(self, name, input_size, output_size):
        with tf.name_scope("rbm_" + name):
            self.weights = tf.Variable(
                tf.truncated_normal([input_size, output_size],
                    stddev=1.0 / math.sqrt(float(input_size))), name="weights")
            self.v_bias = tf.Variable(tf.zeros([input_size]), name="v_bias")
            self.h_bias = tf.Variable(tf.zeros([output_size]), name="h_bias")

    def propup(self, visible):
        return tf.nn.sigmoid(tf.matmul(visible, self.weights) + self.h_bias)

    def propdown(self, hidden):
        return tf.nn.sigmoid(tf.matmul(hidden, tf.transpose(self.weights)) + self.v_bias)

    def sample_h_given_v(self, v_sample):
        return sample_prob(self.propup(v_sample))

    def sample_v_given_h(self, h_sample):
        return sample_prob(self.propdown(h_sample))

    def gibbs_hvh(self, h0_sample):
        v_sample = self.sample_v_given_h(h0_sample)
        h_sample = self.sample_h_given_v(v_sample)
        return [v_sample, h_sample]

    def gibbs_vhv(self, v0_sample):
        h_sample = self.sample_h_given_v(v0_sample)
        v_sample = self.sample_v_given_h(h_sample)
        return  [h_sample, v_sample]

    def cd1(self, visibles, learning_rate=0.1):
        h_start = self.propup(visibles)
        v_end = self.propdown(h_start)
        h_end = self.propup(v_end)
        w_positive_grad = tf.matmul(tf.transpose(visibles), h_start)
        w_negative_grad = tf.matmul(tf.transpose(v_end), h_end)
        update_w = self.weights.assign_add(learning_rate * (w_positive_grad - w_negative_grad))
        update_vb = self.v_bias.assign_add(learning_rate * tf.reduce_mean(visibles - v_end, 0))
        update_hb = self.h_bias.assign_add(learning_rate * tf.reduce_mean(h_start - h_end, 0))
        return [update_w, update_vb, update_hb]

    def reconstruction_error(self, dataset):
        err = tf.stop_gradient(dataset - self.gibbs_vhv(dataset)[1])
        return tf.reduce_sum(err * err)

rbm_MNIST_test.py

import tensorflow as tf
import numpy as np
import rbm
import input_data

def build_model(X, w1, b1, wo, bo):
    h1 = tf.nn.sigmoid(tf.matmul(X, w1)+b1)
    model = tf.nn.sigmoid(tf.matmul(h1, wo)+bo)
    return model

def init_weight(shape):
    return tf.Variable(tf.random_normal(shape, mean=0.0, stddev=0.01))

def init_bias(dim):
    return tf.Variable(tf.zeros([dim]))

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
trX, trY, teX, teY = mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels

X = tf.placeholder("float", [None, 784])
Y = tf.placeholder("float", [None, 10])

rbm_layer = rbm.RBM("mnist", 784, 500)

for i in range(10):
    print "RBM CD: ", i
    rbm_layer.cd1(trX)

rbm_w, rbm_vb, rbm_hb = rbm_layer.cd1(trX)


wo = init_weight([500,10])
bo = init_bias(10)
py_x = build_model(X, rbm_w, rbm_hb, wo, bo)

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(py_x, Y))
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)
predict_op = tf.argmax(py_x, 1)

sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)

for i in range(10):
    for start, end in zip(range(0, len(trX), 128), range(128, len(trX), 128)):
        sess.run(train_op, feed_dict={X: trX[start:end], Y: trY[start:end]})
    print i, np.mean(np.argmax(teY, axis=1) ==
                     sess.run(predict_op, feed_dict={X: teX, Y: teY}))

но здесь появляется ошибка:

Файл "/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py", строка 1626, в as_graph_def поднять ValueError("GraphDef не может быть больше 2 ГБ.") ValueError: GraphDef не может быть больше, чем 2 ГБ.

Может кто-нибудь помочь мне решить это?

2 ответа

TensorFlow имеет ограничение 2 ГБ на GraphDef protos, что связано с ограничением реализации буферов протокола. Вы можете быстро достичь этого предела, если на вашем графике есть большие постоянные тензоры. В частности, если вы используете один и тот же массив NumPy несколько раз, TensorFlow добавит к вашему графику несколько постоянных тензоров.

В твоем случае, mnist.train.images вернулся input_data.read_data_sets это массив с плавающей точкой с формой (55000, 784)так что это о 164 MB, Вы передаете этот массив NumPy в rbm_layer.cd1и внутри этой функции, каждый раз, когда вы используете visiblesТензорный поток Const узел создается из массива numpy. Ты используешь visibiles в 3 местах, так что каждый звонок cd1 увеличивает размер графика примерно 492 MB, так что вы легко превышаете лимит. Решение состоит в том, чтобы создать константу TensorFlow один раз и передать эту константу cd1 функционировать так:

trX_constant = tf.constant(trX)
for i in range(10):
    print "RBM CD: ", i
    rbm_layer.cd1(trX_constant)

Кстати, я не уверен, каково ваше намерение в вышеупомянутом цикле. Обратите внимание, что cd1 функция просто добавляет assign_add узлы на графике, и на самом деле не выполняет присваивания. Если вы действительно хотите, чтобы эти назначения выполнялись во время обучения, вам следует рассмотреть возможность объединения этих назначений с помощью управляющих зависимостей в финал. train_op узел.

Чтобы ответить на вопрос @keveman, я думаю, что вы пытаетесь CD-k (Contrastive Divergence) шаг с помощью этого цикла.

Но я боюсь, что код так далеко не уместен, так как CD-k это функция, которая должна занять позицию автоматического дифференцирования в RBM, Это означает, что cost а также train_op неправильный способ использования градиентного спуска в RBM (что связано с особой ролью CD-k). Кстати, уровень RBM должен проходить обучение один за другим без полностью подключенного уровня, которого нет в вашем коде.

Я новичок в tenorflow, и я также хочу получить реализацию. Я думаю, что я бы предпочел не использовать Gradient Descent, предоставляемый tenorflow, поскольку CD-k для специальной дифференциации. Хотел бы я найти решение в ближайшее время.

Обновление: я работал над этой реализацией целый рабочий день. Итак, вот текущий статус. Я реализовал простую простую версию, но это просто неверный результат. Пожалуйста, обратитесь к коду и результат

Я просто ссылаюсь на конкретный подход от DeepLearnToolbox. Я думаю, что процедура, которую я пытаюсь реализовать через tensorflow Это нормально, но не знаю, что не так с практическим кодом.

Обновление 2: я пересмотрел код, и теперь я реализовал самый простой rbm через tenorflow. увидеть code and result ссылка выше.

Другие вопросы по тегам