Typo.
[dagnn.git] / test-dagnn.lua
1 #!/usr/bin/env luajit
2
3 --[[
4
5    Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
6    Written by Francois Fleuret <francois.fleuret@idiap.ch>
7
8    This file is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License version 3 as
10    published by the Free Software Foundation.
11
12    It is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this file.  If not, see <http://www.gnu.org/licenses/>.
19
20 ]]--
21
22 require 'torch'
23 require 'nn'
24 require 'dagnn'
25
26 -- torch.setnumthreads(params.nbThreads)
27 torch.setdefaulttensortype('torch.DoubleTensor')
28 torch.manualSeed(2)
29
30 function checkGrad(model, criterion, input, target)
31    local params, gradParams = model:getParameters()
32
33    local epsilon = 1e-5
34
35    local output = model:forward(input)
36    local loss = criterion:forward(output, target)
37    local gradOutput = criterion:backward(output, target)
38    gradParams:zero()
39    model:backward(input, gradOutput)
40    local analyticalGradParam = gradParams:clone()
41
42    for i = 1, params:size(1) do
43       local x = params[i]
44
45       params[i] = x - epsilon
46       local output0 = model:forward(input)
47       local loss0 = criterion:forward(output0, target)
48
49       params[i] = x + epsilon
50       local output1 = model:forward(input)
51       local loss1 = criterion:forward(output1, target)
52
53       params[i] = x
54
55       local ana = analyticalGradParam[i]
56       local num = (loss1 - loss0) / (2 * epsilon)
57       local err
58
59       if num == ana then
60          err = 0
61       else
62          err = torch.abs(num - ana) / torch.abs(num)
63       end
64
65       print(
66          'CHECK '
67             .. err
68             .. ' checkGrad ' .. i
69             .. ' analytical ' .. ana
70             .. ' numerical ' .. num
71       )
72    end
73
74 end
75
76 function printTensorTable(t)
77    if torch.type(t) == 'table' then
78       for i, t in pairs(t) do
79          print('-- ELEMENT [' .. i .. '] --')
80          printTensorTable(t)
81       end
82    else
83       print(tostring(t))
84    end
85 end
86
87 --                     +--> c ----> e --+
88 --                    /            /     \
89 --                   /            /       \
90 --  input --> a --> b ---> d ----+         g --> output
91 --                          \             /
92 --                           \           /
93 --                            +--> f ---+
94
95 a = nn.Linear(50, 10)
96 b = nn.ReLU()
97 c = nn.Linear(10, 15)
98 d = nn.Linear(10, 15)
99 e = nn.CMulTable()
100 f = nn.Linear(15, 15)
101 g = nn.CAddTable()
102
103 model = nn.DAG()
104
105 model:addEdge(a, b)
106 model:addEdge(b, nn.Linear(10, 5), nn.ReLU(), nn.Linear(5, 10), c)
107 model:addEdge(b, d)
108 model:addEdge(c, e)
109 model:addEdge(d, e)
110 model:addEdge(d, f)
111 model:addEdge(e, g)
112 model:addEdge(f, nn.Mul(-1), g)
113
114 model:setInput(a)
115 model:setOutput(g)
116
117 local input = torch.Tensor(30, 50):uniform()
118 local output = model:updateOutput(input):clone()
119
120 output:uniform()
121
122 checkGrad(model, nn.MSECriterion(), input, output)