[软件工程应用与实践]lingvo学习笔记

[软件工程应用与实践]lingvo学习笔记

2021SC@SDUSC

lingvo.core.egdd module

指数梯度Delta-Delta优化器 Exponentiated Gradient Delta-Delta optimizer

classlingvo.core.egdd.EGDD(
	learning_rate, 
	momentum, 
	beta=0.9, 
	gain_learning_rate=0.01, 
	scale_learning_rate=0.001, 
	initial_gain=1.0, 
	min_gain=0.01, 
	max_gain=100.0, 
	initial_scale=1.0, 
	min_scale=0.1, 
	max_scale=10.0, 
	use_directions=True, 
	use_signs=True, 
	name='EGDD')

基于tensorflow.python.training.optimizer.Optimizer , GD momentum的一个版本,具有自适应增益和学习速率。
Exponentiated Gradient Delta-delta优化器开始时,每个权重的局部增益为1.0,所有权重的lr_scale为1.0。EGDD更新规则适用于 :

  • momentum <- mu * momentum + learning_rate * gain * grad var <- var - lr_scale * momentum
  • 增益和lr_scale使用非归一化指数梯度算法进行更新

参数列表

  • learning_rate : floatTensor, 学习率
  • momentum : floatTensor
  • beta : float, EMA 梯度下降率

指数移动平均(Exponential Moving Average)也叫权重移动平均(Weighted Moving Average),是一种给予近期数据更高权重的平均方法。

  • gain_learning_rate : float, 知识增益率
  • scale_learning_rate : float, 规模学习速率
  • initial_gain : float, 初始增益
  • min_gain : float, 最小增益
  • max_gain : float, 最大增益
  • initial_scale : float, 初始规模
  • min_scale : float, 最小学习规模
  • max_scale : float, 最大规模
  • use_directions : bool, 判断方向是否仅应用于更新规模
  • use_signs : bool, 判断更新增益时是否有符号
  • name : 应用时创建的操作的可选名称前缀梯度

方法

_create_slots(var_list)

参数列表 :

  • var_list : variable 对象列表

函数作用 : 创建变量所需的所有槽。

源码:

  def _create_slots(self, var_list):

遍历参数列表并创建所需的槽

    for v in var_list:
      self._zeros_slot(v, "momentum", self._name)
      self._zeros_slot(v, "gbar", self._name)
      g_tensor = ops.convert_to_tensor(v)
      gain_init = self._initial_gain * array_ops.ones_like(g_tensor)
      _ = self._get_or_make_slot(v, self._initial_scale * array_ops.ones((1)),
                                 "lr_scale", self._name)
      _ = self._get_or_make_slot(v, gain_init, "gain", self._name)
      _ = self._get_or_make_slot(v, array_ops.zeros((1)), "counter", self._name)

_prepare()

函数作用 : 在应用梯度之前创建所有需要的张量。使用用户为梯度选择的“name”来调用name_scope。

源码 :

  def _prepare(self):

创建 learning_rate 的张量

    learning_rate = self._call_if_callable(self._learning_rate)
    self._learning_rate_tensor = ops.convert_to_tensor(
        learning_rate, name="learning_rate")

创建 momentum 的张量

    momentum = self._call_if_callable(self._momentum)
    self._momentum_tensor = ops.convert_to_tensor(momentum, name="momentum")

_apply_dense(grad, var)

参数 :

  • grad : Tensor
  • var : variable 对象
  • 返回 : Operation

函数作用 : 添加 ops 以应用梯度密度函数到 var

  def _apply_dense(self, grad, var):

获得变量的槽

    lr_scale = self.get_slot(var, "lr_scale")
    momentum = self.get_slot(var, "momentum")
    gbar = self.get_slot(var, "gbar")
    gain = self.get_slot(var, "gain")

计数更新次数

    counter = self.get_slot(var, "counter")
    counter_updated = state_ops.assign(counter, counter + 1)

