のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Torch7によるニューラルネットワークを使った機械学習

Sponsored Links

皆さんこんにちは
お元気ですか。私は元気です。

Torch7を使って具体的に、機械学習を実装してみようと思います。

Torch7におけるフレームワーク

基本的に以下に添って実装すれば問題ありません。

1.データセットを構築する
2.モデルを構築する
3.学習する
4.テストする

※コードはこちらを参考にさせて頂いてます。
nn/training.md at master · torch/nn · GitHub

実際の過程

データセット構築

データセットの入力と出力の構築は基本的にtorch.Tensorで行います。

dataset={};
function dataset:size() return 100 end
for i=1,dataset:size() do 
  local input = torch.randn(2);
  local output = torch.Tensor(1);
  if input[1]*input[2]>0 then
    output[1] = -1;
  else
    output[1] = 1
  end
  dataset[i] = {input, output}
end

①datasetテーブルを設定し、入力と出力を入れること
入力、出力共に、torch.Tensorで設定しますが、それぞれをテーブルに入れます。
それを以下の通り入力します。

dataset[i] = {input, output}

②labelもinputもtorch.Tensorで

local input = torch.randn(2);
local output = torch.Tensor(1);

③function dataset:size() return 100 endを定義すること
後述するトレーニング内の関数で、この関数を呼び出しているので、なければ、動きません。

モデル構築

nnパッケージを使って実装します。
nn.Sequential()が層を作るように
nn.Linearの追加により層を増やすことができます。
よくある発火関数、Tanhを後で追加することで、ニューラルネットワークを構成することができます。

以下、入力層2,中間層50,出力層1のニューラルネットワークです。組み合わせ方によってConvolutional Neural NetworkやAutoEncoderを作ることができるそうです。

model = nn.Sequential();
model:add(nn.Linear(2,50))
model:add(nn.Tanh())
model:add(nn.Linear(50, 1))
model:add(nn.Tanh())

因みに内部の構成は以下のような感じになります。

nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> output]
  (1): nn.Linear(2 -> 50)
  (2): nn.Tanh
  (3): nn.Linear(50 -> 1)
  (4): nn.Tanh
}

学習する

誤差関数を指定し、学習を開始します。(以下のは2乗誤差)
trainerのメンバ変数(luaではなんと呼ぶのでしょうか?)にパラメータを与えることで学習回数や学習係数を設定することができます

criterion = nn.MSECriterion() 
trainer = nn.StochasticGradient(model, criterion)
trainer.learningRate = 0.01 --学習係数
trainer.maxIteration = 100 --学習回数
trainer:train(dataset)

テストする

先程、学習したモデルでforwardを実行します。与え方はtorch.Tensorで与えます。

x = torch.Tensor(2)
x[1] =  0.5; x[2] =  0.5; print(model:forward(x))
x[1] =  0.5; x[2] = -0.5; print(model:forward(x))
x[1] = -0.5; x[2] =  0.5; print(model:forward(x))
x[1] = -0.5; x[2] = -0.5; print(model:forward(x))

Source Code 全文

require 'torch'
require 'nn'

dataset={};
function dataset:size() return 100 end
for i=1,dataset:size() do 
  local input = torch.randn(2);
  local output = torch.Tensor(1);
  if input[1]*input[2]>0 then
    output[1] = -1;
  else
    output[1] = 1
  end
  dataset[i] = {input, output}
end

model = nn.Sequential();
model:add(nn.Linear(2,50))
model:add(nn.Tanh())
model:add(nn.Linear(50, 1))
model:add(nn.Tanh())

criterion = nn.MSECriterion() 
trainer = nn.StochasticGradient(model, criterion)
trainer.learningRate = 0.01 --学習係数
trainer.maxIteration = 100 --学習回数
trainer:train(dataset)

x = torch.Tensor(2)
x[1] =  0.5; x[2] =  0.5; print(model:forward(x))
x[1] =  0.5; x[2] = -0.5; print(model:forward(x))
x[1] = -0.5; x[2] =  0.5; print(model:forward(x))
x[1] = -0.5; x[2] = -0.5; print(model:forward(x))