In [ ]:
require 'torch'
require 'nn'
require 'image'
require 'optim'
data = torch.Tensor{ {6.1101,17.592}, {5.5277,9.1302}, {8.5186,13.662}, {7.0032,11.854}, {5.8598,6.8233}, {8.3829,11.886}, {7.4764,4.3483}, {8.5781,12}, {6.4862,6.5987}, {5.0546,3.8166}, {5.7107,3.2522}, {14.164,15.505}, {5.734,3.1551}, {8.4084,7.2258}, {5.6407,0.71618}, {5.3794,3.5129}, {6.3654,5.3048}, {5.1301,0.56077}, {6.4296,3.6518}, {7.0708,5.3893}, {6.1891,3.1386}, {20.27,21.767}, {5.4901,4.263}, {6.3261,5.1875}, {5.5649,3.0825}, {18.945,22.638}, {12.828,13.501}, {10.957,7.0467}, {13.176,14.692}, {22.203,24.147}, {5.2524,-1.22}, {6.5894,5.9966}, {9.2482,12.134}, {5.8918,1.8495}, {8.2111,6.5426}, {7.9334,4.5623}, {8.0959,4.1164}, {5.6063,3.3928}, {12.836,10.117}, {6.3534,5.4974}, {5.4069,0.55657}, {6.8825,3.9115}, {11.708,5.3854}, {5.7737,2.4406}, {7.8247,6.7318}, {7.0931,1.0463}, {5.0702,5.1337}, {5.8014,1.844}, {11.7,8.0043}, {5.5416,1.0179}, {7.5402,6.7504}, {5.3077,1.8396}, {7.4239,4.2885}, {7.6031,4.9981}, {6.3328,1.4233}, {6.3589,-1.4211}, {6.2742,2.4756}, {5.6397,4.6042}, {9.3102,3.9624}, {9.4536,5.4141}, {8.8254,5.1694}, {5.1793,-0.74279}, {21.279,17.929}, {14.908,12.054}, {18.959,17.054}, {7.2182,4.8852}, {8.2951,5.7442}, {10.236,7.7754}, {5.4994,1.0173}, {20.341,20.992}, {10.136,6.6799}, {7.3345,4.0259}, {6.0062,1.2784}, {7.2259,3.3411}, {5.0269,-2.6807}, {6.5479,0.29678}, {7.5386,3.8845}, {5.0365,5.7014}, {10.274,6.7526}, {5.1077,2.0576}, {5.7292,0.47953}, {5.1884,0.20421}, {6.3557,0.67861}, {9.7687,7.5435}, {6.5159,5.3436}, {8.5172,4.2415}, {9.1802,6.7981}, {6.002,0.92695}, {5.5204,0.152}, {5.0594,2.8214}, {5.7077,1.8451}, {7.6366,4.2959}, {5.8707,7.2029}, {5.3054,1.9869}, {8.2934,0.14454}, {13.394,9.0551}, {5.4369,0.61705} }
In [ ]:
-- reload the array
file = torch.DiskFile('ex1data1.txt', 'r')
data = file:readObject()
In [ ]:
model = nn.Sequential()
ninputs = 1; noutputs = 1
model:add(nn.Linear(ninputs, noutputs))
In [ ]:
criterion = nn.MSECriterion()
In [ ]:
x, dl_dx = model:getParameters()
In [ ]:
feval = function(x_new)
-- set x to x_new, if differnt
-- (in this simple example, x_new will typically always point to x,
-- so the copy is really useless)
if x ~= x_new then
x:copy(x_new)
end
-- select a new training sample
_nidx_ = (_nidx_ or 0) + 1
if _nidx_ > (#data)[1] then _nidx_ = 1 end
local sample = data[_nidx_]
local target = sample[{ {2} }] -- this funny looking syntax allows
local inputs = sample[{ {1} }] -- slicing of arrays.
-- reset gradients (gradients are always accumulated, to accommodate
-- batch methods)
dl_dx:zero()
-- evaluate the loss function and its derivative wrt x, for that sample
local loss_x = criterion:forward(model:forward(inputs), target)
model:backward(inputs, criterion:backward(model.output, target))
-- return loss(x) and dloss/dx
return loss_x, dl_dx
end
In [ ]:
sgd_params = {
learningRate = 1e-4,
learningRateDecay = 1e-5,
weightDecay = 0,
momentum = 0
}
In [ ]:
for i = 1,1e4 do
-- this variable is used to estimate the average loss
current_loss = 0
-- an epoch is a full loop over our training data
for i = 1,(#data)[1] do
-- optim contains several optimization algorithms.
-- All of these algorithms assume the same parameters:
-- + a closure that computes the loss, and its gradient wrt to x,
-- given a point x
-- + a point x
-- + some parameters, which are algorithm-specific
_,fs = optim.sgd(feval,x,sgd_params)
-- Functions in optim all return two things:
-- + the new x, found by the optimization method (here SGD)
-- + the value of the loss functions at all points that were used by
-- the algorithm. SGD only estimates the function once, so
-- that list just contains one value.
current_loss = current_loss + fs[1]
end
-- report average error on epoch
current_loss = current_loss / (#data)[1]
if i %100 == 0 then
print('current loss = ' .. current_loss)
end
end
In [ ]:
-- reload the array
file = torch.DiskFile('ex1data2.txt', 'r')
test = file:readObject()
In [ ]:
print('id approx text')
current_loss = 0
for i = 1,(#test)[1] do
local myPrediction = model:forward(test[i][1])
print(string.format("%2d %6.2f %6.2f", i, myPrediction[1], test[i][2]))
current_loss = current_loss + (myPrediction[1] - test[i][2])*(myPrediction[1] - test[i][2])
end
current_loss = current_loss / (#test)[1]
print('evaluation = ' .. current_loss)