因为大多数机器学习任务就是最小化损失,在损失定义的情况下,后面的工作就交给了优化器。因为深度学习常见的是对于梯度的优化,也就是说,优化器最后其实就是各种对于梯度下降算法的优化。
常用的optimizer类
- Optimizer
- GradientDescentOptimizer
- AdagradOptimizer
- AdagradDAOptimizer
- MomentumOptimizer
- AdamOptimizer
- FtrlOptimizer
- RMSPropOptimizer
1. class tf.train.Optimizer
优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。你基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer.等等这些。
操作 | 描述 |
---|
class tf.train.Optimizer | 基本的优化类,该类不常常被直接调用,而较多使用其子类,比如GradientDescentOptimizer, AdagradOptimizer或者MomentumOptimizer | tf.train.Optimizer.init(use_locking, name) | 创建一个新的优化器,该优化器必须被其子类(subclasses)的构造函数调用 | tf.train.Optimizer.minimize(loss, global_step=None, var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, name=None, grad_loss=None) | 添加操作节点,用于最小化loss,并更新var_list该函数是简单的合并了compute_gradients()与apply_gradients()函数返回为一个优化更新后的var_list,如果global_step非None,该操作还会为global_step做自增操作 | tf.train.Optimizer.apply_gradients(grads_and_vars, global_step=None, name=None) | 将计算出的梯度应用到变量上,是函数minimize()的第二部分,返回一个应用指定的梯度的操作Operation,对global_step做自增操作 | tf.train.Optimizer.compute_gradients(loss,var_list=None, gate_gradients=1, aggregation_method=None, colocate_gradients_with_ops=False, grad_loss=None) | 对var_list中的变量计算loss的梯度该函数为函数minimize()的第一部分,返回一个以元组(gradient, variable)组成的列表 |
即:
minimize() 函数处理了梯度计算和参数更新两个操作 compute_gradients() 函数用于获取梯度 apply_gradients() 用于更新参数
其中的minimize可以拆为以下两个步骤: ① 梯度计算 ② 将计算出来的梯度应用到变量的更新中 拆开的好处是,可以对计算的梯度进行限制,防止梯度消失和爆炸
class tf.train.Optimizer 用法
opt = GradientDescentOptimizer(learning_rate=0.1)
opt_op = opt.minimize(cost, var_list=<list of variables>)
opt_op.run()
或者
import tensorflow as tf
x = tf.Variable(5, name='x', dtype=tf.float32)
log_x = tf.log(x)
log_x_squared = tf.square(log_x)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.5)
train = optimizer.minimize(log_x_squared)
init = tf.initialize_all_variables()
def optimize():
with tf.Session() as session:
session.run(init)
print("starting at", "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))
for step in range(100):
session.run(train)
print("step", step, "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))
optimize()
注意事项:在使用它们之前处理梯度
使用minimize()操作,该操作不仅可以计算出梯度,而且还可以将梯度作用在变量上。如果想在使用它们之前处理梯度,可以按照以下三步骤使用optimizer :
1、使用函数compute_gradients()计算梯度 2、按照自己的愿望处理梯度 3、使用函数apply_gradients()应用处理过后的梯度
例如:
opt = GradientDescentOptimizer(learning_rate=0.1)
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]
opt.apply_gradients(capped_grads_and_vars)
实际例子
import tensorflow as tf
tf.reset_default_graph()
with tf.variable_scope('var'):
weights=tf.get_variable(name='w',initializer=tf.constant(2.0))
input=tf.get_variable(name='x',initializer=tf.constant(3.0))
loss=weights*input*input
print(loss)
print('weight_name:', weights.name)
print('input_name:', input.name)
optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.4)
list_of_grad_var1 = optimizer.compute_gradients(loss,[weights,input])
list_of_grad_var2=list_of_grad_var1.copy()
for i,(grad,var_initial) in enumerate(list_of_grad_var1):
list_of_grad_var2[i] = (tf.clip_by_norm(grad,10),var_initial)
train_op = optimizer.apply_gradients(list_of_grad_var2)
config=tf.ConfigProto()
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(list_of_grad_var1))
print(sess.run(list_of_grad_var2))
sess.run(train_op)
print(sess.run(loss))
Reference
|