aboutsummaryrefslogtreecommitdiff
path: root/nerv/layer/graph.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nerv/layer/graph.lua')
-rw-r--r--nerv/layer/graph.lua63
1 files changed, 63 insertions, 0 deletions
diff --git a/nerv/layer/graph.lua b/nerv/layer/graph.lua
index 5790f95..5b5d4c7 100644
--- a/nerv/layer/graph.lua
+++ b/nerv/layer/graph.lua
@@ -1,5 +1,68 @@
+--- Implements a special kind of layers having an internal structure, a
+-- directed graph of connected sub-level layers.
+
+--- The class describing the concept of a graph layer having an internal
+-- structure, a directed graph of connected sub-level layers. Some of these
+-- sub-level layers can again be graph layers, thus, it enables nested and
+-- recursive layer declaration. The graph layer can be regarded as a container of
+-- its sub-level layers. A layer other than a graph layer is also referenced as
+-- "*primitive layer*".
+-- @type nerv.GraphLayer
+
local GraphLayer = nerv.class('nerv.GraphLayer', 'nerv.Layer')
+--- The constructor.
+-- @param id the identifier
+-- @param global_conf see `self.gconf` of `nerv.Layer.__init`
+-- @param layer_conf a table providing with settings dedicated for the layer,
+-- the following fields should be specified:
+--
+-- * `lrepo`: the layer repo that should be used to find the sub-level layers
+-- * `connections`: an array of 3-tuples describing the connections of
+-- sub-level layers, the structure is as follow:
+--
+-- {
+-- {<from_port1>, <to_port1>, <time_shift1>}, -- tuple 1
+-- {<from_port2>, <to_port2>, <time_shift2>}, -- tuple 2
+-- {<from_port3>, <to_port3>, <time_shift3>}, -- tuple 3
+-- ...
+-- }
+-- Each tuple stands for a directed edge between two ports. The first two
+-- elements in the tuple are called *port specification* which is a string
+-- with the following format:
+--
+-- <layer_id>[<port_idx>]
+-- where the `<layer_id>` is a string that identifies the layer in
+-- `lconf.lrepo`, and `<port_id>` is the input or output port index when used
+-- in the first or second port specification respectively.
+--
+-- The third element in the tuple is an integer specifying the time delay of
+-- this connection. In most cases, it will be simply zero. But for an
+-- recurrent network, a positive value `i` means the output from `<from_port>`
+-- will be used as the input to `<to_port>` in `i`th computation of the future.
+-- Negative values are also allowed to propagate the output to the past.
+--
+-- Note that there are two possible strings of `<layer_id>` that have special
+-- meanings: the string `"<input>"` and `"<output>"` are placeholders of the
+-- the input and output ports of the outer graph layer. The input for the graph
+-- layer as a whole can be used by establishing connections from
+-- `"<input>[i]"`, and vice versa for the output.
+--
+-- As an example, tuples:
+--
+-- {
+-- {"<input>[1]", "affine0[1]", 0},
+-- {"affine0[1]", "sigmoid0[1]", 0},
+-- {"sigmoid0[1]", "affine1[1]", 0},
+-- {"affine1[1]", "<output>[1]", 0}
+-- }
+-- Specify a graph layer that contains two stacked and fully connected linear
+-- transformation sub-level layers.
+--
+-- * `reversed`: optional, reverse the time shifting of all connections if true
+--
+-- For other `layer_conf` fields that are shared by all layers, see `nerv.Layer.__init`.
+
function GraphLayer:__init(id, global_conf, layer_conf)
nerv.Layer.__init(self, id, global_conf, layer_conf)
self.lrepo = layer_conf.layer_repo