我正在构建一个 RNN LSTM 网络,根据作者的年龄对文本进行分类(二元分类 - 年轻/成人)。
看起来网络没有学习并突然开始过度拟合:
Red: train
Blue: validation
一种可能是数据表示不够好。我只是按频率对独特的单词进行排序并给它们索引。例如。:
unknown -> 0
the -> 1
a -> 2
. -> 3
to -> 4
所以我试图用词嵌入来代替它。
我看到了几个例子,但我无法在我的代码中实现它。大多数示例如下所示:
embedding = tf.Variable(tf.random_uniform([vocab_size, hidden_size], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, input_data)
这是否意味着我们正在构建一个层learns嵌入?我认为应该下载一些 Word2Vec 或 Glove 并使用它。
无论如何,假设我想构建这个嵌入层......
如果我在代码中使用这两行,我会收到错误:
类型错误:传递给参数“索引”的值的数据类型 float32 不在允许值列表中:int32、int64
所以我想我必须改变input_data
键入至int32
。所以我这样做了(毕竟都是索引),我得到了这个:
类型错误:输入必须是序列
我尝试包裹inputs
(论点tf.contrib.rnn.static_rnn
)和一个列表:[inputs]
如建议的这个答案 https://stackoverflow.com/a/45217776/900394,但这又产生了另一个错误:
ValueError:输入大小(输入的维度 0)必须可通过
形状推断,但看到值 None。
Update:
我正在拆开张量x
在将其传递给之前embedding_lookup
。我在嵌入后移动了拆垛。
更新的代码:
MIN_TOKENS = 10
MAX_TOKENS = 30
x = tf.placeholder("int32", [None, MAX_TOKENS, 1])
y = tf.placeholder("float", [None, N_CLASSES]) # 0.0 / 1.0
...
seqlen = tf.placeholder(tf.int32, [None]) #list of each sequence length*
embedding = tf.Variable(tf.random_uniform([VOCAB_SIZE, HIDDEN_SIZE], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, x) #x is the text after converting to indices
inputs = tf.unstack(inputs, MAX_POST_LENGTH, 1)
outputs, states = tf.contrib.rnn.static_rnn(lstm_cell, inputs, dtype=tf.float32, sequence_length=seqlen) #---> Produces error
*seqlen:我对序列进行了零填充,因此所有序列都具有相同的列表大小,但由于实际大小不同,我准备了一个描述没有填充的长度的列表。
新错误:
ValueError:层 basic_lstm_cell_1 的输入 0 与
该层:预期 ndim=2,发现 ndim=3。收到的完整形状:[无,
1, 64]
64是每个隐藏层的大小。
很明显,我的尺寸有问题......如何使输入在嵌入后适合网络?