首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >两个序列模型在GradientTape中变权和的GradientTape

两个序列模型在GradientTape中变权和的GradientTape
EN

Stack Overflow用户
提问于 2022-05-25 21:24:28
回答 1查看 174关注 0票数 1

假设我们希望使用梯度下降最小化以下方程:

min f(alpha * v + (1-alpha)*w)vw一起表示模型的权重,而alpha的权重在0到1之间,用于导致组合模型v_barū (此处称为m)的总和。

代码语言:javascript
复制
alpha = tf.Variable(0.01, name='Alpha', constraint=lambda t: tf.clip_by_value(t, 0, 1))
w_weights = tff.learning.ModelWeights.from_model(w)
v_weights = tff.learning.ModelWeights.from_model(v)
m_weights = tff.learning.ModelWeights.from_model(m)

m_weights_trainable = tf.nest.map_structure(lambda v, w: alpha*v + (tf.constant(1.0) - alpha)*w, v_weights.trainable, w_weights.trainable)
tf.nest.map_structure(lambda v, t: v.assign(t), m_weights.trainable, m_weights_trainable)

自适应个性化联合学习论文中,带更新步骤的alpha公式建议根据应用于小型批处理的模型m的梯度更新alpha。不管有没有手表,我都试过了,但它总是通向No gradients provided for any variable

代码语言:javascript
复制
with tf.GradientTape(watch_accessed_variables=False) as tape:
   tape.watch([alpha])
   outputs_m = m.forward_pass(batch)
grad = tape.gradient(outputs_m.loss, alpha)
optimizer.apply_gradients(zip([grad], [alpha]))

关于模型初始化的更多信息:

m.forward_pass(batch)是来自tff.learning.Model (发现的这里)的默认实现,通过使用tff.learning.from_keras_modeltf.keras.Sequential模型创建模型。

代码语言:javascript
复制
def model_fn():
   keras_model = create_keras_model()
   return tff.learning.from_keras_model(
     keras_model,
     input_spec = element_spec,
     loss = tf.keras.losses.MeanSquaredError(),
     metrics = [tf.keras.metrics.MeanSquaredError(),
                tf.keras.metrics.MeanAbsoluteError()],
   )
w = model_fn()
v = model_fn()
m = model_fn()

以下是Zachary Garrett提出的更多实验:

似乎只要计算出这个加权和,并为模型分配新的权重,它就失去了两个求和模型先前可训练变量的跟踪。同样,每当调用No gradients provided for any variable时,它都会导致optimizer.apply_gradients(zip([grad], [alpha]))。所有的梯度似乎都是None

代码语言:javascript
复制
with tf.GradientTape() as tape:
   alpha = tf.Variable(0.01, name='Alpha', constraint=lambda t: tf.clip_by_value(t, 0, 1))

   m_weights_t = tf.nest.map_structure(lambda w, v: tf.math.scalar_mul(alpha, v, name=None) + tf.math.scalar_mul(tf.constant(1.0) - alpha, w, name=None),
                                w.trainable,
                                v.trainable)

   m_weights = tff.learning.ModelWeights.from_model(m)
   tf.nest.map_structure(lambda v, t: v.assign(t), m_weights.trainable,
                  m_weights_trainable)

   outputs_m = m.forward_pass(batch)

grad = tape.gradient(outputs_m.loss, alpha)
optimizer.apply_gradients(zip([grad], [alpha]))

另一个编辑:我认为我有一个让它工作的策略,但是手动设置trainable_weights_trainable_weights不起作用,这是错误的做法。有什么改进的建议吗?

代码语言:javascript
复制
  def do_weighted_combination():

    def _mapper(target_layer, v_layer, w_layer):
      target_layer.kernel = v_layer.kernel * alpha + w_layer.kernel * (1-alpha)
      target_layer.bias = v_layer.bias * alpha + w_layer.bias * (1-alpha)

    tf.nest.map_structure(_mapper, m.layers, v.layers, w.layers)


  with tf.GradientTape(persistent=True) as tape: 
    do_weighted_combination()

    predictions = m(x_data)
    loss = m.compiled_loss(y_data, predictions)


  g1 = tape.gradient(loss, v.trainable_weights) # Not None
  g2 = tape.gradient(loss, alpha) # Not None
EN

回答 1

Stack Overflow用户

发布于 2022-06-03 18:37:30

对于使用TensorFlow的tf.GradientTape自动区分,必须在tf.GradientTape Python上下文管理器中进行操作,以便TensorFlow能够“看到”它们。

这里可能发生的情况是,在设置模型变量时,在磁带上下文之外/之前使用了alpha。然后,当m.forwad_pass被调用时,TensorFlow看不到对alpha的任何访问,因此无法计算它的梯度(相反,返回None)。

移动

代码语言:javascript
复制
alpha*v + (tf.constant(1.0) - alpha)*w, v_weights.trainable, w_weights.trainable

tf.GradientTape上下文管理器中的逻辑(可能在m.forward_pass中)可能是一个解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72384343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档