Python 3.x 如何使用Tensorflow 2在自定义优化器上更新可训练变量

Python 3.x 如何使用Tensorflow 2在自定义优化器上更新可训练变量,python-3.x,optimization,tensorflow2.0,loss-function,cnn,Python 3.x,Optimization,Tensorflow2.0,Loss Function,Cnn,我现在是个学习卷积神经网络的新手 因此,我一直在参考一篇题为“深卷积神经网络的图像网络分类”的论文来实现AlexNet,该论文在anaconda环境中使用了Tensorflow 2.3。 然而,我在实现自定义优化器时感到沮丧 我的问题是:我必须根据AlexNet论文修改优化器。我无法找到如何更新使用TensorflowV2的变量的引用,但我在谷歌上搜索过。只有“tf.assign()”使用,它在Tensorflow V2中不受支持,但如果要使用此函数,我还担心V1和V2之间的兼容性 我只知道我必

我现在是个学习卷积神经网络的新手

因此,我一直在参考一篇题为“深卷积神经网络的图像网络分类”的论文来实现AlexNet,该论文在anaconda环境中使用了Tensorflow 2.3。 然而,我在实现自定义优化器时感到沮丧

我的问题是:我必须根据AlexNet论文修改优化器。我无法找到如何更新使用TensorflowV2的变量的引用,但我在谷歌上搜索过。只有“tf.assign()”使用,它在Tensorflow V2中不受支持,但如果要使用此函数,我还担心V1和V2之间的兼容性

我只知道我必须定制“\u resource\u apply\u dense”函数来适应我的更新规则。然后,我在那里加载了一些超参数。但我不知道如何更新超参数

(tf.Variable()可以用作python变量,因此我假设它与tf.Variable()相同。)

感谢所有先进的读者^_^

这是密码

- update rule in AlexNet
 v_(i+1)= momentum * v_i- 0.0005 * learning_rate * w_i - learning_rate * gradient
 w_(i+1) = w_i + v_(i+1)

# where
# w_i = weight
# v_i = velocity
来自tensorflow.python.framework的

从tensorflow.python.keras.optimizer\u v2导入optimizer\u v2
从tensorflow.python.ops导入数组
从tensorflow.python.ops导入资源变量
从tensorflow.python.training导入培训
从tensorflow.python.util.tf_导出导入keras_导出
导入tensorflow作为tf
类AlexSGD(优化器_v2.OptimizerV2):
_HAS_AGGREGATE_GRAD=True
定义初始化(自我,
学习率=0.01,
重量衰减=0.0005,
动量=0.9,
name=“AlexSGD”,
**kwargs):
超级(AlexSGD,self)。\uuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
自我设置超(“学习率”,kwargs.get(“lr”,学习率))
self.\u设置\u超(“衰减”,self.\u初始衰减)
self.\u is\u first=真
自我设置超(“vx”,0)
自我设置超(“pg”,0)
自我设置超(“pv”,0)
自身重量衰减=错误
如果存在(重量衰减,运算张量)或可调用(重量衰减),或
重量衰减>0:
自身重量衰减=真
如果存在(权重衰减,(int,float))和(权重衰减<0或
重量(衰减>1):
raise VALUE ERROR('weight_DECATION'必须介于[0,1]之间)
自我设置超(“重量衰减”,重量衰减)
自身动量=假
如果isinstance(动量,运算张量)或callable(动量)或动量>0:
自身动量=真
如果isinstance(动量,(int,float))和(动量<0或动量>1):
raise VALUEMERROR(“'MONTORM'必须介于[0,1]之间”)
自我设定超(“动量”,动量)
def_创建_插槽(自身、变量列表):
如果是自动量:
对于var_列表中的var:
自我添加(变量,“动量”)
如果自身重量衰减:
对于var_列表中的var:
自添加槽(变量,“重量衰减”)
对于var_列表中的var:
自加_槽(var,'pv')#前一个变量,即重量或偏差
对于var_列表中的var:
self.add_slot(var,'pg')#上一个渐变
对于var_列表中的var:
self.add_插槽(var,'vx')#更新速度
定义准备本地(自身、变量设备、变量数据类型、应用状态):
超级(AlexSGD,self)。\u准备\u本地(变量设备、变量数据类型、应用状态)
应用状态[(变量设备,变量数据类型)][“动量”]=数组操作标识(
self.\u get\u hyper(“动量”,变量类型))
应用状态[(变量设备,变量数据类型)][“权重衰减”]=数组操作标识(
self.\u get\u hyper(“权重衰减”,变量数据类型))
应用状态[(变量设备,变量数据类型)][“vx”]=数组操作标识(
自我。获取超(“vx”,变量数据类型))
应用状态[(变量设备,变量数据类型)][“pv”]=阵列操作标识(
自我。获取超(“pv”,变量类型))
应用状态[(变量设备,变量数据类型)][“pg”]=数组操作标识(
self.\u get\u hyper(“pg”,var\u dtype))
#主要功能
@功能
定义资源应用密集(自、梯度、变量、应用状态=无):
var\u设备,var\u dtype=var.device,var.dtype.base\u dtype
系数=((应用状态或{}).get((变量设备,变量数据类型))
或自身。\回退\应用\状态(变量设备、变量数据类型))
动量=self.get\u槽(var,“动量”)
重量衰减var=self.get\u槽(var,“重量衰减”)
vx_var=self.get_插槽(var,“vx”)
pv_var=自取槽(var,“pv”)
pg_var=self.get_槽(var,“pg”)
lr\u t=自衰减的lr(变量类型)
#AlexNet中的更新规则
#v_(i+1)=动量*v_i-0.0005*lr*w_i-lr*梯度
#w_(i+1)=w_i+v_(i+1)
#在哪里
#w_i=var
#vx,v_i=速度(感觉需要将此变量设置为插槽)
#lr=学习率
#梯度=梯度
#我不明白为什么要声明pv,pg变量。。。
#是否由var和grad替代?(pv、pg参考博客)
#pv=以前的var
#pg=先前的梯度
如果self.\u是第一个:
self.\u is\u first=False
vx_var=梯度
新的变量=变量+vx变量
其他:
vx_var=动量_var*vx_var-重量_衰减_var*lr_t*pv_var-
lr_t*pg_var
新的变量=变量+vx变量
打印(“梯度:,梯度)
打印(“变量:”,变量)
打印(“vx\U变量:”,vx\U变量)
打印(“新变量:”,新变量)
打印(“pv_变量:”,pv_变量)
打印(“pg_变量:”,pg_变量)
#TODO:我被困在如何更新变量的问题上,因为tf.assign()函数
#在Tensorflow V2中不推荐使用
pg_var=梯度
pv_var=var
如果var==新变量:
var=新的
#TODO:为了更新变量,我找不到等价的变量
#TFV2中的“tf.assign”方法
#pg_变量赋值(g
m_t = m.assign(tf.maximum(beta_t * m + eps, tf.abs(grad)))