Edge Impulse Experts / Adiuvo_BrainChip_VWW Public

Training settings

Please provide a valid number of training cycles (numeric only)
Please provide a valid number for the learning rate (between 0 and 1)
Please provide a valid training processor option

Augmentation settings

Advanced training settings

Neural network architecture

import math, random import tensorflow as tf from tensorflow.keras.layers import Activation, Dropout, Flatten, Reshape from tensorflow.keras.optimizers import Adam from keras import Model from keras.layers import Activation, Dropout, Reshape, Flatten from akida_models.layer_blocks import dense_block from akida_models import akidanet_imagenet from ei_tensorflow import training import cnn2snn BATCH_SIZE = 32 #! Implements the data augmentation policy def augmentation_function(input_shape: tuple): def augment_image(image, label): image = tf.image.random_flip_left_right(image) #! Increase the image size, then randomly crop it down to #! the original dimensions resize_factor = random.uniform(1, 1.2) new_height = math.floor(resize_factor * input_shape[0]) new_width = math.floor(resize_factor * input_shape[1]) image = tf.image.resize_with_crop_or_pad(image, new_height, new_width) image = tf.image.random_crop(image, size=input_shape) #! Vary the brightness of the image image = tf.image.random_brightness(image, max_delta=0.2) return image, label return augment_image def train(train_dataset: tf.data.Dataset, validation_dataset: tf.data.Dataset, num_classes: int, pretrained_weights: str, input_shape: tuple, learning_rate: int, epochs: int, dense_layer_neurons: int, dropout: float, data_augmentation: bool, callbacks, alpha: float, best_model_path: str, quantize_function, qat_function, edge_learning_function=None, additional_classes=None, neurons_per_class=None, X_train=None): #! Create a quantized base model without top layers base_model = akidanet_imagenet(input_shape=input_shape, classes=num_classes, alpha=alpha, include_top=False, input_scaling=None, pooling='avg') #add gamma constraint # from akida_models import add_gamma_constraint # base_model = add_gamma_constraint(base_model) import akida print(akida.__version__) base_model.summary() base_model.load_weights(pretrained_weights, by_name=True, skip_mismatch=True) base_model.summary() #! Freeze that base model, so it won't be trained base_model.trainable = False output_model = base_model.output output_model = Flatten()(output_model) if dense_layer_neurons > 0: output_model = dense_block(output_model, units=dense_layer_neurons, add_batchnorm=False, add_activation=True) if dropout > 0: output_model = Dropout(dropout)(output_model) output_model = dense_block(output_model, units=num_classes, add_batchnorm=False, add_activation=False) output_model = Activation('softmax')(output_model) output_model = Reshape((num_classes,))(output_model) #! Build the model model = Model(base_model.input, output_model) opt = Adam(learning_rate=learning_rate) model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy']) if data_augmentation: train_dataset = train_dataset.map(augmentation_function(input_shape), num_parallel_calls=tf.data.AUTOTUNE) #! This controls the batch size, or you can manipulate the tf.data.Dataset objects yourself train_dataset = train_dataset.batch(BATCH_SIZE, drop_remainder=False) validation_dataset = validation_dataset.batch(BATCH_SIZE, drop_remainder=False) #! Train the neural network model.fit(train_dataset, epochs=epochs, validation_data=validation_dataset, verbose=2, callbacks=callbacks) print('') print('Initial training done.', flush=True) print('') #! Unfreeze the model before QAT model.trainable = False #! Quantize model to 4/4/8 akida_model = quantize_function(keras_model=model) akida_model.summary() #! Do a quantization-aware training akida_model = qat_function(akida_model=akida_model, train_dataset=train_dataset, validation_dataset=validation_dataset, optimizer=Adam(learning_rate=learning_rate), fine_tune_loss='categorical_crossentropy', fine_tune_metrics=['accuracy'], callbacks=callbacks) #! Optionally, build the edge learning model if edge_learning_function: akida_edge_model = edge_learning_function(quantized_model=akida_model, X_train=X_train, train_dataset=train_dataset, validation_dataset=validation_dataset, callbacks=callbacks, optimizer=opt, fine_tune_loss='categorical_crossentropy', fine_tune_metrics=['accuracy'], additional_classes=additional_classes, neurons_per_class=neurons_per_class, num_classes=num_classes, qat_function=qat_function) else: akida_edge_model = None return model, akida_model, akida_edge_model import tensorflow as tf def akida_quantize_model( keras_model, weight_quantization: int = 4, activ_quantization: int = 4, input_weight_quantization: int = 8, ): import cnn2snn print("Performing post-training quantization...") akida_model = cnn2snn.quantize( keras_model, weight_quantization=weight_quantization, activ_quantization=activ_quantization, input_weight_quantization=input_weight_quantization, ) print("Performing post-training quantization OK") print("") return akida_model def akida_perform_qat( akida_model, train_dataset: tf.data.Dataset, validation_dataset: tf.data.Dataset, optimizer: str, fine_tune_loss: str, fine_tune_metrics: "list[str]", callbacks, stopping_metric: str = "val_accuracy", fit_verbose: int = 2, qat_epochs: int = 2#30, ): early_stopping = tf.keras.callbacks.EarlyStopping( monitor=stopping_metric, mode="max", verbose=1, min_delta=0, patience=10, restore_best_weights=True, ) callbacks.append(early_stopping) print("Running quantization-aware training...") akida_model.compile( optimizer=optimizer, loss=fine_tune_loss, metrics=fine_tune_metrics ) akida_model.fit( train_dataset, epochs=qat_epochs, verbose=fit_verbose, validation_data=validation_dataset, callbacks=callbacks, ) print("Running quantization-aware training OK") print("") return akida_model EPOCHS = 20#args.epochs or 20 LEARNING_RATE = args.learning_rate or 0.001 # Available pretrained_weights are: # akidanet_imagenet_224_alpha_100.h5 - float32 model, 224x224x3, alpha=1.00 # akidanet_imagenet_224_alpha_50.h5 - float32 model, 224x224x3, alpha=0.50 # akidanet_imagenet_224_alpha_25.h5 - float32 model, 224x224x3, alpha=0.25 # akidanet_imagenet_160_alpha_100.h5 - float32 model, 160x160x3, alpha=1.00 # akidanet_imagenet_160_alpha_50.h5 - float32 model, 160x160x3, alpha=0.50 # akidanet_imagenet_160_alpha_25.h5 - float32 model, 160x160x3, alpha=0.25 model, akida_model, akida_edge_model = train(train_dataset=train_dataset, validation_dataset=validation_dataset, num_classes=classes, pretrained_weights='./transfer-learning-weights/akidanet/akidanet_imagenet_160_alpha_25.h5', input_shape=(160, 160, 3,), learning_rate=LEARNING_RATE, epochs=EPOCHS, dense_layer_neurons=0, dropout=0.1, data_augmentation=True, callbacks=callbacks, alpha=0.25, best_model_path=BEST_MODEL_PATH, quantize_function=akida_quantize_model, qat_function=akida_perform_qat, edge_learning_function=None, additional_classes=None, neurons_per_class=None, X_train=X_train)
Input layer (27,648 features)
AkidaNet (alpha=0.25) @160x160x3 (no final dense layer, 0.1 dropout)
Output layer (2 classes)