今回は前回の記事で紹介したSP(Spatial Pooler)を用いた簡単な分類問題を行います。
今回行う分類は、
・cat
・dog
・monkey
・loris
の4つです。
Spatial Poolerによるカテゴリ分類
まずは、分類するために、0,1のビットで表現する様にエンコードを行います。
import numpy
from nupic.encoders.category import CategoryEncoder
categories = ("cat", "dog", "monkey", "slow loris")
encoder = CategoryEncoder(w=3, categoryList=categories, forced=True)
cat = encoder.encode("cat")
dog = encoder.encode("dog")
monkey = encoder.encode("monkey")
loris = encoder.encode("slow loris")
print "cat = ", cat
print "dog = ", dog
print "monkey = ", monkey
print "slow loris =", loris
出力結果
cat = [0 0 0 1 1 1 0 0 0 0 0 0 0 0 0]
dog = [0 0 0 0 0 0 1 1 1 0 0 0 0 0 0]
monkey = [0 0 0 0 0 0 0 0 0 1 1 1 0 0 0]
slow loris = [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
Spatial Poolerの設計
sp = SpatialPooler(inputDimensions=(15,),
columnDimensions=(4,),
potentialRadius=15,
numActiveColumnsPerInhArea=1,
globalInhibition=True,
synPermActiveInc=0.03,
potentialPct=1.0)
Spatial Poolerの学習
とりあえず、
sp.compute()で20回と200回の学習を行う。
print "============"*4
print "20回の学習"
print "============"*4
for _ in xrange(20):
sp.compute(cat, learn=True, activeArray=output)
sp.compute(dog, learn=True, activeArray=output)
sp.compute(monkey, learn=True, activeArray=output)
sp.compute(loris, learn=True, activeArray=output)
print "------------"*4
print "シナプス"
for column in xrange(4):
connected = numpy.zeros((15,), dtype="int")
sp.getConnectedSynapses(column, connected)
print connected
print "============"*4
print "200回の学習"
print "============"*4
for _ in xrange(200):
sp.compute(cat, learn=True, activeArray=output)
sp.compute(dog, learn=True, activeArray=output)
sp.compute(monkey, learn=True, activeArray=output)
sp.compute(loris, learn=True, activeArray=output)
print "------------"*4
for column in xrange(4):
connected = numpy.zeros((15,), dtype="int")
sp.getConnectedSynapses(column, connected)
print connected
出力結果
シナプス
[1 1 0 0 0 0 0 1 0 0 1 0 0 0 1]
[1 0 1 1 0 1 0 0 0 0 1 0 1 1 0]
[0 0 0 1 0 1 1 0 1 1 1 0 1 0 0]
[0 0 0 1 1 0 0 1 0 1 0 0 1 1 0]
------------------------------------------------
output [0 0 0 0]
================================================
20回の学習
================================================
cat_output [0 0 0 1]
dog_output [0 0 1 0]
monkey_output [0 0 1 0]
loris_output [0 0 0 1]
------------------------------------------------
シナプス
[1 1 0 0 0 0 0 1 0 0 1 0 0 0 1]
[1 0 1 1 0 1 0 0 0 0 1 0 1 1 0]
[0 0 0 0 0 1 1 1 1 1 1 1 1 0 0]
[0 0 0 1 1 1 0 0 0 1 0 0 1 1 1]
================================================
200回の学習
================================================
cat_output [0 0 0 1]
dog_output [0 0 1 0]
monkey_output [0 0 1 0]
loris_output [0 0 0 1]
------------------------------------------------
[1 1 0 0 0 0 0 1 0 0 1 0 0 0 1]
[1 0 1 1 0 1 0 0 0 0 1 0 1 1 0]
[0 0 0 0 0 0 1 1 1 1 1 1 0 0 0]
[0 0 0 1 1 1 0 0 0 0 0 0 1 1 1]
出力結果を見てみると、
シナプスは学習が進んでいる様に見える。
outputを見てみると、
cat_outputとloris_outputが同じものだと分類されている。
また、
dog_outputとmonkey_outputも同じものに分類されている。
つまり、学習が上手く出来ていない!
そこで、どうしたら上手く学習が行えるかをnumentaの資料などを読みながら考えました。結果、Spatial Poolerの設計でのパラメータをいじれば上手くいきそうな気がしましたので実験結果を次に載せます。
Spatial Poolerの設計②
NupicのDocumentationを読むと、
Spatial Poolerの引数の説明に、以下の文章がありました。(Google翻訳後)
・synPermActiveInc - (float)各ラウンドでアクティブシナプスがインクリメントされる量。完全に成長したシナプスのパーセントで指定されます。デフォルト0.05。
つまり、synPermActiveIncを小さくすることによって、シナプスがアクティブになり難くなる。なので、より細かな分類ができると考えました。では実際にsynPermActiveIncを1/10して実験を行なって見ます。
sp = SpatialPooler(inputDimensions=(15,),
columnDimensions=(4,),
potentialRadius=15,
numActiveColumnsPerInhArea=1,
globalInhibition=True,
synPermActiveInc=0.003,
potentialPct=1.0)
synPermActiveInc=0.003
に変更した。
出力結果
------------------------------------------------
シナプス
[0 0 1 0 0 1 1 0 1 0 0 0 1 1 0]
[1 1 1 0 0 1 0 0 1 0 0 0 1 1 1]
[1 1 1 1 1 0 1 0 1 0 1 0 1 1 1]
[1 1 1 0 1 0 1 1 0 1 0 0 0 1 0]
------------------------------------------------
output [0 0 0 0]
================================================
20回の学習
================================================
cat_output [0 0 1 0]
dog_output [0 0 0 1]
monkey_output [0 0 0 1]
loris_output [0 1 0 0]
------------------------------------------------
シナプス
[0 0 1 0 0 1 1 0 1 0 0 0 1 1 0]
[1 0 1 0 0 1 0 0 1 0 0 0 1 1 1]
[1 1 1 1 1 1 1 0 1 0 1 0 1 0 1]
[1 1 1 0 1 0 1 1 0 1 0 0 0 1 0]
================================================
200回の学習
================================================
cat_output [0 0 1 0]
dog_output [1 0 0 0]
monkey_output [0 0 0 1]
loris_output [0 1 0 0]
------------------------------------------------
[0 0 0 0 0 0 1 1 1 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1]
[0 0 0 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1 1 1 0 0 0]
今回は上手く分類が出来た様です!
こんな感じで、私自身学びながら、これからもHTMを紹介していこうと思います。
皆さんもHTMを試して見てください!