难以理解 TensorFlow 如何接收和处理数据
Trouble with understanding how TensorFlow receives and processes data
我最近开始学习深度学习,我对自己对 RNN 和 LSTM 的理论和深入实践的理解充满信心。我写了一个非常简单的 RNN,它学习将两个二进制数相加,只使用 numpy。我现在正在尝试熟悉 TensorFlow API,这样我就不必再从头开始构建模型了。
尽管我对自己对神经网络的理解和编程能力很有信心,但在理解 TensorFlow 抽象模型的高层以及如何使用数据时,我总是碰壁,这让我感到非常沮丧应该结构化。下面的代码是我撞墙的一个例子,我试图实现一个简单的 RNN,它接受一个 lists/sequences 整数列表,然后将学习如何将单个序列分类为增加或减少。 generate_data()
输出两个列表:
data
是[[1, 2, 3], [9, 8, 7]]
上的形式,是输入序列。
labels
是 1
s 或 0
s 的列表 - 1 表示相应的序列在增加,0 表示减少。
x
是输入序列的占位符,y
是相应标签的占位符。我的想法是让 RNN 接收每个输入序列作为 x
,一个单列张量,每行是序列的单个整数 - 展开的 RNN 中的单个时间步。然后,RNN 将在 RNN 的每次完全前向传播之后(在处理完一个完整的 x
张量之后输出一个整数(0
或 1
)。
我收到一个错误,在最后一行输入必须是一个序列。我不明白为什么这个单列张量不被认为是一个序列,以及它需要如何整形才能成为一个序列。
附带说明一下,我的下一个最大误解是,在我读过的所有 RNN 理论解释中,有 3 个加权矩阵 - 一个从输入到隐藏状态,一个从隐藏状态到输出,以及每个时间步的隐藏状态之间的一个。我看到的所有使用 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)
tf.static_rnn
需要 documentation 的 Tensors
列表,因此它可以确定您的 RNN 的长度(请注意,这必须在运行时之前确定,这就是您需要的原因传递 Tensors
的 python 列表而不是 Tensor
):
inputs: A length T list of inputs, each a Tensor of shape [batch_size, input_size], or a nested tuple of such elements.
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
。这是模型的一部分,它将实现 input
到 state
、state
到 state
和 state
到 output
逻辑。
我最近开始学习深度学习,我对自己对 RNN 和 LSTM 的理论和深入实践的理解充满信心。我写了一个非常简单的 RNN,它学习将两个二进制数相加,只使用 numpy。我现在正在尝试熟悉 TensorFlow API,这样我就不必再从头开始构建模型了。
尽管我对自己对神经网络的理解和编程能力很有信心,但在理解 TensorFlow 抽象模型的高层以及如何使用数据时,我总是碰壁,这让我感到非常沮丧应该结构化。下面的代码是我撞墙的一个例子,我试图实现一个简单的 RNN,它接受一个 lists/sequences 整数列表,然后将学习如何将单个序列分类为增加或减少。 generate_data()
输出两个列表:
data
是[[1, 2, 3], [9, 8, 7]]
上的形式,是输入序列。labels
是1
s 或0
s 的列表 - 1 表示相应的序列在增加,0 表示减少。
x
是输入序列的占位符,y
是相应标签的占位符。我的想法是让 RNN 接收每个输入序列作为 x
,一个单列张量,每行是序列的单个整数 - 展开的 RNN 中的单个时间步。然后,RNN 将在 RNN 的每次完全前向传播之后(在处理完一个完整的 x
张量之后输出一个整数(0
或 1
)。
我收到一个错误,在最后一行输入必须是一个序列。我不明白为什么这个单列张量不被认为是一个序列,以及它需要如何整形才能成为一个序列。
附带说明一下,我的下一个最大误解是,在我读过的所有 RNN 理论解释中,有 3 个加权矩阵 - 一个从输入到隐藏状态,一个从隐藏状态到输出,以及每个时间步的隐藏状态之间的一个。我看到的所有使用 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)
tf.static_rnn
需要 documentation 的 Tensors
列表,因此它可以确定您的 RNN 的长度(请注意,这必须在运行时之前确定,这就是您需要的原因传递 Tensors
的 python 列表而不是 Tensor
):
inputs: A length T list of inputs, each a Tensor of shape [batch_size, input_size], or a nested tuple of such elements.
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
。这是模型的一部分,它将实现 input
到 state
、state
到 state
和 state
到 output
逻辑。