Реализация 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
ссылка выше.