【问题标题】:RBM implementation with tensorflow使用张量流实现 RBM
【发布时间】:2016-07-13 21:10:55
【问题描述】:

我正在尝试用 tensorflow 实现 RBM,代码如下:

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 中 raise ValueError("GraphDef 不能大于 2GB。") ValueError: GraphDef 不能大于 2GB。

有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    TensorFlow 在GraphDef protos 上确实有 2GB 的限制,这源于协议缓冲区实现的限制。如果您的图表中有较大的常数张量,您可以快速达到该限制。特别是,如果您多次使用 same numpy 数组,TensorFlow 会在您的图中添加多个常量张量。

    在您的情况下,input_data.read_data_sets 返回的mnist.train.images 是一个形状为(55000, 784) 的numpy 浮点数组,所以它大约是164 MB。您将该 numpy 数组传递给 rbm_layer.cd1,然后在该函数内部,每次使用 visibles 时,都会从该 numpy 数组创建一个 TensorFlow Const 节点。您在 3 个位置使用 visibiles,因此每次调用 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 节点。

    【讨论】:

      【解决方案2】:

      为了解决@keveman 的问题,我认为您正在尝试通过使用该循环来实现CD-k(对比分歧)步骤。

      但我担心代码远不合适,因为CD-k 是应该在RBM 中占据自动微分位置的函数。这意味着costtrain_op 不是与RBM 中的梯度下降 一起使用的正确方法(这是因为CD-k 的特殊作用)。顺便说一句,RBM 层应该在没有全连接层的情况下一层一层地训练,这不在你的代码中。

      我是 tensorflow 的新手,我也想获得实现。我想我宁愿不使用 tensorflow 提供的 Gradient Descent ,因为我需要 CD-k 进行特殊区分。希望我能尽快找到解决方案。

      更新: 我已经为这个实现工作了一整天。所以,这是当前的状态。我已经实现了一个简单直接的版本,但它只是得到错误的结果。 请参考code and result

      我只是参考DeepLearnToolbox的具体做法。我认为我试图通过tensorflow 实现的过程是可以的,但不知道实际代码出了什么问题。

      更新2:我已经修改了代码,现在我已经通过tensorflow实现了最简单的rbm。请参阅上面的code and result 链接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-10
        • 1970-01-01
        相关资源
        最近更新 更多