lr_scale 更新使用归一化梯度和 momentum 而独立于维度

    normalized_grad = grad / (linalg_ops.norm(grad) + 1e-10)
    normalized_momentum = momentum / (linalg_ops.norm(momentum) + 1e-10)

在 lr_scale 上应用 EG 更新 :

公式 :

  • grad_lr_scale = -inner_product(current_grad, old_momentum)
  • lr_scale <- lr_scale * exp(-scale_learning_rate * grad_lr_scale)
    lr_scale_unnormalized_updated = clip_ops.clip_by_value(
        lr_scale * math_ops.exp(
            self._scale_learning_rate * math_ops.reduce_sum(grad * momentum)),
        self._min_scale, self._max_scale)
    lr_scale_normalized_updated = clip_ops.clip_by_value(
        lr_scale * math_ops.exp(self._scale_learning_rate * math_ops.reduce_sum(
            normalized_grad * normalized_momentum)), self._min_scale,
        self._max_scale)
    lr_scale_updated = state_ops.assign(
        lr_scale,
        array_ops.where(self._use_directions, lr_scale_normalized_updated,
                        lr_scale_unnormalized_updated))

移除 gbar 中初始化为零的 bias

    corrected_gbar = gbar / (
        1.0 - self._beta**math_ops.maximum(counter_updated - 1, 1))

应用EG更新增益 :

公式 :

  • grad_gain = - current_grad * old_gbar
  • gain <- gain * exp(-gain_learning_rate * grad_gain)
    gain_unnormalized_updated = clip_ops.clip_by_value(
        gain * math_ops.exp(self._gain_learning_rate * grad * corrected_gbar),
        self._min_gain, self._max_gain)

规范化----使用 sign(grad) *sign(gbar) 代替 grad_gain。

    gain_normalized_updated = clip_ops.clip_by_value(
        gain * math_ops.exp(self._gain_learning_rate * math_ops.sign(grad) *
                            math_ops.sign(gbar)), self._min_gain,
        self._max_gain)
    gain_updated = state_ops.assign(
        gain,
        array_ops.where(self._use_signs, gain_normalized_updated,
                        gain_unnormalized_updated))
    scaled_g = self._learning_rate_tensor * gain_updated * grad

返回Operation

    with ops.control_dependencies([lr_scale_updated, scaled_g]):
      momentum_updated = state_ops.assign(
          momentum, self._momentum_tensor * momentum + scaled_g)
      gbar_updated = state_ops.assign(
          gbar, self._beta * gbar + (1.0 - self._beta) * grad)
    with ops.control_dependencies([gbar_updated]):
      return state_ops.assign_sub(var, lr_scale_updated * momentum_updated)

_resource_apply_dense(grad, var)

参数 :

  • grad : Tensor, 表示梯度
  • handle : 数据类型为 resourceTensor, 指向要更新的变量
  • 返回 : operation, 更新变量值

添加 operation 以将密度梯度应用于变量句柄。

源码 :
调用_apply_dense方法

  def _resource_apply_dense(self, grad, var):
    return self._apply_dense(grad, var)

_resource_apply_sparse(grad_values, var, grad_indices)

参数 :

  • grad : Tensor, 表示受影响指数的梯度
  • handle : 数据类型为 resourceTensor, 指向要更新的变量
  • indices : 表示梯度不为零的指标的整型Tensorindices是唯一的。
  • 返回 : operation, 更新变量值

源码 :

  # Sparse gradients are not handled currently and is part of future work.
  def _resource_apply_sparse(self, grad_values, var, grad_indices):
    return control_flow_ops.no_op()

_apply_sparse(grad, var)

参数 :

  • grad : IndexedSlices, 没有重复的指标
  • var : Variable 对象
  • 返回 : operation

源码 :

  def _apply_sparse(self, grad, var):
    return control_flow_ops.no_op()

该 module 重点为使用了梯度下降算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值