TensorFlow2自动梯度与优化器

自动梯度与优化器

待优化张量

为了区分需要计算梯度信息的张量(如参数)与不需要计算梯度信息的普通张量,tensorflow增加了一种专门的数据类型来支持梯度信息的记录:tf.Variable
可以通过tf.Variable()方法将普通张量转换成待优化张量

a=tf.constant([1,2,3])
aa=tf.Variable(a)

tf.Variable()也可以直接创建待优化张量,用法与tf.constant()相同

a=tf.Variable([[1,2],[3,4]])

梯度带

tf.GradientTape() 是一个自动求梯度的记录器。只要进入了 with tf.GradientTape() as tape 的上下文环境,则默认在该环境中的所有待优化张量的计算步骤都会被自动记录。
离开上下文环境后,记录停止,但是tape依旧可用,可以通过y_grad = tape.gradient(y,x) tensorflow将根据记录的计算步骤求张量 y 对变量 x 的导数

import tensorflow as tf
x = tf.Variable(initial_value=3.)
with tf.GradientTape() as tape: #tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导
	y = tf.square(x)
y_grad = tape.gradient(y, x) # 计算y关于x的导数
print([y, y_grad]) #输出标量9.0 和标量6.0

梯度带默认记录tf.Variable创建的待优化张量,如果想记录普通张量,可使用GradientTape.watch()方法

x = tf.constant(3.0)
with tf.GradientTape() as tape:  
	tape.watch(x)  
	y = x * x
dy_dx = tape.gradient(y, x) # Will compute to 6.0

默认情况下,只要调用一次GradientTape.gradient(),就会释放GradientTape拥有的资源。要在同一计算上计算多个梯度,请创建一个持久梯度带,将参数persisent=True:

x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as g:
	g.watch(x)  
	y = x * x
	z = y * y
dz_dx = g.gradient(z, x)  # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x)  # 6.0 
del g  # Drop the reference to the tape

可以通过嵌套梯度带计算高层导数

x = tf.constant(3.0)
with tf.GradientTape() as g:
  g.watch(x)
    with tf.GradientTape() as gg:
        gg.watch(x)
        y = x * x  
        dy_dx = gg.gradient(y, x) # Will compute to 6.0
        d2y_dx2 = g.gradient(dy_dx, x) # Will compute to 2.0

优化器

优化器是继承自tf.optimizers.Optimizer类的子类,例如随机梯度下降优化器 tf.optimizers.SGD,Adam优化器tf.optimizers.Adam,通过调用Optimizer.minimize()方法实现自动梯度并更新参量。

tf.keras.optimizers 和 tf.optimizers 完全相同,tf.optimizers.SGD即tf.keras.optimizers.SGD

优化器实例化

不同优化器有不同的实例化参数,但是大同小异,以SGD为例,下面是SGD的实例化方法

__init__(
    learning_rate=0.01,#浮点型超参数,应该>0,学习率
    momentum=0.0,#浮点型大于0的超参数,动量,帮助加速收敛
    nesterov=False,#是否使用nesterovd动量
    name='SGD',    
    **kwargs
)

其中kwargs为关键字参数, 允许指为 {clipnorm, clipvalue, lr,decay}。clipnorm 按范数梯度截断,当梯度得L2范数值大于一定值时发生截断; clipvalue 按值梯度截断,当梯度大于一定值时发生截断, decay 是为了向后兼容所以被包含在kwargs中,该参量用于设计学习率的逆时衰减; lr 也是为了向后兼容,现在推荐用learning_rate取代kwargs的lr。
简单SGD只需设置学习率即可,实例化一个SGD优化器对象:

opt = tf.optimizers.SGD(learning_rate=0.1)

此后可以通过opt.*的方式调用优化器的的相关方法

minimize方法

优化器的minimize方法定义如下:

minimize(
    loss,#一个函数对象,要求无参数且有可以被最小化的返回值,minimize方法会通过更新参量令将该函数的返回值最小
    var_list, #元素为tf.Variable类型的序列对象,loss函数的返回值应该依赖这些待优化张量,minimize调用会改变这些张量 
    grad_loss=None,#可选,loss的梯度张量
    name=None #可选
)

使用过程如下:

opt = tf.keras.optimizers.SGD(learning_rate=0.1) #创建优化器对象
loss = lambda: 3 * var1 * var1 + 2 * var2 * var2 #定义损失函数,loss应该是一个无参且有返回值函数对象
opt.minimize(loss, var_list=[var1, var2]) #eager模式中(tf2默认开启),直接调用opt.minimize()即可根据优化器的优化算法(本例的SGD)更新var_list中的张量

