我正在尝试使用tensorflow的dynamic_rnn设计RNN以进行序列分类。我的例子长度各不相同,通过我的研究,我了解到我可以通过" sequence_length"作为指定我的示例长度的参数。但是,当我尝试这样做时,我得到了一些奇特的结果。简而言之,包含变量会阻止我的系统学习,谢天谢地我仍然可以训练,当我用0s缓冲到最大长度的序列时,但我真的想知道我未来的工作出了什么问题。 / p>
我想学习的模式很简单,如果我们看到1本身我们将它分配给类1,如果我们在序列中的任何地方看到它被分配为类2,并且如果我们在第一个中看到1则我们应该分配第3课。第二时间片。
这是我的测试代码:
from __future__ import print_function
import tensorflow as tf
import numpy as np
import random
dataset = [[1, 0], [2, 0], [1,2], [1,1]]
labels = [[1,0,0], [0,1,0], [0,1,0], [0,0,1]]
#---------------------------------------------
#define model
# placeholders
data_ph = tf.placeholder("float", [1, None, 1], name="data_placeholder")
len_ph = tf.placeholder("int32", [1], name="seq_len_placeholder")
y_ph = tf.placeholder("float", [1, None, 3], name="y_placeholder")
n_hidden = 10
n_out = len(labels[0])
# variable definition
out_weights=tf.Variable(tf.random_normal([n_hidden,n_out]))
out_bias=tf.Variable(tf.random_normal([n_out]))
# lstm definition
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden, state_is_tuple=True)
state_series, final_state = tf.nn.dynamic_rnn(
cell=lstm_cell,
inputs=data_ph,
dtype=tf.float32,
sequence_length=len_ph,
time_major=False
)
out = state_series[:, -1, :]
prediction=tf.nn.softmax(tf.matmul(out,out_weights)+out_bias)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y_ph))
optimizer=tf.train.AdamOptimizer(learning_rate=1e-3).minimize(loss)
#---------------------------------------------
#run model
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
#TRAIN
for iteration in range(5000):
if (iteration%100 == 0):
print(iteration)
ind = random.randint(0, len(dataset)-1)
example = np.reshape(dataset[ind], (1,-1,1))
label = np.reshape(labels[ind], (1,-1,3))
vals={data_ph: example,
len_ph: [len(example)],
y_ph: label,
}
#print(sess.run(state_series, feed_dict=vals))
sess.run(optimizer, feed_dict=vals)
#TEST
for x in range(len(dataset)):
example = np.reshape(dataset[x], (1,-1,1))
label = np.reshape(labels[x], (1,-1,3))
vals = {data_ph: example,
len_ph: [len(example)],
y_ph: label,
}
classification = sess.run([prediction, loss], feed_dict=vals)
print("predicted values: "+str(np.matrix.round(classification[0][0], decimals=2)), "loss: "+str(classification[1]))
当我在定义sequence_length时评估系统时,我的所有测试示例都会返回相同的预测:
predicted values: [ 0.25999999 0.58999997 0.15000001] loss: 1.19235
predicted values: [ 0.25999999 0.58999997 0.15000001] loss: 0.855842
predicted values: [ 0.25999999 0.58999997 0.15000001] loss: 0.855842
predicted values: [ 0.25999999 0.58999997 0.15000001] loss: 1.30355
将这些结果与未定义序列长度或将长度固定为2的时间进行比较:
predicted values: [ 0.99000001 0. 0.01 ] loss: 0.559447
predicted values: [ 0. 1. 0.] loss: 0.554004
predicted values: [ 0. 0.92000002 0.08 ] loss: 0.603042
predicted values: [ 0.02 0.02 0.95999998] loss: 0.579448
任何输入都将不胜感激。谢谢
答案 0 :(得分:2)
您传递的sequence_length
参数实际上设置为1
而不是2
,这就是网络无法训练的原因。
len(example)
会返回1
,因为它的形状为(1,2,1)
。你可以使用len(example.flatten())
修复它,你应该看到正确的输出。