求梯度测试
静态图
1. tf.gradients
x=tf.ones([4.0,1.0])
t=tf.ones([4.0,1.0])
# 注意这里合并了
X= tf.concat([x,t],1)
w=tf.constant([[2.0],[1.0]])
y=tf.matmul(X,w)
g1=tf.gradients(y,x)
g2=tf.gradients(y,t)
with tf.compat.v1.Session() as sess:
print(sess.run(g1))
print(sess.run(g2))
# 结果正确
def gra_fun(X):
w=tf.constant([[2.0],[1.0]])
y=tf.tanh(tf.matmul(X,w))
return y
x=tf.ones([4.0,1.0])
t=tf.ones([4.0,1.0])
X= tf.concat([x,t],1)
y=gra_fun(X)
g1=tf.gradients(y,x)
# g1,g2=tf.gradients(y,[x,t]) 也正确
g2=tf.gradients(y,t)
gg1=tf.gradients(g1,x)
ggg1=tf.gradients(gg1,x)
# 在调用函数的情况下,求导正确
# 分别为:0.01973224
# 0.00986612
# -0.07853862
# 0.31104344
# 又测试了y=X^4,结果完全正确。
2. tf.GradientTape()
# 如果tape1和tape2都对大X求导,可运行,结果为[x',t'], 二阶导结果为[x'',t'']
# 如果只对最后一个小x求导,可运行,但xiaox求导结果为0
# 如果对倒数第二个对小x求导,失败。
x=tf.ones([4.0,1.0])
t=tf.ones([4.0,1.0])
X= tf.concat([x,t],1)
w=tf.constant([[2.0],[1.0]])
with tf.GradientTape() as tape1:
tape1.watch(X)
with tf.GradientTape() as tape2:
tape2.watch(X)
y=gra_fun(X)
g1=tape2.gradient(y,X)
# g2=tape2.gradient(y,t)
gg1=tape1.gradient(g1,x)
#ggg1=tape.gradient(gg1,x)
# Cannot convert value None to a TensorFlow DType.
x=tf.ones([4.0,1.0])
t=tf.ones([4.0,1.0])*2.0
X= tf.concat([x,t],1)
w=tf.constant([[2.0],[1.0]])
#X=X**4
#y=tf.sin(tf.matmul(X,w))
with tf.GradientTape() as tape1:
tape1.watch(X)
with tf.GradientTape() as tape2:
tape2.watch(X)
y=gra_fun(X)
g1=tape2.gradient(y,X)
# g2=tape2.gradient(y,t)
gg1=tape1.gradient(g1,X)
#ggg1=tape.gradient(gg1,x)
with tf.compat.v1.Session() as sess:
print(sess.run(g1))
# print(sess.run(g2))
print(sess.run(gg1[:,0:1]))
# print(sess.run(ggg1))
# results [[ 4. 32.] [ 4. 32.] [ 4. 32.] [ 4. 32.]] [[12.] [12.] [12.] [12.]]
即刻执行模式
tf.graidents无法使用
或者加上@tf.function可以用
2. tf.GradientTape()
x=tf.constant([[4.0],[1.0]])
t=tf.constant([[4.0],[1.0]])*2.0
X= tf.concat([x,t],1)
w=tf.constant([[2.0],[1.0]])
#X=X**4
#y=tf.sin(tf.matmul(X,w))
with tf.GradientTape() as tape1:
tape1.watch(X)
with tf.GradientTape() as tape2:
tape2.watch(X)
# 这里也可以调用y=fun(x)
y=X*X*X*X
g1=tape2.gradient(y,X)
# g2=tape2.gradient(y,t)
gg1=tape1.gradient(g1,X)
#ggg1=tape.gradient(gg1,x)
[[ 256. 2048.] [ 4. 32.]] [[192. 768.] [ 12. 48.]]
求偏导数
x=tf.constant([[4.0],[1.0]])
t=tf.constant([[4.0],[1.0]])*2.0
X= tf.concat([x,t],1)
w=tf.constant([[2.0],[1.0]])
#X=X**4
#y=tf.sin(tf.matmul(X,w))
with tf.GradientTape() as tape1:
tape1.watch(X)
with tf.GradientTape() as tape2:
tape2.watch(X)
y=gra_fun(X)
g1=tape2.gradient(y,X)
# g2=tape2.gradient(y,t)
g1_t=g1[:,1:2]
# gg1=tape1.gradient(g1,X)
gg1_t=tape1.gradient(g1_t,X)
#ggg1=tape.gradient(gg1,x)
print(g1.numpy())
#print(gg1.numpy())
print(g1_t.numpy())
print(gg1_t.numpy())
[[ 256. 2048.] [ 4. 32.]] [[2048.] [ 32.]] [[ 0. 768.] [ 0. 48.]]
似乎可行
总结
即刻模式下,用tf.GradientTape()对直接自变量(函数中输入的那个量,而不是其变换前的量)求导,
静态图模式下,可以用tf.gradients对自变量(包括变换过的量)求导,但必须全部在tensor中运行,然后用session变为数组