I’m diving into Flux.jl for my research. My objective is to define a loss function that would measure, so to speak, the convergence of the model towards a uniform data distribution.
I generate K random fictitious observations and compare how many of them are smaller than the true data in the training set. In other words, the model generates K simulations, and we determine the number of simulations where the generated data is smaller than the actual data. If the model is well trained, this distribution should converge to a uniform distribution.
However, since the resulting histogram is not differentiable, I needed to approximate this idea using compositions of continuous differentiable functions.
η = 0.1; num_epochs = 100; n_samples = 1000
optim = Flux.setup(Flux.Adam(η), model)
losses = []
l = CustomLoss(2)
for epoch in 1:num_epochs
loss, grads = Flux.withgradient(model) do m
aₖ = zeros(l.K+1)
for _ in 1:n_samples
x = rand(Normal(μ, stddev), l.K)
yₖ = m(x')
y = target(rand(Normal(μ, stddev)))
aₖ += generate_aₖ(l, yₖ, y)
end
scalar_diff(l, aₖ ./ sum(aₖ))
end
Flux.update!(optim, model, grads[1])
push!(losses, loss)
end
So, generate_aₖ(l, yₖ, y) would return a vector of size K+1, where the element at index k is close to 1 if y is greater than k elements of the vector yₖ.
Finally, scalar_diff calculates the squared difference between the calculated aₖ and the uniform distribution.
However, this code is not functioning correctly, and I am encountering the following issue due to the line aₖ += generate_aₖ(l, yₖ, y),
Mutating arrays is not supported -- called copyto!(Vector{Float64}, ...)
This error occurs when you ask Zygote to differentiate operations that change
the elements of arrays in place (e.g. setting values with x .= ...)
I’m not sure how to solve this problem. Does anyone have any ideas for a workaround? I need to differentiate it against aₖ .