Я пытаюсь реализовать алгоритм обратного распространения, и я создал код ниже. Нет очевидных ошибок, но когда я пытаюсь обучить сеть чему-то столь же простому, как проблема XOR, функция стоимости очень спорадическая c и на самом деле не так уж и улучшается за целых 10.000 итераций. Я не могу найти свою ошибку, но, возможно, что-то не так с моим умножением матриц?
О коде: сначала я запускаю ввод по сети с помощью функции «forward» и сохраняю все выходы слоя. Затем я вызываю «обратное распространение» с желаемым выходом и обучаю сеть. Матрица математики выполняется с помощью библиотеки математики. js.
class Neuralnetwork {
constructor(layers) {
this.weights = []
this.biases = []
this.learningRate = 0.1
for (let i = 1; i < layers.length; i++) {
this.weights.push(math.ones(layers[i], layers[i - 1]).map((x) => randomGaussian(0, 3)))
this.biases.push(math.ones(layers[i], 1).map((x) => randomGaussian(0, 3)))
}
}
forward(input) {
this.layerOutputs = []
let output = math.matrix(input)
this.layerOutputs.push(output)
for (let i in this.weights) {
output = math.multiply(this.weights[i], output)
output = math.add(output, this.biases[i])
output = output.map(Neuralnetwork.activation)
this.layerOutputs.push(output)
}
return output.valueOf()
}
backpropagate(target) {
let error = math.subtract(target, this.layerOutputs[this.layerOutputs.length - 1])
let deltaWeights = []
let deltaBiases = []
for (let i = this.layerOutputs.length - 1; i >= 1; i--) {
let gradient = math.dotMultiply(this.layerOutputs[i].map(x => x * (1 - x)), error)
deltaWeights.unshift(math.multiply(math.multiply(gradient, math.transpose(this.layerOutputs[i - 1])), this.learningRate))
deltaBiases.unshift(math.multiply(gradient, this.learningRate))
if (i > 1) {
error = math.multiply(math.transpose(this.weights[i - 1]), error)
}
}
for (let i in this.weights) {
this.weights[i] = math.add(this.weights[i], deltaWeights[i])
this.biases[i] = math.add(this.biases[i], deltaBiases[i])
}
}
static activation(x) {
return 1 / (1 + Math.pow(Math.E, -x))
}
}