Python 得到一个keras模型以输出一个结果,另一个使用ma权重

Python 得到一个keras模型以输出一个结果,另一个使用ma权重,python,tensorflow,keras,moving-average,Python,Tensorflow,Keras,Moving Average,给定两个具有相同体系结构的keras模型model1和model2,我需要使用模型权重训练第一个模型,使用模型权重的移动平均值训练第二个模型。下面是一个例子来说明: from tensorflow.keras.models import Model from tensorflow.keras.optimizers import Adam from tensorflow_addons.optimizers import MovingAverage import tensorflow as tf

给定两个具有相同体系结构的keras模型
model1
model2
,我需要使用模型权重训练第一个模型,使用模型权重的移动平均值训练第二个模型。下面是一个例子来说明:

from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow_addons.optimizers import MovingAverage
import tensorflow as tf


model1 = Model(...)
model2 = tf.keras.models.clone_model(model1)
opt1 = Adam()
opt2 = MovingAverage(Adam())
model1.compile(optimizer=opt1)
model2.compile(optimizer=opt2)
with tf.GradientTape() as tape, tf.GradientTape() as tape2:
    loss = calculate_loss()  # the loss is the same
grads1 = tape.gradient(loss, model1.trainable_variables)
grads2 = tape2.gradient(loss, model2.trainable_variables)
model1.optimizer.apply_gradients(zip(grads1, model1.trainable_variables))
model2.optimizer.apply_gradients(zip(grads2, model2.trainable_variables))
每次梯度更新后,两个模型将在同一输入上调用,以输出单独的值

v1 = model1(inp)
v2 = model2(inp)

是否有可能消除双重逻辑
tape1
tape2
grads1
grads2
。。。通过合并两个模型以某种方式输出权重和平均权重的结果?

基本上,您可以在一个模型下创建同一网络的两个副本,但在不同的名称范围下,然后在优化时,使用一个优化器更新您的
常规
权重,让另一个优化器只更新你的
移动平均值
权重

资料
将numpy导入为np
导入tensorflow作为tf
从tensorflow_addons.optimizers导入移动平均值
从tensorflow.keras.optimizers导入Adam
#假数据
X=tf.random.normal([1000128])
y=tf.1\u热(
tf.random.uniform(
[1000, ],
minval=0,
maxval=3,
dtype=tf.int64),3)
自定义模型
#在特定名称范围下具有权重的自定义模型
二级重量模型(tf.keras.Model):
定义初始单位(自我,数量单位=256):
super()。\uuuu init\uuuuu()
self.num\u units=num\u units
self.x_r=tf.keras.layers.density(self.num_单位)
self.l_r=tf.keras.layers.density(3,activation=“softmax”)
self.x_ma=tf.keras.layers.density(self.num_单位)
self.l_ma=tf.keras.layers.density(3,activation=“softmax”)
def呼叫(自我,x):
使用tf.name_范围(“常规”):
out\u r=self.l\r(self.x\u r(x))
具有tf.name_范围(“ma”):
out_ma=self.l_ma(self.x_ma(x))
退场,退场
#损失函数
def钙损失(y_真,y_pred):
返回tf.keras.loss.CategoricalCrossentropy()(y_true,y_pred)
优化
#优化器
opt_r=Adam(1e-4)
选择=移动平均值(Adam(1e-4))
#实例化模型
模型=双权重模型()
#定义一个训练步骤
def系列步骤(X,y):
#前传
使用tf.GradientTape(persistent=True)作为磁带:
y_hat_r,y_hat_ma=模型(X)
r\u损失=计算损失(y,y\u)
平均损失=计算损失(y,y)
#在每个名称范围下获取可训练变量
r_vars=[]
ma_vars=[]
对于模型中的v.trainable_变量:
如果v.name中的“常规”:
r_变量附加(v)
如果v.name中的“ma”:
附加变量(v)
#优化
r_梯度=磁带梯度(r_损耗,r_变量)
ma_梯度=磁带梯度(ma_损耗,ma_变量)
选择应用渐变(zip(渐变、渐变))
选择应用梯度(zip(梯度、变量))
返回r_损失,ma_损失
列车模型
#列车
训练iter=iter(tf.data.Dataset.from_tensor_切片((X,y)).batch(32))
对于范围内的历元(10):
r_损失,ma_损失=[],[]
对于范围(100)内的批次:
X\U列,y\U列=下一列(iter列)
r_损失,ma_损失=列车步进(X_列车,y_列车)
r_损失。追加(r_损失)
马_损失。追加(马_损失)
如果批次%5==0:
msg=(f“r_损失:{np.平均值(r_损失):.4f}”
f“\tma_损失:{np.平均值(ma_损失):.4f}”)
打印(msg)
r_损失=[]
马乌损失=[]
#r_损失:1.6749毫安损失:1.7274
#r_损失:1.4319 ma_损失:1.6590
# ...

不清楚您的目标是什么。你把两个模型合并成一个是什么意思?我会编辑来解释。对不起,我没电了。谢谢,这和我想做的很相似。不过我有个问题,损失可以分担吗?我的意思是,两者都可以使用
r\u损耗
优化权重吗?这个方法比最初的例子更有效吗?我不确定我是否理解你的第一个问题。关于第二个,虽然我还没有对初始示例与我的解决方案进行基准测试或比较,但我假设创建一个具有双重权重的模型会减少代码、更容易训练、更容易推理等等……不过,我认为您的解决方案可以做到这一点,谢谢