Hi all,
In order to be able to recreate a previously trained ensemble, one has to use the encoder values, and not the scaled_encoders, from an ensemble at the end of a training stage to initialize a identically behaving ensemble (explained in NengoDL simulator provides different results in training network - #4 by xchoo). The NengoDL simulator provides a function to get these parameters, aptly named get_nengo_params
, but the Nengo Core simulator does not. I am using the nengo_dl.simulator.get_nengo_params
function as a template for a function so that allows me to later create an Ensemble with the same scaled_encoders
as that of a previously trained ensemble.
Instead of starting with a trained network, I just start with a model that has a single ensemble
I have the following code:
import numpy as np
import nengo
from nengo.dists import Uniform
def calculate_params(simulator, ens, s_encoders):
# calculate the "unscaled" encoders
# based on the `get_nengo_params` func from the nengoDL simulator
gain = sim.model.params[ens].gain
radius = ens.radius
encoders = s_encoders * radius / gain[:, None]
return encoders, gain, radius
n_neurons = 2
Dim = 1
seed = 1
model = nengo.Network()
intercepts = [0,0]
encoders = np.array([[.5],[.3]])
with model:
A = nengo.Ensemble(
n_neurons,
dimensions=Dim,
intercepts=intercepts,
encoders=encoders,
seed=seed
)
probe_encoders = nengo.Probe(A, 'scaled_encoders')
sim = nengo.Simulator(model, progress_bar=False)
sim.run(0.001)
scaled_encoders = sim.data[probe_encoders][0]
encoders_calculated, gain, radius = calculate_params(sim, A, scaled_encoders)
print(f"initalized encoders: \n{encoders}")
print(f"radius: {radius}")
print(f"gain: {gain}")
print(f"probed scaled_encoders: \n{scaled_encoders}")
print(f"calculated encoders: \n{encoders_calculated}")
The output is:
initalized encoders:
[[0.5]
[0.3]]
radius: 1.0
gain: [29.76470771 36.98730496]
probed scaled_encoders:
[[29.76470771]
[36.98730496]]
calculated encoders:
[[1.]
[1.]]
As you see, the initialized encoders and calculated encoders are not the same. However, the values for the calculated encoders are correct given the value for the scaled encoders of the ensemble A, and the gain values.
The problem is then that is look to me like the scaled_encoder
values are not correct. Given how scaled_encoders are calculated during the build process, I would expect these to be
[[0.5 * 29.76470771]
[0.3 * 36.98730496]]
How the scaled encoders are now, it looks like the nengo simulator acts as if the (not scaled) encoders are set as [[1.],[1.]], while I explicitly set them to [[0.5], [0.3]]
So my question is: Am I misunderstanding how scaled encoders are calculated? What is going on?