【问题标题】:tf.IndexedSlicesValue when returned from tf.gradients()从 tf.gradients() 返回时的 tf.IndexedSlicesValue
【发布时间】:2022-03-03 22:25:13
【问题描述】:

我遇到了以下问题,我有四个嵌入矩阵,并且想要获取我的损失函数相对于这些矩阵的梯度。

当我运行会话以返回渐变值时,其中两个返回的对象是 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)

【问题讨论】:

    标签: machine-learning tensorflow


    【解决方案1】:

    我遇到了同样的问题,显然 IndexedSlices 对象是在计算它们的梯度时为某些嵌入矩阵自动创建的,

    如果您想访问 Embedding 的可训练变量的梯度,您需要将 IndexedSlices 转换为张量,只需使用:

    tf.convert_to_tensor(gradients_of_the_embedding_layer)
    

    【讨论】:

      猜你喜欢
      • 2021-05-27
      • 2021-06-04
      • 2023-01-13
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      相关资源
      最近更新 更多