Skip to content

Commit 1710365

Browse files
committed
- code for single layer perceptron
1 parent 4309e85 commit 1710365

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

basics/fixed_width_3.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'nn'
2+
toy = require 'toy'
3+
4+
-- Allow for command-line control over the seed and number of examples.
5+
cmd = torch.CmdLine()
6+
cmd:text()
7+
cmd:text('Simulate from toy model, all examples have 3 inputs')
8+
cmd:text()
9+
cmd:text('Options')
10+
cmd:option('-seed',os.time(),'initial random seed (defaults to current time)')
11+
cmd:option('-n',1000,'number of examples to simulate')
12+
cmd:option('-sd',0.2,'noise standard deviation')
13+
cmd:text()
14+
15+
-- parse input params
16+
params = cmd:parse(arg)
17+
18+
-- Make it reproduceable
19+
torch.manualSeed(params.seed)
20+
21+
-- Simulate n examples. Each example will have three inputs, namely our function
22+
-- valuated at time lags of 0, 1, and 2. i.e. f(target), f(target-1), f(target-2)
23+
n = params.n
24+
target = torch.rand(n,1):mul(toy.max_target)
25+
inputs = toy.target_to_inputs(target, params.sd)
26+
27+
-- Save the data as four columns, targets last, in a t7 file.
28+
data = nn.JoinTable(2):forward({inputs,target})
29+
torch.save('fixed_width_3.t7', data)

basics/fixed_width_3.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
th fixed_width_3.lua -n 200000 -sd 0.1 -seed 1

basics/mlp_1.lua

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
require 'nn'
2+
toy = require 'toy'
3+
4+
-- take command line arguments to control parameters
5+
cmd = torch.CmdLine()
6+
cmd:text()
7+
cmd:text('Train MLP')
8+
cmd:text()
9+
cmd:text('Options')
10+
cmd:option('-seed', os.time(), 'initial random seed (defult: current time)')
11+
cmd:option('-hidden', 25, 'hidden state size')
12+
cmd:option('-batch', 5, 'batch size')
13+
cmd:option('-rate', 0.03, 'learn rate')
14+
cmd:option('-iterations', 100, 'maximum number of iterations of SGD')
15+
cmd:option('-trained', 'trained_mlp_1.t7', 'filename for saved trained model')
16+
cmd:option('-grid', 'grid_predictions_mlp_1.csv', 'file name for saved grid predictions')
17+
cmd:text()
18+
19+
-- parse input parameters
20+
params = cmd:parse(arg)
21+
22+
-- set 'random seed' to make the result reproduceable
23+
torch.manualSeed(params.seed)
24+
25+
--[[
26+
read data
27+
N: number of rows of data
28+
n_inputs: number of input variables (all columns in data - target column)
29+
]]--
30+
d = torch.load('fixed_width_3.t7')
31+
N = d:size(1)
32+
n_inputs = d:size(2) - 1
33+
34+
-- separate data into inputs (x) and targets (y)
35+
x = d:narrow(2, 1, n_inputs)
36+
y = d:narrow(2, n_inputs + 1, 1)
37+
38+
-- train/test split sizes
39+
test_frac = 0.3
40+
n_test = torch.floor(N * test_frac)
41+
n_train = N - n_test
42+
43+
-- train/test splits
44+
x_train = x:narrow(1, 1, n_train)
45+
y_train = y:narrow(1, 1, n_train)
46+
47+
x_test = x:narrow(1, n_train + 1, n_test)
48+
y_test = y:narrow(1, n_train + 1, n_test)
49+
50+
-- normalize training inputs
51+
norm_mean = x_train:mean()
52+
norm_std = x_train:std()
53+
x_train_n = (x_train - norm_mean) / norm_std
54+
55+
-- normalize test inputs based on training data normalization values
56+
x_test_n = (x_test - norm_mean) / norm_std
57+
58+
-- the nn SGD trainer needs a data structure where examples can be accessed via
59+
-- the index operator, [], and should have a size() method
60+
dataset = {}
61+
function dataset:size()
62+
return torch.floor(n_train / params.batch)
63+
end
64+
for i = 1, dataset:size() do
65+
local start = (i - 1) * params.batch + 1
66+
dataset[i] = {x_train_n:narrow(1, start, params.batch),
67+
y_train:narrow(1, start, params.batch)}
68+
end
69+
70+
-- set up the neural net
71+
n_hidden = params.hidden
72+
mlp = nn.Sequential()
73+
mlp:add(nn.Linear(n_inputs, n_hidden))
74+
mlp:add(nn.Sigmoid())
75+
mlp:add(nn.Linear(n_hidden, 1))
76+
77+
-- get all parameters packaged into a vector
78+
mlp_params = mlp:getParameters()
79+
80+
-- we need our model to learn to predict real values target, so setting
81+
-- least-square loss as the objective function
82+
criterion = nn.MSECriterion()
83+
84+
-- set up trainer to use SGD - Stochastic Gradient Descent
85+
trainer = nn.StochasticGradient(mlp, criterion)
86+
trainer.maxIteration = params.iterations
87+
trainer.learningRate = params.rate
88+
function trainer:hookIteration(iteration)
89+
print('# test error = ' .. criterion:forward(mlp:forward(x_test_n), y_test))
90+
end
91+
92+
-- train the model, after randomly initializing the parameters and clearing out
93+
-- any existing gradient.
94+
mlp_params:uniform(-0.1, 0.1)
95+
mlp:zeroGradParameters()
96+
print("parameter count: " .. mlp_params:size(1))
97+
print("initial error before training = " .. criterion:forward(mlp:forward(x_test_n), y_test))
98+
trainer:train(dataset)
99+
100+
-- save the trained model
101+
torch.save(params.trained, {mlp = mlp, params = mlp_params})
102+
103+
-- Output predictions along a grid so we can see how well it learned the
104+
-- function. We'll generate inputs without noise so we can see how well it does
105+
-- in the absence of noise, which will give us a sense of whether it's learned
106+
-- the true underlying function.
107+
grid_size = 200
108+
target_grid = torch.linspace(0, toy.max_target, grid_size):view(grid_size,1)
109+
inputs_grid = toy.target_to_inputs(target_grid, 0)
110+
inputs_grid_n = (inputs_grid - norm_mean) / norm_std
111+
predictions = mlp:forward(inputs_grid_n)
112+
113+
-- Use penlight to write the data
114+
pldata = require 'pl.data'
115+
pred_d = pldata.new(predictions:totable())
116+
pred_d:write(params.grid)

