我试图用tensorflow实现一个基于窗口的分类器,
单词嵌入矩阵被调用word_vec
并随机初始化(我也试过Xavier).
并且ind
变量是来自矩阵的词向量的索引的向量.
第一层是config['window_size']
(5)连接的单词向量.
word_vecs = tf.Variable(tf.random_uniform([len(words), config['embed_size']], -1.0, 1.0),dtype=tf.float32) ind = tf.placeholder(tf.int32, [None, config['window_size']]) x = tf.concat(1,tf.unpack(tf.nn.embedding_lookup(word_vecs, ind),axis=1)) W0 = tf.Variable(tf.random_uniform([config['window_size']*config['embed_size'], config['hidden_layer']])) b0 = tf.Variable(tf.zeros([config['hidden_layer']])) W1 = tf.Variable(tf.random_uniform([config['hidden_layer'], out_layer])) b1 = tf.Variable(tf.zeros([out_layer])) y0 = tf.nn.tanh(tf.matmul(x, W0) + b0) y1 = tf.nn.softmax(tf.matmul(y0, W1) + b1) y_ = tf.placeholder(tf.float32, [None, out_layer]) cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y1), reduction_indices=[1])) train_step = tf.train.AdamOptimizer(0.5).minimize(cross_entropy)
这就是我运行图表的方式:
init = tf.global_variables_initializer() sess = tf.Session() sess.run(init) for i in range(config['iterations'] ): r = random.randint(0,len(sentences)-1) inds=generate_windows([w for w,t in sentences[r]]) #inds now contains an array of n rows on window_size columns ys=[one_hot(tags.index(t),len(tags)) for w,t in sentences[r]] #ys now contains an array of n rows on output_size columns sess.run(train_step, feed_dict={ind: inds, y_: ys})
维度工作,代码运行
但是,准确度几乎为零,我怀疑单词向量没有正确更新.
如何让tensorflow从连接窗口形式更新单词向量?
您的嵌入是初始化tf.Variable
的,默认情况下是可训练的.他们将更新.问题可能在于您计算损失的方式.请看以下这些行
y1 = tf.nn.softmax(tf.matmul(y0, W1) + b1) y_ = tf.placeholder(tf.float32, [None, out_layer]) cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y1), reduction_indices=[1]))
在这里,您将计算softmax函数,该函数将分数转换为概率
如果此处的分母变得太大或太小,那么此函数可以进行折腾.为了避免这种数值不稳定,通常epsilon
会添加如下的小数据.这确保了数值稳定性.
您可以看到,即使添加epsilon
了softmax函数值,仍然保持不变.如果您不自行处理此问题,则渐变可能无法正确更新,因为渐变消失或爆炸.
避免使用三行代码并使用tensorflow版本
tf.nn.sparse_softmax_cross_entropy_with_logits
请注意,此函数将在内部计算softmax函数.建议使用它而不是手动计算损失.您可以按如下方式使用它
y1 = tf.matmul(y0, W1) + b1 y_ = tf.placeholder(tf.float32, [None, out_layer]) cross_entropy = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y1, labels=y_))