Files
AI-on-the-edge-device/pmd-effnet-zca.ipynb
2022-05-24 21:41:45 +02:00

1 line
15 KiB
Plaintext

{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"#### About\n\nUsing effnet model.\n\naugmentation uses sca and standard augmentations + invert. \n\nValidation data has no augmentations","metadata":{"papermill":{"duration":0.022496,"end_time":"2022-05-05T11:24:06.118995","exception":false,"start_time":"2022-05-05T11:24:06.096499","status":"completed"},"tags":[]}},{"cell_type":"code","source":"########### Basic Parameters for Running: ################################\n \nTraining_Percentage = 0.2 \nEpoch_Anz = 80\nnb_classes = 100 # move to 1. step\n#input_shape = (32, 20,1) # will be calculated\nBatch_Size = 32\nuse_grayscale = True # grayscale or rgb\nmodel_filename = \"effnet.h5\"\n\n\n########################### data paths ##################################\n\n\ntmnist_dir = 'datasets'\nziffer_dir = 'images'","metadata":{"papermill":{"duration":0.02918,"end_time":"2022-05-05T11:24:14.108133","exception":false,"start_time":"2022-05-05T11:24:14.078953","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:38:39.941817Z","iopub.execute_input":"2022-05-24T19:38:39.942124Z","iopub.status.idle":"2022-05-24T19:38:39.949753Z","shell.execute_reply.started":"2022-05-24T19:38:39.942094Z","shell.execute_reply":"2022-05-24T19:38:39.948840Z"},"trusted":true},"execution_count":11,"outputs":[]},{"cell_type":"code","source":"import sys\nimport os\n\n### for kaggle the input paths must be changed\nif (os.path.exists('/kaggle/input/between-numbers/')):\n package_paths = [\n '/kaggle/input/between-numbers/',\n ]\n\n for pth in package_paths:\n sys.path.append(pth)\n\n tmnist_dir = '/kaggle/input/percentile-tmnist-for-electric-meters'\n ziffer_dir = '/kaggle/input/between-numbers/images/images'","metadata":{"execution":{"iopub.status.busy":"2022-05-24T19:38:39.951627Z","iopub.execute_input":"2022-05-24T19:38:39.951902Z","iopub.status.idle":"2022-05-24T19:38:39.966040Z","shell.execute_reply.started":"2022-05-24T19:38:39.951872Z","shell.execute_reply":"2022-05-24T19:38:39.965235Z"},"trusted":true},"execution_count":12,"outputs":[]},{"cell_type":"markdown","source":"### Load data\n\nLike the distillation network meter digits will be trained with font builded images.\n\nThe meter digits are all 0-9 ziffer_raw + my own data 0-9. \nAt now no images used between two digits. Many images from 0-9 are +/- 0.2 devergent and not correctly labeled. (See the last result)","metadata":{"papermill":{"duration":0.020231,"end_time":"2022-05-05T11:24:14.149547","exception":false,"start_time":"2022-05-05T11:24:14.129316","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from b2n.data.ziffer import ziffer_data\nfrom b2n.data.tmnist import tmnist_percentals\nfrom sklearn.utils import shuffle\nfrom b2n.plotfunctions import plot_dataset\nfrom b2n.encodings.class_encoding import class_encoding\nimport numpy as np\n\nxz_data, yz_data, fz_data = ziffer_data(ziffer_dir, use_grayscale=use_grayscale)\n\n\nx_data, y_data = tmnist_percentals(tmnist_dir, use_grayscale=use_grayscale)\nx_data = np.concatenate((x_data, xz_data))\ny_data = np.concatenate((y_data, yz_data))\nx_data, y_data = shuffle(x_data, y_data)\n\ninput_shape=x_data[0].shape\nprint(f\"dataset x_data-size={len(x_data)}\")\nplot_dataset(x_data, y_data)\n\ny_data = class_encoding(y_data, nb_classes)","metadata":{"papermill":{"duration":81.057792,"end_time":"2022-05-05T11:25:35.227814","exception":false,"start_time":"2022-05-05T11:24:14.170022","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:38:39.967766Z","iopub.execute_input":"2022-05-24T19:38:39.968090Z","iopub.status.idle":"2022-05-24T19:39:52.234044Z","shell.execute_reply.started":"2022-05-24T19:38:39.968045Z","shell.execute_reply":"2022-05-24T19:39:52.232610Z"},"trusted":true},"execution_count":13,"outputs":[{"name":"stdout","text":"Ziffer data count: 6415\n","output_type":"stream"},{"traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)","\u001b[0;32m/tmp/ipykernel_33/2528061570.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mx_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtmnist_percentals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtmnist_dir\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0muse_grayscale\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0muse_grayscale\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0mx_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mxz_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0my_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0myz_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m/kaggle/input/between-numbers/b2n/data/tmnist.py\u001b[0m in \u001b[0;36mtmnist_percentals\u001b[0;34m(input_dir, use_grayscale)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 43\u001b[0;31m \u001b[0mx_train\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_images\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx_train\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 44\u001b[0m \u001b[0my_train\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconcatenate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my_tmnist\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_train\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;31m#print(\">10\", y_train[y_train>10])\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;32m<__array_function__ internals>\u001b[0m in \u001b[0;36mconcatenate\u001b[0;34m(*args, **kwargs)\u001b[0m\n","\u001b[0;31mKeyboardInterrupt\u001b[0m: "],"ename":"KeyboardInterrupt","evalue":"","output_type":"error"}]},{"cell_type":"markdown","source":"### Augmentation\nSee augementation above for augmentation values.\nStandard augmentation of image generator is used plus inverting images.","metadata":{"papermill":{"duration":0.023702,"end_time":"2022-05-05T11:25:35.276412","exception":false,"start_time":"2022-05-05T11:25:35.252710","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom b2n.augmentation.generator import augmentation, augmentation_validation\nfrom b2n.plotfunctions import plot_dataset_it\n\naugmentations={\"Width_Shift_Range\" : 3,\n \"Height_Shift_Range\" : 1,\n \"Brightness_Range\" : [0.4,1.5],\n \"Rotation_Angle\": 3,\n \"ZoomRange_Out\" : 0.1,\n \"ZoomRange_In\" : 0.1,\n \"ShearRange\" : 2,\n \"Channel_Shift\" : 0.2,\n \"zca_whitening\" : True\n}\n\n# Split train and validation data \nx_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=Training_Percentage)\n\ntrain_iterator = augmentation(x_train, y_train, augmentations=augmentations, Batch_Size=Batch_Size)\nvalidation_iterator = augmentation_validation(x_test, y_test)\n\nplot_dataset_it(train_iterator) \n","metadata":{"papermill":{"duration":8.713367,"end_time":"2022-05-05T11:25:44.014279","exception":false,"start_time":"2022-05-05T11:25:35.300912","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:39:52.235428Z","iopub.status.idle":"2022-05-24T19:39:52.235736Z","shell.execute_reply.started":"2022-05-24T19:39:52.235583Z","shell.execute_reply":"2022-05-24T19:39:52.235599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### The Model\n\nIs an small EfficientNet like model with a dense output of 100 at top. ","metadata":{"papermill":{"duration":0.02918,"end_time":"2022-05-05T11:25:44.073414","exception":false,"start_time":"2022-05-05T11:25:44.044234","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import tensorflow as tf\nfrom b2n.models.effnet import Effnet\n\nmodel = Effnet(input_shape, nb_classes, activation_top=None)\n\nmodel.compile(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True), \n optimizer=\"adam\", metrics = [\"accuracy\"])","metadata":{"papermill":{"duration":0.361475,"end_time":"2022-05-05T11:25:44.464621","exception":false,"start_time":"2022-05-05T11:25:44.103146","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:39:52.236867Z","iopub.status.idle":"2022-05-24T19:39:52.237148Z","shell.execute_reply.started":"2022-05-24T19:39:52.237004Z","shell.execute_reply":"2022-05-24T19:39:52.237019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import LearningRateScheduler\nfrom b2n.plotfunctions import plot_acc_loss\n\nannealer = LearningRateScheduler(lambda x: 1e-3 * 0.96 ** x, verbose=0)\n\nhistory = model.fit(train_iterator, \n validation_data=validation_iterator, \n batch_size=Batch_Size, \n epochs = Epoch_Anz,\n callbacks=[annealer],\n verbose=1)\n\nplot_acc_loss(history, \"Trainingsresults\")\n\nmodel.save(model_filename)","metadata":{"papermill":{"duration":28727.762738,"end_time":"2022-05-05T19:24:32.256769","exception":false,"start_time":"2022-05-05T11:25:44.494031","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:39:52.238227Z","iopub.status.idle":"2022-05-24T19:39:52.238647Z","shell.execute_reply.started":"2022-05-24T19:39:52.238476Z","shell.execute_reply":"2022-05-24T19:39:52.238496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Verfify the training\n\nNow a few (5000) images from validation set will be used to evaluate the model.\n\nAll the first (max 30) false predicted images will be shown.\n\nIf all fine the predictions will be shown in a diagram and it should be a sinus and cosinus wave. The glitches are the false predictions.","metadata":{"papermill":{"duration":0.068785,"end_time":"2022-05-05T19:24:32.394252","exception":false,"start_time":"2022-05-05T19:24:32.325467","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import numpy as np\nfrom b2n.encodings.class_encoding import class_decoding\nfrom b2n.plotfunctions import plot_divergence, plot_dataset\n\nres = []\nstat_Anz = []\nstat_Abweichung = []\nfalse_img = []\nfalse_label = []\ntest_count = 5000\n\nfor i in range(100):\n stat_Anz.append(0)\n stat_Abweichung.append(0)\n\nfor x_test, y_test in validation_iterator:\n if (test_count<0):\n break\n test_count = test_count - Batch_Size\n \n for (x, y) in zip(x_test, y_test):\n \n target = class_decoding([y])\n classes = model.predict(np.expand_dims(x.reshape(input_shape), axis=0))\n \n \n out_target = class_decoding(classes)[0]\n\n \n if target != out_target:\n lbl_text = \"Expected: \" + str(target) + \"\\n Predicted: \" + str(out_target)\n print(\"Exp: \" + str(target) + \" Pred: \" + str(out_target))\n false_img.append(x)\n false_label.append(lbl_text)\n \nfor i in range(100):\n if (stat_Anz[i] != 0):\n stat_Abweichung[i] = stat_Abweichung[i] / stat_Anz[i]\n\nres = np.asarray(res)\nres_step_1 = res\nprint(f\"{len(false_label)} false predicted\")\nplot_dataset(np.array(false_img), false_label, columns=11, rows=4)\n\n","metadata":{"papermill":{"duration":328.639219,"end_time":"2022-05-05T19:30:01.102847","exception":false,"start_time":"2022-05-05T19:24:32.463628","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-05-24T19:39:52.239564Z","iopub.status.idle":"2022-05-24T19:39:52.239838Z","shell.execute_reply.started":"2022-05-24T19:39:52.239693Z","shell.execute_reply":"2022-05-24T19:39:52.239708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Ziffer images\n\nThe model is build for predicting meter digit images (Ziffer). So we test *all* meter digit images of the dataset (not only the validation set)\n\nmax_delta can set a value, that ignored convergence +/- of the value and accept it as predicted correctly.\n\nBecause of the meter digit dataset (only 0.0, 1.0, ... 9.0) We have no real answer how good the images between two digits are predicted.","metadata":{}},{"cell_type":"code","source":"import numpy as np\nfrom b2n.encodings.class_encoding import class_decoding\nfrom b2n.plotfunctions import plot_divergence, plot_dataset\n\nres = []\nstat_Abweichung = np.zeros(nb_classes)\nfalse_img = []\nfalse_label = []\nmax_delta = 0.11\n\ndef isclose(a, b, delta):\n return min(abs(a-b),abs(a-(10-b)))<=delta\n\n\nfor x, y, filename in zip(xz_data, yz_data, fz_data):\n\n target = y\n classes = model.predict(np.expand_dims(x.reshape(input_shape), axis=0))\n out_target = class_decoding(classes)[0]\n res.append(out_target)\n \n if not isclose(target, out_target, max_delta) :\n lbl_text = \"Expected: \" + str(target) + \"\\n Predicted: \" + str(out_target) + \"\\n\" + filename[0][:-4]\n #print(\"Exp: \" + str(target) + \" Pred: \" + str(out_target))\n false_img.append(x)\n false_label.append(lbl_text)\n stat_Abweichung[int(abs(target-out_target)*10)] = stat_Abweichung[int(abs(target-out_target)*10)]+1\n # move image to failure_dir \n #move_to_failure_dir(filename[0])\n\n\nprint(f\"Tested images: {len(yz_data)}. {len(false_label)} false predicted. Accuracy is: {1-len(false_label)/len(yz_data)}\")\nplot_divergence(stat_Abweichung, \"Divergation of false predicted\", nb_classes)\n#print(confusion_matrix(np.asarray(res), yz_data, nb_classes))\nplot_dataset(np.array(false_img), false_label, columns=8, rows=5, figsize=(18,16))","metadata":{"execution":{"iopub.status.busy":"2022-05-24T19:39:52.240926Z","iopub.status.idle":"2022-05-24T19:39:52.241206Z","shell.execute_reply.started":"2022-05-24T19:39:52.241066Z","shell.execute_reply":"2022-05-24T19:39:52.241081Z"},"trusted":true},"execution_count":null,"outputs":[]}]}