Skip to content

Instantly share code, notes, and snippets.

@krngrvr09
Created March 25, 2018 11:21
Show Gist options
  • Select an option

  • Save krngrvr09/39b0a2532bde8e531ff1fb828138e47d to your computer and use it in GitHub Desktop.

Select an option

Save krngrvr09/39b0a2532bde8e531ff1fb828138e47d to your computer and use it in GitHub Desktop.
-- LUA WARNINGS
-- Array starts from index 1
-- obj.func() is equivalent to obj:func()
-- Loop:
-- for start_, end_ do
-- end
-- Condition:
-- if <condition> then
-- end
-- Function:
-- func_name = function(arguments)
-- <do stuff>
-- end
-- require: load module
-- OOP: Object is metatable.
-- Table and Array use {} to create.
require 'nn';
require 'os';
-- Spequentail or Concat or Parallel
net = nn.Sequential()
-- Every neural network module in Torch has automatic differentiation.
-- It has a :forword(input) method that computes the output for a given input
-- Flowing the inpt through the net.
-- It also has :backward(input, gradient) method that differentiates each
-- neuron in the net.
-- Layers
-- Torch supports many layers for your net.
-- See more: https://github.com/torch/nn/blob/master/doc/convolution.md
-- It also updates many state-of-the-art architectures and different kind of layers.
-- 3 input image plane
-- 6 output planes
-- 5x5 filter
-- (dW, dH) step
-- (padW, padH) padding
net:add(nn.SpatialConvolution(3, 6, 5, 5)) -- add a new spatial convolution layer
-- to the net
-- net:add(nn.ReLU()) -- add ReLU layer
-- SpatialMaxPooling: apply 2D max-pooling operation
-- in kW-kH regions by step size dWxdH, padding padWxpadH
-- SpatialMaxPooling(kW, kH, [ dW, dH, padW, padH])
-- 2x2 regions, step 2x2
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.Threshold()) -- add Threshold layer
-- Convolution layer
-- Input layers: 6 planes
-- Output layers: 16 planes
-- Kernel size: 5x5
net:add(nn.SpatialConvolution(6, 16, 5, 5))
-- apply Relu
-- net:add(nn.ReLU())
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.Threshold())
-- reshape tensor with size 16*5*5 into 1D vector with length 16*5*5
net:add(nn.View(16*5*5))
-- Apply fully connected layer
net:add(nn.Linear(16*5*5, 120))
net:add(nn.Threshold())
net:add(nn.Linear(120, 84))
net:add(nn.Threshold())
net:add(nn.Linear(84, 10))
net:add(nn.LogSoftMax())
print ("Lenet5\n" .. net:__tostring());
-- Create input data
input = torch.rand(3, 32, 32)
-- Feed the input to the net
output = net:forward(input)
-- zero the internal gradients
net:zeroGradParameters()
-- Defining a loss function
-- Link: https://github.com/torch/nn/blob/master/doc/criterion.md
-- Many defined loss functions
criterion = nn.ClassNLLCriterion() -- a nagative log-likelihood criterion
-- criterion has 2 main methods:
-- (1) :forward(input, target): calculates loss value based input and target value
-- (2) :backward(input, target): calculates the gradient of the loss function
-- associated to the cirterion and return the result.
loss = criterion:forward(output, 3)
gradients = criterion:backward(output, 3)
gradInput = net:backward(input, gradients)
-- Learnable parameters
m = nn.SpatialConvolution(1, 3, 2, 2) -- 1 plane input, 3 2x2 Convolution filters
-- Every layer having learnable parameters has 2 properties:
-- (1) : m.weights
-- (2) : m.bias
--
-- Update rule: weight = weight + learningRate * gradWeights
-- TRAINING PHASE
-- Loading data
-- e.x: CIFAR 10
-- Uncomment to download CIFAR 10
-- os.execute("wget -c https://s3.amazonaws.com/torch7/data/cifar10torchsmall.zip")
-- os.execute("unzip cifar10torchsmall.zip")
train_set = torch.load("cifar10-train.t7")
test_set = torch.load("cifar10-test.t7")
classes = { "airplane", "automobile", "bird", "cat", "deer",
"dog", "frog", "horse", "ship", "truck" }
-- Torch supports Stochastic Gradient
-- To use it, the training data must have :size() function and
-- index operator ([index])
-- add index operator to the training set
setmetatable(train_set,
{
__index = function(t, i)
return {t.data[i], t.label[i]}
end
});
train_set.data = train_set.data:double() -- convert to double type
function train_set:size()
return self.data:size(1)
end
-- -- Preprocess data
-- -- zero mean data
-- mean = {}
-- stdv = {}
-- for i=1, 3 do -- each channel in the image
-- mean[i] = train_set.data[ {{}, {i}, {}, {}} ]:mean() -- mean estimation
-- train_set.data[{{}, {i}, {}, {}}]:add(-mean[i]) -- mean subtraction
-- stdv[i] = train_set.data[{{}, {i}, {}, {}}]:std() -- std estimation
-- train_set.data[{ {}, {i}, {}, {} }]:div(stdv[i]) -- std scaling
-- end
-- train the data
trainer = nn.StochasticGradient(net, criterion)
trainer.learningRate = 0.001
trainer.maxIteration = 20
trainer:train(train_set)
print(net.modules)
print(net.modules[12].output)
print(net.modules[13].output)
torch.save("./l1_weights.txt",net.modules[1].weight,'ascii')
torch.save("./l1_bias.txt",net.modules[1].bias,'ascii')
torch.save("./l2_weights.txt",net.modules[4].weight,'ascii')
torch.save("./l2_bias.txt",net.modules[4].bias,'ascii')
torch.save("./l3_weights.txt",net.modules[8].weight,'ascii')
torch.save("./l3_bias.txt",net.modules[8].bias,'ascii')
torch.save("./l4_weights.txt",net.modules[10].weight,'ascii')
torch.save("./l4_bias.txt",net.modules[10].bias,'ascii')
torch.save("./l5_weights.txt",net.modules[12].weight,'ascii')
torch.save("./l5_bias.txt",net.modules[12].bias,'ascii')
-- test the net
test_set.data = test_set.data:double() -- convert from byte to double
-- -- preprocess data
-- for i=1, 3 do
-- test_set.data[{{}, {i}, {}, {}}]:add(-mean[i])
-- test_set.data[{{}, {i}, {}, {}}]:div(stdv[i])
-- end
-- print(test_set.data[1])
predicted = net:forward(test_set.data[1])
print(predicted)
predicted:exp()
print(predicted)
print(test_set.label[1])
for i=1,predicted:size(1) do
print(classes[i], predicted[i])
end
-- measure the accuracy
class_perf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
accuracy = 0
nClock = os.clock()
print("Hahaha")
for i=1,1000 do
local groundtruth = test_set.label[i]
local prediction = net:forward(test_set.data[i])
local conf, indexes = torch.sort(prediction, true)
if (groundtruth == indexes[1]) then
class_perf[groundtruth] = class_perf[groundtruth] + 1
accuracy = accuracy + 1
end
end
print("Elapsed time: " .. os.clock() - nClock)
for i=1, #classes do
print(classes[i], 1000*class_perf[i]/1000 .. " %")
end
print("Accuracy: ", accuracy * 1000 / 10000 .. " . %")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment