{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"latex_envs":{"LaTeX_envs_menu_present":true,"autoclose":false,"autocomplete":true,"bibliofile":"biblio.bib","cite_by":"apalike","current_citInitial":1,"eqLabelWithNumbers":true,"eqNumInitial":1,"hotkeys":{"equation":"Ctrl-E","itemize":"Ctrl-I"},"labels_anchors":false,"latex_user_defs":false,"report_style_numbering":false,"user_envs_cfg":false},"toc":{"base_numbering":1,"nav_menu":{},"number_sections":true,"sideBar":true,"skip_h1_title":false,"title_cell":"Table of Contents","title_sidebar":"Contents","toc_cell":false,"toc_position":{},"toc_section_display":true,"toc_window_display":false},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":75110,"databundleVersionId":8241956,"sourceType":"competition"}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# EMNIST Number & Character Recognition","metadata":{}},{"cell_type":"markdown","source":"Build a classifier for handwritten digit and character recognition\n\nSteps:\n- Environment Check\n- Data Import\n- Train Test Split\n- Image Processing Functions\n- Sighting the data\n- Build Classifiers\n- Evaluate Classifiers\n- Submit Kaggle Solution\n- Build Gradio User Interface","metadata":{}},{"cell_type":"markdown","source":"## Environment Check","metadata":{}},{"cell_type":"code","source":"import sys\ntype(sys.path)\nfor path in sys.path:\n    print(path)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:37:31.343037Z","iopub.execute_input":"2024-04-15T08:37:31.344595Z","iopub.status.idle":"2024-04-15T08:37:31.393680Z","shell.execute_reply.started":"2024-04-15T08:37:31.344531Z","shell.execute_reply":"2024-04-15T08:37:31.391995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Show a list of directories in which installed packages are searched for. This gives information about the currently used environment","metadata":{}},{"cell_type":"code","source":"import gc\nimport os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom time import time\nimport seaborn as sns\nsns.set_theme(style=\"whitegrid\")\nsns.color_palette(\"viridis\", as_cmap=True)\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score\nimport itertools\n\nimport tensorflow as tf\nfrom tensorflow.python.client import device_lib\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D\nfrom tensorflow.keras.optimizers import RMSprop, Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\n\nphysical_devices = tf.config.list_physical_devices('GPU')\nprint(physical_devices)","metadata":{"_cell_guid":"f67b9393-8ea1-4e23-b856-2ce149cfe421","_execution_state":"idle","_uuid":"72334cb006d02a4bcfc2a2fe622524eba824c6f8","execution":{"iopub.status.busy":"2024-04-15T08:40:48.654019Z","iopub.execute_input":"2024-04-15T08:40:48.654576Z","iopub.status.idle":"2024-04-15T08:40:48.671726Z","shell.execute_reply.started":"2024-04-15T08:40:48.654536Z","shell.execute_reply":"2024-04-15T08:40:48.669982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_available_gpus():\n    local_device_protos = device_lib.list_local_devices()\n    print(local_device_protos)\n    return [x.name for x in local_device_protos if x.device_type == \"GPU\"]\n\nget_available_gpus()","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:38:14.364588Z","iopub.execute_input":"2024-04-15T08:38:14.365481Z","iopub.status.idle":"2024-04-15T08:38:14.378226Z","shell.execute_reply.started":"2024-04-15T08:38:14.365442Z","shell.execute_reply":"2024-04-15T08:38:14.377054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Check Compute capabilities. Important for GPU accessability for CNN training later on","metadata":{}},{"cell_type":"code","source":"IMSIZE = 28\nNUM_CLASSES = 62\nBATCH_SIZE = 1024","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:38:17.771338Z","iopub.execute_input":"2024-04-15T08:38:17.771996Z","iopub.status.idle":"2024-04-15T08:38:17.776197Z","shell.execute_reply.started":"2024-04-15T08:38:17.771961Z","shell.execute_reply":"2024-04-15T08:38:17.775328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The images are 28x28 pixels, there are 62 classes 0-9 / a-z / A-Z, Batch Size is 1024.","metadata":{}},{"cell_type":"markdown","source":"## Data Import & Check","metadata":{}},{"cell_type":"code","source":"def plot_label_distribution(labels):\n    plt.figure(figsize=(10,5))\n    chart = sns.countplot(x=labels, palette=\"viridis\")\n    response = chart.set_xticklabels(chart.get_xticklabels(), rotation=45, fontweight='light', fontsize='x-small')","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:38:19.321146Z","iopub.execute_input":"2024-04-15T08:38:19.321601Z","iopub.status.idle":"2024-04-15T08:38:19.330081Z","shell.execute_reply.started":"2024-04-15T08:38:19.321562Z","shell.execute_reply":"2024-04-15T08:38:19.328136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir(\"/kaggle/input/emnistfhj-2024/\")","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:40:54.421220Z","iopub.execute_input":"2024-04-15T08:40:54.421624Z","iopub.status.idle":"2024-04-15T08:40:54.431646Z","shell.execute_reply.started":"2024-04-15T08:40:54.421593Z","shell.execute_reply":"2024-04-15T08:40:54.430309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load training data\ntrain_df = pd.read_csv(\"/kaggle/input/emnistfhj-2024/train.csv\", index_col=\"id_code\")\n# Load test data\ntest_df = pd.read_csv(\"/kaggle/input/emnistfhj-2024/test.csv\", index_col=\"id_code\")\n# Show some lines\ntrain_df.head(10)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:40:55.877825Z","iopub.execute_input":"2024-04-15T08:40:55.878305Z","iopub.status.idle":"2024-04-15T08:42:37.824078Z","shell.execute_reply.started":"2024-04-15T08:40:55.878269Z","shell.execute_reply":"2024-04-15T08:42:37.822005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_classes = train_df[\"label\"].unique()\nall_classes = list(np.sort(all_classes))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:40.492234Z","iopub.execute_input":"2024-04-15T08:42:40.492704Z","iopub.status.idle":"2024-04-15T08:42:40.507146Z","shell.execute_reply.started":"2024-04-15T08:42:40.492667Z","shell.execute_reply":"2024-04-15T08:42:40.505583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class2ascii = {}\nascii2class = {}\nfor idx, num_ascii in enumerate(all_classes):\n    class2ascii[idx] = num_ascii\n    ascii2class[num_ascii] = idx","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:42.186395Z","iopub.execute_input":"2024-04-15T08:42:42.186912Z","iopub.status.idle":"2024-04-15T08:42:42.194965Z","shell.execute_reply.started":"2024-04-15T08:42:42.186874Z","shell.execute_reply":"2024-04-15T08:42:42.192978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class2ascii","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:42.743898Z","iopub.execute_input":"2024-04-15T08:42:42.744384Z","iopub.status.idle":"2024-04-15T08:42:42.756410Z","shell.execute_reply.started":"2024-04-15T08:42:42.744347Z","shell.execute_reply":"2024-04-15T08:42:42.755163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ascii2class","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:43.276845Z","iopub.execute_input":"2024-04-15T08:42:43.277418Z","iopub.status.idle":"2024-04-15T08:42:43.291007Z","shell.execute_reply.started":"2024-04-15T08:42:43.277342Z","shell.execute_reply":"2024-04-15T08:42:43.289107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Training labels\ntrain_y_df = train_df[[\"label\"]]\ntrain_y_np = train_y_df.values\ntrain_y_np = train_y_np.flatten()\ntrain_y_np = np.array([ascii2class[x] for x in list(train_y_np)])\nprint(f\"Training label shape: {train_y_np.shape}\")","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:44.102189Z","iopub.execute_input":"2024-04-15T08:42:44.102715Z","iopub.status.idle":"2024-04-15T08:42:44.384340Z","shell.execute_reply.started":"2024-04-15T08:42:44.102667Z","shell.execute_reply":"2024-04-15T08:42:44.382860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare Training Features\ntrain_X_df = train_df.drop(labels = [\"label\"], axis = 1) \n# Memory saving & ready for scaling\ntrain_X_df = train_X_df.astype(\"float32\")\n# Normalize values & reshape training data (height = 28px, width = 28px , canal = 1)\ntrain_X_df = train_X_df / 255.0\ntrain_X_np = train_X_df.values\nprint(f\"Training data shape: {train_X_np.shape}\")\n# Del unused varaibles from memory\ndel train_df, train_X_df, train_y_df\ngc.collect()\n\n# Same for test data\ntest_X_df = test_df\ntest_X_df = test_X_df.astype(\"float32\")\ntest_X_df = test_X_df / 255.0\ntest_X_np = test_X_df.values\nprint(f\"Test data shape: {test_X_np.shape}\")\ndel test_X_df\ngc.collect()","metadata":{"_cell_guid":"86570a36-5c20-460a-9dfd-2070548532a7","_execution_state":"idle","_uuid":"1213b979d5ed3e0d13824d17d694c79d2ece92fa","execution":{"iopub.status.busy":"2024-04-15T08:42:45.985941Z","iopub.execute_input":"2024-04-15T08:42:45.986736Z","iopub.status.idle":"2024-04-15T08:42:52.259275Z","shell.execute_reply.started":"2024-04-15T08:42:45.986690Z","shell.execute_reply":"2024-04-15T08:42:52.257822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Training and Testdata are spit into Feature and Target Matrices/Vectors.\n\nDatatype \"float32\" is used instead of default \"float64\" to save memory.\n\nFeature Matrix is brought into the shape that is needed for training.","metadata":{}},{"cell_type":"code","source":"plot_label_distribution(train_y_np)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:55.296162Z","iopub.execute_input":"2024-04-15T08:42:55.296968Z","iopub.status.idle":"2024-04-15T08:42:56.801288Z","shell.execute_reply.started":"2024-04-15T08:42:55.296928Z","shell.execute_reply":"2024-04-15T08:42:56.799425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Label distribution is not uniform. However, every class has at least 2k examples after a brief examination.","metadata":{}},{"cell_type":"code","source":"print(train_y_np[0:10])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:42:58.942555Z","iopub.execute_input":"2024-04-15T08:42:58.943054Z","iopub.status.idle":"2024-04-15T08:42:58.951588Z","shell.execute_reply.started":"2024-04-15T08:42:58.943018Z","shell.execute_reply":"2024-04-15T08:42:58.949528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The label vector represents each class as its ASCII Code.","metadata":{}},{"cell_type":"markdown","source":"## Train Test Split & Stratified Split","metadata":{}},{"cell_type":"markdown","source":"https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html\n\nhttps://stackoverflow.com/questions/34842405/parameter-stratify-from-method-train-test-split-scikit-learn","metadata":{}},{"cell_type":"code","source":"# Split the train and the validation set for the fitting\ntrain_X, validate_X, train_y, validate_y = train_test_split(train_X_np, train_y_np, \n                                                            test_size = 0.2, random_state=42)","metadata":{"_cell_guid":"dcd25ebb-d845-4d32-9867-082e352b1396","_execution_state":"idle","_uuid":"b779ac76d8317647db92d5a88b4098d212d72884","execution":{"iopub.status.busy":"2024-04-15T08:43:01.293173Z","iopub.execute_input":"2024-04-15T08:43:01.293575Z","iopub.status.idle":"2024-04-15T08:43:13.301004Z","shell.execute_reply.started":"2024-04-15T08:43:01.293543Z","shell.execute_reply":"2024-04-15T08:43:13.299378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_label_distribution(train_y)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:13.304038Z","iopub.execute_input":"2024-04-15T08:43:13.304440Z","iopub.status.idle":"2024-04-15T08:43:14.724156Z","shell.execute_reply.started":"2024-04-15T08:43:13.304410Z","shell.execute_reply":"2024-04-15T08:43:14.722672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_label_distribution(validate_y)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:14.726062Z","iopub.execute_input":"2024-04-15T08:43:14.726587Z","iopub.status.idle":"2024-04-15T08:43:16.139084Z","shell.execute_reply.started":"2024-04-15T08:43:14.726542Z","shell.execute_reply":"2024-04-15T08:43:16.137683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Implement a stratified train-test-split here to assure that the percentage of samles in each class is exactly the same in training and validation set","metadata":{}},{"cell_type":"code","source":"# Stratified Split","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:18.575138Z","iopub.execute_input":"2024-04-15T08:43:18.575649Z","iopub.status.idle":"2024-04-15T08:43:18.580145Z","shell.execute_reply.started":"2024-04-15T08:43:18.575610Z","shell.execute_reply":"2024-04-15T08:43:18.579107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot_label_distribution(revert_onehot(train_y, label_list))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:19.277939Z","iopub.execute_input":"2024-04-15T08:43:19.278676Z","iopub.status.idle":"2024-04-15T08:43:19.283696Z","shell.execute_reply.started":"2024-04-15T08:43:19.278641Z","shell.execute_reply":"2024-04-15T08:43:19.281839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plot_label_distribution(revert_onehot(validate_y, label_list))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:19.565531Z","iopub.execute_input":"2024-04-15T08:43:19.566799Z","iopub.status.idle":"2024-04-15T08:43:19.572336Z","shell.execute_reply.started":"2024-04-15T08:43:19.566737Z","shell.execute_reply":"2024-04-15T08:43:19.570271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image Processing & First sight","metadata":{}},{"cell_type":"code","source":"import albumentations\nimport cv2\n\n#Image Helper Functions\n\ndef show_image(image, figsize=None, title=None):\n    if figsize is not None:\n        fig = plt.figure(figsize=figsize)\n    if image.ndim == 2:\n        plt.imshow(image,cmap='gray')\n    elif image.ndim == 3:\n        if image.shape[2] == 1:\n            image = image[:,:,0]\n            plt.imshow(image,cmap='gray')\n        elif image.shape[2] == 3:\n            plt.imshow(image)\n        else:\n            print(\"Invalid image dimension\")\n    if title is not None:\n        plt.title(title)\n\n        \ndef show_Nimages(imgs, classifications, scale=1):\n    N=len(imgs)\n    fig = plt.figure(figsize=(25/scale, 16/scale))\n    for i in range(N):\n        ax = fig.add_subplot(1, N, i + 1, xticks=[], yticks=[])\n        show_image(imgs[i], title=\"C:{}\".format(classifications[i]))\n\n        \ndef show_Nerrorimages(imgs, predval, trueval, delta=[], cols=None):\n    N=len(imgs)\n    if cols == None:\n        cols = int(np.sqrt(N))\n    rows = (N//cols) + 1\n    fig = plt.figure(figsize=(cols*2, rows*2))\n    \n    for i in range(N):\n        ax = fig.add_subplot(rows, cols, i + 1, xticks=[], yticks=[])\n        if len(delta) == 0:\n            show_image(imgs[i], title=\"P:{} T:{}\".format(predval[i], trueval[i]))\n        else:\n            show_image(imgs[i], title=\"P:{} T:{} d:{}\".format(predval[i], trueval[i], delta[i]))\n            \n\ndef show_Nrandomimages(data_np, label_np, N=10):\n    indices = (np.random.rand(N)*data_np.shape[0]).astype(int)\n    show_Nimages(data_np[indices], label_np[indices])\n\n    \ndef show_Nimages_of_class(data_np, label_np, classification=0, N=10):\n    label_df = pd.DataFrame(data=label_np, columns=[\"label\"])\n    indices = label_df[label_df[\"label\"] == classification].sample(N).index\n    show_Nimages(data_np[indices], label_np[indices])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:21.011327Z","iopub.execute_input":"2024-04-15T08:43:21.011852Z","iopub.status.idle":"2024-04-15T08:43:21.682381Z","shell.execute_reply.started":"2024-04-15T08:43:21.011808Z","shell.execute_reply":"2024-04-15T08:43:21.680998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_index = 24790\nshow_image(train_X_np[test_index].reshape(IMSIZE,IMSIZE), title=\"Class = {}\".format(train_y_np[test_index]))","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:21.723234Z","iopub.execute_input":"2024-04-15T08:43:21.724208Z","iopub.status.idle":"2024-04-15T08:43:22.210685Z","shell.execute_reply.started":"2024-04-15T08:43:21.724165Z","shell.execute_reply":"2024-04-15T08:43:22.209310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_Nrandomimages(train_X.reshape(-1,28,28,1), train_y, 10)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:23.400567Z","iopub.execute_input":"2024-04-15T08:43:23.402011Z","iopub.status.idle":"2024-04-15T08:43:24.317225Z","shell.execute_reply.started":"2024-04-15T08:43:23.401957Z","shell.execute_reply":"2024-04-15T08:43:24.316053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_Nimages_of_class(train_X.reshape(-1,28,28,1), train_y, classification=15)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:25.306644Z","iopub.execute_input":"2024-04-15T08:43:25.310285Z","iopub.status.idle":"2024-04-15T08:43:26.206929Z","shell.execute_reply.started":"2024-04-15T08:43:25.310228Z","shell.execute_reply":"2024-04-15T08:43:26.205389Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"chr(class2ascii[15])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:27.183925Z","iopub.execute_input":"2024-04-15T08:43:27.184396Z","iopub.status.idle":"2024-04-15T08:43:27.193778Z","shell.execute_reply.started":"2024-04-15T08:43:27.184363Z","shell.execute_reply":"2024-04-15T08:43:27.192261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build Classifiers","metadata":{}},{"cell_type":"code","source":"print(train_X.shape)\nprint(train_y.shape)\nprint(validate_X.shape)\nprint(validate_y.shape)\nprint(test_X_np.shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:29.309838Z","iopub.execute_input":"2024-04-15T08:43:29.310248Z","iopub.status.idle":"2024-04-15T08:43:29.319583Z","shell.execute_reply.started":"2024-04-15T08:43:29.310218Z","shell.execute_reply":"2024-04-15T08:43:29.318089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validate_y[0:15]","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:30.882207Z","iopub.execute_input":"2024-04-15T08:43:30.882623Z","iopub.status.idle":"2024-04-15T08:43:30.891428Z","shell.execute_reply.started":"2024-04-15T08:43:30.882590Z","shell.execute_reply":"2024-04-15T08:43:30.889969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Logistic Regression","metadata":{}},{"cell_type":"markdown","source":"https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html\n\nhttps://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html\n\nhttps://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html","metadata":{}},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nlogistic_regressor = LogisticRegression(multi_class=\"multinomial\")\nlogistic_regressor.fit(train_X, train_y)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:43:33.005941Z","iopub.execute_input":"2024-04-15T08:43:33.006354Z","iopub.status.idle":"2024-04-15T08:51:20.217955Z","shell.execute_reply.started":"2024-04-15T08:43:33.006323Z","shell.execute_reply":"2024-04-15T08:51:20.215831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred_logreg = logistic_regressor.predict(validate_X)\ny_true_logreg = validate_y\naccuracy_logreg = accuracy_score(y_true_logreg, y_pred_logreg)\nprint(f\"Accuracy Logistic Regression: {(accuracy_logreg * 100.0)}\")","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:54:26.189875Z","iopub.execute_input":"2024-04-15T08:54:26.190308Z","iopub.status.idle":"2024-04-15T08:54:26.975687Z","shell.execute_reply.started":"2024-04-15T08:54:26.190277Z","shell.execute_reply":"2024-04-15T08:54:26.974570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_regressor.predict(validate_X[0:10])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:54:31.496085Z","iopub.execute_input":"2024-04-15T08:54:31.496475Z","iopub.status.idle":"2024-04-15T08:54:31.514143Z","shell.execute_reply.started":"2024-04-15T08:54:31.496445Z","shell.execute_reply":"2024-04-15T08:54:31.512229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_regressor.predict_proba(validate_X[0:2])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:54:32.299110Z","iopub.execute_input":"2024-04-15T08:54:32.299492Z","iopub.status.idle":"2024-04-15T08:54:32.309900Z","shell.execute_reply.started":"2024-04-15T08:54:32.299463Z","shell.execute_reply":"2024-04-15T08:54:32.308882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Random Forest","metadata":{}},{"cell_type":"markdown","source":"https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html","metadata":{}},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Gradient Boosting","metadata":{}},{"cell_type":"code","source":"from xgboost import XGBClassifier","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"https://xgboost.readthedocs.io/en/stable/index.html\n\nhttps://xgboost.readthedocs.io/en/stable/get_started.html\n\nhttps://xgboost.readthedocs.io/en/stable/gpu/index.html","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Evaluate models","metadata":{}},{"cell_type":"markdown","source":"https://scikit-learn.org/stable/modules/generated/sklearn.metrics.accuracy_score.html\n    \nhttps://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_score.html#sklearn.metrics.precision_score \n\nhttps://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html#sklearn.metrics.recall_score","metadata":{}},{"cell_type":"code","source":"# Plot confusion matrix \ndef plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Blues):\n    fig = plt.figure(figsize=(16, 16))\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j], horizontalalignment=\"center\", \n                 color=\"white\" if cm[i, j] > thresh else \"black\",\n                 fontsize='xx-small',\n                )\n\n    plt.grid(False)\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n    \ndef evaluate_metrics(y_true, y_pred):\n    # Print out accuracy, precision, recall, F1-Score\n    print('-'*100)\n    print(f\"Accuracy Score: {accuracy_score(y_true, y_pred):.2f}\")\n    print('-'*100)","metadata":{"_cell_guid":"11361e73-8250-4bf5-a353-b0f8ea83e659","_execution_state":"idle","_uuid":"16e161179bf1b51ba66c39b2cead883f1db3a9c7","execution":{"iopub.status.busy":"2024-04-15T08:54:39.256394Z","iopub.execute_input":"2024-04-15T08:54:39.256920Z","iopub.status.idle":"2024-04-15T08:54:39.270161Z","shell.execute_reply.started":"2024-04-15T08:54:39.256862Z","shell.execute_reply":"2024-04-15T08:54:39.269125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction_val = logistic_regressor.predict(validate_X)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:54:39.799875Z","iopub.execute_input":"2024-04-15T08:54:39.801063Z","iopub.status.idle":"2024-04-15T08:54:40.505427Z","shell.execute_reply.started":"2024-04-15T08:54:39.801021Z","shell.execute_reply":"2024-04-15T08:54:40.503684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction_val","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:18.455626Z","iopub.execute_input":"2024-04-15T08:55:18.456120Z","iopub.status.idle":"2024-04-15T08:55:18.465317Z","shell.execute_reply.started":"2024-04-15T08:55:18.456085Z","shell.execute_reply":"2024-04-15T08:55:18.463536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"validate_y","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:19.236205Z","iopub.execute_input":"2024-04-15T08:55:19.236602Z","iopub.status.idle":"2024-04-15T08:55:19.245326Z","shell.execute_reply.started":"2024-04-15T08:55:19.236573Z","shell.execute_reply":"2024-04-15T08:55:19.243056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"evaluate_metrics(validate_y, prediction_val)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:21.159527Z","iopub.execute_input":"2024-04-15T08:55:21.160043Z","iopub.status.idle":"2024-04-15T08:55:21.180806Z","shell.execute_reply.started":"2024-04-15T08:55:21.160000Z","shell.execute_reply":"2024-04-15T08:55:21.179774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Confusion Matrix\nconfusion_mtx = confusion_matrix(validate_y, prediction_val)\nplot_confusion_matrix(confusion_mtx, classes = [chr(x) for x in all_classes]) ","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:22.221314Z","iopub.execute_input":"2024-04-15T08:55:22.221849Z","iopub.status.idle":"2024-04-15T08:55:34.676988Z","shell.execute_reply.started":"2024-04-15T08:55:22.221799Z","shell.execute_reply":"2024-04-15T08:55:34.675867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Show Some Classification Errors","metadata":{}},{"cell_type":"code","source":"prediction_label_np = np.array(prediction_val)\ntrue_label_np = np.array(validate_y)\n# Errors are difference between predicted labels and true labels\nerrors = (prediction_label_np - true_label_np != 0)\n# true_label\n# prediction_label\nerror_X = validate_X[errors]\nerror_y_true = true_label_np[errors]\nerror_y_pred = prediction_label_np[errors]\n\nindices = (np.random.rand(100)*error_X.shape[0]).astype(int)\nshow_Nerrorimages(error_X[indices].reshape(-1, IMSIZE, IMSIZE, 1), \n                  predval=np.array([chr(class2ascii[x]) for x in list(error_y_pred[indices])]), \n                  trueval=np.array([chr(class2ascii[x]) for x in list(error_y_true[indices])]))","metadata":{"_cell_guid":"7b0f31b8-c18b-4529-b0d8-eb4c31e30bbf","_execution_state":"idle","_uuid":"e7a3d6449b499a29db224e42e950f21ca1ec4e36","execution":{"iopub.status.busy":"2024-04-15T08:55:38.540292Z","iopub.execute_input":"2024-04-15T08:55:38.540775Z","iopub.status.idle":"2024-04-15T08:55:47.412434Z","shell.execute_reply.started":"2024-04-15T08:55:38.540723Z","shell.execute_reply":"2024-04-15T08:55:47.410943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"error_y_pred[indices]","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:47.415084Z","iopub.execute_input":"2024-04-15T08:55:47.415598Z","iopub.status.idle":"2024-04-15T08:55:47.428449Z","shell.execute_reply.started":"2024-04-15T08:55:47.415557Z","shell.execute_reply":"2024-04-15T08:55:47.426808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.array([chr(class2ascii[x]) for x in list(error_y_pred[indices])])","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:47.431224Z","iopub.execute_input":"2024-04-15T08:55:47.431806Z","iopub.status.idle":"2024-04-15T08:55:47.444112Z","shell.execute_reply.started":"2024-04-15T08:55:47.431739Z","shell.execute_reply":"2024-04-15T08:55:47.442677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Kaggle Submission","metadata":{}},{"cell_type":"code","source":"# predict results logistic regression\nkaggle_results_logreg = logistic_regressor.predict(test_X_np)\nresults = np.array([class2ascii[x] for x in list(kaggle_results_logreg)])\nsubmission_filename = \"emnist_logreg_baseline_submission.csv\"","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:52.024858Z","iopub.execute_input":"2024-04-15T08:55:52.025314Z","iopub.status.idle":"2024-04-15T08:55:53.589348Z","shell.execute_reply.started":"2024-04-15T08:55:52.025280Z","shell.execute_reply":"2024-04-15T08:55:53.588365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict results random forest\n","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:53.722474Z","iopub.execute_input":"2024-04-15T08:55:53.723468Z","iopub.status.idle":"2024-04-15T08:55:53.729162Z","shell.execute_reply.started":"2024-04-15T08:55:53.723420Z","shell.execute_reply":"2024-04-15T08:55:53.728017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predict results Gradient Boosting\n","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:54.014650Z","iopub.execute_input":"2024-04-15T08:55:54.015445Z","iopub.status.idle":"2024-04-15T08:55:54.020596Z","shell.execute_reply.started":"2024-04-15T08:55:54.015392Z","shell.execute_reply":"2024-04-15T08:55:54.019114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results_df = pd.DataFrame(results, columns=[\"label\"])\nresults_df","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:55:55.098237Z","iopub.execute_input":"2024-04-15T08:55:55.098992Z","iopub.status.idle":"2024-04-15T08:55:55.113098Z","shell.execute_reply.started":"2024-04-15T08:55:55.098952Z","shell.execute_reply":"2024-04-15T08:55:55.111992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission = pd.read_csv(\"/kaggle/input/emnistfhj-2024/sample_submission.csv\")\nsample_submission[\"label\"] = results_df[\"label\"]\nsample_submission.to_csv(\"/kaggle/working/\"+submission_filename, index=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:57:04.708699Z","iopub.execute_input":"2024-04-15T08:57:04.709744Z","iopub.status.idle":"2024-04-15T08:57:05.105432Z","shell.execute_reply.started":"2024-04-15T08:57:04.709704Z","shell.execute_reply":"2024-04-15T08:57:05.103953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:57:13.751470Z","iopub.execute_input":"2024-04-15T08:57:13.752363Z","iopub.status.idle":"2024-04-15T08:57:13.768622Z","shell.execute_reply.started":"2024-04-15T08:57:13.752316Z","shell.execute_reply":"2024-04-15T08:57:13.767434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Gradio User Interface","metadata":{}},{"cell_type":"code","source":"import gradio as gr\nimport cv2\n\ndef predict_character(sketch):\n    img = cv2.resize(sketch, (28, 28))\n    img = img.reshape(1, IMSIZE*IMSIZE)\n    img = img.astype(\"float\")/255\n    \n    result_class = logistic_regressor.predict(img)[0]\n    return f\"Classification result: '{chr(class2ascii[result_class])}'\"\n    \niface = gr.Interface(fn=predict_character, inputs='sketchpad', outputs=['text']).launch(share=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-15T08:57:16.601453Z","iopub.execute_input":"2024-04-15T08:57:16.602333Z","iopub.status.idle":"2024-04-15T08:57:16.681985Z","shell.execute_reply.started":"2024-04-15T08:57:16.602278Z","shell.execute_reply":"2024-04-15T08:57:16.680216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}