Hello all,
Problem: I have four methods (sepal_length, sepal_width, petal_length and petal_width) in DataFeeder class. I want to update the counter value only once in each run, but share this updated counter value with all 4 methods.
Background
I am working on Iris dataset which looks like:
df = pd.read_csv(dataset)
features = df.iloc[:, 1:5].values
print(df.head())
Output
ID SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
1 5.1 3.5 1.4 0.2 Iris-setosa
2 4.9 3.0 1.4 0.2 Iris-setosa
3 4.7 3.2 1.3 0.2 Iris-setosa
I would like to retain each features for a particular time period (let’s say 50 ms) separately using a function (project requirement). To give you an example:
features[0,0] = 5.1 |
features[0,1] = 3.5 |
features[0,2] = 1.4 | -> from 0 to 0.049 (that's 50 ms, since python indexing starts from 0)
features[0,3] = 0.2 |
in the next run
features[1,0] = 4.9 |
features[1,1] = 3.0 |
features[1,2] = 1.4 | -> from 0.05 to 0.099
features[1,3] = 0.2 |
and so on for all 150 rows. I created a class called Datafeeder. I have two variable called window and counter which is explained in the code below.
class DataFeeder:
def __init__(self, window=50, time_step=1e-3, counter=0):
self.t = 0
self.idx = 0 # in this case, row index. For iris dataset it will be from 0 to 149, since there are 150 rows.
self.window = window # I want to keep each feature for 50 ms
self.time_step = time_step
self.counter = counter
def index(self):
self.idx = int(self.t / self.time_step)
# Example, run 1: self.idx = 0. Counter value is immediately updated, which is okay.
# Now, self.counter is 1.
# Run 2: self.idx = 1. The if condition is not satisfied, until self.idx = 50.
# The counter is updated to 2 after 50 ms
if self.idx % self.window == 0:
self.counter += 1
return self.counter
def sepal_length(self, t):
self.t = t
self.counter = self.index()
print(self.counter)
return features[self.counter % features.shape[0], 0]
def sepal_width(self, t):
self.t = t
self.counter = self.index()
return features[self.counter % features.shape[0], 1]
def petal_length(self, t):
self.t = t
self.counter = self.index()
return features[self.counter % features.shape[0], 2]
def petal_width(self, t):
self.t = t
self.counter = self.index()
return features[self.counter % features.shape[0], 3]
model = nengo.Network()
with model:
data_feeder = DataFeeder()
feature_1 = nengo.Node(output=data_feeder.sepal_length, label="Features 1")
feature_2 = nengo.Node(output=data_feeder.sepal_width, label="Features 2")
feature_3 = nengo.Node(output=data_feeder.petal_length, label="Features 3")
feature_4 = nengo.Node(output=data_feeder.petal_width, label="Features 4")
feature_1_probe = nengo.Probe(feature_1)
feature_2_probe = nengo.Probe(feature_2)
feature_3_probe = nengo.Probe(feature_3)
feature_4_probe = nengo.Probe(feature_4)
ens = nengo.Ensemble(n_neurons=10, dimensions=1, label="Encoder", neuron_type=nengo.LIF(amplitude=10))
ens_probe = nengo.Probe(ens)
ens_spikes = nengo.Probe(ens.neurons)
nengo.Connection(feature_1, ens)
nengo.Connection(feature_2, ens)
nengo.Connection(feature_3, ens)
nengo.Connection(feature_4, ens)
dt = 1e-3
with nengo.Simulator(model, dt=dt) as sim:
sim.run(dt * 1000) #14900
spike_count = np.sum(sim.data[ens_spikes] > 0, axis=0)
print(f'spike counts are {spike_count}')
The above code works as expected. But, the problem is
-
index function is called only in sepal_length function. If, for some reason, I decide not to use sepal_length feature in my code, the counter value wont be updated. Hence, not the efficient way of coding
-
If index method is called in all the method (i.e. sepal_length, sepal_width, petal_length and petal_width), the counter value is updated 4 times. So, run 1: features[1,0] for 50 ms. After 50 ms, features[4,0] etc which is not what I want.
Tried so far: In order to eliminate calling index method only in sepal_length method, I tried
- Updating the counter variable in init
- Calling index method in init
- Counter variable is made a class variable and then updating it in init
- Using everything, that’s in init, as a class variable
None of the above solutions worked for me. The counter value doesn’t update after 50 ms, unless it is done in one of the methods (i.e. sepal_length, sepal_width, petal_length and petal_width). self.t is updated inside the method (I checked), but not in init
Does anyone know how can I update the counter value only once in each run and without calling (index method) in any of the other methods, but share it among all the methods in the class?