synapticを使ってXORをニューラルネットワークで再現する

ニューラルネットワーク自作入門を読んでいてサンプルはPythonで書かれているのだけれども、Nodeで書けないかなと思って調べてみたらsynapticというnpmがあったので本で読んだことを踏まえつつXOR(排他的論理和)を再現してみることにした。

www.npmjs.com

XORを再現するために入力層2段, 隠れ層3段, 出力層1段でニューラルネットワークを構成してみる。

var synaptic = require('synaptic');
var Layer = synaptic.Layer,
    Network = synaptic.Network,
    Trainer = synaptic.Trainer;

function Perceptron(input, hidden, output)
{
  // create the layers
  var inputLayer = new Layer(input);
  var hiddenLayer = new Layer(hidden);
  var outputLayer = new Layer(output);

  // connect the layers
  inputLayer.project(hiddenLayer);
  hiddenLayer.project(outputLayer);

  // set the layers
  this.set({
    input: inputLayer,
    hidden: [hiddenLayer],
    output: outputLayer
  });
}

Perceptron.prototype = new Network();
Perceptron.prototype.constructor = Perceptron;

var myPerceptron = new Perceptron(2,3,1);
var myTrainer = new Trainer(myPerceptron);

var learning = [
  {input:[0,0], output:[0]},
  {input:[1,0], output:[1]},
  {input:[0,1], output:[1]},
  {input:[1,1], output:[0]}
];

var parameters = {
  iterations: 2000,
  shuffle: true,
  cost: Trainer.cost.MSE
};

var results = myTrainer.train(learning, parameters);
console.log(`Error rate = ${results.error}`);

// calculate
console.log(`xor(0,0) = ${myPerceptron.activate([0,0])}`);
console.log(`xor(1,0) = ${myPerceptron.activate([1,0])}`);
console.log(`xor(0,1) = ${myPerceptron.activate([0,1])}`);
console.log(`xor(0,0) = ${myPerceptron.activate([1,1])}`);

上を実行すると以下の様にXORを再現できている。(2入力の双方に同値が入れば0に近くなり、異値が入れば1に近くなっている)

$ node xor.js
Error rate = 0.004983333135247337
xor(0,0) = 0.051013797211575035
xor(1,0) = 0.932949883533232
xor(0,1) = 0.9341209212942756
xor(0,0) = 0.08390604881521503

上のプログラム中では学習回数を2000回にしてあるけれども各回数で試行に対しての誤り率をプロットすると以下の様な感じになった。1000回超えると収束していっているのがわかる。

学生時代に簡単にニューラルネットワークについて眺めるくらいはしていたり、今回買った本を読んで原理についてはわかったつもりなのだけれども実際に自分で試してみると学習された様子がわかって面白い。何一つXORのロジックを書いてないのにXOR回路が再現できている。

参考図書

ニューラルネットワーク自作入門

ニューラルネットワーク自作入門

参考サイト

postd.cc