Please show me how to pass 2 tuples as arguments to a function

While studying neural networks, I have the following function defined.

function update_loss!()
     push!(train_loss, L(trainbatch...).data)
     push!(test_loss, L(testbatch...).data)
     @printf("train loss = %.2f, test loss = %.2f\n", train_loss[end], test_loss[end]) 
end

I use the function in the following statement and it works just fine:

@time Flux.train!(L, params(model), Iterators.repeated(trainbatch, 1000), opt;
            cb = Flux.throttle(update_loss!, 4))

The update_loss! function currently uses trainbatch and testbatch without them being passed as arguments; two tuples that are defined outside the function; but what I want is to pass the tuples as arguments to the update_loss! function so I can use it more generically; with any two tuples.

julia> typeof(trainbatch)
Tuple{Array{Float64,2},Flux.OneHotMatrix{Array{Flux.OneHotVector,1}}}

I’ve googled a lot on this without success; using several “…” tries, but I usually get a:

"MethodError: objects of type Nothing are not callable"

Just use a closure to pass additional parameters to a callback function.

Consider using a closure (a function that returns a function).

function update_loss!(trainbatch, testbatch)
    return () -> begin 
          push!(train_loss, L(trainbatch...).data)
          push!(test_loss, L(testbatch...).data)
          @printf("train loss = %.2f, test loss = %.2f\n", train_loss[end], test_loss[end]) 
    end
end

cb = Flux.throttle(update_loss!(trainbatch, testbatch), 4))
1 Like

@stevengj Thank you! This was hard to glean without your help!

@jandehann Thank you for such a clear explanation!