{"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)\nfrom tensorflow import keras\nfrom keras import layers\nfrom keras.utils.np_utils import to_categorical\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","_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-02-15T16:50:02.540733Z","iopub.execute_input":"2022-02-15T16:50:02.541033Z","iopub.status.idle":"2022-02-15T16:50:07.689489Z","shell.execute_reply.started":"2022-02-15T16:50:02.540974Z","shell.execute_reply":"2022-02-15T16:50:07.688608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We start by loading in the data.","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(\"../input/digit-recognizer/train.csv\")\ntest = pd.read_csv(\"../input/digit-recognizer/test.csv\")\n\ntrain.sample(frac=1)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-02-15T16:50:07.690874Z","iopub.execute_input":"2022-02-15T16:50:07.691202Z","iopub.status.idle":"2022-02-15T16:50:12.620510Z","shell.execute_reply.started":"2022-02-15T16:50:07.691173Z","shell.execute_reply":"2022-02-15T16:50:12.619723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"After the data is loaded, we split into x and y portions for training and accuracy scores. We'll also randomize the order of the data, for the sake of splitting the dataset in the future.","metadata":{}},{"cell_type":"code","source":"np.random.seed(42)\n\ny_train = train['label']\ny_train = to_categorical(y_train, num_classes = 10)\nx_train = train.drop(labels = 'label', axis = 1)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:50:12.621748Z","iopub.execute_input":"2022-02-15T16:50:12.622530Z","iopub.status.idle":"2022-02-15T16:50:12.739744Z","shell.execute_reply.started":"2022-02-15T16:50:12.622487Z","shell.execute_reply":"2022-02-15T16:50:12.739019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Normalize the MNIST x data. Values are between 0 and 255. Models tend to converge faster on values between 0 and 1.","metadata":{}},{"cell_type":"code","source":"x_train, test = x_train / 255.0, test / 255.0","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:50:12.741314Z","iopub.execute_input":"2022-02-15T16:50:12.741539Z","iopub.status.idle":"2022-02-15T16:50:12.849389Z","shell.execute_reply.started":"2022-02-15T16:50:12.741512Z","shell.execute_reply":"2022-02-15T16:50:12.848652Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Make a simple sequential model. I didn't change up the hyperparameters at all, just chose them so there would be about 784 * 2/3 nodes. ","metadata":{}},{"cell_type":"code","source":"model = keras.models.Sequential([\n  keras.layers.Dense(128, activation='relu', input_shape = (1, 784)),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n\n  keras.layers.Dropout(0.2),\n  keras.layers.Dense(10, activation = 'softmax')\n])\nweights = model.get_weights()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-02-15T16:50:12.850215Z","iopub.execute_input":"2022-02-15T16:50:12.850407Z","iopub.status.idle":"2022-02-15T16:50:13.386452Z","shell.execute_reply.started":"2022-02-15T16:50:12.850384Z","shell.execute_reply":"2022-02-15T16:50:13.385869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Set the training parameters and relatively few epochs since accuracy is not all important. ","metadata":{}},{"cell_type":"code","source":"model.compile(optimizer='adam',\n              loss=\"categorical_crossentropy\",\n              metrics=['accuracy'])\n\n#Save these for quick reinitialization of the model. Don't have to reset everything\n\nmodel.fit(x_train, y_train, epochs=20)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:50:13.387437Z","iopub.execute_input":"2022-02-15T16:50:13.387792Z","iopub.status.idle":"2022-02-15T16:51:38.122702Z","shell.execute_reply.started":"2022-02-15T16:50:13.387748Z","shell.execute_reply":"2022-02-15T16:51:38.122045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Run predict for the results for the data comp. and export to .csv. Submission stuff copied from https://www.kaggle.com/yassineghouzam/introduction-to-cnn-keras-0-997-top-6.\n","metadata":{}},{"cell_type":"code","source":"results = model.predict(test)\nresults = pd.Series(np.argmax(results,axis = 1), name=\"Label\")\nsubmission = pd.concat([pd.Series(range(1,28001),name = \"ImageId\"),results],axis = 1)\nsubmission.to_csv(\"submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:51:38.123819Z","iopub.execute_input":"2022-02-15T16:51:38.124099Z","iopub.status.idle":"2022-02-15T16:51:39.647864Z","shell.execute_reply.started":"2022-02-15T16:51:38.124062Z","shell.execute_reply":"2022-02-15T16:51:39.647188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Part 2: Splitting the data.\nThere are two cases. First, train on half the original data and test on the other half. Second, train on the digits 0-4 and test on the digits 5-9.\nI'll be using the same model for these.","metadata":{}},{"cell_type":"code","source":"train = train.sample(frac=1)\n\nsize = train.shape[0] // 2\ntrain_p2 = train.iloc[:size, :]\ntest_p2 = train.iloc[size:, :]\n\ntrain_p2.to_csv(\"./train_halfImages.csv\",index=False)\ntest_p2.to_csv(\"./test_halfImages.csv\",index=False)\n\nmask = train['label'] < 5\ntrain_p3 = train[mask]\n# size = train.shape[0]\n# train_p3 = train.iloc[:size, :]\ntest_p3 = train[~mask]\n\ntrain_p3.to_csv(\"./train_halfDigits.csv\",index=False)\ntest_p3.to_csv(\"./test_halfDigits.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:55:07.775203Z","iopub.execute_input":"2022-02-15T16:55:07.775703Z","iopub.status.idle":"2022-02-15T16:55:16.785717Z","shell.execute_reply.started":"2022-02-15T16:55:07.775667Z","shell.execute_reply":"2022-02-15T16:55:16.784966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Reading in the data from csv per instructions.","metadata":{}},{"cell_type":"code","source":"train_p2 = pd.read_csv(\"./train_halfImages.csv\")\ntest_p2 = pd.read_csv(\"./test_halfImages.csv\")\n\ntrain_p3 = pd.read_csv(\"./train_halfDigits.csv\")\ntest_p3 = pd.read_csv(\"./test_halfDigits.csv\")\n\ny_train_p2 = train_p2['label']\ny_train_p2 = to_categorical(y_train_p2, num_classes = 10)\nx_train_p2 = train_p2.drop(labels = 'label', axis = 1)\n\ny_test_p2 = test_p2['label']\ny_test_p2 = to_categorical(y_test_p2, num_classes = 10)\nx_test_p2 = test_p2.drop(labels = 'label', axis = 1)\n\ny_train_p3 = train_p3['label']\ny_train_p3 = to_categorical(y_train_p3, num_classes =10)\nx_train_p3 = train_p3.drop(labels = 'label', axis = 1)\n\ny_test_p3 = test_p3['label']\ny_test_p3 = to_categorical(y_test_p3, num_classes = 10)\nx_test_p3 = test_p3.drop(labels = 'label', axis = 1)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:55:22.059027Z","iopub.execute_input":"2022-02-15T16:55:22.060572Z","iopub.status.idle":"2022-02-15T16:55:26.747781Z","shell.execute_reply.started":"2022-02-15T16:55:22.060416Z","shell.execute_reply":"2022-02-15T16:55:26.746900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The model is retrained and tested using halves of the training data.","metadata":{}},{"cell_type":"code","source":"model.set_weights(weights)\n\nmodel.compile(optimizer='adam',\n              loss=\"categorical_crossentropy\",\n              metrics=['accuracy'])\n\nmodel.fit(x_train_p2, y_train_p2, epochs=20)\npredictions = model.predict(x_test_p2)\n\nmodel.evaluate(x_test_p2, y_test_p2, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:51:52.640325Z","iopub.execute_input":"2022-02-15T16:51:52.640631Z","iopub.status.idle":"2022-02-15T16:52:37.437799Z","shell.execute_reply.started":"2022-02-15T16:51:52.640605Z","shell.execute_reply":"2022-02-15T16:52:37.436973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Then, we reset the model again and train on the digits 0-4. Then, test on the digits 5-9.","metadata":{}},{"cell_type":"code","source":"model = keras.models.Sequential([\n  keras.layers.Dense(128, activation='relu', input_shape = (1, 784)),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n  keras.layers.Dense(128, activation='relu'),\n\n  keras.layers.Dropout(0.2),\n  keras.layers.Dense(10, activation = 'softmax') #Maybe this redefinition of the model isn't needed, as 5-9 will never be the result\n])\n\nmodel.compile(optimizer='adam',\n              loss=\"categorical_crossentropy\",\n              metrics=['accuracy'])\n\nmodel.fit(x_train_p3, y_train_p3, epochs=2)\npredictions = model.predict(x_test_p3)\n\nmodel.evaluate(x_test_p3, y_test_p3, verbose=2)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T16:55:42.403016Z","iopub.execute_input":"2022-02-15T16:55:42.403628Z","iopub.status.idle":"2022-02-15T16:55:50.446583Z","shell.execute_reply.started":"2022-02-15T16:55:42.403592Z","shell.execute_reply":"2022-02-15T16:55:50.445919Z"},"trusted":true},"execution_count":null,"outputs":[]}]}