Tensorflow 通过 RNN 进行反向传播的 ValueError

我在 Tensorflow 中使用带有 BasicLSTMCells 的循环神经网络。基本来说,我有一个词 ID 的输入序列,我将每个 ID 转换为词嵌入,然后一次通过 RNN 传递词嵌入,并在读取整个序列后对单个词进行预测。我的嵌入矩阵的维度为 V x H,其中 V 是我的词汇表大小,H 是我的 RNN 中的隐藏单元数。为了预测下一个词,我将隐藏向量乘以大小为 H x V 的权重矩阵,然后计算 softmax。使用我描述的设置,一切似乎都按预期工作。我能够在一些示例上进行训练并做出合理的预测。然而,我注意到如果我尝试使用嵌入矩阵的转置,这将是一个大小为 H x V 的矩阵,而不是单独的 softmax 层矩阵,Tensorflow 会引发一个值错误,声称它未指定的某些东西的维度没有相同的秩。我已经验证了我的嵌入矩阵(嗯,它的转置)的维度与我创建的单独的 softmax 矩阵的维度相同。仅更改一行代码,从使用我的嵌入矩阵改为使用单独的 softmax 权重矩阵就会导致错误。我创建了一个相对较小的程序来演示我想做的事情,并展示是什么导致了错误。当我尝试使用只有单个隐藏层网络时,我无法在较小的网络上使错误发生。

import sysimport timeimport tensorflow as tffrom tensorflow.models.rnn import rnnfrom tensorflow.models.rnn import rnn_cellfrom tensorflow.models.rnn.rnn_cell import BasicLSTMCellimport numpy as npINPUT_LENGTH = 17BATCH_SIZE = 20VOCAB_SIZE = 11NUM_EPOCHS = 1000HIDDEN_UNITS = 100class Model(object):    def __init__(self, is_training):        initializer = tf.random_uniform_initializer(-1.0, 1.0)        self._target = tf.placeholder(tf.float32, [BATCH_SIZE, VOCAB_SIZE])        self._input_data=tf.placeholder(tf.int32,[BATCH_SIZE, INPUT_LENGTH])        self.embedding = tf.get_variable("embedding",                                    [VOCAB_SIZE, HIDDEN_UNITS],                                    initializer=initializer)        self.inputs = tf.split(1, INPUT_LENGTH,                          tf.nn.embedding_lookup(self.embedding, self._input_data))        self.inputs2 = [tf.squeeze(input_, [1]) for input_ in self.inputs]        cell = rnn_cell.BasicLSTMCell(num_units=HIDDEN_UNITS)        initial_state = cell.zero_state(BATCH_SIZE, tf.float32)        outputs, states = rnn.rnn(cell, self.inputs2,                                  initial_state=initial_state)        self._outputs = outputs[-1]        self.soft_w = tf.get_variable("softmax_w",                                 [HIDDEN_UNITS, VOCAB_SIZE],                                 initializer=initializer)        prod = tf.matmul(self._outputs, self.soft_w)#取消注释以下行会导致错误#        prod = tf.matmul(self._outputs, self.embedding, False, True)        soft_b = tf.get_variable("softmax_b", [VOCAB_SIZE],                                 initializer=initializer)        self._logits = tf.nn.bias_add(prod,soft_b)        self._loss = tf.nn.softmax_cross_entropy_with_logits(self._logits,                                                             self._target)        if not is_training:            return        learning_rate = .010001        optimizer = tf.train.GradientDescentOptimizer(learning_rate)        self._train_op = optimizer.minimize(self._loss)    def train(self, sess, inputs, targets):        t = np.zeros((BATCH_SIZE, VOCAB_SIZE))        for i, target in enumerate(targets):            t[i,target] = 1.0        inputs = np.array(inputs)        inputs = inputs.reshape(BATCH_SIZE,INPUT_LENGTH)        fd = {self._target:t,              self._input_data:inputs}        o = sess.run([self._train_op, self._loss, self._outputs, self.embedding, self.soft_w], feed_dict = fd)        print o[2].shape        print o[3].shape        print o[4].shape        sys.exit()        return np.mean(o[1])#这只是生成虚拟数据def read_data_rows(count):    ret = []    for i in range(count):        inputs = [4] * INPUT_LENGTH        output = 1        ret.append((inputs, output))    return retdef main():    start = time.time()    tf.set_random_seed(1)    print "creating model",time.time()-start    m = Model(is_training=True)    with tf.Session() as sess:        print "initializing variables", time.time()-start        tf.initialize_all_variables().run()        for epoch in range(NUM_EPOCHS):            train_rows = read_data_rows(100)            for row_num in range(0, len(train_rows), BATCH_SIZE):                qs = []                ans = []                batch = train_rows[row_num:row_num+BATCH_SIZE]                for b in batch:                    qs.append(b[0])                    ans.append(b[1])                m.train(sess, qs, ans)if __name__ == "__main__":    main()

我看到的错误是 ValueError:当取消注释我上面提到的行时,Shapes TensorShape([Dimension(100)]) 和 TensorShape([Dimension(17), Dimension(100)]) 必须具有相同的秩。导致我看到的错误的原因是什么?为什么嵌入矩阵不像矩阵 self.soft_w 那样被处理?


回答:

TensorFlow 的 0.6.0(及更早版本)发布中,在 tf.nn.embedding_lookup()tf.gather() 的梯度实现中存在一个错误,当索引参数(在您的代码中为 self._input_data)具有多个维度时。

升级到最新的源代码发布应该可以修复此错误。否则,这个提交包含了对 array_grad.py 的相关更改,这将使您的程序能够工作。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注