diff --git a/dnn/dump_lpcnet.py b/dnn/dump_lpcnet.py index 936074c7..d16a8a2d 100755 --- a/dnn/dump_lpcnet.py +++ b/dnn/dump_lpcnet.py @@ -12,6 +12,9 @@ import keras.backend as K import h5py import re +max_rnn_neurons = 1 +max_conv_inputs = 1 + def printVector(f, vector, name): v = np.reshape(vector, (-1)); #print('static const float ', name, '[', len(v), '] = \n', file=f) @@ -36,6 +39,7 @@ def dump_layer_ignore(self, f, hf): Layer.dump_layer = dump_layer_ignore def dump_gru_layer(self, f, hf): + global max_rnn_neurons name = self.name print("printing layer " + name + " of type " + self.__class__.__name__) weights = self.get_weights() @@ -50,9 +54,12 @@ def dump_gru_layer(self, f, hf): reset_after = 0 else: reset_after = 1 + neurons = weights[0].shape[1]//3 + max_rnn_neurons = max(max_rnn_neurons, neurons) f.write('const GRULayer {} = {{\n {}_bias,\n {}_weights,\n {}_recurrent_weights,\n {}, {}, ACTIVATION_{}, {}\n}};\n\n' .format(name, name, name, name, weights[0].shape[0], weights[0].shape[1]//3, activation, reset_after)) - hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) + hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) + hf.write('#define {}_STATE_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) hf.write('extern const GRULayer {};\n\n'.format(name)); return True CuDNNGRU.dump_layer = dump_gru_layer @@ -67,7 +74,7 @@ def dump_dense_layer(self, f, hf): activation = self.activation.__name__.upper() f.write('const DenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, weights[0].shape[0], weights[0].shape[1], activation)) - hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1])) + hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1])) hf.write('extern const DenseLayer {};\n\n'.format(name)); return False Dense.dump_layer = dump_dense_layer @@ -82,23 +89,26 @@ def dump_mdense_layer(self, f, hf): activation = self.activation.__name__.upper() f.write('const MDenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}_factor,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, name, weights[0].shape[0], weights[0].shape[1], weights[0].shape[2], activation)) - hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[0])) + hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[0])) hf.write('extern const MDenseLayer {};\n\n'.format(name)); return False MDense.dump_layer = dump_mdense_layer def dump_conv1d_layer(self, f, hf): + global max_conv_inputs name = self.name print("printing layer " + name + " of type " + self.__class__.__name__) weights = self.get_weights() printVector(f, weights[0], name + '_weights') printVector(f, weights[-1], name + '_bias') activation = self.activation.__name__.upper() + max_conv_inputs = max(max_conv_inputs, weights[0].shape[1]*weights[0].shape[0]) f.write('const Conv1DLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, weights[0].shape[1], weights[0].shape[0], weights[0].shape[2], activation)) - hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1])) + hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[2])) + hf.write('#define {}_STATE_SIZE ({}*{})\n'.format(name.upper(), weights[0].shape[1], (weights[0].shape[0]-1))) hf.write('extern const Conv1DLayer {};\n\n'.format(name)); - return False + return True Conv1D.dump_layer = dump_conv1d_layer @@ -109,7 +119,7 @@ def dump_embedding_layer(self, f, hf): printVector(f, weights[0], name + '_weights') f.write('const EmbeddingLayer {} = {{\n {}_weights,\n {}, {}\n}};\n\n' .format(name, name, weights[0].shape[0], weights[0].shape[1])) - hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1])) + hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1])) hf.write('extern const EmbeddingLayer {};\n\n'.format(name)); return False Embedding.dump_layer = dump_embedding_layer @@ -125,7 +135,6 @@ f = open(sys.argv[2], 'w') hf = open(sys.argv[3], 'w') - f.write('/*This file is automatically generated from a Keras model*/\n\n') f.write('#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n#include "nnet.h"\n#include "foo.h"\n\n') @@ -137,9 +146,12 @@ for i, layer in enumerate(model.layers): if layer.dump_layer(f, hf): layer_list.append(layer.name) +hf.write('#define MAX_RNN_NEURONS {}\n\n'.format(max_rnn_neurons)) +hf.write('#define MAX_CONV_INPUTS {}\n\n'.format(max_conv_inputs)) + hf.write('struct RNNState {\n') for i, name in enumerate(layer_list): - hf.write(' float {}_state[{}_SIZE];\n'.format(name, name.upper())) + hf.write(' float {}_state[{}_STATE_SIZE];\n'.format(name, name.upper())) hf.write('};\n') hf.write('\n\n#endif\n') diff --git a/dnn/nnet.c b/dnn/nnet.c index 9c567687..b1b945fb 100644 --- a/dnn/nnet.c +++ b/dnn/nnet.c @@ -157,11 +157,11 @@ void compute_gru(const GRULayer *gru, float *state, const float *input) int i; int N, M; int stride; - float tmp[MAX_NEURONS]; - float z[MAX_NEURONS]; - float r[MAX_NEURONS]; - float h[MAX_NEURONS]; - celt_assert(gru->nb_neurons <= MAX_NEURONS); + float tmp[MAX_RNN_NEURONS]; + float z[MAX_RNN_NEURONS]; + float r[MAX_RNN_NEURONS]; + float h[MAX_RNN_NEURONS]; + celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS); M = gru->nb_inputs; N = gru->nb_neurons; stride = 3*N; diff --git a/dnn/nnet.h b/dnn/nnet.h index 18916470..a3666825 100644 --- a/dnn/nnet.h +++ b/dnn/nnet.h @@ -28,9 +28,6 @@ #ifndef _NNET_H_ #define _NNET_H_ -#define MAX_NEURONS 1024 -#define MAX_CONV_INPUTS 1024 - #define ACTIVATION_LINEAR 0 #define ACTIVATION_SIGMOID 1 #define ACTIVATION_TANH 2