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