eag*_*arn 6 machine-learning tensorflow
我遇到了以下问题,我有四个嵌入矩阵,想获得我的损失函数相对于这些矩阵的梯度。
当我运行会话以返回梯度值时,其中两个返回的对象是 tensorflow.python.framework.ops.IndexedSlicesValue 类型,另外两个是 numpy 数组。现在对于 numpy 数组,它们的形状对应于它们对应的嵌入矩阵的形状,但是我在使用 IndexedSlicesValue 对象时遇到了问题。
如果我在其中一个对象上调用 .values,我会得到一个形状与渐变不匹配的数组,嵌入矩阵的形状是 [22,30],但是在 IndexedSlicesValue 对象上调用 .values 会得到一个数组形状为 [4200,30] (我输入张量的形状尺寸为 [30,20,7],这些尺寸的乘积等于 4200,不确定这是否相关)。IndexedSlicesValue 对象有一个名为dense_shape 的属性,它是一个数组,保存梯度应该具有的维度,即array([22,30]) 是.dense_shape 返回的值。
我不太了解这里的文档:https : //www.tensorflow.org/versions/r0.7/api_docs/python/state_ops.html#IndexedSlices
它说:
IndexedSlices 通常用于表示形状为 [LARGE0, D1, .. , DN] 的较大张量密集的子集,其中 LARGE0 >> D0。索引中的值是从较大张量中提取的切片的第一维中的索引。
那么这个形状数组 (4200,30) 是从一个数组中提取的,该数组对应于一个更大的密集张量?
这个 IndexedSlicesValue 对象中的梯度到底是什么,为什么 tensorflow 会自动将这种类型用于 tf.gradients() 返回的某些梯度?
这是我的代码:
input_tensor = tf.placeholder(tf.int32, shape = [None, memory_size, max_sent_length], name = 'Input')
q_tensor = tf.placeholder(tf.int32, shape = [None,max_sent_length], name = 'Question')
a_tensor = tf.placeholder(tf.float32, shape = [None,V+1], name = 'Answer')
# Embedding matrices
A_prior = tf.get_variable(name = 'A', shape = [V+1,d], initializer = tf.random_normal_initializer(stddev = 0.1))
A = tf.concat(0,[tf.zeros(shape = tf.pack([1,tf.shape(A_prior)[1]])),tf.slice(A_prior,[1,0],[-1,-1])])
B = tf.get_variable(name = 'B', shape = [V+1,d], initializer = tf.random_normal_initializer(stddev = 0.1))
C = tf.get_variable(name = 'C', shape = [V+1,d], initializer = tf.random_normal_initializer(stddev = 0.1))
W = tf.get_variable(name = 'W', shape = [V+1,d], initializer= tf.random_normal_initializer(stddev = 0.1))
embeddings = tf.reduce_sum(tf.nn.embedding_lookup(A,input_tensor),2)
u = tf.reshape(tf.reduce_sum(tf.nn.embedding_lookup(B,q_tensor),1),[-1,1,d])
test = tf.transpose(embeddings, perm = [0,2,1])
test_batch_mul = tf.squeeze(tf.batch_matmul(u,test))
cond = tf.not_equal(test_batch_mul,0.0)
tt = tf.fill(tf.shape(test_batch_mul),-1000.0)
softmax_in = tf.select(cond, test_batch_mul, tt)
p_values = tf.nn.softmax(softmax_in)
c_values = tf.reduce_sum(tf.nn.embedding_lookup(C,input_tensor),2)
o = tf.squeeze(tf.batch_matmul(tf.expand_dims(p_values,1),c_values))
a_pred = tf.nn.softmax(tf.matmul(tf.squeeze(u)+o,tf.transpose(W)))
loss = tf.nn.softmax_cross_entropy_with_logits(a_pred, a_tensor, name = 'loss')
cost = tf.reduce_mean(loss)
global_step = tf.Variable(0,name = 'global_step', trainable= False)
#optimizer = tf.train.MomentumOptimizer(0.01,0.9)
vars_list = tf.trainable_variables()
grads = tf.gradients(cost, vars_list)
#train_op = optimizer.minimize( cost, global_step, vars_list, name = 'train_op')
sess = tf.Session()
init = tf.initialize_all_variables()
sess.run(init)
input_feed = {input_tensor : phrases, q_tensor : questions, a_tensor : answers}
grad_results = sess.run(grads, feed_dict = input_feed)
Run Code Online (Sandbox Code Playgroud)
小智 0
我遇到了同样的问题,显然 IndexedSlices 对象是在计算梯度时自动为某些嵌入矩阵创建的,
如果要访问嵌入的可训练变量的梯度,则需要将 IndexedSlices 转换为张量,只需使用:
tf.convert_to_tensor(gradients_of_the_embedding_layer)
Run Code Online (Sandbox Code Playgroud)