Skip to content

Commit

Permalink
docs/book: add building networks chapter
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHirn committed Mar 31, 2016
1 parent 4e5c5f6 commit f648454
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 6 deletions.
67 changes: 66 additions & 1 deletion doc/book/building-networks.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,72 @@ <h1 class="menu-title"></h1>
</div>

<div id="content" class="content">
<h1>Network from Layers</h1>
<h1>Create a Network</h1>
<p>In the previous chapters, we learned that everything is a layer. Even the network
itself is a layer and therefore behaves like any other layer which means,
that it could be used to create even bigger networks. This is possible, because
a <code>Layer</code> can implement any behavior as long as it takes an input and produces
an output. In <a href="./layer-lifecycle.html">2.1 Layer Lifecycle</a>
we have seen, that only one <code>LayerConfig</code> can be used to turn it via
<code>Layer::from_config</code> into an actual <code>Layer</code>. But as Deep Learning relies on
chaining multiple layers together, we need a <code>Layer</code>, who implements this
behavior for us. Enter the container layers.</p>
<h3>Networks via the <code>Sequential</code> layer</h3>
<p>A <code>Sequential</code> is a layer of the container layer category. The config of a
container layer, e.g. <code>SequentialConfig</code> has a special method called,
<code>.add_layer</code> which takes one <code>LayerConfig</code> and adds it to an ordered list in the
<code>SequentialConfig</code>.</p>
<p>When turning a <code>SequentialConfig</code> into a <code>Layer</code> by passing the config to
<code>Layer::from_config</code>, the behavior of the Sequential is to initialize all the
layers which were added via <code>.add_layer</code> and connect the layers with each other.
This means, the output of one layer becomes the input of the next layer in the
list. The input of a <code>Layer</code> with a sequential worker, becomes the input of the
first layer in the sequential worker, the sequential worker then takes care
of passing the input through all the layers and the output of the last layer
then becomes the output of the <code>Layer</code> with the sequential worker. Therefore
a sequential <code>Layer</code> fulfills the requirements of a <code>Layer</code>.</p>
<pre><code class="language-rust">// short form for: &amp;LayerConfig::new(&quot;net&quot;, LayerType::Sequential(cfg))
let mut net_cfg = SequentialConfig::default();

