因此,我是ML的新手,并试图创建一个简单的“库”,以便我可以了解有关神经网络的更多信息。
我的问题: 根据我的理解,我必须根据它们的激活函数取每一层的导数,以便我可以计算它们的增量并调整它们的权重等。
对于ReLU,Sigmoid,tanh,使用Java(这是我使用的BTW语言)实现它们非常简单
但是要从输出转到输入,我必须(显然)从具有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;
}
}
我期望得到以下问题的答案:是否需要softmax的派生词? 如果可以,该如何实施?
答案 0 :(得分:0)
第一个问题的简短答案是 是 ,您需要计算softmax的导数。
较长的版本将涉及一些计算,因为要实现反向传播,您需要借助一阶优化算法来训练网络,该算法需要计算权重不等于成本函数的偏导数,即:
但是 ,由于您在最后一层使用softmax,因此很有可能在训练神经网络时将优化交叉熵代价函数网络,即:
其中 t j 是目标值, a j 是类 j 的softmax结果。
Softmax本身代表 n 类上的概率分布:
其中所有 z 都是前一层激活函数的结果与相应权重的简单和:
其中 n 是层数, i 是前一层的神经元数, j 是我们softmax层中神经元的数量。
因此,为了对这些权重中的任何一个取偏导数,应该计算:
其中二阶导数 ∂a k /∂z j 确实是softmax导数,可以是计算方法如下:
但是 ,如果您尝试计算上述成本函数w.r.t的导数之和项。重量,您将得到:
因此,在这种特殊情况下,结果是计算的最终结果非常整洁,并且代表了网络输出与目标值之间的简单差异,仅此而已,即,您需要计算出的总和偏导数的项就是:
因此,要回答您的第二个问题,您可以将交叉熵成本函数w.r.t输出激活的偏导数(即softmax)的计算与输出激活w.r.t的偏导数结合起来。 z j 会导致实现简短明了,如果您使用的是非矢量化形式,则将如下所示:
for (int i = 0; i < lenOfClasses; ++i)
{
dCdz[i] = t[i] - a[i];
}
随后,您可以使用 dCdz 向后传播到神经网络的其余层。