Updated the headers.
[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
25 require 'dagnn'
26
27 function checkGrad(model, criterion, input, target)
28    local params, gradParams = model:getParameters()
29
30    local epsilon = 1e-5
31
32    local output = model:forward(input)
33    local loss = criterion:forward(output, target)
34    local gradOutput = criterion:backward(output, target)
35    gradParams:zero()
36    model:backward(input, gradOutput)
37    local analyticalGradParam = gradParams:clone()
38
39    for i = 1, params:size(1) do
40       local x = params[i]
41
42       params[i] = x - epsilon
43       local output0 = model:forward(input)
44       local loss0 = criterion:forward(output0, target)
45
46       params[i] = x + epsilon
47       local output1 = model:forward(input)
48       local loss1 = criterion:forward(output1, target)
49
50       params[i] = x
51
52       local ana = analyticalGradParam[i]
53       local num = (loss1 - loss0) / (2 * epsilon)
54       local err
55
56       if num == ana then
57          err = 0
58       else
59          err = torch.abs(num - ana) / torch.abs(num)
60       end
61
62       print(
63          'CHECK '
64             .. err
65             .. ' checkGrad ' .. i
66             .. ' analytical ' .. ana
67             .. ' numerical ' .. num
68       )
69    end
70
71 end
72
73 function printTensorTable(t)
74    if torch.type(t) == 'table' then
75       for i, t in pairs(t) do
76          print('-- ELEMENT [' .. i .. '] --')
77          printTensorTable(t)
78       end
79    else
80       print(tostring(t))
81    end
82 end
83
84 -- torch.setnumthreads(params.nbThreads)
85 torch.setdefaulttensortype('torch.DoubleTensor')
86 torch.manualSeed(2)
87
88 --                     +--> c ----> e --+
89 --                    /            /     \
90 --                   /            /       \
91 --  input --> a --> b ---> d ----+         g --> output
92 --                          \             /
93 --                           \           /
94 --                            +--> f ---+
95
96 a = nn.Linear(10, 10)
97 b = nn.ReLU()
98 c = nn.Linear(10, 3)
99 d = nn.Linear(10, 3)
100 e = nn.CMulTable()
101 f = nn.Linear(3, 3)
102 g = nn.CAddTable()
103
104 model = nn.DAG()
105
106 model:addEdge(a, b)
107 model:addEdge(b, c)
108 model:addEdge(b, d)
109 model:addEdge(c, e)
110 model:addEdge(d, e)
111 model:addEdge(d, f)
112 model:addEdge(e, g)
113 model:addEdge(f, g)
114
115 model:setInput(a)
116 model:setOutput(g)
117
118 input = torch.Tensor(3, 10):uniform()
119
120 print('******************************************************************')
121 print('** updateOutput **************************************************')
122 print('******************************************************************')
123
124 output = model:updateOutput(input):clone()
125
126 printTensorTable(output)
127
128 print('******************************************************************')
129 print('** updateGradInput ***********************************************')
130 print('******************************************************************')
131
132 gradInput = model:updateGradInput(input, output)
133
134 printTensorTable(gradInput)
135
136 print('******************************************************************')
137 print('** checkGrad *****************************************************')
138 print('******************************************************************')
139
140 output:uniform()
141
142 checkGrad(model, nn.MSECriterion(), input, output)