SSブログ

torch7で小さくディープラーニング(6)パターン認識 [人工知能(ディープラーニング)]

今回はパターン認識をしてみます。
さらには、これまではプログラムの中で学習用データを作成していましたが、外部のデータを読み込んで処理をします。

まずは、以下のテキストデータをNUMBERS.CSVとしてセーブします。
========================= CSV FILEここの下から
1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,0
0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,1
1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,2
1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,3
1,0,1,1,0,1,1,1,1,0,0,1,0,0,1,4
1,1,1,1,0,0,1,1,1,0,0,1,1,1,1,5
1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,6
1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,7
1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,8
1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,9
========================= CSV FILEここの上まで

実はこのデータ、縦5、横3のピクセルで数字の0〜9を表しています。
例えば数字の9ならば以下のような形です。
===9===
1 1 1
1 0 1
1 1 1
0 0 1
0 0 1
=======
(数字の1が9の形に並んでいます)
これを横一列に並べれば、数字の9は…
1,1,1,1,0,1,1,1,1,0,0,1,0,0,1
というデータになります。
さらに、データを入れたCSVファイルの各行のいちばん右側の数字は、データに対する答えです。

こんな形で0〜9に対応するデータを用意し、それをニューラル・ネットワークで認識できるようにします。

※なお、torch7でCSVファイルを扱えるように、csvigoライブラリーをインストールしておく必要があります。
「luarocks install csvigo」でインストールしてください。

 CSVファイルから読み込んだデータは、そのままでは行列データのtorch.Tensorではなく、連想配列といわれるテーブル形式なので、「1」という数字も実際にはテキストの「1」扱いになっているので、それを数値に変えてあげる作業が必要です。

 で、パターン認識のプログラムは以下のようになります。
=====================================ここから
require 'nn'
require 'csvigo'
-- ####”luarocks install csvigo” でインストールしておいてください


-- CSVファイルのデータをロード
m=csvigo.load{path='NUMBERS.CSV',mode='large'}
print ("####### DATA LOAD! ######")

dataset={}

function dataset:size() return 10 end

-- 読み込んだデータをtorch.Tensorに直して学習出来るようにする。
for i=1,dataset:size() do
input =torch.Tensor(15)
output=torch.Tensor(10):zero()
input[1]=m[i][1]
input[2]=m[i][2]
input[3]=m[i][3]
input[4]=m[i][4]
input[5]=m[i][5]
input[6]=m[i][6]
input[7]=m[i][7]
input[8]=m[i][8]
input[9]=m[i][9]
input[10]=m[i][10]
input[11]=m[i][11]
input[12]=m[i][12]
input[13]=m[i][13]
input[14]=m[i][14]
input[15]=m[i][15]
a=m[i][16]
-- 10チャンネルの出力のうち、答えになるところを1に設定する
-- Torchの配列などは0スタートではなく、1がスタートになるので注意!
output[a+1]=1
dataset[i]={input,output}
print("###########",m[i][16])
print(input[1],input[2],input[3])
print(input[4],input[5],input[6])
print(input[7],input[8],input[9])
print(input[10],input[11],input[12])
print(input[13],input[14],input[15])
end
print ("####### DATASET! ######")

model=nn.Sequential();
model:add(nn.Linear(15,15))
model:add(nn.Tanh())
model:add(nn.Linear(15,30))
model:add(nn.Tanh())
model:add(nn.Linear(30,10))
-- 今回はソフトマックスも入れてみますが、これがなくともそれぞれの合計が1にならないだけで、順序そのものが入れ替わるなどの変化はありません
model:add(nn.SoftMax())
print ("####### MODEL SET OK! ######")

criterion = nn.MSECriterion()
trainer=nn.StochasticGradient(model,criterion)
trainer.learningRate=0.01
trainer.maxIteration=10000
print ("####### TARINER SET! ######")

trainer:train(dataset)


print ("####### LEARNING...DONE! ######")


-- 学習結果の検証
for i=1,dataset:size() do
input =torch.Tensor(15)
input[1]=m[i][1]
input[2]=m[i][2]
input[3]=m[i][3]
input[4]=m[i][4]
input[5]=m[i][5]
input[6]=m[i][6]
input[7]=m[i][7]
input[8]=m[i][8]
input[9]=m[i][9]
input[10]=m[i][10]
input[11]=m[i][11]
input[12]=m[i][12]
input[13]=m[i][13]
input[14]=m[i][14]
input[15]=m[i][15]

a=model:forward(input)

print ("#############CHECK!",i-1)
print (input:reshape(input,5,3),a)

end

=====================================ここまで

これをファイルに保存し、dofile 'ファイル名'で実行をすると…

Screenshot from 2017-01-16 19:27:59.png
それぞれのデータ(行列データ)を認識すると、それに応じて、0〜9の位置の数値が1に近い数値が返ってきます。
※今回のプログラムでは、答えになる部分を数字にしたため、9などの数字としてますが、これを
0,0,0,0,0,0,0,0,1というデータ形式に変えるのも面白いと思います。

 15個の数字の配置状況から、それに応じた答えを返す人工知能の完成です。

 ここまでくると、なんか面白い(不気味?)ですよね。
 IF文が全く存在しないのに、期待する答えが出てきてしまいます。
 プログラム主体ではなく、データ主体で動作が決まるので、これまでのプログラム作成になれている人には特に違和感を感じるかもしれません。

 (ちなみに…このプログラムにも落とし穴があって、データが1つがズレると、正しい答えが得られなくなってしまいます。それを解決する方法はまた次回以降でお話しします)


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。