Tensorflow核心二—Gradient Descent
What’s Gradient
什么是梯度?
从高中学到的导数就是变动率(函数沿着某一方向变动变化率)。针对与某一轴变动就是针对与某一轴的偏微分,每个轴的偏微分的向量和就叫做梯度。
如图,-2x和2y就是偏微分,合在一起的向量就叫做梯度
What does it mean
箭头的方向就是梯度的方向,改变的速率就是模长。
How to Search
Search for minima:
在正常程序编写中,根据这个基本原理,衍生出很多优化器(具体优化器的对比在下一篇博客中)。
AutoGrad
了解GradientTap
class GradientTape(object):
def __init__(self, persistent=False, watch_accessed_variables=True):
"""构建函数"""
def __enter__(self):
"""用于支持with上下文管理器,进入记录的计算图"""
def __exit__(self, typ, value, traceback):
"""用于支持with上下文管理器,离开计算图"""
def watch(self, tensor):
"""设定需要“监控”的变量"""
def stop_recording(self):
"""一个类似with的上下文管理器,tape将不会记录其中的运算操作"""
def reset(self):
"""清除已有的计算图"""
def watched_variables(self):
"""返回被“监控”的变量"""
def gradient(self, target, sources, output_gradients=None,
unconnected_gradients=UnconnectedGradients.NONE):
"""计算梯度,返回的梯度与 sources 同结构"""
def jacobian(self, target, sources, unconnected_gradients=UnconnectedGradients.NONE,
parallel_iterations=None, experimental_use_pfor=True):
"""计算jacobian矩阵"""
def batch_jacobian(target, source, unconnected_gradients=tf.UnconnectedGradients.NONE, parallel_iterations=None, experimental_use_pfor=True):
"""批量计算jacobian"""
常用的几个函数
gradient
def gradient(self, target, sources, output_gradients=None,
unconnected_gradients=UnconnectedGradients.NONE):
"""计算梯度,返回的梯度与 sources 同结构"""
target: Tensor (or list of tensors) 求导的因变量 target node 。
sources: Tensor (or list of tensors) 求导的自变量 sources node 。
unconnected_gradients: 无法求导时,返回的值,有两个可选值[“none”, “zero”],默认"none"。例如,当 target node 与 sources node 之间在计算图上没有办法联通时,将会返回None。
例子:
with tf.GradientTape() as tape:
#Build computation graph
tape.watch([w, b])
logits = tf.sigmoid(x@w+b)
#𝑙𝑜𝑠𝑠 = 𝑓𝜃(𝑥)
loss = tf.reduce_mean(tf.losses.MSE(y, logits))
grads = tape.gradient(loss, [w, b])
2nd-order
二阶求导
with tf.GradientTape() as t1:
with tf.GradientTape() as t2:
y=x*w+b
dy_dw,dy_db = t2.gradient(y,[w,b])
d2y_dw = t1.gradient(dy_dw,[w])