程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Tensorflow 2 中的控制流 - 梯度为无大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Tensorflow 2 中的控制流 - 梯度为无?

开发过程中遇到Tensorflow 2 中的控制流 - 梯度为无的问题如何解决?下面主要结合日常开发的经验,给出你关于Tensorflow 2 中的控制流 - 梯度为无的解决方法建议,希望对你解决Tensorflow 2 中的控制流 - 梯度为无有所启发或帮助;

我有一个 Tensorflow 2.x 模型,目的是动态选择计算路径。这是该模型的示意图:

Tensorflow 2 中的控制流 - 梯度为无

唯一可训练的模块是决策模块 (DM),它本质上是一个具有单个二进制输出(0 或 1;它可以使用称为改进语义哈希的技术)的全连接层。网络 A 和 B 具有相同的网络架构。 在训练过程中,我将一批图像前馈到 DM 的输出,然后逐个图像处理决策,将每个图像定向到确定的网络(A 或 B)。预测连接成一个张量,用于评估性能。这是训练代码(sigma 是 DM 的输出;@H_633_10@model 包括特征提取器和 DM):

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=TruE)
optimizer = tf.keras.optimizers.Adam()
Train_loss = tf.keras.metrics.Mean(name='Train_loss')
Train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='Train_accuracy')


@tf.function
def Train_step(images,labels):
    with tf.GradIEntTape() as tape:
        # Training=True is only needed if there are custom_layers with different
        # behavior during Training versus inference (e.g. Dropout).
        _,sigma = model(images,Training=TruE)
        out = []
        for img,s in zip(images,sigma):
            if s == 0:
                o = binary_classifIEr_model_a(tf.expand_dims(img,axis=0),Training=falsE)
            else:
                o = binary_classifIEr_model_b(tf.expand_dims(img,Training=falsE)
            out.append(o)

        preDictions = tf.concat(out,axis=0)
        loss = loss_object(labels,preDictions)
    gradIEnts = tape.gradIEnt(loss,model.Trainable_variables)
    optimizer.apply_gradIEnts(zip(gradIEnts,model.Trainable_variables))

    Train_loss(loss)
    Train_accuracy(labels,preDictions)

问题 - 运行此代码时,gradIEnts 返回 [None,None]。 我现在知道的是:

@H_489_25@
  • 模型的第一部分(直到 DM 的输出)是可微的;我通过仅运行此部分并应用损失函数 (MSE) 然后应用 tape.gradIEnts 来测试它 - 我得到了实际的梯度。
  • 我尝试选择单个(常数)网络 - 例如,网络 A - 并简单地将其输出乘以 s(0 或 1);这是代替代码中的 if-else 块执行的。在这种情况下,我也得到了渐变。
  • 我担心这样的事情可能是不可能的 - 引用自 official docs:

    x = tf.constant(1.0)
    
    v0 = tf.Variable(2.0)
    v1 = tf.Variable(2.0)
    
    with tf.GradIEntTape(persistent=TruE) as tape:
      tape.watch(X)
      if x > 0.0:
        result = v0
      else:
        result = v1**2 
    

    根据上例中 x 的值,磁带要么 记录结果 = v0 或结果 = v1**2。 关于梯度 x 始终为 None。

    dx = tape.gradIEnt(result,X)
    print(dX)
    >> None
    

    我不是 100% 确定这是我的情况,但我想在这里询问专家的意见。 我正在尝试做的可能吗?如果是 - 我应该改变什么才能使它起作用? 谢谢

    解决方法

    您正确识别了问题。条件的控制语句是不可微的,所以你失去了与产生 sigma 的模型变量的链接。

    在您的情况下,因为您声明 sigma 是 1 或 0,所以您可以使用 sigma 的值作为掩码,并跳过条件语句(甚至循环)。

    with tf.GradientTape() as tape:
        _,sigma = model(images,Training=TruE)
        preDictions = (1.0 - sigma) * binary_classifier_model_a(images,Training=falsE)\
                       + sigma * binary_classifier_model_b(images,Training=falsE)
        loss = loss_object(labels,preDictions)
    

    大佬总结

    以上是大佬教程为你收集整理的Tensorflow 2 中的控制流 - 梯度为无全部内容,希望文章能够帮你解决Tensorflow 2 中的控制流 - 梯度为无所遇到的程序开发问题。

    如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
    如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。