In [1]:
require 'nn'
require 'optim'

In [2]:
local matio = require 'matio'
data = matio.load('ex3data1.mat')

In [97]:
trainset = {}

In [98]:
trainset.data = data.X

In [99]:
mean = {}
stdv = {}
for i=1,400 do
    mean[i] = trainset.data[{ {},{i} }]:mean()
    stdv[i] = trainset.data[{ {}, {i} }]:std()
    --print(i .. 'th mean: ' .. mean[i])
    --print(i .. 'th std dev: ' .. stdv[i])
    trainset.data[{ {},{i} }]:add(-mean[i])
    if stdv[i] ~= 0 then
        trainset.data[{ {},{i} }]:div(stdv[i])
    end
end

In [100]:
trainset.label = torch.Tensor(data.y):resize(5000)

In [101]:
trainset

In [102]:
numOutput = torch.max(trainset.label) - torch.min(trainset.label) + 1


Out[102]:
{
  data : DoubleTensor - size: 5000x400
  label : DoubleTensor - size: 5000
}

In [103]:
-- ignore setmetatable for now, it is a feature beyond the scope of this tutorial. It sets the index operator.
setmetatable(trainset,
    {__index = function(t,i)
                return {t.data[i], t.label[i]}
        end}
);

function trainset:size()
    return self.data:size(1)
end

In [104]:
model = nn.Sequential()
model:add(nn.Linear(400,10))
model:add(nn.Sigmoid())
model:add(nn.LogSoftMax())

In [105]:
criterion = nn.ClassNLLCriterion()

In [106]:
trainer = nn.StochasticGradient(model, criterion)
trainer.learningRate = 0.001
trainer.maxIteration = 2e1

In [107]:
trainset

In [108]:
trainer:train(trainset)


Out[108]:
{
  data : DoubleTensor - size: 5000x400
  size : function: 0x40a53cc8
  label : DoubleTensor - size: 5000
}
# StochasticGradient: training	
Out[108]:
# current error = 2.0314825492176	
Out[108]:
# current error = 1.892785270708	
Out[108]:
# current error = 1.857515794643	
Out[108]:
# current error = 1.8362176983487	
Out[108]:
# current error = 1.8201991297292	
Out[108]:
# current error = 1.8070407034207	
Out[108]:
# current error = 1.7957306828976	
Out[108]:
# current error = 1.7857439502779	
Out[108]:
# current error = 1.7767694930645	
Out[108]:
# current error = 1.7686057142731	
Out[108]:
# current error = 1.7611128587086	
Out[108]:
# current error = 1.7541888513453	
Out[108]:
# current error = 1.7477559231712	
Out[108]:
# current error = 1.7417525512366	
Out[108]:
# current error = 1.7361285707694	
Out[108]:
# current error = 1.7308424704224	
Out[108]:
# current error = 1.725859821649	
Out[108]:
# current error = 1.7211520244222	
Out[108]:
# current error = 1.7166950702014	

In [109]:
acc = 0.0
for i = 1, trainset:size() do
    local groundtruth = trainset.label[i]
    local prediction = model:forward(trainset.data[i])
    local confidences, indices = torch.sort(prediction, true) -- true means descending order
    if groundtruth == indices[1] then
        acc = acc + 1
    end
end
print('accuracy: ' .. 100*acc/trainset:size() .. '%')


Out[109]:
accuracy: 84.48%	

In [ ]: