私はLSTMネットワークを学習し、合成テストを試みることにしました。最も簡単な機能認識のためにLSTMを学習する方法
- ライン:Y = K * X + B
- 放物線:Y = K * X^2 + B 私はいくつかの点(X、Y)によって供給されるLSTMネットワークは、3つの基本的な機能を区別します
- SQRT:Y = K *のSQRT(X)+ B
IはLUA +トーチを使用しています。
データセットは完全に仮想です。これは、「データセット」オブジェクトでオンザフライで作成されます。トレーニングサイクルがサンプルの別のminibatchを要求すると、関数mt .__ indexは動的に作成されたsampleを返します。記述された3つの関数の中からランダムに選択し、ランダムな点を選択します。
LSTMネットワークは、最後のポイントがどのような種類の機能に属しているかを認識するためのいくつかの機能を学習することが考えられます。
完全かつシンプルなソーススクリプトが含ま:
require "torch"
require "nn"
require "rnn"
-- hyper-parameters
batchSize = 8
rho = 5 -- sequence length
hiddenSize = 100
outputSize = 3
lr = 0.001
-- Initialize synthetic dataset
-- dataset[index] returns table of the form: {inputs, targets}
-- where inputs is a set of points (x,y) of a randomly selected function: line, parabola, sqrt
-- and targets is a set of corresponding class of a function (1=line, 2=parabola, 3=sqrt)
local dataset = {}
dataset.size = function (self)
return 1000
end
local mt = {}
mt.__index = function (self, i)
local class = math.random(3)
local t = torch.Tensor(3):zero()
t[class] = 1
local targets = {}
for i = 1,batchSize do table.insert(targets, class) end
local inputs = {}
local k = math.random()
local b = math.random()*5
-- Line
if class == 1 then
for i = 1,batchSize do
local x = math.random()*10 + 5
local y = k*x + b
input = torch.Tensor(2)
input[1] = x
input[2] = y
table.insert(inputs, input)
end
-- Parabola
elseif class == 2 then
for i = 1,batchSize do
local x = math.random()*10 + 5
local y = k*x*x + b
input = torch.Tensor(2)
input[1] = x
input[2] = y
table.insert(inputs, input)
end
-- Sqrt
else
for i = 1,batchSize do
local x = math.random()*5 + 5
local y = k*math.sqrt(x) + b
input = torch.Tensor(2)
input[1] = x
input[2] = y
table.insert(inputs, input)
end
end
return { inputs, targets }
end -- dataset.__index meta function
setmetatable(dataset, mt)
-- Initialize random number generator
math.randomseed(os.time())
-- build simple recurrent neural network
local model = nn.Sequencer(
nn.Sequential()
:add(nn.LSTM(2, hiddenSize, rho))
:add(nn.Linear(hiddenSize, outputSize))
:add(nn.LogSoftMax())
)
print(model)
-- build criterion
local criterion = nn.SequencerCriterion(nn.ClassNLLCriterion())
-- training
model:training()
local epoch = 1
while true do
print ("Epoch "..tostring(epoch).." started")
for iteration = 1, dataset:size() do
-- 1. Load minibatch of samples
local sample = dataset[iteration] -- pick random sample (dataset always returns random set)
local inputs = sample[1]
local targets = sample[2]
-- 2. Perform forward run and calculate error
local outputs = model:forward(inputs)
local err = criterion:forward(outputs, targets)
print(string.format("Epoch %d Iteration %d Error = %f", epoch, iteration, err))
-- 3. Backward sequence through model(i.e. backprop through time)
local gradOutputs = criterion:backward(outputs, targets)
-- Sequencer handles the backwardThroughTime internally
model:backward(inputs, gradOutputs)
model:updateParameters(lr)
model:zeroGradParameters()
end -- for dataset
epoch = epoch + 1
end -- while epoch
問題がある:ネットワークが収束しません。 私が間違っているアイディアを共有できますか?
は、マルチン、ありがとうございました。私は今それを得ると思います。さらに、問題のコードは、反復ごとにランダムなkとbを生成するため、NNが任意のフィーチャを学習する機会はありません。私は2つの可能な解決法を見ています:1.起動時にkとbを一度だけ生成します。つまり、固定線、放物線、およびsqrtを取得します。 2.入力ポイントを順次生成する。 (2.)はオプションですが。私は(1.)を実装しようとした - それは働いた!唯一の千回の反復後NNは、99%の精度で機能を認識することができます! –