【问题标题】:Non-smooth and non-differentiable customized loss function tensorflow非平滑不可微的自定义损失函数 tensorflow
【发布时间】:2017-04-06 18:34:53
【问题描述】:
  1. 在tensorflow中,能不能用non-smooth function作为损失函数,比如piece-wise(或者if-else)?如果不能,为什么可以使用 ReLU?

  2. 在此链接中 SLIM ,它说

“例如,我们可能希望最大限度地减少对数损失,但我们感兴趣的指标可能是 F1 分数或 Intersection Over Union 分数(不可微分,因此不能用作损失)。”

这是否意味着“不可微分”,例如集合问题?因为对于 ReLU,在点 0,它是不可微的。

  1. 如果使用这种自定义的损失函数,是否需要自己实现梯度?还是 tensorflow 可以自动为您完成?我检查了一些自定义的损失函数,他们没有为他们的损失函数实现梯度。

【问题讨论】:

  • 也在寻找关于#3 的答案。谢谢你的好问题

标签: tensorflow


【解决方案1】:

问题不在于损失是分段的或不平滑的。问题是我们需要一个损失函数,当输出和预期输出之间存在误差时,它可以将非零梯度发送回网络参数(dloss/dparameter)。这适用于模型内部使用的几乎所有函数(例如损失函数、激活函数、注意力函数)。

例如,感知器使用unit step H(x) 作为激活函数(如果 x > 0 则 H(x) = 1 否则为 0)。由于 H(x) 的导数始终为零(在 x=0 时未定义),因此来自损失的梯度不会通过它返回到权重(链式法则),因此在网络中的该函数之前没有权重可以更新使用梯度下降。基于此,梯度下降不能用于感知器,但可以用于使用sigmoid 激活函数的传统神经元(因为所有 x 的梯度都不是零)。

对于 Relu,x > 0 的导数为 1,否则为 0。虽然导数在 x=0 时未定义,但当 x>0 时,我们仍然可以通过它反向传播损失梯度。这就是它可以使用的原因。

这就是为什么我们需要一个具有非零梯度的损失函数。像accuracy和F1这样的函数到处都有零梯度(或者在某些x值处未定义),所以它们不能被使用,而像交叉熵、L2L1这样的函数有非零梯度,所以它们可以使用。 (注意L1“绝对差”是分段的,在x=0时不平滑但仍然可以使用)

如果您必须使用不符合上述条件的函数,请尝试使用reinforcement learning methods(例如策略梯度)。

【讨论】:

  • 但是,直观地说,intersection-over-union 应该可以用非零梯度区分,只要它严格在零和一之间。
  • IoU 的工作原理是将交集的像素数除以并集的像素数。在这种情况下,它不应该是可微的,因为像素数是离散的。我相信如果我们使用边界框的实值坐标,IoU 将是可区分的。此外,This paper 提出了一种方法,通过修改基于像素的 IoU 来区分像素属于某个类别的概率。
【解决方案2】:

就 OP 的问题 #3 而言,您实际上不必自己实现梯度计算。 Tensorflow 将为您做到这一点,这是我喜欢它的原因之一!

【讨论】:

    【解决方案3】:
    1. tf 不会自动计算所有函数的梯度,即使使用一些后端函数也是如此。请参见。 Errors when Building up a Custom Loss Function我做了一个任务,然后我自己找到了答案。

    2. 话虽如此,人们只能逼近分段可微函数以实现例如分段常数/阶跃函数。以下是我在 MATLAB 中按照这样的想法实现的。人们可以很容易地将其扩展到具有更多阈值(接合点)和期望边界条件的情况。

    function [s, ds] = QPWC_Neuron(z, sharp)
    % A special case of (quadraple) piece-wise constant neuron composing of three Sigmoid functions
    % There are three thresholds (junctures), 0.25, 0.5, and 0.75, respectively
    % sharp determines how steep steps are between two junctures.
    % The closer a point to one of junctures, the smaller its gradient will become. Gradients at junctures are zero.
    % It deals with 1D signal only are present, and it must be preceded by another activation function, the output from which falls within [0, 1]
    % Example:
    % z = 0:0.001:1;
    % sharp = 100;
    
    LZ = length(z);
    s = zeros(size(z));
    ds = s;
    for l = 1:LZ
        if z(l) <= 0
            s(l) = 0;
            ds(l) = 0;
        elseif (z(l) > 0) && (z(l) <= 0.25)
            s(l) = 0.25 ./ (1+exp(-sharp*((z(l)-0.125)./0.25)));
            ds(l) = sharp/0.25 * (s(l)-0) * (1-(s(l)-0)/0.25);
        elseif (z(l) > 0.25) && (z(l) <= 0.5)
            s(l) = 0.25 ./ (1+exp(-sharp*((z(l)-0.375)./0.25))) + 0.25;
            ds(l) = sharp/0.25 * (s(l)-0.25) * (1-(s(l)-0.25)/0.25);
        elseif (z(l) > 0.5) && (z(l) <= 0.75)
            s(l) = 0.25 ./ (1+exp(-sharp*((z(l)-0.625)./0.25))) + 0.5;
            ds(l) = sharp/0.25 * (s(l)-0.5) * (1-(s(l)-0.5)/0.25);
        elseif (z(l) > 0.75) && (z(l) < 1)
            % If z is larger than 0.75, the gradient shall be descended to it faster than other cases
            s(l) = 0.5 ./ (1+exp(-sharp*((z(l)-1)./0.5))) + 0.75;
            ds(l) = sharp/0.5 * (s(l)-0.75) * (1-(s(l)-0.75)/0.5);
        else
            s(l) = 1;
            ds(l) = 0;
        end
    end
    figure;
    subplot 121, plot(z, s); xlim([0, 1]);grid on;
    subplot 122, plot(z, ds); xlim([0, 1]);grid on;
    
    end
    
    

    1. 关于 Python 和 tf 中的实现,可以参考@papaouf_ai 的出色逐步说明。 How to make a custom activation function with only Python in Tensorflow?

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2018-07-11
      • 2018-10-28
      • 2017-12-29
      • 2018-12-28
      • 2022-06-13
      • 2021-10-26
      • 2020-09-12
      • 2019-04-12
      相关资源
      最近更新 更多