人工知性を作りたい

私が日々、挑戦したことや学んだことなどを紹介していく雑記ブログです。 (新しいAI技術HTM, 専門の音声信号処理, 趣味のアニメ等も書いてます。)

HTM(Hierarchical Temporal Memory)におけるSP(Spatial Pooler)での学習②

今回は前回の記事で紹介した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を試して見てください!