build based on 2ae4a23
This commit is contained in:
parent
992cabb03f
commit
c0e1497b26
@ -104,7 +104,7 @@ Contributing & Help
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/contributing.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/contributing.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -107,7 +107,7 @@ Logistic Regression
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/examples/logreg.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/examples/logreg.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -110,7 +110,7 @@ Home
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/index.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/index.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -104,7 +104,7 @@ Internals
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/internals.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/internals.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -128,7 +128,7 @@ Model Building Basics
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/models/basics.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/models/basics.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
@ -340,7 +340,68 @@ The above code is almost exactly how
|
|||||||
<code>Affine</code>
|
<code>Affine</code>
|
||||||
is defined in Flux itself! There's no difference between "library-level" and "user-level" models, so making your code reusable doesn't involve a lot of extra complexity. Moreover, much more complex models than
|
is defined in Flux itself! There's no difference between "library-level" and "user-level" models, so making your code reusable doesn't involve a lot of extra complexity. Moreover, much more complex models than
|
||||||
<code>Affine</code>
|
<code>Affine</code>
|
||||||
are equally simple to define, and equally close to the mathematical notation; read on to find out how.
|
are equally simple to define.
|
||||||
|
</p>
|
||||||
|
<h3>
|
||||||
|
<a class="nav-anchor" id="Sub-Templates-1" href="#Sub-Templates-1">
|
||||||
|
Sub-Templates
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<code>@net</code>
|
||||||
|
models can contain sub-models as well as just array parameters:
|
||||||
|
</p>
|
||||||
|
<pre><code class="language-julia">@net type TLP
|
||||||
|
first
|
||||||
|
second
|
||||||
|
function (x)
|
||||||
|
l1 = σ(first(x))
|
||||||
|
l2 = softmax(second(l1))
|
||||||
|
end
|
||||||
|
end</code></pre>
|
||||||
|
<p>
|
||||||
|
Just as above, this is roughly equivalent to writing:
|
||||||
|
</p>
|
||||||
|
<pre><code class="language-julia">type TLP
|
||||||
|
first
|
||||||
|
second
|
||||||
|
end
|
||||||
|
|
||||||
|
function (self::TLP)(x)
|
||||||
|
l1 = σ(self.first)
|
||||||
|
l2 = softmax(self.second(l1))
|
||||||
|
end</code></pre>
|
||||||
|
<p>
|
||||||
|
Clearly, the
|
||||||
|
<code>first</code>
|
||||||
|
and
|
||||||
|
<code>second</code>
|
||||||
|
parameters are not arrays here, but should be models themselves, and produce a result when called with an input array
|
||||||
|
<code>x</code>
|
||||||
|
. The
|
||||||
|
<code>Affine</code>
|
||||||
|
layer fits the bill so we can instantiate
|
||||||
|
<code>TLP</code>
|
||||||
|
with two of them:
|
||||||
|
</p>
|
||||||
|
<pre><code class="language-julia">model = TLP(Affine(10, 20),
|
||||||
|
Affine(20, 15))
|
||||||
|
x1 = rand(20)
|
||||||
|
model(x1) # [0.057852,0.0409741,0.0609625,0.0575354 ...</code></pre>
|
||||||
|
<p>
|
||||||
|
You may recognise this as being equivalent to
|
||||||
|
</p>
|
||||||
|
<pre><code class="language-julia">Chain(
|
||||||
|
Affine(10, 20), σ
|
||||||
|
Affine(20, 15)), softmax</code></pre>
|
||||||
|
<p>
|
||||||
|
given that it's just a sequence of calls. For simple networks
|
||||||
|
<code>Chain</code>
|
||||||
|
is completely fine, although the
|
||||||
|
<code>@net</code>
|
||||||
|
version is more powerful as we can (for example) reuse the output
|
||||||
|
<code>l1</code>
|
||||||
|
more than once.
|
||||||
</p>
|
</p>
|
||||||
<footer>
|
<footer>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -107,7 +107,7 @@ Debugging
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/models/debugging.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/models/debugging.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -107,7 +107,7 @@ Recurrence
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/e15a6e4896ae4c433d476880b1a118ce4e655432/docs/src/models/recurrent.md">
|
<a class="edit-page" href="https://github.com/MikeInnes/Flux.jl/tree/2ae4a23efe49056eb55914c2984478747eb002c8/docs/src/models/recurrent.md">
|
||||||
<span class="fa">
|
<span class="fa">
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
|
@ -69,7 +69,15 @@ var documenterSearchIndex = {"docs": [
|
|||||||
"page": "Model Building Basics",
|
"page": "Model Building Basics",
|
||||||
"title": "The Template",
|
"title": "The Template",
|
||||||
"category": "section",
|
"category": "section",
|
||||||
"text": "... Calculating Tax Expenses ...So how does the Affine template work? We don't want to duplicate the code above whenever we need more than one affine layer:W₁, b₁ = randn(...)\naffine₁(x) = W₁*x + b₁\nW₂, b₂ = randn(...)\naffine₂(x) = W₂*x + b₂\nmodel = Chain(affine₁, affine₂)Here's one way we could solve this: just keep the parameters in a Julia type, and define how that type acts as a function:type MyAffine\n W\n b\nend\n\n# Use the `MyAffine` layer as a model\n(l::MyAffine)(x) = l.W * x + l.b\n\n# Convenience constructor\nMyAffine(in::Integer, out::Integer) =\n MyAffine(randn(out, in), randn(out))\n\nmodel = Chain(MyAffine(5, 5), MyAffine(5, 5))\n\nmodel(x1) # [-1.54458,0.492025,0.88687,1.93834,-4.70062]This is much better: we can now make as many affine layers as we want. This is a very common pattern, so to make it more convenient we can use the @net macro:@net type MyAffine\n W\n b\n x -> W * x + b\nendThe function provided, x -> W * x + b, will be used when MyAffine is used as a model; it's just a shorter way of defining the (::MyAffine)(x) method above.However, @net does not simply save us some keystrokes; it's the secret sauce that makes everything else in Flux go. For example, it analyses the code for the forward function so that it can differentiate it or convert it to a TensorFlow graph.The above code is almost exactly how Affine is defined in Flux itself! There's no difference between \"library-level\" and \"user-level\" models, so making your code reusable doesn't involve a lot of extra complexity. Moreover, much more complex models than Affine are equally simple to define, and equally close to the mathematical notation; read on to find out how."
|
"text": "... Calculating Tax Expenses ...So how does the Affine template work? We don't want to duplicate the code above whenever we need more than one affine layer:W₁, b₁ = randn(...)\naffine₁(x) = W₁*x + b₁\nW₂, b₂ = randn(...)\naffine₂(x) = W₂*x + b₂\nmodel = Chain(affine₁, affine₂)Here's one way we could solve this: just keep the parameters in a Julia type, and define how that type acts as a function:type MyAffine\n W\n b\nend\n\n# Use the `MyAffine` layer as a model\n(l::MyAffine)(x) = l.W * x + l.b\n\n# Convenience constructor\nMyAffine(in::Integer, out::Integer) =\n MyAffine(randn(out, in), randn(out))\n\nmodel = Chain(MyAffine(5, 5), MyAffine(5, 5))\n\nmodel(x1) # [-1.54458,0.492025,0.88687,1.93834,-4.70062]This is much better: we can now make as many affine layers as we want. This is a very common pattern, so to make it more convenient we can use the @net macro:@net type MyAffine\n W\n b\n x -> W * x + b\nendThe function provided, x -> W * x + b, will be used when MyAffine is used as a model; it's just a shorter way of defining the (::MyAffine)(x) method above.However, @net does not simply save us some keystrokes; it's the secret sauce that makes everything else in Flux go. For example, it analyses the code for the forward function so that it can differentiate it or convert it to a TensorFlow graph.The above code is almost exactly how Affine is defined in Flux itself! There's no difference between \"library-level\" and \"user-level\" models, so making your code reusable doesn't involve a lot of extra complexity. Moreover, much more complex models than Affine are equally simple to define."
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"location": "models/basics.html#Sub-Templates-1",
|
||||||
|
"page": "Model Building Basics",
|
||||||
|
"title": "Sub-Templates",
|
||||||
|
"category": "section",
|
||||||
|
"text": "@net models can contain sub-models as well as just array parameters:@net type TLP\n first\n second\n function (x)\n l1 = σ(first(x))\n l2 = softmax(second(l1))\n end\nendJust as above, this is roughly equivalent to writing:type TLP\n first\n second\nend\n\nfunction (self::TLP)(x)\n l1 = σ(self.first)\n l2 = softmax(self.second(l1))\nendClearly, the first and second parameters are not arrays here, but should be models themselves, and produce a result when called with an input array x. The Affine layer fits the bill so we can instantiate TLP with two of them:model = TLP(Affine(10, 20),\n Affine(20, 15))\nx1 = rand(20)\nmodel(x1) # [0.057852,0.0409741,0.0609625,0.0575354 ...You may recognise this as being equivalent toChain(\n Affine(10, 20), σ\n Affine(20, 15)), softmaxgiven that it's just a sequence of calls. For simple networks Chain is completely fine, although the @net version is more powerful as we can (for example) reuse the output l1 more than once."
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user