{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Using Convolutional Neural Networks to reverse time\n\nIt seems natural that the task of reversing a 2D grid can be done by using convolutional neural networks, because the convolutional layers can encode the vicinity of each pixel giving us the chance to solve this task, but when we try to use CNNs this seems to be a not so easy task. In this notebook I will attempt to solve this problem using CNNs!"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport os\nimport tensorflow as tf\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/conways-reverse-game-of-life-2020/train.csv')\ntest_df = pd.read_csv(\"/kaggle/input/conways-reverse-game-of-life-2020/test.csv\")\nsample_submission = pd.read_csv(\"/kaggle/input/conways-reverse-game-of-life-2020/sample_submission.csv\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's split the starting conditions and the stop conditions, the stop conditions are fed into the neural network and the start conditions are what we want the network to predict."},{"metadata":{"trusted":true},"cell_type":"code","source":"start_features = [f for f in train_df.columns if \"start\" in f]\nstop_features = [f for f in train_df.columns if \"stop\" in f]\n\nfeatures_in = stop_features + [\"delta\"]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now we need to have a validation dataset to see how the model is learning, and if the model will overfit or not."},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ndelta_train, delta_validation, stop_train, stop_validation, Y_train, Y_valid = train_test_split(train_df[\"delta\"].values, \n                                                                                                train_df[stop_features].values.reshape(-1, 25, 25, 1).astype(float),\n                                                                                                train_df[start_features].values.reshape(-1, 25, 25, 1).astype(float),\n                                                                                                test_size=0.33,\n                                                                                                )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = [delta_train, stop_train]\nX_valid = [delta_validation, stop_validation]\nX_test = [test_df[\"delta\"].values, test_df[stop_features].values.reshape(-1, 25, 25, 1).astype(float)]\n\nX_all_train = [train_df[\"delta\"].values, train_df[stop_features].values.reshape(-1, 25, 25, 1).astype(float)]\nY_all_train = train_df[start_features].values.reshape(-1, 25, 25, 1).astype(float)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def conv_block(inputs, filters, index, activation='relu'):\n    \"\"\" Creates a convolutional block with batch normalization.\n    \n    Args:\n        inputs: input layer.\n        filters: number of filters in the convolutional layer.\n        index: Index for the name of the convolutional layer.\n        activation: Activation of the convolutional block. \n        (default='relu')\n    \n    Out:\n        keras.layer: Layer of the convolutional block.\n        \n    \"\"\"\n    x = layers.Conv2D(filters, kernel_size=(3,3), padding=\"SAME\", name=f'conv{index}')(inputs)\n    x = layers.BatchNormalization()(x)\n    return layers.Activation(activation, name=activation + str(index))(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras import layers\nfrom tensorflow.keras.models import Model\ndef create_model(dropout_prob=0.3):\n    \"\"\" Creates the CNN model with the convolutional block.\n    \"\"\"\n    input_delta = layers.Input(shape=(1,), name=\"input_delta\")\n    dense_delta = layers.Dense(25*25, name='dense_delta')(input_delta)\n    dense_reshape = layers.Reshape((25,25,1), name='reshape_delta')(dense_delta)\n\n    input_image = layers.Input(shape=(25,25,1), name=\"input_images\")\n    all_inputs = layers.Concatenate(axis=3, name='concatenate')([input_image, dense_reshape])\n\n    x = conv_block(all_inputs, 32, index=1)    \n    x = layers.Dropout(dropout_prob)(x)\n    \n    x = conv_block(x, 128, index=2)    \n    x = layers.Dropout(dropout_prob)(x)\n    \n    x = conv_block(x, 256, index=3)\n    x = layers.Dropout(dropout_prob)(x)\n    \n    x = conv_block(x, 64, index=4)\n    x = layers.Dropout(dropout_prob)(x)\n    \n    out = conv_block(x, 1, index=5, activation='sigmoid')\n\n    return Model(inputs=[input_delta, input_image], outputs=out)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_model()\nmodel.compile(loss=\"bce\", optimizer=tf.keras.optimizers.Adam(), metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"history = model.fit(x=X_train,\n                    y=Y_train, \n                    batch_size=128,\n                    epochs=25,\n                    validation_data=(X_valid, Y_valid))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"loss = history.history['loss']\nval_loss = history.history['val_loss']\naccuracy = history.history['accuracy']\nval_accuracy = history.history['val_accuracy']\nepochs = range(len(loss))\n\nfig = plt.figure(figsize=(12,6))\ngs = fig.add_gridspec(1, 2)\nax1 = fig.add_subplot(gs[0, 0])\nax2 = fig.add_subplot(gs[0, 1])\n\nax1.plot(epochs, loss, 'r', label='Training')\nax1.plot(epochs, val_loss, 'b', label='Validation')\nax1.set_xlabel('Epochs', size=16)\nax1.set_ylabel('Loss', size=16)\nax1.legend()\n\nax2.plot(epochs, accuracy, 'r', label='Training')\nax2.plot(epochs, val_accuracy, 'b', label='Validation')\nax2.set_xlabel('Epochs', size=16)\nax2.set_ylabel('Accuracy', size=16)\nax2.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"idx = 2\n\ndelta_sample = X_valid[0][idx]\nimg_sample = X_valid[1][idx]\nout_sample = Y_valid[idx]\npredicted = model.predict(X_valid)\n\nfig, (ax1, ax2, ax3) = plt.subplots(1, 3)\nfig.suptitle(\"Delta: \" + str(delta_sample))\n\nax1.imshow((img_sample.reshape(25, 25)), cmap=\"gray\")\nax1.set_title(\"Stop Setting\")\n\nax2.imshow((out_sample.reshape(25, 25)), cmap=\"gray\")\nax2.set_title(\"Start Setting\")\n\nax3.imshow((predicted[idx]>=0.5).reshape(25, 25), cmap=\"gray\")\nax3.set_title(\"Predicted Setting\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train on all training dataset\n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_model()\nmodel.compile(loss=\"bce\", optimizer=tf.keras.optimizers.Adam(), metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"history = model.fit(x=X_all_train,\n                    y=Y_all_train, \n                    batch_size=128,\n                    epochs=20,\n                   )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Creating a submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_prediction = model.predict(X_test)\ntest_prediction = (test_prediction > 0.5).astype(int).reshape(test_df.shape[0], -1)\nsub = test_df[[\"id\"]].copy()\ntmp = pd.DataFrame(test_prediction, columns=start_features)\nsubmission = sub.join(tmp)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Thanks for reading. :)"}],"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":4,"nbformat_minor":4}