{"cells":[{"metadata":{"_uuid":"f0388acc7735ccd4921dd24554d0a4be55052a7e"},"cell_type":"markdown","source":"In this kernel we will try to detect if theres is a ship in the image. For that we will build a Convoluional Neural Network and solve the problem as a binary classification problem."},{"metadata":{"_uuid":"502729d5b1087fc47d7292b63cf993de591bd44c"},"cell_type":"markdown","source":"# 0. Importing the libraries"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"collapsed":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.preprocessing.image import load_img\nfrom keras.preprocessing.image import img_to_array\nfrom keras.models import Sequential\nfrom keras.layers import Convolution2D\nfrom keras.layers import MaxPooling2D\nfrom keras.layers import Dense\nfrom keras.layers import Flatten\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import SGDClassifier\n\nimport seaborn as sns\n\nfrom tqdm import tqdm\nimport os","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"23ebb7bd3c4e8acbf56145471ca28ed21506001d"},"cell_type":"markdown","source":"# 1. Data preperation and preprocessing"},{"metadata":{"_uuid":"7346a9dcdf964eb12798154924e0afc31f4e533e"},"cell_type":"markdown","source":"## 1.1 Feature engineering"},{"metadata":{"trusted":true,"_uuid":"318dade4223bd7417926c4035abccaf55ecfd715","collapsed":true},"cell_type":"code","source":"# Initialize global variables\nSAMPLE_SIZE = 10000\nBATCH_SIZE = 32\nTEST_PERC = 0.2","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"collapsed":true},"cell_type":"code","source":"segmentations = pd.read_csv(\"../input/train_ship_segmentations.csv\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5808776d1f6787b7003f835cc0d9f70573d8f0ec"},"cell_type":"markdown","source":"Let's add a new column to our dataframe which will give us the paths to each image in the dataframe"},{"metadata":{"trusted":true,"_uuid":"460f5992adf74bfb8ce19d564d9fc69901637aff","collapsed":true},"cell_type":"code","source":"segmentations['path'] = '../input/train/' + segmentations['ImageId']\nsegmentations.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"53e8a08dd6d2ada5f346936075ae97e2383f251a"},"cell_type":"markdown","source":"Since the data is too big, we will not need to use all the data for training. Here we take a sample from our data."},{"metadata":{"trusted":true,"_uuid":"47a3b860c8b6d127bd29aa15170b0a7da02bd66d","collapsed":true},"cell_type":"code","source":"segmentations = segmentations.sample(n=SAMPLE_SIZE)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b8ac25cdafc1268e1c6e680cbcaff2bf608de884"},"cell_type":"markdown","source":"Now let's add a column which will indicate whether there is ship in the image or no. "},{"metadata":{"trusted":true,"_uuid":"c39f995e88321fc4eec79a1674f31dd3a40df6f5","collapsed":true},"cell_type":"code","source":"def has_ship(encoded_pixels):\n    hs = [0 if pd.isna(n) else 1 for n in tqdm(encoded_pixels)]\n    return hs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0c72ad0b991b99a78f8d31fb991914dddd2d7542","collapsed":true},"cell_type":"code","source":"segmentations['HasShip'] = has_ship(segmentations['EncodedPixels'].values)\nsegmentations['HasShip'].head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eacb28fd7d30762279abb54f761b6984ff7582da","collapsed":true},"cell_type":"code","source":"segmentations.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"63a33125192e0aa91d3affeb4df642842b2c038f"},"cell_type":"markdown","source":"Now let's see what we got"},{"metadata":{"trusted":true,"_uuid":"b434c1f26f90852d554820ea0b19722db6baee7b","collapsed":true},"cell_type":"code","source":"sns.countplot(segmentations['HasShip'])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"916a2dfd4f5455648417baaab2a609bf9e2b7a88"},"cell_type":"markdown","source":"## 1.2 Image preprocessing"},{"metadata":{"trusted":true,"_uuid":"77a95a8773b8b63644cbc17e015501efc9213af5","collapsed":true},"cell_type":"code","source":"np.shape(load_img(segmentations['path'].values[0]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"401406a7d4aa9d2d068baaa1d886a34b363d53d6","collapsed":true},"cell_type":"code","source":"train,test = train_test_split(segmentations, test_size=TEST_PERC)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4b4817609a8cfafa7a230d9e2887469d71fb982a","collapsed":true},"cell_type":"code","source":"idg_train = ImageDataGenerator(rescale=1. / 255,\n                               shear_range=0.2,\n                               zoom_range=0.2,\n                               horizontal_flip=True)\n\nidg_test = ImageDataGenerator(rescale=1. / 255)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8493c615a76b1c0481b227ab213c5eff7515b1ae","collapsed":true},"cell_type":"code","source":"def flow_from_dataframe(img_data_gen, in_df, path_col, y_col, **dflow_args):\n    base_dir = os.path.dirname(in_df[path_col].values[0])\n    print('## Ignore next message from keras, values are replaced anyways')\n    df_gen = img_data_gen.flow_from_directory(base_dir, \n                                     class_mode = 'sparse',\n                                    **dflow_args)\n    df_gen.filenames = in_df[path_col].values\n    df_gen.classes = np.stack(in_df[y_col].values)\n    df_gen.samples = in_df.shape[0]\n    df_gen.n = in_df.shape[0]\n    df_gen._set_index_array()\n    df_gen.directory = '' # since we have the full path\n    print('Reinserting dataframe: {} images'.format(in_df.shape[0]))\n    return df_gen","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"453f07496582b0522fd68024c076677b36a919e3","scrolled":true,"collapsed":true},"cell_type":"code","source":"train_images = flow_from_dataframe(idg_train, train, 'path', 'HasShip', batch_size=BATCH_SIZE, target_size=(256, 256))\ntest_images = flow_from_dataframe(idg_train, test, 'path', 'HasShip', batch_size=BATCH_SIZE, target_size=(256, 256))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c8d5af03eacd4d9157af3fe1900092b331e03d51","collapsed":true},"cell_type":"code","source":"train_images.target_size","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"904fc66b25f4455cf9cdedc3e11057b9a6d6c880"},"cell_type":"markdown","source":"# 2. Creating the NN Model"},{"metadata":{"_uuid":"63a38a47e764d3d4e98283ee0ba37ba1931ba240"},"cell_type":"markdown","source":"We will create the following model\n\nInput -> 3 Convolutional and Max Pooling Layers -> Fully connected ANN with 2 hidden layers"},{"metadata":{"trusted":true,"_uuid":"1cdda2634245dfd9bf970c49dca8eb512670f42c","collapsed":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Convolution2D(32, (3, 3),\n                       input_shape=(256, 256, 3),\n                       activation='relu'))\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Convolution2D(32, (3, 3),\n                       input_shape=(256, 256, 3),\n                       activation='relu'))\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Convolution2D(32, (3, 3),\n                       input_shape=(256, 256, 3),\n                       activation='relu'))\n\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n\nmodel.add(Flatten())\n\nmodel.add(Dense(units=128, activation='relu', kernel_initializer='normal'))\nmodel.add(Dense(units=1, activation='sigmoid', kernel_initializer='normal'))\n\nmodel.compile(optimizer='adam',\n             loss='binary_crossentropy',\n             metrics=['accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c4aba13fbac0578719c18169c81478b616b6736d","collapsed":true},"cell_type":"code","source":"fitted_model = model.fit_generator(train_images,\n                   steps_per_epoch=SAMPLE_SIZE*(1-TEST_PERC)/BATCH_SIZE,\n                   epochs=20,\n                   validation_data=test_images,\n                   validation_steps=SAMPLE_SIZE*(TEST_PERC)/BATCH_SIZE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"6ef7e7e9e80da9fe371c934242895df1a1ca467a"},"cell_type":"markdown","source":"Now Let's plot the Accuracy and Loss history of our model for both train and validation sets"},{"metadata":{"trusted":true,"_uuid":"29becd04fa6f0c64e8f6be309e53869fc7b96edc","collapsed":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport pylab\n\n\npath = 'results'\nname = 'adam'\n\nplt.plot(fitted_model.history['acc'])\nplt.plot(fitted_model.history['val_acc'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"01644e8f70cecffbba6f7ad4340e2279c84372b1","collapsed":true},"cell_type":"code","source":"plt.figure()\nplt.gcf().clear()\nplt.plot(fitted_model.history['loss'])\nplt.plot(fitted_model.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\n\nplt.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"8d3f6a5687189b95c3c82021a0bec853961cd0cd"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}