{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# CNN Model For Image Classification\n***********************************\n\n## The Model\nThe model has a simple architecture, similar to LeNet, owing to the similarity of the task to be performed.\n\nWe maintain two lists, train_x and train_y. \n\nWe fetch the names of the files from the 'training_labels.csv' file. For each row in the csv file, we fetch the name of the file and the label associated with it. \n\nThe image file is fetched using its name from the input folder.\n\nSince the sizes of the images in the training folder are not same, we resize them to a common dimension of 600x1000\n\nThis image is then converted to a numpy array, normalised by dividing it by 255, and its dimensions are expanded by adding a third dimension, the number of color channels, which is set to 1.\n\nThis array is then appended to the train_x list.\n\nWe one hot encode the label manually. A temporary list with 16 0s is initialised and the index of the list which is equal to the label is made 1. This array is appended to test_y.\n\nFinally the lists are converted to numpy array and returned from the load data function.\n\nFor the testing set, the images were taken from the folder and then preprocesses in the same way as the training instances were. The predicted class was stored in a list and later converted to numoy array and then to a dataframe.\n\n","metadata":{}},{"cell_type":"code","source":"import math, re, os\nimport tensorflow as tf\nfrom tensorflow import keras\nimport numpy as np \nimport pandas as pd \nfrom PIL import Image\nimport os\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, AveragePooling2D, Flatten, Dense\nfrom tensorflow.keras.models import Sequential\nfrom skimage.io import imread\nfrom skimage.transform import resize\n\n!nvidia-smi\n\ndef batch_generator(Train_df, batch_size, steps):\n    idx=1\n    while True: \n        yield load_data(Train_df,idx-1,batch_size)\n        if idx<steps:\n            idx+=1\n        else:\n            idx=1\n\ndef load_data(Train_df, idx, batch_size):\n    dirname = '/kaggle/input/datathonindoml-2022/train/train/'\n    df = pd.read_csv(Train_df, skiprows=idx*batch_size, nrows=batch_size)\n    df.columns = ['id', 'label']\n    train_x, train_y = [], []\n    for label in df['id']:\n        train_x.append(np.asarray(Image.open(dirname+str(label)+\".tif\").resize((600, 1000))).reshape(600, 1000, 1)/255)\n        temp = [0]*16\n        temp[df.loc[df['id'] == label, 'label'].item()] = 1\n        train_y.append(temp)\n    train_x = np.array(train_x)\n    train_y = np.array(train_y)\n    return (train_x, train_y)\n\nbatch_size = 64\nnb_epoch = 12\nsteps_per_epoch=np.ceil(16000/batch_size)\n\nmodel = Sequential()\nmodel.add(Conv2D(16, (5,5), padding=\"same\", input_shape=(600, 1000, 1)))\nmodel.add(MaxPooling2D())\nmodel.add(Conv2D(32, (3,3), padding=\"same\"))\nmodel.add(MaxPooling2D())\nmodel.add(Conv2D(64, (3,3), padding=\"same\"))\nmodel.add(MaxPooling2D())\nmodel.add(Conv2D(128, (3,3), padding=\"same\"))\nmodel.add(MaxPooling2D())\nmodel.add(Flatten())\nmodel.add(Dense(100, activation='relu'))\nmodel.add(Dense(16, activation='softmax'))\n\nmodel.compile(loss='categorical_crossentropy', optimizer=\"adam\", metrics=[\"accuracy\"])\nmodel.summary()\n\nmodel_checkpoint = tf.keras.callbacks.ModelCheckpoint(filepath = './checkpt.h5',monitor='accuracy', mode='max', save_best_only=True)\ncallbacks_list = [model_checkpoint]\ntraining_batch_generator = batch_generator('/kaggle/input/datathonindoml-2022/train_labels.csv', batch_size, steps_per_epoch)","metadata":{"execution":{"iopub.status.busy":"2022-10-08T16:12:32.668300Z","iopub.execute_input":"2022-10-08T16:12:32.668617Z","iopub.status.idle":"2022-10-08T16:12:43.060437Z","shell.execute_reply.started":"2022-10-08T16:12:32.668542Z","shell.execute_reply":"2022-10-08T16:12:43.058485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit_generator(training_batch_generator, epochs=nb_epoch,steps_per_epoch=steps_per_epoch, callbacks=callbacks_list, verbose=1)","metadata":{"execution":{"iopub.status.busy":"2022-10-08T16:12:43.062931Z","iopub.execute_input":"2022-10-08T16:12:43.063318Z","iopub.status.idle":"2022-10-08T17:00:06.916658Z","shell.execute_reply.started":"2022-10-08T16:12:43.063279Z","shell.execute_reply":"2022-10-08T17:00:06.915707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import load_model\nmodel = load_model('./checkpt.h5')\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-10-08T17:00:06.918381Z","iopub.execute_input":"2022-10-08T17:00:06.918777Z","iopub.status.idle":"2022-10-08T17:00:07.911191Z","shell.execute_reply.started":"2022-10-08T17:00:06.918738Z","shell.execute_reply":"2022-10-08T17:00:07.910085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_dir = '../input/datathonindoml-2022/validation/validation/'\nresults = []\nfor file in os.listdir(val_dir):\n    image = np.asarray(Image.open(val_dir+file).resize((600, 1000))).reshape(1,600, 1000, 1)/255\n    id_ = file.split(\".\")[0]\n    label = np.argmax(model.predict(image) , axis=1)[0]\n    results.append([id_, label])\ndf = pd.DataFrame(np.array(results), columns = ['id','label'])\ndf.to_csv('./results.csv')","metadata":{"execution":{"iopub.status.busy":"2022-10-08T17:00:07.913569Z","iopub.execute_input":"2022-10-08T17:00:07.913980Z","iopub.status.idle":"2022-10-08T17:00:55.848934Z","shell.execute_reply.started":"2022-10-08T17:00:07.913942Z","shell.execute_reply":"2022-10-08T17:00:55.847918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}