我正在建立一个RNN LSTM网络,根据作者的年龄(二进制分类 - 年轻/成人)对文本进行分类。
似乎网络没有学习,突然开始过度拟合:
一种可能性是数据表示不够好。我只是按照它们的频率对这些独特的单词进行了排序并给出了它例如。:
unknown -> 0
the -> 1
a -> 2
. -> 3
to -> 4
所以我试图用word嵌入替换它。我看了几个例子,但是我无法在我的代码中实现它。大多数示例如下所示:
embedding = tf.Variable(tf.random_uniform([vocab_size, hidden_size], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, input_data)
这是否意味着我们正在构建一个学习嵌入的层?我认为应该下载一些Word2Vec或Glove并使用它。
无论如何,让我说我想构建这个嵌入层...... 如果我在我的代码中使用这两行,我会收到一个错误:
TypeError:传递给参数'indices'的值的DataType float32不在允许值列表中:int32,int64
所以我想我必须将input_data
类型更改为int32
。所以我这样做(毕竟这是所有指数),我得到了这个:
TypeError:输入必须是序列
我尝试用inputs
中的建议包装tf.contrib.rnn.static_rnn
([inputs]
的参数):this answer,但这又产生了另一个错误:
ValueError:输入大小(输入的维度0)必须可通过形状推理访问,但锯值为None。
更新:
在将张量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与图层不兼容:expected ndim = 2,found ndim = 3。收到的完整形状:[无,1,64]
64是每个隐藏层的大小。
很明显我的尺寸有问题......如何在嵌入后使输入适合网络?
从tf.nn.static_rnn,我们可以看到inputs
的论点是:
输入的长度为T的列表,每个都是形状张量[batch_size,input_size]
所以你的代码应该是这样的:
x = tf.placeholder("int32", [None, MAX_TOKENS])
...
inputs = tf.unstack(inputs, axis=1)
tf.squeeze是一种从张量中去除尺寸1的尺寸的方法。如果最终目标是将输入形状设置为[None,64],则将类似于inputs = tf.squeeze(inputs)
的行放置,这将解决您的问题。