OCD cosmetics.
[dagnn.git] / README.md
1 # Introduction #
2
3 This package implements a new module nn.DAG for the [torch framework](https://torch.ch),
4 which inherits from [nn.Container](https://github.com/torch/nn/blob/master/Container.lua) and allows to combine modules in an
5 arbitrary [Directed Acyclic Graph (DAG).](https://en.wikipedia.org/wiki/Directed_acyclic_graph)
6
7 ## Example ##
8
9 A typical use would be:
10
11 ```lua
12 model = nn.DAG()
13
14 a = nn.Linear(100, 10)
15 b = nn.ReLU()
16 c = nn.Linear(10, 15)
17 d = nn.CMulTable()
18 e = nn.Linear(15, 15)
19
20 model:connect(a, b)
21 model:connect(b, nn.Linear(10, 15), nn.ReLU(), d)
22 model:connect(b, c)
23 model:connect(c, d)
24 model:connect(c, nn.Mul(-1), e)
25
26 model:setInput(a)
27 model:setOutput({ d, e })
28
29 input = torch.Tensor(30, 100):uniform()
30 output = model:updateOutput(input)
31
32 ```
33
34 which would encode the following graph
35
36                  +- Linear(10, 10) -> ReLU ---> d -->
37                 /                              /
38                /                              /
39     --> a --> b -----------> c --------------+
40                               \
41                                \
42                                 +-- Mul(-1) --> e -->
43
44 and run a forward pass with a random batch of 30 samples.
45
46 Note that DAG:connect allows to add a bunch of edges at once. This is
47 particularly useful to add anonymous modules which have a single
48 predecessor and successor.
49
50 # Usage #
51
52 ## Input and output ##
53
54 The DAG can deal with modules which take as input and produce as
55 output tensors and nested tables of tensors.
56
57 If a node has a single predecessor, the output of the latter is taken
58 as-is as the input to the former. If it has multiple predecessors, all
59 the outputs are collected into a table, and the table is used as
60 input. The indexes of the outputs in that table reflect the
61 chronological order in which the edges where created in the
62 DAG:connect() commands.
63
64 The input to the DAG (respectively the produced output) is a nested
65 table of inputs reflecting the structure of the nested table of
66 modules given as argument to DAG:setInput (respectively DAG:setOutput)
67
68 So for instance, in the example above, the model expects a tensor as
69 input, since it is the input to the module a, and its output is a
70 table composed of two tensors, corresponding to the outputs of d and e
71 respectively.
72
73 ## Functions ##
74
75 ### nn.DAG() ###
76
77 Create a new empty DAG, which inherits from nn.Container.
78
79 ### nn.DAG:connect(module1, module2 [, module3, [...]]) ###
80
81 Add new nodes corresponding to the modules passed as arguments if they
82 have not been already added in a previous call. Add edges between
83 every two nodes associated to two successive modules in the
84 arguments.
85
86 Calling this function with n > 2 arguments is strictly equivalent to
87 calling it n-1 times on the pairs of successive arguments.
88
89 Accepting more than two arguments allows in particular to add
90 anonymous modules, which are not associated to variables. In principle
91 the only ones that have to be non-anonymous are those that have more
92 than one successor/predecessor and/or are inputs/outputs.
93
94 ### nn.DAG:setInput(i) ###
95
96 Define the content and structure of the input. The argument should be
97 either a module, or a (nested) table of modules. The input to the DAG
98 should be a (nested) table of inputs, with the corresponding
99 structure.
100
101 ### nn.DAG:setOutput(o) ###
102
103 Similar to DAG:setInput().
104
105 ### nn.DAG:print() ###
106
107 Print the list of nodes.
108
109 ### nn.DAG:saveDot(filename) ###
110
111 Save a dot file to be used by the Graphviz set of tools for graph
112 visualization. This dot file can than be used for instance to produce
113 a pdf file such as [this one](https://fleuret.org/git-extract/dagnn/graph.pdf) with
114
115 ```
116 dot graph.dot -T pdf -o graph.pdf
117 ```
118
119 ### nn.DAG:setLabel(module, name) ###
120
121 Add a label to the given module, that will be used for DAG:print() and DAG:saveDot()