http://blog.csdn.net/lenbow/article/details/52218551
1. 优化器的种类
Optimizer GradientDescentOptimizer AdagradOptimizer AdagradDAOptimizer MomentumOptimizer AdamOptimizer FtrlOptimizer RMSPropOptimizer
2. GradientDescentOptimizer with tf.name_scope("cross_ent"): loss = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits=score, labels=y)) # Train op with tf.name_scope("train"): # Get gradients of all trainable variables gradients = tf.gradients(loss, var_list) #导数 gradients = list(zip(gradients, var_list)) # Create optimizer and apply gradient descent to the trainable variables optimizer = tf.train.GradientDescentOptimizer(learning_rate) train_op = optimizer.apply_gradients(grads_and_vars=gradients) 其中tf.train.Optimizer.apply_gradients(grads_and_vars, global_step=None, name=None)
Apply gradients to variables.This is the second part of minimize(). It returns an Operation that applies gradients. Args: grads_and_vars: List of (gradient, variable) pairs as returned by compute_gradients(). global_step: Optional Variable to increment by one after the variables have been updated. name: Optional name for the returned operation. Default to the name passed to the Optimizer constructor. Returns: An Operation that applies the specified gradients. If global_step was not None, that operation also increments global_step.
tf中各种优化类提供了为损失函数计算梯度的方法,其中包含比较经典的优化算法,比如GradientDescent 和Adagrad。
▶▶class tf.train.Optimizer
操作描述class tf.train.Optimizer基本的优化类,该类不常常被直接调用,而较多使用其子类, 比如GradientDescentOptimizer, AdagradOptimizer 或者MomentumOptimizertf.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.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)组成的列表tf.train.Optimizer.apply_gradients(grads_and_vars, global_step=None, name=None)将计算出的梯度应用到变量上,是函数minimize()的第二部分,返回一个应用指定的梯度的操作Operation,对global_step做自增操作tf.train.Optimizer.get_name()获取名称▷ class tf.train.Optimizer 用法
1 # Create an optimizer with the desired parameters. opt = GradientDescentOptimizer(learning_rate=0.1) # Add Ops to the graph to minimize a cost by updating a list of variables. # "cost" is a Tensor, and the list of variables contains tf.Variable objects. opt_op = opt.minimize(cost, var_list=<list of variables>) # Execute opt_op to do one step of training: opt_op.run()▶▶在使用它们之前处理梯度 使用minimize()操作,该操作不仅可以计算出梯度,而且还可以将梯度作用在变量上。如果想在使用它们之前处理梯度,可以按照以下三步骤使用optimizer :
1、使用函数compute_gradients()计算梯度 2、按照自己的愿望处理梯度 3、使用函数apply_gradients()应用处理过后的梯度例如:
# 创建一个optimizer. opt = GradientDescentOptimizer(learning_rate=0.1) # 计算<list of variables>相关的梯度 grads_and_vars = opt.compute_gradients(loss, <list of variables>) # grads_and_vars为tuples (gradient, variable)组成的列表。 #对梯度进行想要的处理,比如cap处理 capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars] # 令optimizer运用capped的梯度(gradients) opt.apply_gradients(capped_grads_and_vars)▶▶选通梯度(Gating Gradients) 函数minimize() 与compute_gradients()都含有一个参数gate_gradient,用于控制在应用这些梯度时并行化的程度。
其值可以取:GATE_NONE, GATE_OP 或 GATE_GRAPH GATE_NONE : 并行地计算和应用梯度。提供最大化的并行执行,但是会导致有的数据结果没有再现性。比如两个matmul操作的梯度依赖输入值,使用GATE_NONE可能会出现有一个梯度在其他梯度之前便应用到某个输入中,导致出现不可再现的(non-reproducible)结果 GATE_OP: 对于每个操作Op,确保每一个梯度在使用之前都已经计算完成。这种做法防止了那些具有多个输入,并且梯度计算依赖输入情形中,多输入Ops之间的竞争情况出现。 GATE_GRAPH: 确保所有的变量对应的所有梯度在他们任何一个被使用前计算完成。该方式具有最低级别的并行化程度,但是对于想要在应用它们任何一个之前处理完所有的梯度计算时很有帮助的。
一些optimizer的之类,比如 MomentumOptimizer 和 AdagradOptimizer 分配和管理着额外的用于训练的变量。这些变量称之为’Slots’,Slots有相应的名称,可以向optimizer访问的slots名称。有助于在log debug一个训练算法以及报告slots状态
操作描述tf.train.Optimizer.get_slot_names()返回一个由Optimizer所创建的slots的名称列表tf.train.Optimizer.get_slot(var, name)返回一个name所对应的slot,name是由Optimizer为var所创建 var为用于传入 minimize() 或 apply_gradients()的变量class tf.train.GradientDescentOptimizer使用梯度下降算法的Optimizertf.train.GradientDescentOptimizer.__init__(learning_rate, use_locking=False, name=’GradientDescent’)构建一个新的梯度下降优化器(Optimizer)class tf.train.AdadeltaOptimizer使用Adadelta算法的Optimizertf.train.AdadeltaOptimizer.__init__(learning_rate=0.001, rho=0.95, epsilon=1e-08, use_locking=False, name=’Adadelta’)创建Adadelta优化器class tf.train.AdagradOptimizer使用Adagrad算法的Optimizertf.train.AdagradOptimizer.__init__(learning_rate, initial_accumulator_value=0.1, use_locking=False, name=’Adagrad’)创建Adagrad优化器class tf.train.MomentumOptimizer使用Momentum算法的Optimizertf.train.MomentumOptimizer.__init__(learning_rate, momentum, use_locking=False, name=’Momentum’, use_nesterov=False)创建momentum优化器 momentum:动量,一个tensor或者浮点值class tf.train.AdamOptimizer使用Adam 算法的Optimizertf.train.AdamOptimizer.__init__(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, use_locking=False, name=’Adam’)创建Adam优化器class tf.train.FtrlOptimizer使用FTRL 算法的Optimizertf.train.FtrlOptimizer.__init__(learning_rate, learning_rate_power=-0.5, initial_accumulator_value=0.1, l1_regularization_strength=0.0, l2_regularization_strength=0.0, use_locking=False, name=’Ftrl’)创建FTRL算法优化器class tf.train.RMSPropOptimizer使用RMSProp算法的Optimizertf.train.RMSPropOptimizer.__init__(learning_rate, decay=0.9, momentum=0.0, epsilon=1e-10, use_locking=False, name=’RMSProp’)创建RMSProp算法优化器▷ tf.train.AdamOptimizer Adam 的基本运行方式,首先初始化:
m_0 <- 0 (Initialize initial 1st moment vector) v_0 <- 0 (Initialize initial 2nd moment vector) t <- 0 (Initialize timestep)在论文中的 section2 的末尾所描述了更新规则,该规则使用梯度g来更新变量:
t <- t + 1 lr_t <- learning_rate * sqrt(1 - beta2^t) / (1 - beta1^t) m_t <- beta1 * m_{t-1} + (1 - beta1) * g v_t <- beta2 * v_{t-1} + (1 - beta2) * g * g variable <- variable - lr_t * m_t / (sqrt(v_t) + epsilon)其中epsilon 的默认值1e-8可能对于大多数情况都不是一个合适的值。例如,当在ImageNet上训练一个 Inception network时比较好的选择为1.0或者0.1。 需要注意的是,在稠密数据中即便g为0时, m_t, v_t 以及variable都将会更新。而在稀疏数据中,m_t, v_t 以及variable不被更新且值为零。
TensorFlow 提供了计算给定tf计算图的求导函数,并在图的基础上增加节点。优化器(optimizer )类可以自动的计算网络图的导数,但是优化器中的创建器(creators )或者专业的人员可以通过本节所述的函数调用更底层的方法。
操作描述tf.gradients(ys, xs, grad_ys=None, name=’gradients’, colocate_gradients_with_ops=False, gate_gradients=False, aggregation_method=None)构建一个符号函数,计算ys关于xs中x的偏导的和, 返回xs中每个x对应的sum(dy/dx)tf.stop_gradient(input, name=None)停止计算梯度, 在EM算法、Boltzmann机等可能会使用到tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)基于定义的min与max对tesor数据进行截断操作, 目的是为了应对梯度爆发或者梯度消失的情况tf.clip_by_norm(t, clip_norm, axes=None, name=None)使用L2范式标准化tensor最大值为clip_norm 返回 t * clip_norm / l2norm(t)tf.clip_by_average_norm(t, clip_norm, name=None)使用平均L2范式规范tensor数据t, 并以clip_norm为最大值 返回 t * clip_norm / l2norm_avg(t)tf.clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None)返回t_list[i] * clip_norm / max(global_norm, clip_norm) 其中global_norm = sqrt(sum([l2norm(t)**2 for t in t_list]))tf.global_norm(t_list, name=None)返回global_norm = sqrt(sum([l2norm(t)**2 for t in t_list]))