basics/mlp_1.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
th mlp_1.lua -seed 1 -hidden 152 -batch 20 -rate 0.05 -iterations 50 | tee mlp_1.out

basics/toy.lua

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'nn'
2+
3+
toy = {}
4+
5+
-- This is our arbitrary wavy function. We will try and learn the inverse of
6+
-- this. Expects an tensor or a scalar number.
7+
toy.f = function(x)
8+
-- Convert to tensor if not
9+
if not torch.isTensor(x) then
10+
x = torch.Tensor(1):fill(x)
11+
end
12+
-- Weighted average for four arbitrary sine waves.
13+
return (
14+
torch.sin(x/2 - 1):mul(0.5) +
15+
torch.sin(x) +
16+
torch.sin(x*2 + 2) +
17+
torch.sin(x/4 + 1) + 2)
18+
end
19+
20+
-- Our targets will be in (0,max_target)
21+
toy.max_target = 10
22+
23+
-- The inputs are derived from the target by evaluating the function above at
24+
-- time lags of 0, 1, and 2. i.e. f(target), f(target-1), f(target-2). Noise
25+
-- is then added by sampling N(0,sd)
26+
toy.target_to_inputs = function(target, sd, len)
27+
-- Specify noise standard deviation if this optional parameter is not given
28+
sd = sd or 0.2
29+
len = len or 3
30+
local seq = {}
31+
for i=1,len do
32+
seq[i] = target-i+1
33+
end
34+
35+
local inputs = toy.f(nn.JoinTable(2):forward(seq))
36+
-- Add some noise to the inputs
37+
local n = target:size(1)
38+
return inputs + torch.randn(n,len):mul(sd)
39+
end
40+
41+
return toy

0 commit comments

Comments
 (0)