I see that the build_dense function has been rewritten to better incorporate flatten layers. However, something about how the function has changed is leading to a drop in accuracy when I'm executing the example MNIST network.
When I replace the function with its old version, activation/SR correlation is much improved and accuracy is restored. I can't quite figure out why this is the case since it seems like the two functions should be doing the same thing when no flatten layer is involved.
New Brian2 build_dense function:
def build_dense(self, layer, weights=None):
if layer.activation == 'softmax':
raise warnings.warn("Activation 'softmax' not implemented. Using "
"'relu' activation instead.", RuntimeWarning)
_weights, biases = layer.get_weights()
if weights is None:
weights = _weights
set_biases(biases)
delay = self.config.getfloat('cell', 'delay')
connections = []
if len(self.flatten_shapes) == 1:
print("Swapping data_format of Flatten layer.")
flatten_name, shape = self.flatten_shapes.pop()
if self.data_format == 'channels_last':
y_in, x_in, f_in = shape
else:
f_in, y_in, x_in = shape
for i in range(weights.shape[0]): # Input neurons
# Sweep across channel axis of feature map. Assumes that each
# consecutive input neuron lies in a different channel. This is
# the case for channels_last, but not for channels_first.
f = i % f_in
# Sweep across height of feature map. Increase y by one if all
# rows along the channel axis were seen.
y = i // (f_in * x_in)
# Sweep across width of feature map.
x = (i // f_in) % x_in
new_i = f * x_in * y_in + x_in * y + x
for j in range(weights.shape[1]): # Output neurons
connections.append((new_i, j, weights[i, j], delay))
elif len(self.flatten_shapes) > 1:
raise RuntimeWarning("Not all Flatten layers have been consumed.")
else:
for i in range(weights.shape[0]):
for j in range(weights.shape[1]):
connections.append((i, j, weights[i, j], delay))
connections = np.array(connections)
self.connections[-1].connect(i=connections[:, 0].astype('int64'),
j=connections[:, 1].astype('int64'))
self.connections[-1].w = connections[:, 2]
The old function:
def build_dense(self, layer, input_weight=None):
if layer.activation == 'softmax':
raise warnings.warn("Activation 'softmax' not implemented. Using "
"'relu' activation instead.", RuntimeWarning)
weights, biases = layer.get_weights()
self.set_biases(biases)
self.connections[-1].connect(True)
if input_weight is not None:
self.connections[-1].w = input_weight.flatten()
else:
self.connections[-1].w = weights.flatten()
print("Lenght of weights:{}".format(len(self.connections[-1].w)))
This fix for the flatten layer was introduced because of a change in Keras. Please update your Keras version (I'm using 2.3.1) - the accuracy / correlation should then be OK.
I see that the build_dense function has been rewritten to better incorporate flatten layers. However, something about how the function has changed is leading to a drop in accuracy when I'm executing the example MNIST network.
When I replace the function with its old version, activation/SR correlation is much improved and accuracy is restored. I can't quite figure out why this is the case since it seems like the two functions should be doing the same thing when no flatten layer is involved.
New Brian2 build_dense function:
The old function:
New build_dense:
Old build_dense: