{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-24T11:09:40.451616Z","iopub.execute_input":"2021-11-24T11:09:40.452378Z","iopub.status.idle":"2021-11-24T11:09:40.480254Z","shell.execute_reply.started":"2021-11-24T11:09:40.452266Z","shell.execute_reply":"2021-11-24T11:09:40.479372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\nobjective_df = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:09:40.481763Z","iopub.execute_input":"2021-11-24T11:09:40.481985Z","iopub.status.idle":"2021-11-24T11:09:46.157085Z","shell.execute_reply.started":"2021-11-24T11:09:40.481961Z","shell.execute_reply":"2021-11-24T11:09:46.156393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import datasets, layers, models\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:09:46.158302Z","iopub.execute_input":"2021-11-24T11:09:46.159115Z","iopub.status.idle":"2021-11-24T11:09:51.776718Z","shell.execute_reply.started":"2021-11-24T11:09:46.159079Z","shell.execute_reply":"2021-11-24T11:09:51.775676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy import ndimage\n\ntrain_images = train_df.drop(['label'], axis=1).to_numpy()\ntrain_label = train_df['label'].to_numpy()\n\ntrain_images = train_images / 255\ntrain_images = train_images.reshape(train_images.shape[0], 28, 28)\n\ndef pre(img) :\n    outI = np.where(np.any(img > 0.7, axis = 1))\n    outJ = np.where(np.any(img > 0.7, axis = 0))\n    centerI = (outI[0][0] + outI[0][-1] + 1) / 2\n    centerJ = (outJ[0][0] + outJ[0][-1] + 1) / 2\n    radii = max(\n        (outI[0][-1] - outI[0][0] + 1) / 2,\n        (outJ[0][-1] - outJ[0][0] + 1) / 2\n    )\n    result = ndimage.zoom(\n        img[\n            int(centerI - radii) : int(centerI + radii),\n            int(centerJ - radii) : int(centerJ + radii)\n        ],\n        (28 / (2 * radii))\n    )\n    result.resize((28, 28))\n    result = (result - 0.5) * 10\n    return (1 / (1 + np.exp(- result)) + 1) / 2\n\nfor i in range(train_images.shape[0]) :\n    train_images[i,:,:] = pre(train_images[i])\n\ntrain_images = train_images.reshape((train_images.shape[0], 28, 28, 1))\n\npick = np.arange(train_images.shape[0])\nnp.random.shuffle(pick)\n\nf, axs = plt.subplots(3, 3, figsize=(15,15))\nfor i, ax in zip(pick[:9], axs.reshape(-1)):\n  ax.title.set_text(\"Label : \" + str(train_label[i]))\n  ax.imshow(train_images[i][:,:,0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:09:51.778069Z","iopub.execute_input":"2021-11-24T11:09:51.778321Z","iopub.status.idle":"2021-11-24T11:10:05.175312Z","shell.execute_reply.started":"2021-11-24T11:09:51.778292Z","shell.execute_reply":"2021-11-24T11:10:05.174379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"objective_images = objective_df.to_numpy()\nobjective_images = objective_images / 255\n\nobjective_count = objective_images.shape[0]\nobjective_images = objective_images.reshape((objective_count, 28, 28))\n\nfor i in range(objective_images.shape[0]) :\n    objective_images[i,:,:] = pre(objective_images[i])\n\nobjective_images = objective_images.reshape((objective_images.shape[0], 28, 28, 1))\n\npick = np.arange(objective_count)\nnp.random.shuffle(pick)\n\nf, axs = plt.subplots(3, 3, figsize=(15,15))\nfor i, ax in zip(pick[:9], axs.reshape(-1)):\n  ax.imshow(objective_images[i][:,:,0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:10:05.177793Z","iopub.execute_input":"2021-11-24T11:10:05.178367Z","iopub.status.idle":"2021-11-24T11:10:14.345959Z","shell.execute_reply.started":"2021-11-24T11:10:05.178314Z","shell.execute_reply":"2021-11-24T11:10:14.345130Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.layers import Input, Reshape, Dense, Flatten, Conv2D, MaxPooling2D, Dropout, Concatenate\n\ndef make() :\n    i = h = Input((14, 14, 1))\n    h = Conv2D(32, (3, 3), activation='relu', input_shape=(14, 14, 1), padding=\"same\")(h)\n    h = MaxPooling2D(pool_size=(2, 2))(h)\n    h = Conv2D(64, (3, 3), activation='relu', padding=\"same\")(h)\n    h = MaxPooling2D(pool_size=(2, 2))(h)\n    h = Conv2D(32, (5, 5), activation='relu', padding=\"same\")(h)\n    h = MaxPooling2D(pool_size=(3, 3))(h)\n    h = Flatten()(h)\n    h = Dense(128)(h)\n    h = Dropout(.2)(h)\n    h = Dense(32)(h)\n    o = Dense(4)(h)\n    return Model(inputs=[i], outputs=[o])\n\nclass MyModel :\n    def __init__(self) :\n        \"\"\"\n        #first quadran\n        q1 = make()\n        \n        #second quadran\n        q2 = make()\n        \n        #third quadran\n        q3 = make()\n        \n        #fourth quadran\n        q4 = make()\n        \n        i = h = Input((16,))\n        h = Dense(16, activation='relu', input_shape=(16,))(h)\n        o = Dense(10)(i)\n        ret = Model(inputs=[i], outputs=[o])\n        \n        i = Input((28, 28, 1))\n        z1 = q1(i[:,0:14,0:14,:])\n        z2 = q2(i[:,14:28,0:14,:])\n        z3 = q3(i[:,0:14,14:28,:])\n        z4 = q4(i[:,14:28,14:28,:])\n        z5 = Concatenate(axis=1)([z1, z2, z3, z4])\n        o = ret(z5)\n        \"\"\"\n        \n        self.model = Sequential([\n            Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1), padding=\"same\"),\n            MaxPooling2D(pool_size=(2, 2)),\n            Conv2D(64, (3, 3), activation='relu', padding=\"same\"),\n            MaxPooling2D(pool_size=(2, 2)),\n            Conv2D(32, (5, 5), activation='relu', padding=\"same\"),\n            MaxPooling2D(pool_size=(3, 3)),\n            Flatten(),\n            Dense(512, activation='relu'),\n            Dropout(.2),\n            Dense(64, activation='relu'),\n            Dense(10, activation='softmax')\n        ])\n        self.model.compile(\n            optimizer='adam',\n            loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n            metrics=['accuracy']\n        )","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:10:14.347180Z","iopub.execute_input":"2021-11-24T11:10:14.347526Z","iopub.status.idle":"2021-11-24T11:10:14.362197Z","shell.execute_reply.started":"2021-11-24T11:10:14.347498Z","shell.execute_reply":"2021-11-24T11:10:14.361534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import KFold","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:10:14.363380Z","iopub.execute_input":"2021-11-24T11:10:14.363732Z","iopub.status.idle":"2021-11-24T11:10:15.113845Z","shell.execute_reply.started":"2021-11-24T11:10:14.363704Z","shell.execute_reply":"2021-11-24T11:10:15.113124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folds_cnt = 2\n\nh_fold = []\n\nkfold = KFold(n_splits=folds_cnt, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:10:15.114989Z","iopub.execute_input":"2021-11-24T11:10:15.115422Z","iopub.status.idle":"2021-11-24T11:10:15.119661Z","shell.execute_reply.started":"2021-11-24T11:10:15.115390Z","shell.execute_reply":"2021-11-24T11:10:15.118840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping\n\nmodel = MyModel()\n\nfold_no = 1\nfor train, test in kfold.split(train_images, train_label) :\n    print('------------------------------------------------------------------------')\n    print(f'Training for fold {fold_no} ...')\n    \n    early_stopping = EarlyStopping(monitor='val_accuracy', patience=30, restore_best_weights=True)\n    \n    history = model.model.fit(\n        train_images[train], train_label[train],\n        validation_data=(train_images[test], train_label[test]),\n        batch_size=64,\n        epochs=50,\n        verbose=1\n    )\n    h_fold.append(history)\n    fold_no = fold_no + 1","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:10:15.120966Z","iopub.execute_input":"2021-11-24T11:10:15.121250Z","iopub.status.idle":"2021-11-24T11:11:45.565140Z","shell.execute_reply.started":"2021-11-24T11:10:15.121222Z","shell.execute_reply":"2021-11-24T11:11:45.563732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"res = model.model.predict(objective_images)","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:11:45.566305Z","iopub.status.idle":"2021-11-24T11:11:45.566662Z","shell.execute_reply.started":"2021-11-24T11:11:45.566476Z","shell.execute_reply":"2021-11-24T11:11:45.566494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predicted_label = []\nfor label in np.array(res) :\n  predicted_label.append(np.argmax(label))","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:11:45.568520Z","iopub.status.idle":"2021-11-24T11:11:45.569334Z","shell.execute_reply.started":"2021-11-24T11:11:45.569050Z","shell.execute_reply":"2021-11-24T11:11:45.569079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pick = np.arange(objective_count)\nnp.random.shuffle(pick)\n\nf, axs = plt.subplots(4, 4, figsize=(16,16))\n\nfor i, ax in zip(pick[:16], axs.reshape(-1)):\n  ax.title.set_text('Predicted label : ' + str(predicted_label[i]))\n  ax.imshow(objective_images[i][:,:,0], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:11:45.570664Z","iopub.status.idle":"2021-11-24T11:11:45.571164Z","shell.execute_reply.started":"2021-11-24T11:11:45.570886Z","shell.execute_reply":"2021-11-24T11:11:45.570911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.DataFrame([[i + 1, predicted_label[i]] for i in range(objective_count)], columns=[\"ImageId\", \"Label\"])\ndf","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:11:45.572507Z","iopub.status.idle":"2021-11-24T11:11:45.572990Z","shell.execute_reply.started":"2021-11-24T11:11:45.572726Z","shell.execute_reply":"2021-11-24T11:11:45.572750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-24T11:11:45.574912Z","iopub.status.idle":"2021-11-24T11:11:45.575705Z","shell.execute_reply.started":"2021-11-24T11:11:45.575421Z","shell.execute_reply":"2021-11-24T11:11:45.575447Z"},"trusted":true},"execution_count":null,"outputs":[]}]}