我最近有一个文本分类的NLP任务,我使用LSTM生成输入的表示,然后通过线性层获取它。伪代码是这样的:
final_state = tf.nn.LSTM(....)
logits = tf.softmax(final_state * W + b)
和上面的权重矩阵我使用了函数:
W = tf.get_variable('w', shape = [size, class_vocab], dtype = tf.float32)
直到现在,损失函数是交叉熵,这是这样的:
loss = tf.nn.softmax_cross_entropy(logits,true_labels)
有效。
但现在问题是,当我计算损失时,我必须对我的权重矩阵采取正交约束,这是我的代码:
first_value, rest_value = tf.split(W, [1, length - 1], axis = 1)
rest_value = tf.expand_dims(tf.reduce_mean(rest_value, axis = 1), axis = 1)
orthogonality_matrix = tf.matmul(first_value, rest_value, transpose_b = True)
loss = tf.nn.softmax_cross_entropy(logits,true_labels) + tf.nn.l2_norm(orthogonality_matrix)
我希望权重矩阵的第一列远离其余的向量,因为第一列所代表的类与其他列完全不同。
但是每次执行更新操作时它都不起作用,权重矩阵发生变化,无论我是否采用正交性约束,它都以相同的方式改变。 (为了演示它,我用全零来初始化W。)
我怀疑当我分割W矩阵时我只将值从in复制到一个常数张量中,因此当我使用这些张量来计算损失时,它不能训练原始的W。
那么我应该怎样做才能考虑正交性约束?
或许我应该分别对不同类的final_state和权重向量进行多次而不是整数权重矩阵?但它看起来微不足道:(