0

我最近开始深入学习深度学习,并对我对RNN和LSTM的理论和深入实际实现的理解充满信心。我写了一个非常简单的RNN,学习将两个二进制数字相加,只使用numpy。我现在试图熟悉TensorFlow API,以便不再需要从头开始构建我的模型。了解TensorFlow如何接收和处理数据时遇到的问题

尽管我对自己对神经网络和编程能力的理解充满信心,但在理解TensorFlow抽象模型的高层次以及如何使用数据时结构化。我打过的墙的一个例子是在下面的代码中,我试图实现一个简单的RNN,它接受一列整数列表/序列,然后学习如何将单个序列分类为增加或减少。 generate_data()输出两个列表:

  • data是在上[[1, 2, 3], [9, 8, 7]]的形式,并且是输入序列。
  • labels是列表1 s或0 s - a 1表示相应的序列正在增加,而a表示递减。

x是输入序列的占位符,而y是相应标签的占位符。我的思考过程是RNN接收每个输入序列作为x,单列张量,每行是序列的单个整数 - 展开的RNN中的单个时间步长。该RNN将随后输出RNN(的每个完整向前传播史后的单个INTEGR(01)一个整个x张量之后已经被处理。

我正在一个错误,在最后一行的是输入必须是一个我不明白这个单列张量如何不被视为一个序列,以及它如何被整形以便它成为一个序列。

作为一个附注,我所面临的下一个最大的误解是在所有理论解释中,我已经读过RNN,有3个加权矩阵 - 一个是从输入到隐藏状态,一个是从隐藏状态到输出,另一个是每个时间步的隐藏状态。 n使用TensorFlow似乎只有一个单一的加权矩阵。这是怎么回事? TensorFlow如何使用这个单一矩阵作为3个深层次抽象的抽象?我是否正确地在W = tf.Variable(tf.random_normal([sequence_len, output_dim]))这一行中塑造了这个矩阵?

from __future__ import print_function 
import tensorflow as tf 
from tensorflow.contrib import rnn 
import random 

sequence_len = 5  # Input Dimension 
max_num = 1000   # Must be >= than (sequence_len - 1) 
output_dim = 1 
hidden_dim = 16 
batch_size = 1000 

def generate_data(sample_size, seq_len=sequence_len, max = max_num): 
    data = [] 
    labels = [] 
    for _ in range(sample_size): 
     type = (1 if random.random() < 0.5 else 0) 
     temp = [] 
     if type == 1: 
      labels.append(1) 
      temp.append(random.randint(0, max_num - seq_len + 1)) 
      for i in range(1, seq_len): 
       temp.append(random.randint(temp[i - 1] + 1, max_num - seq_len + i + 1)) 
      data.append(temp) 
     if type == 0: 
      labels.append(0) 
      temp.append(random.randint(0 + seq_len - 1, max_num)) 
      for i in range(1, seq_len): 
       temp.append(random.randint(0 + seq_len - i - 1, temp[i - 1] - 1)) 
      data.append(temp) 
    return data, labels 

input_data, labels = generate_data(100000) 

x = tf.placeholder(tf.int32, [None, sequence_len]) 
y = tf.placeholder(tf.int32, [None, output_dim]) 

W = tf.Variable(tf.random_normal([sequence_len, output_dim])) 
b = tf.Variable(tf.random_normal([output_dim])) 

cell = rnn.BasicRNNCell(hidden_dim) 
outputs, states = tf.nn.static_rnn(cell, x, dtype=tf.int32) 

回答

1

tf.static_rnn预计Tensors按照documentation,因此它可以决定你的RNN的长度(注意,这必须运行之前确定的列表,这就是为什么你需要传递的Tensors,而不是一个Python列表Tensor):

输入:的输入端A长度T列表,每个张量形状[batch_size时,input_size]的,或这些元件的嵌套元组。

outputs, states = tf.nn.static_rnn(cell, [x], dtype=tf.int32)应该工作。

关于你身边的问题,部分答案可以在implementation of BasicRNNCell发现:

def call(self, inputs, state): 
    """Most basic RNN: output = new_state = act(W * input + U * state + B).""" 
    output = self._activation(_linear([inputs, state], self._num_units, True)) 
    return output, output 

但它确实取决于你选择使用RNNCell。这是您的模型的一部分,它将执行inputstate,statestatestateoutput逻辑。

+0

谢谢,这似乎是工作。我将继续使用我的RNN,并让我们知道是否有其他问题或误解。 – KOB

+0

我今天设法得到了我的NN _working_,但是我通过分析一个非常不同的玩具示例的代码来挖掘并实施类似的做法,就像我看到的适合的做法一样。不幸的是,我的模型根本没有学习。它的准确性是完全随机波动的。正如我所说,我是TensorFlow的新手,无法理解它为什么没有正确训练,因为这是我运行的TensorFlow中的第一个模型。这是我的代码:https://pastebin.com/9hJKyVgW – KOB