在tensorflow中,你可以使用非平滑函数作为丢失函数,例如分段(或使用if-else)吗?如果你不能,为什么你可以使用ReLU?
在此链接中 SLIM ,它说
“例如,我们可能希望最大限度地减少对数损失,但我们感兴趣的指标可能是F1得分或交叉点超过联盟得分(不可区分,因此不能用作损失)。”
它是否意味着“不可区分”,例如设置问题?因为对于ReLU,在0点,它是不可区分的。
答案 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值处未定义),因此无法使用它们,而交叉熵,L2和L1等函数则具有非梯度零梯度,因此可以使用它们。 (注意L1"绝对差异"是分段的,在x = 0时不平滑,但仍然可以使用)
如果您必须使用不符合上述条件的功能,请尝试使用reinforcement learning methods(例如政策渐变)。
答案 1 :(得分:4)
就OP的问题#3而言,你实际上并不需要自己实现梯度计算。 Tensorflow将为您做到这一点,这是我喜欢的事情之一!
答案 2 :(得分:0)
tf不会自动为所有函数计算梯度,即使使用某些后端函数也是如此。请参阅。 Errors when Building up a Custom Loss Function完成一项任务,然后我自己找到了答案。
可以说,一个人只能近似地逐段微分函数,以实现例如逐段常数/阶跃函数。以下是我在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