前の記事(PyBrainを使って見たくなった)で、PyBrainの簡単な使い方を書きましたが、ふと思いたって隠れ層を多層にする方法を探してみました。
探してみたと言っても、なんか直感的に試してみたら動いたので書くだけです。
今回はSin(x) + Cos(y)という関数にノイズを乗せたものを学習させてみたいと思います。関数はこんな感じ。
まず、前回のおさらいの隠れ層が一層でニューロンが3つのニューラルネットワークはこんな感じで作れます。
#!/usr/bin/env python # -*- coding: utf-8 -*- from pybrain.datasets import SupervisedDataSet from pybrain.tools.shortcuts import buildNetwork from pybrain.supervised import BackpropTrainer import random import math NN = buildNetwork(2, 3, 1) DataSet = SupervisedDataSet(2, 1) for i in range(0, 1000): x = random.random() * math.pi * 4 y = random.random() * math.pi * 4 DataSet.addSample((x,y), (math.sin(x)+math.cos(y)+random.random()/10,)) trainer = BackpropTrainer(NN, DataSet) for i in range(0,100): trainer.train() TestSet = SupervisedDataSet(2, 1) for i in range(0, 100): for j in range(0, 100): x = i * math.pi * 4 / 100 y = j * math.pi * 4 / 100 r = NN.activate((x, y)) print str(x)+" "+str(y)+" "+str(r[0])
適当に1000個ほど学習用のデータを作り、学習させます。
そして、x = 0 ~ 2π, y = 0 ~ 2πの範囲で100 * 100個ほど要素をとって、gnuplotでグラフ化します。
グラフ化するとこんな感じ。
なんと!まったくまともに学習できていませんね…
次に、隠れ層を多層にした場合。
ちなみにプログラムは10行目の
NN = buildNetwork(2, 3, 1)
を
NN = buildNetwork(2, 3, 4, 5, 1)
のように書き換えます。一つ目が入力層、二つ目から最後のひとつ前までが隠れ層、最後の一つが隠れ層のパラメータになります。これだと、入力層が2ニューロン1つ、隠れ層が3ニューロン、4ニューロン、5ニューロンの3つ、出力層が1ニューロン1つというニューラルネットワークになります。
で、これで学習させた場合はこんな感じのグラフになります。
ちょっと近くなりましたがまだまだですね。
ということで、もっと隠れ層のニューロン数を増やしてみます。
隠れ層を10ニューロン3層に増やした場合、つまりこんな感じのプログラムになります。
NN = buildNetwork(2, 10, 10, 10, 1)
出力をグラフ化してみます。
だいぶ近くなってきましたね!
さらにニューロンの数を増やしてみます。隠れ層を100ニューロン3層へ拡張したときの出力はこんな感じに。
これでかなり目標の関数に近くなりましたね。
ちなみにこの時点での平均エラーは0.024で、平面の裾野になっている部分以外はほとんど正しく学習できているようです。
と、いうことで、隠れ層が多層のNNを構築して学習させてみました。PyBrainって便利で簡単ね!