超言理論

特に益もない日記である

PyBrainで多層ニューラルネットワーク

前の記事(PyBrainを使って見たくなった)で、PyBrainの簡単な使い方を書きましたが、ふと思いたって隠れ層を多層にする方法を探してみました。
探してみたと言っても、なんか直感的に試してみたら動いたので書くだけです。


今回はSin(x) + Cos(y)という関数にノイズを乗せたものを学習させてみたいと思います。関数はこんな感じ。f:id:ma-aqua:20130801151504p:plain

まず、前回のおさらいの隠れ層が一層でニューロンが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でグラフ化します。
グラフ化するとこんな感じ。
f:id:ma-aqua:20130801154241p:plain
なんと!まったくまともに学習できていませんね…


次に、隠れ層を多層にした場合。
ちなみにプログラムは10行目の

NN = buildNetwork(2, 3, 1)

NN = buildNetwork(2, 3, 4, 5, 1)

のように書き換えます。一つ目が入力層、二つ目から最後のひとつ前までが隠れ層、最後の一つが隠れ層のパラメータになります。これだと、入力層が2ニューロン1つ、隠れ層が3ニューロン、4ニューロン、5ニューロンの3つ、出力層が1ニューロン1つというニューラルネットワークになります。

で、これで学習させた場合はこんな感じのグラフになります。
f:id:ma-aqua:20130801154355p:plain
ちょっと近くなりましたがまだまだですね。

ということで、もっと隠れ層のニューロン数を増やしてみます。
隠れ層を10ニューロン3層に増やした場合、つまりこんな感じのプログラムになります。

NN = buildNetwork(2, 10, 10, 10, 1)

出力をグラフ化してみます。
f:id:ma-aqua:20130801154438p:plain
だいぶ近くなってきましたね!

さらにニューロンの数を増やしてみます。隠れ層を100ニューロン3層へ拡張したときの出力はこんな感じに。
f:id:ma-aqua:20130801154742p:plain
これでかなり目標の関数に近くなりましたね。
ちなみにこの時点での平均エラーは0.024で、平面の裾野になっている部分以外はほとんど正しく学習できているようです。


と、いうことで、隠れ層が多層のNNを構築して学習させてみました。PyBrainって便利で簡単ね!


Copyright © 2012-2016 Masahiro MIZUKAMI All Rights Reserved.