Что не так с моим алгоритмом обратного распространения? - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь реализовать алгоритм обратного распространения, и я создал код ниже. Нет очевидных ошибок, но когда я пытаюсь обучить сеть чему-то столь же простому, как проблема 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))
  }
}
...