非平滑且不可微的定制损失函数张量流

时间:2016-11-22 22:28:31

标签: tensorflow

  1. 在tensorflow中,你可以使用非平滑函数作为丢失函数,例如分段(或使用if-else)吗?如果你不能,为什么你可以使用ReLU?

  2. 在此链接中 SLIM ,它说

  3. “例如,我们可能希望最大限度地减少对数损失,但我们感兴趣的指标可能是F1得分或交叉点超过联盟得分(不可区分,因此不能用作损失)。”

    它是否意味着“不可区分”,例如设置问题?因为对于ReLU,在0点,它是不可区分的。

    1. 如果你使用这种定制的损失功能,你需要自己实现渐变吗?或者tensorflow可以自动为您完成吗?我检查了一些保留的损失函数,它们没有为它们的损失函数实现渐变。

3 个答案:

答案 0 :(得分:15)

问题不在于损失是分段还是非顺利。问题是我们需要一个损失函数,当输出和预期输出之间存在误差时,该函数可以将非零梯度发送回网络参数(dloss / dparameter)。这适用于模型中使用的几乎任何函数(例如,损失函数,激活函数,注意函数)。

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

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

这就是为什么我们需要一个具有非零梯度的损失函数。像精度和F1这样的函数在任何地方都有零梯度(或者在某些x值处未定义),因此无法使用它们,而交叉熵,L2L1等函数则具有非梯度零梯度,因此可以使用它们。 (注意L1"绝对差异"是分段的,在x = 0时不平滑,但仍然可以使用)

如果您必须使用不符合上述条件的功能,请尝试使用reinforcement learning methods(例如政策渐变)。

答案 1 :(得分:4)

就OP的问题#3而言,你实际上并不需要自己实现梯度计算。 Tensorflow将为您做到这一点,这是我喜欢的事情之一!

答案 2 :(得分:0)

  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

enter image description here enter image description here enter image description here

  1. 对于Python和tf中的实现,可以从这里引用@papaouf_ai的出色的逐步说明。 How to make a custom activation function with only Python in Tensorflow?