# Flux with early stop and epochs

**URL:** <https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157>\
**Category:** New to Julia\
**Tags:** flux\
**Created:** [December 21, 2020, 6:55am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157 "2020-12-21T06:55:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [December 21, 2020, 6:55am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/1 "2020-12-21T06:55:39Z")

</div>

I’ve found that [Flux](https://fluxml.ai/Flux.jl/stable/) provides early stop by using [callbacks](https://fluxml.ai/Flux.jl/stable/training/training/#Callbacks-1).

Despite of the instruction, it is not compatible with `@epochs` in my case.

For example, codes looks like the following keep run the epochs loop.

```julia
valid_check = function()
    valid_loss = loss(x_test', θ_test', V_test')
    @show valid_loss
    valid_loss < 0.1 && Flux.stop()
end
@epochs 10 Flux.train!(loss, Flux.params(m), data, opt, cb=Flux.throttle(valid_check, 1))

```

Anyone knows what I should do…?

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [December 21, 2020, 7:17am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/2 "2020-12-21T07:17:56Z")

</div>

Is `valid_loss` ever \< 0.1? What happens if you remove the check and always call `Flux.stop()`? If that works, then either the network isn’t learning, the loss threshold is too low or something funky is going on with the call to `loss`.

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [December 21, 2020, 8:16am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/3 "2020-12-21T08:16:21Z")

</div>

Yes, it has been satisfied but keeps running the epochs loop.

Always calling `Flux.stop()` only updates the networks once and terminates only each epochs, that is, update iteration is exactly the same as total number of epochs.

---

<div class="post-metadata">

**Author:** ![anC](https://avatars.discourse-cdn.com/v4/letter/a/d07c76/32.png) [@anC](https://discourse.julialang.org/u/anC)\
**Post date:** [December 21, 2020, 12:07pm UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/4 "2020-12-21T12:07:57Z")

</div>

So, first of all, iHany, I’m new to Julia so this is probably not the best way to solve your problem…  
As far as I can see, @epochs is just a macro to run a “for loop” but also displaying some more info. You can get the outcome you are looking for by replacing the @epochs with

```
for i=1:10
     Flux.train!(loss, Flux.params(m), data, opt, cb=Flux.throttle(valid_check, 1))
     if valid_loss < 0.1
         break
     end
end
```

Although this doesn’t look as elegant as @epochs, I don’t think it will make any difference to the efficiency of your program.

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [December 21, 2020, 1:32pm UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/5 "2020-12-21T13:32:55Z")

</div>

Actually I’m doing what you suggested to detour the problem but it’s slightly different from a desired way.

For example, with that approach, the epochs loop will be terminated (by break) only when the `valid_loss` satisfies the criterion evaluated “outside” `Flux.train!`.

This means that the alternative cannot consider the cases when `valid_loss` satisfies the criterion within `Flux.train!`.

Anyway, the way you suggested would also work well in most of practical problems 🙂

---

<div class="post-metadata">

**Author:** ![anC](https://avatars.discourse-cdn.com/v4/letter/a/d07c76/32.png) [@anC](https://discourse.julialang.org/u/anC)\
**Post date:** [December 21, 2020, 11:27pm UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/6 "2020-12-21T23:27:06Z")

</div>

Again, this is probably very crude, but is this closer to what you were hoping for?

```
@epochs 10 Flux.train!(loss, params(model), data, opt, 
cb = eval(
if valid_loss< 0.1
   break
else
   valid_check
end
))
```

I don’t think it’s exactly what you want, but it might give you something to work on?

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [December 22, 2020, 3:48am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/7 "2020-12-22T03:48:30Z")

</div>

If you want to break out of the entire training loop, there’s little point to using `Flux.@epochs` instead of a plain for loop as written in @anC’s first post (the former literally expands to the latter).

---

<div class="post-metadata">

**Author:** ![iHany](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ihany/32/18151_2.png) [@iHany](https://discourse.julialang.org/u/iHany)\
**Post date:** [December 22, 2020, 4:02am UTC](https://discourse.julialang.org/t/flux-with-early-stop-and-epochs/52157/8 "2020-12-22T04:02:22Z")

</div>

I agree with that the two suggestions are the same.
