Ahm*_*taş 3 java machine-learning derivative backpropagation softmax
因此,我对 ML 很陌生,并尝试创建一个简单的“库”,以便我可以了解有关神经网络的更多信息。
我的问题:根据我的理解,我必须根据每层的激活函数求导数,这样我就可以计算它们的增量并调整它们的权重等......
对于 ReLU、sigmoid、tanh,用 Java 实现它们非常简单(顺便说一句,这是我使用的语言)
但要从输出到输入,我必须从(显然)具有 softmax 激活函数的输出开始。
那么我是否也必须采用输出层的导数,或者它只适用于所有其他层?
如果我确实必须获得导数,我怎样才能在Java中实现导数呢?谢谢。
我已经阅读了很多关于 Softmax 算法导数的解释的页面,但它们对我来说真的很复杂,正如我所说,我刚刚开始学习 ML,我不想使用现成的库,所以在这里我是。
这是我存储激活函数的类。
public class ActivationFunction {
public static double tanh(double val) {
return Math.tanh(val);
}
public static double sigmoid(double val) {
return 1 / 1 + Math.exp(-val);
}
public static double relu(double val) {
return Math.max(val, 0);
}
public static double leaky_relu(double val) {
double result = 0;
if (val > 0) result = val;
else result = val * 0.01;
return result;
}
public static double[] softmax(double[] array) {
double max = max(array);
for (int i = 0; i < array.length; i++) {
array[i] = array[i] - max;
}
double sum = 0;
double[] result = new double[array.length];
for (int i = 0; i < array.length; i++) {
sum += Math.exp(array[i]);
}
for (int i = 0; i < result.length; i++) {
result[i] = Math.exp(array[i]) / sum;
}
return result;
}
public static double dTanh(double x) {
double tan = Math.tanh(x);
return (1 / tan) - tan;
}
public static double dSigmoid(double x) {
return x * (1 - x);
}
public static double dRelu(double x) {
double result;
if (x > 0) result = 1;
else result = 0;
return result;
}
public static double dLeaky_Relu(double x) {
double result;
if (x > 0) result = 1;
else if (x < 0) result = 0.01;
else result = 0;
return result;
}
private static double max(double[] array) {
double result = Double.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (array[i] > result) result = array[i];
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
我期待得到这个问题的答案:我是否需要softmax的导数?如果是这样我该如何实施?
第一个问题的简短回答是肯定的,您需要计算 softmax 的导数。
\n\n较长的版本将涉及一些计算,因为为了实现反向传播,您需要通过一阶优化算法来训练网络,该算法需要计算成本函数相对于权重的偏导数,即:
\n\n\n\n然而,由于您在最后一层使用的是 softmax,因此您很可能会在训练神经网络时优化交叉熵成本函数,即:
\n\n\n\n其中t j是目标值,a j是j类的 softmax 结果。
\n\nSoftmax 本身表示n 个类别的概率分布:
\n\n\n\n其中所有z都是前一层激活函数结果乘以相应权重的简单总和:
\n\n\n\n其中n是层数,i是前一层中神经元的数量,j是 softmax 层中神经元的数量。
\n\n因此,为了对这些权重中的任何一个进行偏导数,应该计算:
\n\n\n\n其中第二偏导数\xe2\x88\x82a k /\xe2\x88\x82z j确实是 softmax 导数,可以通过以下方式计算:
\n\n\n\n但是,如果您尝试计算上述成本函数对权重的导数的总和项,您将得到:
\n\n\n\n因此,在这种特殊情况下,计算的最终结果非常简洁,代表了网络输出与目标值之间的简单差异,仅此而已,即计算该总和所需的全部内容偏导数项就是:
\n\n\n\n因此,为了回答你的第二个问题,你可以将交叉熵成本函数关于输出激活(即softmax)的偏导数的计算与输出激活关于z j的偏导数结合起来,这会导致一个简短而清晰的实现,如果您使用非矢量化形式,它将如下所示:
\n\nfor (int i = 0; i < lenOfClasses; ++i)\n{\n dCdz[i] = t[i] - a[i];\n}\nRun Code Online (Sandbox Code Playgroud)\n\n随后,您可以使用dCdz反向传播到神经网络的其余层。
\n| 归档时间: |
|
| 查看次数: |
5297 次 |
| 最近记录: |