在学习tensorflow的自动求导之前,先要知道什么是Variable对象。
Variable对象其实是对tensor对象的进一步封装,它在模型训练过程中自动记录梯度信息,由算法自动优化。它是一个可以被训练的变量,在机器学习中作为模型参数,可以通过assign()、assign_add()、assign_sub()等函数对它进行赋值。
函数原型:tf.Variable(initial_value,dtype)
其中,initial_value可以是数字,python列表,ndarray对象,tensor对象。dtype是数据类型。
自动求导:
with GradientTape() as tape:
函数表达式
grad=tape.gradient(函数,自变量)
下面通过实例来看tensorflow如何自动求导。
1.简单求导
首先导入tensorflow:
import tensorflow as tf
接着将x声明为一个可赋值的变量:
x=tf.Variable(3.)
求导并打印结果:
with tf.GradientTape() as tape:
y=tf.square(x)
dy_dx=tape.gradient(y,x)
print(y)
print(dy_dx)
输出结果:
tf.Tensor(9.0, shape=(), dtype=float32)
tf.Tensor(6.0, shape=(), dtype=float32)
与手算结果一致。需要注意的是,x=tf.Variable(3.)
中必须要有小数点,否则会报这个错:
WARNING:tensorflow:The dtype of the target tensor must be floating (e.g. tf.float32) when calling GradientTape.gradient, got tf.int32
并且得到的是错误的结果:
tf.Tensor(9, shape=(), dtype=int32)
None
---------------分割线--------------------
2.多元函数求偏导数
代码实现:
import tensorflow as tf
x=tf.Variable(3.)
y=tf.Variable(4.)
with tf.GradientTape() as tape:
f=tf.square(x)+2*tf.square(y)+1
df_dx,df_dy=tape.gradient(f,[x,y])
print("f=",f)
print("df_dx=",df_dx)
print("df_dy=",df_dy)
'''输出结果
f= tf.Tensor(42.0, shape=(), dtype=float32)
df_dx= tf.Tensor(6.0, shape=(), dtype=float32)
df_dy= tf.Tensor(16.0, shape=(), dtype=float32)
'''
---------------分割线--------------------
3.求二阶导数
求一阶导数结果:
二阶导数结果:
代码实现:
import tensorflow as tf
x=tf.Variable(3.)
y=tf.Variable(4.)
with tf.GradientTape() as tape2:
with tf.GradientTape(persistent=True) as tape1:
f=tf.square(x)+2*tf.square(y)+1
first_grads=tape1.gradient(f,[x,y])
second_grads=[tape2.gradient(first_grads,[x,y])]
print("f=",f)
print("first_grads=",first_grads)
print("second_grads=",second_grads)
del tape1
del tape2
'''输出结果
f= tf.Tensor(42.0, shape=(), dtype=float32)
first_grads= [<tf.Tensor: shape=(), dtype=float32, numpy=6.0>, <tf.Tensor: shape=(), dtype=float32, numpy=16.0>]
second_grads= [[<tf.Tensor: shape=(), dtype=float32, numpy=2.0>, <tf.Tensor: shape=(), dtype=float32, numpy=4.0>]]
'''
---------------分割线--------------------
4.对向量求偏导
import tensorflow as tf
x=tf.Variable([1.,2.,3.])
y=tf.Variable([4.,5.,6.])
with tf.GradientTape() as tape:
f=tf.square(x)+2*tf.square(y)+1
df_dx,df_dy=tape.gradient(f,[x,y])
print("f=",f)
print("df_dx=",df_dx)
print("df_dy=",df_dy)
'''输出结果
f= tf.Tensor([34. 55. 82.], shape=(3,), dtype=float32)
df_dx= tf.Tensor([2. 4. 6.], shape=(3,), dtype=float32)
df_dy= tf.Tensor([16. 20. 24.], shape=(3,), dtype=float32)
'''