Я работаю над реализацией нейронной сети в Java. Я реализовал несколько функций активации, используя интерфейс ActivationFunction
:
public interface ActivationFunction {
public double[] activation(double[] input);
public double[] derivative(double[] input);
public String toString();
}
Затем я реализую различные функции активации, например Sigmoid
:
public class Sigmoid implements ActivationFunction {
@Override
public double[] activation(double[] input) {
double[] output = new double[input.length];
for(int neuron = 0; neuron < output.length; neuron++) {
output[neuron] = (1d / (1d + Math.exp(-input[neuron])));
}
return output;
}
@Override
public double[] derivative(double[] input) {
double[] sigmoid = activation(input);
double[] output = new double[input.length];
for(int neuron = 0; neuron < output.length; neuron++) {
output[neuron] = sigmoid[neuron] * (1d - sigmoid[neuron]);
}
return output;
}
@Override
public String toString() {
return "Sigmoid";
}
}
Каждый слой в нейронной сети имеет свой собственный ActivationFunction
, поэтому я просто получаю к нему доступ через интерфейс, не имеет значения, какая функция используется в данный момент, и я могу изменить ее без необходимости что-либо менять в слое.
Однако теперь я хочу реализовать функцию softmax. Метод activation()
не является проблемой, но derivative()
softmax является не вектором, а матрицей, что означает, что он должен будет возвращать двумерный массив.
Это означает, что я, очевидно, не могу перезаписать метод derivative()
интерфейса, так что это наносит ущерб всей цели интерфейса. Я мог бы проверить, если ActivationFunction instanceof Softmax
, и соответственно разыграть его, но я узнал, что это плохая практика.
Какой, на ваш взгляд, самый элегантный подход к решению этой проблемы? Спасибо