net_cfg.add_input(&quot;data&quot;, &amp;vec![batch_size, 28, 28]);
net_cfg.add_layer(LayerConfig::new(&quot;reshape&quot;, ReshapeConfig::of_shape(&amp;vec![batch_size, 1, 28, 28])));
net_cfg.add_layer(LayerConfig::new(&quot;conv&quot;, ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new(&quot;pooling&quot;, PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new(&quot;linear1&quot;, LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new(&quot;sigmoid&quot;, LayerType::Sigmoid));
net_cfg.add_layer(LayerConfig::new(&quot;linear2&quot;, LinearConfig { output_size: 10 }));
net_cfg.add_layer(LayerConfig::new(&quot;log_softmax&quot;, LayerType::LogSoftmax));

// set up the sequential layer aka. a deep, convolutional network
let mut net = Layer::from_config(backend.clone(), &amp;net_cfg);
</code></pre>
<p>As a sequential layer is like any other layer, we can use sequential layers as
building blocks for larger networks. Important building blocks of a network can
be grouped into a sequential layer and published as a crate for others to use.</p>
<pre><code class="language-rust">// short form for: &amp;LayerConfig::new(&quot;net&quot;, LayerType::Sequential(cfg))
let mut conv_net = SequentialConfig::default();

conv_net.add_input(&quot;data&quot;, &amp;vec![batch_size, 28, 28]);
conv_net.add_layer(LayerConfig::new(&quot;reshape&quot;, ReshapeConfig::of_shape(&amp;vec![batch_size, 1, 28, 28])));
conv_net.add_layer(LayerConfig::new(&quot;conv&quot;, ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new(&quot;pooling&quot;, PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new(&quot;linear1&quot;, LinearConfig { output_size: 500 }));
conv_net.add_layer(LayerConfig::new(&quot;sigmoid&quot;, LayerType::Sigmoid));
conv_net.add_layer(LayerConfig::new(&quot;linear2&quot;, LinearConfig { output_size: 10 }));

let mut net_cfg = SequentialConfig::default();

net_cfg.add_layer(conv_net);
net_cfg.add_layer(LayerConfig::new(&quot;linear&quot;, LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new(&quot;log_softmax&quot;, LayerType::LogSoftmax));

// set up the 'big' network
let mut net = Layer::from_config(backend.clone(), &amp;net_cfg);
</code></pre>
<h3>Networks via other container layers</h3>
<p>So far, there is only the sequential layer, but other container layers, with
slightly different behaviors are conceivable. For example a parallel or
concat layer in addition to the sequential layer.</p>

</div>

Expand Down
7 changes: 7 additions & 0 deletions doc/book/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ <h1>Leaf</h1>
portability to Deep Learning. Leaf has a very simple API, <a href="./layers.html">Layers</a> and
<a href="./solvers.html">Solvers</a>, and is one of the fastest Machine Intelligence Frameworks
available.</p>
<p><br/></p>
<div align="center">
<iframe src="https://ghbtns.com/github-btn.html?user=autumnai&repo=leaf&type=star&count=true" frameborder="0" scrolling="0" width="120px" height="20px"></iframe>
<a href="https://twitter.com/autumn_eng" class="twitter-follow-button" data-show-count="false">Follow @autumn_eng</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>
<p><br/></p>
<blockquote>
<p><strong>Assumption</strong><br />
The Leaf Book requires a basic understanding of the fundamental concepts
Expand Down
7 changes: 7 additions & 0 deletions doc/book/leaf.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ <h1>Leaf</h1>
portability to Deep Learning. Leaf has a very simple API, <a href="./layers.html">Layers</a> and
<a href="./solvers.html">Solvers</a>, and is one of the fastest Machine Intelligence Frameworks
available.</p>
<p><br/></p>
<div align="center">
<iframe src="https://ghbtns.com/github-btn.html?user=autumnai&repo=leaf&type=star&count=true" frameborder="0" scrolling="0" width="120px" height="20px"></iframe>
<a href="https://twitter.com/autumn_eng" class="twitter-follow-button" data-show-count="false">Follow @autumn_eng</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>
<p><br/></p>
<blockquote>
<p><strong>Assumption</strong><br />
The Leaf Book requires a basic understanding of the fundamental concepts
Expand Down
74 changes: 73 additions & 1 deletion doc/book/print.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ <h1>Leaf</h1>
portability to Deep Learning. Leaf has a very simple API, <a href="./layers.html">Layers</a> and
<a href="./solvers.html">Solvers</a>, and is one of the fastest Machine Intelligence Frameworks
available.</p>
<p><br/></p>
<div align="center">
<iframe src="https://ghbtns.com/github-btn.html?user=autumnai&repo=leaf&type=star&count=true" frameborder="0" scrolling="0" width="120px" height="20px"></iframe>
<a href="https://twitter.com/autumn_eng" class="twitter-follow-button" data-show-count="false">Follow @autumn_eng</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>
<p><br/></p>
<blockquote>
<p><strong>Assumption</strong><br />
The Leaf Book requires a basic understanding of the fundamental concepts
Expand Down Expand Up @@ -262,7 +269,72 @@ <h3>Backward</h3>
<p>In case the worker layer is a container layer, the <code>backward</code> method of the
container layer takes care of calling the <code>backward_input</code> and <code>backward_parameter</code>
methods of its managed layers in the right order.</p>
<h1>Network from Layers</h1>
<h1>Create a Network</h1>
<p>In the previous chapters, we learned that everything is a layer. Even the network
itself is a layer and therefore behaves like any other layer which means,
that it could be used to create even bigger networks. This is possible, because
a <code>Layer</code> can implement any behavior as long as it takes an input and produces
an output. In <a href="./layer-lifecycle.html">2.1 Layer Lifecycle</a>
we have seen, that only one <code>LayerConfig</code> can be used to turn it via
<code>Layer::from_config</code> into an actual <code>Layer</code>. But as Deep Learning relies on
chaining multiple layers together, we need a <code>Layer</code>, who implements this
behavior for us. Enter the container layers.</p>
<h3>Networks via the <code>Sequential</code> layer</h3>
<p>A <code>Sequential</code> is a layer of the container layer category. The config of a
container layer, e.g. <code>SequentialConfig</code> has a special method called,
<code>.add_layer</code> which takes one <code>LayerConfig</code> and adds it to an ordered list in the
<code>SequentialConfig</code>.</p>
<p>When turning a <code>SequentialConfig</code> into a <code>Layer</code> by passing the config to
<code>Layer::from_config</code>, the behavior of the Sequential is to initialize all the
layers which were added via <code>.add_layer</code> and connect the layers with each other.
This means, the output of one layer becomes the input of the next layer in the
list. The input of a <code>Layer</code> with a sequential worker, becomes the input of the
first layer in the sequential worker, the sequential worker then takes care
of passing the input through all the layers and the output of the last layer
then becomes the output of the <code>Layer</code> with the sequential worker. Therefore
a sequential <code>Layer</code> fulfills the requirements of a <code>Layer</code>.</p>
<pre><code class="language-rust">// short form for: &amp;LayerConfig::new(&quot;net&quot;, LayerType::Sequential(cfg))
let mut net_cfg = SequentialConfig::default();

net_cfg.add_input(&quot;data&quot;, &amp;vec![batch_size, 28, 28]);
net_cfg.add_layer(LayerConfig::new(&quot;reshape&quot;, ReshapeConfig::of_shape(&amp;vec![batch_size, 1, 28, 28])));
net_cfg.add_layer(LayerConfig::new(&quot;conv&quot;, ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new(&quot;pooling&quot;, PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new(&quot;linear1&quot;, LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new(&quot;sigmoid&quot;, LayerType::Sigmoid));
net_cfg.add_layer(LayerConfig::new(&quot;linear2&quot;, LinearConfig { output_size: 10 }));
net_cfg.add_layer(LayerConfig::new(&quot;log_softmax&quot;, LayerType::LogSoftmax));

// set up the sequential layer aka. a deep, convolutional network
let mut net = Layer::from_config(backend.clone(), &amp;net_cfg);
</code></pre>
<p>As a sequential layer is like any other layer, we can use sequential layers as
building blocks for larger networks. Important building blocks of a network can
be grouped into a sequential layer and published as a crate for others to use.</p>
<pre><code class="language-rust">// short form for: &amp;LayerConfig::new(&quot;net&quot;, LayerType::Sequential(cfg))
let mut conv_net = SequentialConfig::default();

conv_net.add_input(&quot;data&quot;, &amp;vec![batch_size, 28, 28]);
conv_net.add_layer(LayerConfig::new(&quot;reshape&quot;, ReshapeConfig::of_shape(&amp;vec![batch_size, 1, 28, 28])));
conv_net.add_layer(LayerConfig::new(&quot;conv&quot;, ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new(&quot;pooling&quot;, PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new(&quot;linear1&quot;, LinearConfig { output_size: 500 }));
conv_net.add_layer(LayerConfig::new(&quot;sigmoid&quot;, LayerType::Sigmoid));
conv_net.add_layer(LayerConfig::new(&quot;linear2&quot;, LinearConfig { output_size: 10 }));

let mut net_cfg = SequentialConfig::default();

net_cfg.add_layer(conv_net);
net_cfg.add_layer(LayerConfig::new(&quot;linear&quot;, LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new(&quot;log_softmax&quot;, LayerType::LogSoftmax));

// set up the 'big' network
let mut net = Layer::from_config(backend.clone(), &amp;net_cfg);
</code></pre>
<h3>Networks via other container layers</h3>
<p>So far, there is only the sequential layer, but other container layers, with
slightly different behaviors are conceivable. For example a parallel or
concat layer in addition to the sequential layer.</p>
<h1>Create a new Layer</h1>
<h1>Solvers</h1>
<h1>Model Training</h1>
Expand Down
78 changes: 77 additions & 1 deletion doc/src/building-networks.md
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
# Network from Layers
# Create a Network

In the previous chapters, we learned that everything is a layer. Even the network
itself is a layer and therefore behaves like any other layer which means,
that it could be used to create even bigger networks. This is possible, because
a `Layer` can implement any behavior as long as it takes an input and produces
an output. In [2.1 Layer Lifecycle](./layer-lifecycle.html)
we have seen, that only one `LayerConfig` can be used to turn it via
`Layer::from_config` into an actual `Layer`. But as Deep Learning relies on
chaining multiple layers together, we need a `Layer`, who implements this
behavior for us. Enter the container layers.

### Networks via the `Sequential` layer

A `Sequential` is a layer of the container layer category. The config of a
container layer, e.g. `SequentialConfig` has a special method called,
`.add_layer` which takes one `LayerConfig` and adds it to an ordered list in the
`SequentialConfig`.

When turning a `SequentialConfig` into a `Layer` by passing the config to
`Layer::from_config`, the behavior of the Sequential is to initialize all the
layers which were added via `.add_layer` and connect the layers with each other.
This means, the output of one layer becomes the input of the next layer in the
list. The input of a `Layer` with a sequential worker, becomes the input of the
first layer in the sequential worker, the sequential worker then takes care
of passing the input through all the layers and the output of the last layer
then becomes the output of the `Layer` with the sequential worker. Therefore
a sequential `Layer` fulfills the requirements of a `Layer`.

```rust
// short form for: &LayerConfig::new("net", LayerType::Sequential(cfg))
let mut net_cfg = SequentialConfig::default();

net_cfg.add_input("data", &vec![batch_size, 28, 28]);
net_cfg.add_layer(LayerConfig::new("reshape", ReshapeConfig::of_shape(&vec![batch_size, 1, 28, 28])));
net_cfg.add_layer(LayerConfig::new("conv", ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new("pooling", PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
net_cfg.add_layer(LayerConfig::new("linear1", LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new("sigmoid", LayerType::Sigmoid));
net_cfg.add_layer(LayerConfig::new("linear2", LinearConfig { output_size: 10 }));
net_cfg.add_layer(LayerConfig::new("log_softmax", LayerType::LogSoftmax));

// set up the sequential layer aka. a deep, convolutional network
let mut net = Layer::from_config(backend.clone(), &net_cfg);
```

As a sequential layer is like any other layer, we can use sequential layers as
building blocks for larger networks. Important building blocks of a network can
be grouped into a sequential layer and published as a crate for others to use.

```rust
// short form for: &LayerConfig::new("net", LayerType::Sequential(cfg))
let mut conv_net = SequentialConfig::default();

conv_net.add_input("data", &vec![batch_size, 28, 28]);
conv_net.add_layer(LayerConfig::new("reshape", ReshapeConfig::of_shape(&vec![batch_size, 1, 28, 28])));
conv_net.add_layer(LayerConfig::new("conv", ConvolutionConfig { num_output: 20, filter_shape: vec![5], stride: vec![1], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new("pooling", PoolingConfig { mode: PoolingMode::Max, filter_shape: vec![2], stride: vec![2], padding: vec![0] }));
conv_net.add_layer(LayerConfig::new("linear1", LinearConfig { output_size: 500 }));
conv_net.add_layer(LayerConfig::new("sigmoid", LayerType::Sigmoid));
conv_net.add_layer(LayerConfig::new("linear2", LinearConfig { output_size: 10 }));

let mut net_cfg = SequentialConfig::default();

net_cfg.add_layer(conv_net);
net_cfg.add_layer(LayerConfig::new("linear", LinearConfig { output_size: 500 }));
net_cfg.add_layer(LayerConfig::new("log_softmax", LayerType::LogSoftmax));

// set up the 'big' network
let mut net = Layer::from_config(backend.clone(), &net_cfg);
```

### Networks via other container layers

So far, there is only the sequential layer, but other container layers, with
slightly different behaviors are conceivable. For example a parallel or
concat layer in addition to the sequential layer.
13 changes: 10 additions & 3 deletions doc/src/leaf.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ portability to Deep Learning. Leaf has a very simple API, [Layers][layers] and
[Solvers][solvers], and is one of the fastest Machine Intelligence Frameworks
available.

<br/>

<div align="center">
<iframe src="https://ghbtns.com/github-btn.html?user=autumnai&repo=leaf&type=star&count=true" frameborder="0" scrolling="0" width="120px" height="20px"></iframe>
<a href="https://twitter.com/autumn_eng" class="twitter-follow-button" data-show-count="false">Follow @autumn_eng</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>

<br/>

> **Assumption**
> The Leaf Book requires a basic understanding of the fundamental concepts
> of Machine and Deep Learning. Recommended resources are
Expand Down Expand Up @@ -44,6 +54,3 @@ Leaf is licensed under either of
* [MIT license](https://github.com/autumnai/leaf/blob/master/LICENSE-MIT)

at your option.



0 comments on commit f648454

Please sign in to comment.