diff --git a/myproject/docker-compose.yml b/myproject/docker-compose.yml index 646ed6edf7373383aaeadede99e06f9863a8b147..976121da56f2d023d43a325fd7948e21340ea351 100644 --- a/myproject/docker-compose.yml +++ b/myproject/docker-compose.yml @@ -19,6 +19,7 @@ services: volumes: - .:/usr/src/app - static_volume:/usr/src/app/static + - ./models:/usr/src/app/models depends_on: - db - tensorflow_serving diff --git a/myproject/models/instrument_model/1/fingerprint.pb b/myproject/models/instrument_model/1/fingerprint.pb deleted file mode 100644 index 141b4c1792009ca22145b9f5ba9c01ed66ce207c..0000000000000000000000000000000000000000 --- a/myproject/models/instrument_model/1/fingerprint.pb +++ /dev/null @@ -1 +0,0 @@ -؋���������ס�ȭ��ʏ����� �Ԛ���ʘ�(����Ǜ 2 \ No newline at end of file diff --git a/myproject/models/instrument_model/1/keras_metadata.pb b/myproject/models/instrument_model/1/keras_metadata.pb index 4d889d7af020adb530b97500ddd438adb64c68a7..17c52e5f3ac95836f44215e4d16ccc8403689e22 100644 --- a/myproject/models/instrument_model/1/keras_metadata.pb +++ b/myproject/models/instrument_model/1/keras_metadata.pb @@ -1,7 +1,7 @@ -�\root"_tf_keras_sequential*�\{"name": "sequential", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": false, "class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_input"}}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 32, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "shared_object_id": 25, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "float32", "conv2d_input"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "float32", "conv2d_input"]}, "keras_version": "2.15.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_input"}, "shared_object_id": 0}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "shared_object_id": 4}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 5}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 6}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 7}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 8}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "shared_object_id": 9}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 10}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 11}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 12}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 13}, {"class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "shared_object_id": 14}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 15}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 16}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 17}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 18}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 32, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 19}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 20}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 21}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 22}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 23}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 24}]}}, "training_config": {"loss": {"class_name": "SparseCategoricalCrossentropy", "config": {"reduction": "auto", "name": "sparse_categorical_crossentropy", "from_logits": true, "ignore_class": null, "fn": "sparse_categorical_crossentropy"}, "shared_object_id": 27}, "metrics": [[{"class_name": "MeanMetricWrapper", "config": {"name": "accuracy", "dtype": "float32", "fn": "sparse_categorical_accuracy"}, "shared_object_id": 28}]], "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2 +�\root"_tf_keras_sequential*�\{"name": "sequential", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": false, "class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_input"}}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 32, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "shared_object_id": 25, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "float32", "conv2d_input"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 128, 44, 1]}, "float32", "conv2d_input"]}, "keras_version": "2.10.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_input"}, "shared_object_id": 0}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "shared_object_id": 4}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 5}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 6}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 7}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 8}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "shared_object_id": 9}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 10}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 11}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 12}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 13}, {"class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "shared_object_id": 14}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 64, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 15}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 16}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 17}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 18}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 32, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 19}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 20}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 21}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 22}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 23}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 24}]}}, "training_config": {"loss": {"class_name": "SparseCategoricalCrossentropy", "config": {"reduction": "auto", "name": "sparse_categorical_crossentropy", "from_logits": true, "ignore_class": null}, "shared_object_id": 27}, "metrics": [[{"class_name": "MeanMetricWrapper", "config": {"name": "accuracy", "dtype": "float32", "fn": "sparse_categorical_accuracy"}, "shared_object_id": 28}]], "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2 �root.layer_with_weights-0"_tf_keras_layer*� -{"name": "conv2d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 1}}, "shared_object_id": 29}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 44, 1]}}2 +{"name": "conv2d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 128, 44, 1]}, "dtype": "float32", "filters": 32, "kernel_size": {"class_name": "__tuple__", "items": [3, 3]}, "strides": {"class_name": "__tuple__", "items": [1, 1]}, "padding": "valid", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1, 1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 2}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 3, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 4, "axes": {"-1": 1}}, "shared_object_id": 29}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 128, 44, 1]}}2 �root.layer-1"_tf_keras_layer*�{"name": "max_pooling2d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": {"class_name": "__tuple__", "items": [2, 2]}, "padding": "valid", "strides": {"class_name": "__tuple__", "items": [2, 2]}, "data_format": "channels_last"}, "shared_object_id": 4, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 4, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 30}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 126, 42, 32]}}2 �root.layer-2"_tf_keras_layer*�{"name": "dropout", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 5, "build_input_shape": {"class_name": "TensorShape", "items": [null, 63, 21, 32]}}2 � @@ -16,5 +16,5 @@ root.layer-9"_tf_keras_layer*�{"name": "dropout_2", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "shared_object_id": 18, "build_input_shape": {"class_name": "TensorShape", "items": [null, 64]}}2 �root.layer_with_weights-4"_tf_keras_layer*�{"name": "dense_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 32, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 19}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 20}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 21, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 64}}, "shared_object_id": 36}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 64]}}2 �root.layer_with_weights-5"_tf_keras_layer*�{"name": "dense_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "preserve_input_structure_in_config": false, "autocast": true, "class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 22}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 23}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 24, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 32}}, "shared_object_id": 37}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 32]}}2 -��root.keras_api.metrics.0"_tf_keras_metric*�{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 38}2 -��root.keras_api.metrics.1"_tf_keras_metric*�{"class_name": "MeanMetricWrapper", "name": "accuracy", "dtype": "float32", "config": {"name": "accuracy", "dtype": "float32", "fn": "sparse_categorical_accuracy"}, "shared_object_id": 28}2 \ No newline at end of file +��root.keras_api.metrics.0"_tf_keras_metric*�{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 38}2 +��root.keras_api.metrics.1"_tf_keras_metric*�{"class_name": "MeanMetricWrapper", "name": "accuracy", "dtype": "float32", "config": {"name": "accuracy", "dtype": "float32", "fn": "sparse_categorical_accuracy"}, "shared_object_id": 28}2 \ No newline at end of file diff --git a/myproject/models/instrument_model/1/saved_model.pb b/myproject/models/instrument_model/1/saved_model.pb index 17ff0d94c083b07b5eb7f1a9348cfb36fa15d532..334a4f1e41dcb57d38aabfc36e2e0af32608617f 100644 Binary files a/myproject/models/instrument_model/1/saved_model.pb and b/myproject/models/instrument_model/1/saved_model.pb differ diff --git a/myproject/models/instrument_model/1/variables/variables.data-00000-of-00001 b/myproject/models/instrument_model/1/variables/variables.data-00000-of-00001 index ad1698fc39af144e83ea1bf207d1908eb51d22c4..6535da5d890975b1eaa6fc5060823c7a6d1018ed 100644 Binary files a/myproject/models/instrument_model/1/variables/variables.data-00000-of-00001 and b/myproject/models/instrument_model/1/variables/variables.data-00000-of-00001 differ diff --git a/myproject/models/instrument_model/1/variables/variables.index b/myproject/models/instrument_model/1/variables/variables.index index 6a8d3e1a107e9ba3b6a210b1af5d176f97f9ef14..28f23f1867b3715a930109b4857a14a0756441ef 100644 Binary files a/myproject/models/instrument_model/1/variables/variables.index and b/myproject/models/instrument_model/1/variables/variables.index differ diff --git a/myproject/myapp/migrations/0002_modelconfig.py b/myproject/myapp/migrations/0002_modelconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..cc16f7a5eda2b34e9d8219d77e9c5c2820e59a04 --- /dev/null +++ b/myproject/myapp/migrations/0002_modelconfig.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.1 on 2024-04-30 23:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('myapp', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ModelConfig', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('selected_model_version', models.CharField(default='2', max_length=255)), + ], + ), + ] diff --git a/myproject/myapp/migrations/0003_modelperformancemetrics.py b/myproject/myapp/migrations/0003_modelperformancemetrics.py new file mode 100644 index 0000000000000000000000000000000000000000..bbaaf929c12d6ca636204521578361f546fef8ba --- /dev/null +++ b/myproject/myapp/migrations/0003_modelperformancemetrics.py @@ -0,0 +1,25 @@ +# Generated by Django 5.0.1 on 2024-05-01 00:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('myapp', '0002_modelconfig'), + ] + + operations = [ + migrations.CreateModel( + name='ModelPerformanceMetrics', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('request_count', models.IntegerField(default=0)), + ('request_latency_sum', models.FloatField(default=0)), + ('request_latency_count', models.IntegerField(default=0)), + ('runtime_latency_sum', models.FloatField(default=0)), + ('runtime_latency_count', models.IntegerField(default=0)), + ('model_load_latency', models.FloatField(default=0)), + ], + ), + ] diff --git a/myproject/myapp/migrations/0004_payment.py b/myproject/myapp/migrations/0004_payment.py new file mode 100644 index 0000000000000000000000000000000000000000..1e06945e7015f4dbcd1d774d1e6e1b6a4c2a2b61 --- /dev/null +++ b/myproject/myapp/migrations/0004_payment.py @@ -0,0 +1,27 @@ +# Generated by Django 5.0.1 on 2024-05-01 00:39 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('myapp', '0003_modelperformancemetrics'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Payment', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('payment_id', models.CharField(max_length=255)), + ('payer_id', models.CharField(max_length=255)), + ('date', models.DateTimeField(auto_now_add=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/myproject/myapp/models.py b/myproject/myapp/models.py index 326123a737d7ef7aca00446c56a78ff39684017b..a67236e7fa208922c551b56bb7d1b251c14fd2ff 100644 --- a/myproject/myapp/models.py +++ b/myproject/myapp/models.py @@ -57,3 +57,43 @@ class Log(models.Model): log = models.JSONField() feedback = models.BooleanField(null=True) +class ModelConfig(models.Model): + selected_model_version = models.CharField(max_length=255, default='2') + + def save(self, *args, **kwargs): + # Ensure there's only one instance of ModelConfig + self.pk = 1 + super().save(*args, **kwargs) + + @classmethod + def load(cls): + obj, _ = cls.objects.get_or_create(pk=1) + return obj + +class ModelPerformanceMetrics(models.Model): + request_count = models.IntegerField(default=0) + request_latency_sum = models.FloatField(default=0) + request_latency_count = models.IntegerField(default=0) + runtime_latency_sum = models.FloatField(default=0) + runtime_latency_count = models.IntegerField(default=0) + model_load_latency = models.FloatField(default=0) + + def reset_metrics(self): + self.request_count = 0 + self.request_latency_sum = 0 + self.request_latency_count = 0 + self.runtime_latency_sum = 0 + self.runtime_latency_count = 0 + self.model_load_latency = 0 + self.save(force_update=True) + +class Payment(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE) + amount = models.DecimalField(max_digits=10, decimal_places=2) + payment_id = models.CharField(max_length=255) + payer_id = models.CharField(max_length=255) + date = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f'Payment by {self.user.username} - Amount: {self.amount}' + diff --git a/myproject/myapp/payments.py b/myproject/myapp/payments.py index dd8e0026c63867cf88788ec2b0979647e3b6c11b..b1108fd9e985622974b0b69dfa042f426da12ac8 100644 --- a/myproject/myapp/payments.py +++ b/myproject/myapp/payments.py @@ -5,6 +5,7 @@ from django.shortcuts import redirect, render from django.urls import reverse from django.shortcuts import redirect, render from django.urls import reverse +from .models import Action, UserTokenCount, Payment from .views import get_log_data, create_log from .models import UserTokenCount, Action from rest_framework.response import Response @@ -82,12 +83,56 @@ def create_payment(request, purchase_type): # Execute a successful payment +# def execute_payment(request): +# # Get payment id and payer id +# payment_id = request.GET.get('paymentId') +# payer_id = request.GET.get('PayerID') + +# #If neither ID, error, restart +# if not payment_id or not payer_id: +# print("no payment") +# #TODO: Change this to a more appropriate path, maybe a generic error page that takes a string:Error to display in a template +# return redirect('handler404') + +# # configure API +# paypalrestsdk.configure({ +# "mode": settings.PAYPAL_MODE, +# "client_id": settings.PAYPAL_CLIENT_ID, +# "client_secret": settings.PAYPAL_CLIENT_SECRET +# }) + +# # Check we've got a successful payment +# payment = paypalrestsdk.Payment.find(payment_id) + +# # If it we do an the payer IDs match +# if payment.execute({"payer_id": payer_id}): +# print("Payment executed successfully!") + +# # Allocate some tokens +# user = request.user +# tokens_purchased = 1 + +# # increment user_tokens +# # commit changes +# # TODO: Change something here such that the token amount added depends on a detail of the transaction, +# # i.e. £9.99 payment for one token or £24.99 for +# # +# if request.user.is_authenticated: +# add_tokens(user, tokens_purchased) +# return redirect('success') +# else: +# return redirect('handler404') +# else: +# #TODO: Change this to a more appropriate error message +# print("exiting at the end of execute_payment()") +# return redirect('handler404') + def execute_payment(request): # Get payment id and payer id payment_id = request.GET.get('paymentId') payer_id = request.GET.get('PayerID') - #If neither ID, error, restart + # If neither ID, error, restart if not payment_id or not payer_id: print("no payment id or payer_id") return Response({"error": "Error: No payment id or payer id was found."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) @@ -102,7 +147,7 @@ def execute_payment(request): # Check we've got a successful payment payment = paypalrestsdk.Payment.find(payment_id) - # If it we do an the payer IDs match + # If it we do and the payer IDs match if payment.execute({"payer_id": payer_id}): print("Payment executed successfully!") print(f"Payment: {payment}") @@ -124,7 +169,6 @@ def execute_payment(request): print("exiting at the end of execute_payment(), incorrect payer id") return Response({"error": "Error: Payment failed to execute, incorrect payer id"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - def add_tokens(user, tokens): token_count_instance, created = UserTokenCount.objects.get_or_create(user=user) token_count_instance.token_count += int(tokens) diff --git a/myproject/myapp/templates/model_performance.html b/myproject/myapp/templates/model_performance.html index 493a96fefbcdd6400b46e9557fba667aa6001aae..30d0227a9162012986db987ee01335e57d991cd3 100644 --- a/myproject/myapp/templates/model_performance.html +++ b/myproject/myapp/templates/model_performance.html @@ -1,18 +1,26 @@ +<!-- model_performance.html --> {% extends "_base.html" %} {% block content %} <div class="container mx-auto px-4"> - <h1 class="text-2xl font-bold mb-4">Model Performance</h1> - - {% if metrics %} + <h1 class="text-2xl font-bold mb-4">Model Performance</h1> + + {% if metrics %} <div class="bg-white shadow-md rounded p-6"> - <p><strong>Request Count:</strong> {{ metrics.request_count }}</p> - <p><strong>Average Request Latency:</strong> {{ metrics.avg_request_latency|floatformat:6 }} seconds</p> - <p><strong>Average Runtime Latency:</strong> {{ metrics.avg_runtime_latency|floatformat:6 }} seconds</p> - <p><strong>Model Load Latency:</strong> {{ metrics.model_load_latency|floatformat:6 }} seconds</p> + <p><strong>Request Count:</strong> {{ metrics.request_count }}</p> + <p><strong>Average Request Latency:</strong> {{ metrics.avg_request_latency|floatformat:6 }} seconds</p> + <p><strong>Average Runtime Latency:</strong> {{ metrics.avg_runtime_latency|floatformat:6 }} seconds</p> + <p><strong>Model Load Latency:</strong> {{ metrics.model_load_latency|floatformat:6 }} seconds</p> </div> - {% else %} + {% else %} <p>Failed to retrieve model performance metrics.</p> - {% endif %} + {% endif %} + + <form method="post" action="{% url 'model_performance' %}" class="mt-4"> + {% csrf_token %} + <button type="submit" name="reset_metrics" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> + Reset Metrics + </button> + </form> </div> {% endblock content %} \ No newline at end of file diff --git a/myproject/myapp/templates/model_selection.html b/myproject/myapp/templates/model_selection.html new file mode 100644 index 0000000000000000000000000000000000000000..d14c882f552a27e1260ecb0641f247918004229b --- /dev/null +++ b/myproject/myapp/templates/model_selection.html @@ -0,0 +1,15 @@ +{% extends '_base.html' %} + +{% block content %} + <h1>Model Version Selection</h1> + <form method="post"> + {% csrf_token %} + <label for="model_version">Select Model Version:</label> + <select name="model_version" id="model_version"> + {% for version in model_versions %} + <option value="{{ version }}" {% if selected_model_version == version %}selected{% endif %}>{{ version }}</option> + {% endfor %} + </select> + <button type="submit">Save</button> + </form> +{% endblock %} \ No newline at end of file diff --git a/myproject/myapp/templates/user_page.html b/myproject/myapp/templates/user_page.html index 94fff4c7e67ee2c07c291645b76abd1283521393..987c029969c603ccae4006aaed7ba29cd5c26af4 100644 --- a/myproject/myapp/templates/user_page.html +++ b/myproject/myapp/templates/user_page.html @@ -1,4 +1,6 @@ -{% extends "_base.html" %} {% block content %} +<!-- user_page.html --> +{% extends "_base.html" %} +{% block content %} <div class="grid grid-cols-1 px-4 pt-6 xl:grid-cols-3 xl:gap-4 dark:bg-grey-300" > @@ -33,7 +35,13 @@ <h3 class="mb-4 text-xl font-semibold dark:text-white">Change your password</h3> <a href="{% url 'password_change' %}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Change Password</a> </div> - + + {% if user_profile.user_type == 2 or user.is_superuser %} + <div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800"> + <h3 class="mb-4 text-xl font-semibold dark:text-white">Model Selection</h3> + <a href="{% url 'model_selection' %}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Select Model</a> + </div> + {% endif %} {% if user_profile.user_type == 3 or user.is_superuser or user_profile.user_type == 1%} <div diff --git a/myproject/myapp/urls.py b/myproject/myapp/urls.py index 6a58000925a139ce144b37b3bffe66981948f90a..a7c38d019e636e988f655430977fb3a3eca36243 100644 --- a/myproject/myapp/urls.py +++ b/myproject/myapp/urls.py @@ -1,5 +1,5 @@ from django.urls import path -from .views import InstrumentDetectionView, ModelPerformanceView, index, log_fileupload, users, maintenance, \ +from .views import InstrumentDetectionView, ModelPerformanceView, ModelSelectionView, index, log_fileupload, users, maintenance, \ handler404, handler500, terms_conditions, privacy_policy, pricing, generate_pdf, admin_table,\ change_user_type, submit_feedback from .payments import create_payment, execute_payment, payment_cancelled, payment_success @@ -26,6 +26,7 @@ urlpatterns = [ path('generate_pdf/', generate_pdf, name='generate_pdf'), path('instrument_detection/', InstrumentDetectionView.as_view(), name='instrument_detection'), path('model_performance/', ModelPerformanceView.as_view(), name='model_performance'), + path('model_selection/', ModelSelectionView.as_view(), name='model_selection'), path('password_change/', auth_views.PasswordChangeView.as_view(template_name='password_change_form.html'), name='password_change'), path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='password_change_done.html'), name='password_change_done'), diff --git a/myproject/myapp/views.py b/myproject/myapp/views.py index f89359211c1c844ac595562a1a452dee9ecffbd0..e65ac6c9f5be9c7e24b166b5748322c5aaa0721a 100644 --- a/myproject/myapp/views.py +++ b/myproject/myapp/views.py @@ -1,3 +1,5 @@ +# views.py +import os from django.contrib.auth import authenticate, login, logout from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User @@ -12,7 +14,7 @@ import json from datetime import datetime from .forms import InstrumentDetectionForm -from .models import Log, Action, User, UserTokenCount, Profile +from .models import Log, Action, User, UserTokenCount, Profile, ModelConfig, ModelPerformanceMetrics from django.http import JsonResponse from django.db import connection @@ -26,8 +28,8 @@ import requests # Authentication Imports from django.urls import reverse_lazy -from django.views import generic -from .models import Profile +from django.views import View, generic +from .models import Profile, ModelConfig from .forms import UserRegisterForm, LoginAuthenticationForm from django.contrib.auth.views import LoginView from django.views.decorators.csrf import csrf_exempt @@ -370,42 +372,50 @@ class InstrumentDetectionView(APIView): else: return super().dispatch(request, *args, **kwargs) def post(self, request): - # Get the user's token count - user_token_count = UserTokenCount.objects.get(user=request.user) - - # Decrease the user's token count by one - user_token_count.token_count -= 1 - user_token_count.save() - - serializer = InstrumentDetectionSerializer(data=request.data) - if serializer.is_valid(): - audio_file = serializer.validated_data['audio_file'] - - # Save the uploaded file temporarily - # with open('temp_audio.wav', 'wb') as f: - # f.write(audio_file.read()) - - # Preprocess the audio file - preprocessed_data = preprocess_audio_for_inference(audio_file) - - # Prepare data for TensorFlow Serving - data = json.dumps({"signature_name": "serving_default", "instances": [window.tolist() for window in preprocessed_data]}) - - # Send request to TensorFlow Serving - url = 'http://tensorflow_serving:8501/v1/models/instrument_model/versions/2:predict' - headers = {"Content-Type": "application/json"} - response = requests.post(url, data=data, headers=headers) - - # Process the response - if response.status_code == 200: - raw_predictions = response.json()['predictions'] - # Convert raw prediction numbers into percentages - formatted_predictions = self.format_predictions(raw_predictions) - return Response({"predictions": formatted_predictions}, status=status.HTTP_200_OK) - else: - return Response({"error": "Failed to get predictions"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) - - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + try: + model_config = ModelConfig.load() + selected_model_version = model_config.selected_model_version + # Get the user's token count + user_token_count = UserTokenCount.objects.get(user=request.user) + + # Decrease the user's token count by one + user_token_count.token_count -= 1 + user_token_count.save() + + serializer = InstrumentDetectionSerializer(data=request.data) + if serializer.is_valid(): + audio_file = serializer.validated_data['audio_file'] + + # Save the uploaded file temporarily + # with open('temp_audio.wav', 'wb') as f: + # f.write(audio_file.read()) + + # Preprocess the audio file + preprocessed_data = preprocess_audio_for_inference(audio_file) + + # Prepare data for TensorFlow Serving + data = json.dumps({"signature_name": "serving_default", "instances": [window.tolist() for window in preprocessed_data]}) + + # Send request to TensorFlow Serving + # url = 'http://tensorflow_serving:8501/v1/models/instrument_model/versions/2:predict' + url = f'http://tensorflow_serving:8501/v1/models/instrument_model/versions/{selected_model_version}:predict' + headers = {"Content-Type": "application/json"} + response = requests.post(url, data=data, headers=headers) + + # Process the response + if response.status_code == 200: + print('Predictions received') + raw_predictions = response.json()['predictions'] + # Convert raw prediction numbers into percentages + formatted_predictions = self.format_predictions(raw_predictions) + return Response({"predictions": formatted_predictions}, status=status.HTTP_200_OK) + else: + return Response({"error": "Failed to get predictions"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + except Exception as e: + logger.error(f"An error occurred: {e}") + messages.error(request, 'An error occurred: {e}') + return redirect('index') def format_predictions(self, predictions): @@ -433,10 +443,10 @@ class ModelPerformanceView(UserPassesTestMixin, TemplateView): def dispatch(self, request, *args, **kwargs): if request.user.is_anonymous: - messages.info(request, 'Must be logged in as an ML Engineer or Admin to access this page.') + messages.info(request, 'Must be logged in as an ML Engineer or Superuser to access this page.') return redirect('login') elif request.user.profile.user_type != 2 and not request.user.is_superuser: - messages.info(request, 'Must be logged in as an ML Engineer or Admin to access this page.') + messages.info(request, 'Must be logged in as an ML Engineer or Superuser to access this page.') return redirect('users') else: return super().dispatch(request, *args, **kwargs) @@ -461,21 +471,73 @@ class ModelPerformanceView(UserPassesTestMixin, TemplateView): runtime_latency_count = re.search(r':tensorflow:serving:runtime_latency_count{model_name="instrument_model",API="Predict",runtime="TF1"} (\d+)', metrics_data) model_load_latency = re.search(r':tensorflow:cc:saved_model:load_latency{model_path="/models/instrument_model/2"} (\d+)', metrics_data) + # Get or create the ModelPerformanceMetrics instance + metrics, _ = ModelPerformanceMetrics.objects.get_or_create(pk=1) + + # Update the metrics in the database + metrics.request_count = int(request_count.group(1)) if request_count else 0 + metrics.request_latency_sum = float(request_latency_sum.group(1)) if request_latency_sum else 0 + metrics.request_latency_count = int(request_latency_count.group(1)) if request_latency_count else 0 + metrics.runtime_latency_sum = float(runtime_latency_sum.group(1)) if runtime_latency_sum else 0 + metrics.runtime_latency_count = int(runtime_latency_count.group(1)) if runtime_latency_count else 0 + metrics.model_load_latency = float(model_load_latency.group(1)) if model_load_latency else 0 + metrics.save() + # Calculate average latencies in seconds - avg_request_latency = float(request_latency_sum.group(1)) / float(request_latency_count.group(1)) / 1e6 if request_latency_sum and request_latency_count else None - avg_runtime_latency = float(runtime_latency_sum.group(1)) / float(runtime_latency_count.group(1)) / 1e6 if runtime_latency_sum and runtime_latency_count else None - model_load_latency_seconds = float(model_load_latency.group(1)) / 1e6 if model_load_latency else None + avg_request_latency = metrics.request_latency_sum / metrics.request_latency_count / 1e6 if metrics.request_latency_count else None + avg_runtime_latency = metrics.runtime_latency_sum / metrics.runtime_latency_count / 1e6 if metrics.runtime_latency_count else None context['metrics'] = { - 'request_count': request_count.group(1) if request_count else None, + 'request_count': metrics.request_count, 'avg_request_latency': avg_request_latency, 'avg_runtime_latency': avg_runtime_latency, - 'model_load_latency': model_load_latency_seconds + 'model_load_latency': metrics.model_load_latency / 1e6 } else: context['metrics'] = None return context + def post(self, request, *args, **kwargs): + if 'reset_metrics' in request.POST: + metrics = ModelPerformanceMetrics.objects.get(pk=1) + metrics.reset_metrics() + metrics.save() + return redirect('users') + else: + messages.error(request, 'Invalid request') + return redirect('users') + +class ModelSelectionView(UserPassesTestMixin, View): + def dispatch(self, request, *args, **kwargs): + if request.user.is_anonymous: + messages.info(request, 'Must be logged in as an ML Engineer or Superuser to access this page.') + return redirect('login') + elif request.user.profile.user_type != 2 and not request.user.is_superuser: + messages.info(request, 'Must be logged in as an ML Engineer or Superuser to access this page.') + return redirect('users') + else: + return super().dispatch(request, *args, **kwargs) + + def test_func(self): + return self.request.user.is_authenticated and self.request.user.profile.user_type == 2 + + def get(self, request): + model_versions = os.listdir('models/instrument_model') + model_config = ModelConfig.load() + context = { + 'model_versions': model_versions, + 'selected_model_version': model_config.selected_model_version, + } + return render(request, 'model_selection.html', context) + + def post(self, request): + selected_model_version = request.POST.get('model_version') + model_config = ModelConfig.load() + model_config.selected_model_version = selected_model_version + model_config.save() + return redirect('model_selection') + + def change_user_type(request, user_id): if request.method == 'POST': @@ -487,7 +549,4 @@ def change_user_type(request, user_id): def user_has_credits(): has_credits = False - - - return has_credits