opt.minimize()方法干了两件事:

  1. 使用tf.GradientTape计算梯度
  2. 使用opt.apply_gradients()依据优化器的优化算法更新参量
apply_gradients方法

apply_gradients方法定义如下

apply_gradients(
    grads_and_vars,#元素为(梯度,待优化张量)对的列表对象
    name=None
 )

opt.apply_gradients()会直接根据优化器的优化算法,将梯度应用在可优化张量上,使其更新。
注意参数grads_and_vars期望的是(gradient, variable)对的列表,通常借助python的zip函数:

X = tf.constant(X)
y = tf.constant(y)
a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.)
with tf.GradientTape() as tape:
	y_pred = a * X + b
    loss = 0.5 * tf.reduce_sum(tf.square(y_pred - y))
grads = tape.gradient(loss, [a, b])
optimizer.apply_gradients(grads_and_vars=zip(grads, [a, b]))
#zip()被称为拉链函数,会将两个等长序列对象中的元素按对应位置两两一组行程值对,存于list之中

如果想在应用梯度之前对梯度进行处理,则需要进行以下三个步骤:

  1. 使用tf.GradientTape计算梯度
  2. 对梯度进行处理
  3. 使用opt.apply_gradients()依据优化器的优化算法更新参量
注意

从一定程度上讲,使用minimize或者使用apply_gradients都能达成目标,在不考虑进行优化前对梯度进行的处理的情况下,二者作用等价,显然minimize更为简洁,但是有需要注意:

  • minimize的参数loss,要求为无参数且有具体的返回值的可调用对象,注意没有参数,tf内预设的loss函数是有参数的,不能直接拿来用,可套上lambda使用。
  • apply_gradients的参数,要求的是张量列表,列表元素是(梯度,待优化张量),其中梯度由tape.gradient(loss, [a, b])得到,tape.gradient也是接受具体的张量。tf内预设的loss函数会返回计算后的张量,所以可直接将其返回值作为tape.gradient的参数进行计算
TF2预设的优化器

Adadelta优化器: Optimizer that implements the Adadelta algorithm.
Adagrad优化器: Optimizer that implements the Adagrad algorithm.
Adam优化器: Optimizer that implements the Adam algorithm.
Adamax优化器: Optimizer that implements the Adamax algorithm.
Ftrl优化器: Optimizer that implements the FTRL algorithm.
Nadam优化器: Optimizer that implements the NAdam algorithm.
RMSprop优化器: Optimizer that implements the RMSprop algorithm.
SGD优化器: Stochastic gradient descent and momentum optimizer.

本文摘录、翻译自

Keras中文文档
https://keras.io/zh/

TensorFlow官方
https://tensorflow.google.cn/

最全Tensorflow2.0 入门教程持续更新
https://zhuanlan.zhihu.com/p/59507137

简单粗暴TensorFlow2
https://tf.wiki/zh/preface.html

  • 13
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
TensorFlow 2优化器是一种用于训练神经网络的工具,能够自动地调整网络中的参数,以最小化损失函数,从而提高模型的准确性和性能。TensorFlow 2提供了多个优化器选项,以满足不同类型的问题和需求。 其中最常用的优化器之一是梯度下降优化器(Gradient Descent Optimizer)。该优化器通过不断地计算损失函数对网络参数的偏导数,并根据这些导数来更新参数的值,以降低损失函数的值。梯度下降优化器有很多变种,如批量梯度下降(Batch Gradient Descent)、随机梯度下降(Stochastic Gradient Descent)和小批量梯度下降(Mini-batch Gradient Descent)等。 此外,TensorFlow 2还提供了一些更高级的优化器,如Adam、Adagrad和RMSprop等。这些优化器结合了梯度下降的思想,并引入了更加复杂的更新策略。例如,Adam优化器结合了梯度的一阶矩估计和二阶矩估计,从而使用动态学习率来调整参数更新的步长,从而更加高效地训练模型。 在选择优化器时,需要根据具体的问题和数据集特点来进行权衡。例如,对于大规模数据集,可以考虑使用随机梯度下降优化器;对于稀疏数据集,可以使用Adagrad优化器;对于参数更新较为频繁的网络,可以选择RMSprop优化器等。 总之,TensorFlow 2的优化器为用户提供了多个选择,可以根据问题的特点来选择适合的优化器,以获得更好的训练效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值