【问题标题】:How to write a custom loss function in Tensorflow?如何在 Tensorflow 中编写自定义损失函数?
【发布时间】:2016-01-19 11:44:35
【问题描述】:

我是tensorflow 的新手。我想编写自己的自定义损失函数。有没有关于这个的教程?例如,铰链损失或 sum_of_square_loss(尽管这已经在 tf 中)? 我可以直接在python中做还是我必须编写cpp代码?

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    我们需要写下损失函数。例如,我们可以使用基本均方误差作为预测 y 和目标 y_ 的损失函数:

     loss_mse = 1/n(Sum((y-y_)^2))
    

    张量有一些基本函数,如tf.add(x,y)、tf.sub(x,y)、tf.square(x)、tf.reduce_sum(x)、 etc。

    然后我们可以在 Tensorflow 中定义我们的损失函数,如下所示:

    cost = tf.reduce_mean(tf.square(tf.sub(y,y_)))
    

    注意:y 和 y_ 是张量。

    此外,如果我们可以写下方程式,我们可以定义任何其他损失函数。对于一些训练算子(最小化器),损失函数应该满足一些条件(平滑、可微...)。

    一言以蔽之,Tensorflow 将数组、常量、变量定义为张量,使用 tf 函数定义计算,使用 session 运行通过图。我们可以定义任何我们喜欢的东西并最终运行它。

    【讨论】:

      【解决方案2】:

      除了其他答案,如果可以将损失函数表示为现有函数的组合,您可以在 Python 中编写损失函数。

      例如,看一下sigmoid_cross_entropy_with_logits link 的实现,它是使用基本转换实现的。

      【讨论】:

      【解决方案3】:

      几乎在所有 tensorflow 教程中,他们都使用自定义函数。例如在beginning tutorial 中他们编写了一个自定义函数:

      对当前模型和提供的数据之间的增量平方求和

      squared_deltas = tf.square(linear_model - y)
      loss = tf.reduce_sum(squared_deltas)
      

      在下MNIST for beginners they use a cross-entropy:

      cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
      

      正如您所见,这并不难:您只需将函数编码为张量格式并使用它们的基本函数。

      例如,这里是如何实现 F-beta 分数(F1 score 的一般方法)。其公式为:

      我们唯一需要做的就是找出如何计算布尔值或 0/1 值的 true_positive、false_positive、false_negative。如果您有 0/1 值的向量,则可以将每个值计算为:

      TP = tf.count_nonzero(actual, predicted)
      FP = tf.count_nonzero((actual - 1) * predicted)
      FN = tf.count_nonzero((predicted - 1) * actual)
      

      现在,一旦你知道了这些值,你就可以很容易地得到你的

      denom = (1 + b**2) * TP + b**2 TN + FP
      Fb = (1 + b**2) * TP / denom
      

      【讨论】:

      • 不幸的是,您的 F-beta 分数实现存在多个问题: - 第一行应该是:TP = tf.count_nonzero(actual * predicted) - denom = (1 + b**2) * TP + b**2 FN + FP - 但是,这里的主要问题是这个实现不能用作自定义损失函数,因为没有办法计算梯度。例如,没有确定predicted 值的线性方法。
      • 解决梯度问题的一种方法是使用Scherzinger et al.所述的预测概率来计算TP、FP和FN
      【解决方案4】:
      def focal_loss(y_true, y_pred):
        pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
        pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
        custom_loss=kb.square((pt_1-pt_0)/10)
        return custom_loss    
      
      model.compile(loss=focal_loss,
                optimizer='adam',
                metrics=['accuracy'])
      

      【讨论】:

        【解决方案5】:

        我用 Kullbak-Leibler 散度实现自定义损失函数,其中 p = 常数。 我在自动编码器中使用它。

        rho = 0.05
        
        class loss_with_KLD(losses.Loss):
            
            def __init__(self, rho):
                super(loss_with_KLD, self).__init__()
                self.rho = rho
                self.kl = losses.KLDivergence()
                self.mse = losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM)
                
            def call(self, y_true, y_pred):
                mse = self.mse(y_true, y_pred)
                kl = self.kl(self.rho, y_pred)
                return mse + kl
        

        可能对任何人都有帮助。

        【讨论】:

          猜你喜欢
          • 2021-10-08
          • 2021-03-22
          • 2021-09-21
          • 2018-10-28
          • 2017-12-29
          • 1970-01-01
          • 2021-06-07
          • 2019-12-16
          • 2020-07-29
          相关资源
          最近更新 更多