实现具有连续输入和离散输出的生成 RNN
Implementing a Generative RNN with continuous input and discrete output
我目前正在使用生成 RNN 对序列中的索引进行分类(有点像说某事是噪音还是不是噪音)。
我的输入是连续的(即介于 0 和 1 之间的实数值),我的输出是(0 或 1)。
例如,如果模型将大于 0.5 的数字标记为 1,否则标记为 0,
[.21, .35, .78, .56, ..., .21] => [0, 0, 1, 1, ..., 0]:
0 0 1 1 0
^ ^ ^ ^ ^
| | | | |
o->L1 ->L2 ->L3 ->L4 ->... ->L10
^ ^ ^ ^ ^
| | | | |
.21 .35 .78 .56 ... .21
使用
n_steps = 10
n_inputs = 1
n_neurons = 7
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])
cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn.relu)
rnn_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
rnn_outputs 变成一个 (?, 10, 7) 形状的张量,假设每 10 个时间步长有 7 个输出。
以前,我 运行 包装输出投影的以下片段 rnn_outputs
以获得每个序列的分类标签。
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
loss = tf.reduce_mean(xentropy)
我如何 运行 类似 rnn_outputs 的内容来获得序列?
具体来说,
1.我可以从每个步骤中获取 rnn_output 并将其输入 softmax 吗?
curr_state = rnn_outputs[:,i,:]
logits = tf.layers.dense(states, n_outputs)
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
2。我应该使用什么损失函数,它应该应用于每个序列的每个值吗?(对于序列 i 和步骤 j , loss = y_{ij} (true) - y_{ij}(predicted)
)?
我的损失应该是loss = tf.reduce_mean(np.sum(xentropy))
吗?
编辑
看来我正在尝试实现类似于 https://machinelearningmastery.com/develop-bidirectional-lstm-sequence-classification-python-keras/ in TensorFlow 中的类似内容。
在 Keras 中,有一个 TimeDistributed
函数:
You can then use TimeDistributed to apply a Dense layer to each of the
10 timesteps, independently
我将如何在 Tensorflow 中实现类似的东西?
首先,您似乎在进行 seq-to-seq 建模。在这类问题中,使用编码器-解码器架构通常是一个好主意,而不是从相同的 RNN 预测序列。 Tensorflow 在名称 "Neural Machine Translation (seq2seq) Tutorial" 下有一个关于它的大教程,我建议您查看。
但是,如果 n_steps
是已知的 静态 (尽管使用 dynamic_rnn
),您所询问的体系结构也是可能的。在这种情况下,可以计算每个单元格输出的交叉熵,然后将所有损失相加。如果 RNN 长度也是动态的也是可能的,但会更复杂。这是代码:
n_steps = 2
n_inputs = 3
n_neurons = 5
X = tf.placeholder(dtype=tf.float32, shape=[None, n_steps, n_inputs], name='x')
y = tf.placeholder(dtype=tf.int32, shape=[None, n_steps], name='y')
basic_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
# Reshape to make `time` a 0-axis
time_based_outputs = tf.transpose(outputs, [1, 0, 2])
time_based_labels = tf.transpose(y, [1, 0])
losses = []
for i in range(n_steps):
cell_output = time_based_outputs[i] # get the output, can do apply further dense layers if needed
labels = time_based_labels[i] # get the label (sparse)
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=cell_output)
losses.append(loss) # collect all losses
total_loss = tf.reduce_sum(losses) # compute the total loss
我目前正在使用生成 RNN 对序列中的索引进行分类(有点像说某事是噪音还是不是噪音)。
我的输入是连续的(即介于 0 和 1 之间的实数值),我的输出是(0 或 1)。
例如,如果模型将大于 0.5 的数字标记为 1,否则标记为 0,
[.21, .35, .78, .56, ..., .21] => [0, 0, 1, 1, ..., 0]:
0 0 1 1 0
^ ^ ^ ^ ^
| | | | |
o->L1 ->L2 ->L3 ->L4 ->... ->L10
^ ^ ^ ^ ^
| | | | |
.21 .35 .78 .56 ... .21
使用
n_steps = 10
n_inputs = 1
n_neurons = 7
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])
cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn.relu)
rnn_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
rnn_outputs 变成一个 (?, 10, 7) 形状的张量,假设每 10 个时间步长有 7 个输出。
以前,我 运行 包装输出投影的以下片段 rnn_outputs
以获得每个序列的分类标签。
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)
loss = tf.reduce_mean(xentropy)
我如何 运行 类似 rnn_outputs 的内容来获得序列?
具体来说,
1.我可以从每个步骤中获取 rnn_output 并将其输入 softmax 吗?
curr_state = rnn_outputs[:,i,:]
logits = tf.layers.dense(states, n_outputs)
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=logits)
2。我应该使用什么损失函数,它应该应用于每个序列的每个值吗?(对于序列 i 和步骤 j , loss = y_{ij} (true) - y_{ij}(predicted)
)?
我的损失应该是loss = tf.reduce_mean(np.sum(xentropy))
吗?
编辑 看来我正在尝试实现类似于 https://machinelearningmastery.com/develop-bidirectional-lstm-sequence-classification-python-keras/ in TensorFlow 中的类似内容。
在 Keras 中,有一个 TimeDistributed
函数:
You can then use TimeDistributed to apply a Dense layer to each of the 10 timesteps, independently
我将如何在 Tensorflow 中实现类似的东西?
首先,您似乎在进行 seq-to-seq 建模。在这类问题中,使用编码器-解码器架构通常是一个好主意,而不是从相同的 RNN 预测序列。 Tensorflow 在名称 "Neural Machine Translation (seq2seq) Tutorial" 下有一个关于它的大教程,我建议您查看。
但是,如果 n_steps
是已知的 静态 (尽管使用 dynamic_rnn
),您所询问的体系结构也是可能的。在这种情况下,可以计算每个单元格输出的交叉熵,然后将所有损失相加。如果 RNN 长度也是动态的也是可能的,但会更复杂。这是代码:
n_steps = 2
n_inputs = 3
n_neurons = 5
X = tf.placeholder(dtype=tf.float32, shape=[None, n_steps, n_inputs], name='x')
y = tf.placeholder(dtype=tf.int32, shape=[None, n_steps], name='y')
basic_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
# Reshape to make `time` a 0-axis
time_based_outputs = tf.transpose(outputs, [1, 0, 2])
time_based_labels = tf.transpose(y, [1, 0])
losses = []
for i in range(n_steps):
cell_output = time_based_outputs[i] # get the output, can do apply further dense layers if needed
labels = time_based_labels[i] # get the label (sparse)
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=cell_output)
losses.append(loss) # collect all losses
total_loss = tf.reduce_sum(losses) # compute the total loss