# Could one chain chains?

**URL:** https://discourse.julialang.org/t/could-one-chain-chains/30642
**Category:** Machine Learning
**Tags:** flux
**Created:** [November 3, 2019, 2:48am UTC](https://discourse.julialang.org/t/could-one-chain-chains/30642 "2019-11-03T02:48:31Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![zht](https://avatars.discourse-cdn.com/v4/letter/z/67e7ee/32.png) [@zht](https://discourse.julialang.org/u/zht)
#### Post date: [November 3, 2019, 2:48am UTC](https://discourse.julialang.org/t/could-one-chain-chains/30642/1 "2019-11-03T02:48:32Z")

</div>

Is it okay for the layers used in a chain to be chains themselves? Such as Chain(Chain(A, B), C)? All the examples I have seen so far do not use Chain recurrently so I am thinking this may not be kosher. Does this mean that in order to build a sub-structure such as a ResNet block I need to build a custom layer through a structure and @treelike?

---

<div class="post-metadata">

### Author: ![zht](https://avatars.discourse-cdn.com/v4/letter/z/67e7ee/32.png) [@zht](https://discourse.julialang.org/u/zht)
#### Post date: [November 3, 2019, 11:18pm UTC](https://discourse.julialang.org/t/could-one-chain-chains/30642/2 "2019-11-03T23:18:49Z")

</div>

Simple chaining like this does not appear to work:

```julia
function ResNetBlock(nfilter=64)
    return 
    Chain(
        SkipConnection(
            Chain( * [
                Conv((3,3), nfilter=>nfilter, pad=1),
                BatchNorm(nfilter, relu),
                Conv((3,3), nfilter=>nfilter, pad=1),
                BatchNorm(nfilter)),
            +),
        x -> relu.(x))
end

```

This was inspired by @jonathan-laurent[AlphaZero](https://github.com/jonathan-laurent/AlphaZero.jl/blob/ef4ee1d6f4cedc1aff143397755d0b4424e5299d/src/Flux/ResNet.jl#L27) but it does not work for me, meaning running params on returned chain gave an empty parameter list. I believe he defines his own helper functions to interface with Flux/gpu.

---

<div class="post-metadata">

### Author: ![zht](https://avatars.discourse-cdn.com/v4/letter/z/67e7ee/32.png) [@zht](https://discourse.julialang.org/u/zht)
#### Post date: [November 3, 2019, 11:33pm UTC](https://discourse.julialang.org/t/could-one-chain-chains/30642/3 "2019-11-03T23:33:26Z")

</div>

Weird thing is if I run the code interactively then it works

```julia
nfilter = 2
nn = Chain(
        SkipConnection(
            Chain(
                Conv((3,3), nfilter=>nfilter, pad=1),
                BatchNorm(nfilter, relu),
                Conv((3,3), nfilter=>nfilter, pad=1),
                BatchNorm(nfilter)),
            +),
        x -> relu.(x))
params(nn)

```

After some experimentation it appears I must not have understood `return` correctly. ~~After I got rid of the `return` keyword then the function wrapper also works. I am new to Julia so I don’t know if this is a bug or feature of Julia.~~ Duh, `return` on its own line would return an empty object! So it was a newbie syntax error.

Okay chain of chains do appear to work! Great!

---

<div class="post-metadata">

### Author: ![MacKenzieHnC](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mackenziehnc/32/16429_2.png) [@MacKenzieHnC](https://discourse.julialang.org/u/MacKenzieHnC)
#### Post date: [October 7, 2020, 7:47pm UTC](https://discourse.julialang.org/t/could-one-chain-chains/30642/4 "2020-10-07T19:47:10Z")

</div>

Don’t forget to call `Flux.@functor` for custom-defined layers
