我注意到,当损失函数将输入转换为numpy数组以计算输出值时,Tensorflow的自动微分不会给出与有限差分相同的值。下面是这个问题的一个最低工作示例:
import tensorflow as tf
import numpy as np
def lossFn(inputTensor):
# Input is a rank-2 square tensor
return tf.linalg.trace(inputTensor @ inputTensor)
def lossFnWithNumpy(inputTensor):
# Same function, but converts input to a numpy array before performing the norm
inputArray = inputTensor.numpy()
return tf.linalg.trace(inputArray @ inputArray)
N = 2
tf.random.set_seed(0)
randomTensor = tf.random.uniform([N, N])
# Prove that the two functions give the same output; evaluates to exactly zero
print(lossFn(randomTensor) - lossFnWithNumpy(randomTensor))
theoretical, numerical = tf.test.compute_gradient(lossFn, [randomTensor])
# These two values match
print(theoretical[0])
print(numerical[0])
theoretical, numerical = tf.test.compute_gradient(lossFnWithNumpy, [randomTensor])
# The theoretical value is [0 0 0 0]
print(theoretical[0])
print(numerical[0])函数tf.test.compute_gradients用自动微分法计算“理论”梯度,用有限差分法计算数值梯度。如代码所示,如果在损失函数中使用.numpy(),自动微分不计算梯度。
有人能解释一下原因吗?
发布于 2020-11-10 15:32:44
来自指南:渐变和自动微分简介
如果计算退出TensorFlow,则磁带无法记录梯度路径。例如: X= tf.Variable([1.0,2.0,3.0,4.0],dtype=tf.float32),用tf.GradientTape()作为磁带: x2 = x**2 #--这一步是用NumPy y= np.mean(x2,axis=0) #计算的,与大多数操作一样,reduce_mean会使用
tf.convert\_to\_tensor将NumPy数组转换为一个常数张量#。Y= tf.reduce_mean(y,axis=0)打印(tape.gradient(y,x)) 输出None
在对tf.linalg.trace的调用中,numpy值将被转换为一个常量张量,Tensorflow无法计算梯度。
https://stackoverflow.com/questions/64771324
复制相似问题