{"cells":[{"metadata":{"_uuid":"da035fe58e548e8b1b7e8e89725b9e6bc745aa7b"},"cell_type":"markdown","source":"# Humpback Whale Identification - CNN with Keras\nThis kernel is based on [Anezka Kolaceke](https://www.kaggle.com/anezka)'s awesome work: [CNN with Keras for Humpback Whale ID](https://www.kaggle.com/anezka/cnn-with-keras-for-humpback-whale-id)"},{"metadata":{"trusted":true,"_uuid":"0d9c73ad23e6c2eae3028255ee00c3254fe66401"},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport os\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mplimg\nfrom matplotlib.pyplot import imshow\nfrom keras import optimizers\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.preprocessing import OneHotEncoder\n\nfrom keras import layers\nfrom keras.preprocessing import image\nfrom keras.applications.imagenet_utils import preprocess_input\nfrom keras.layers import Input, Dense, Activation, BatchNormalization, Flatten, Conv2D\nfrom keras.layers import AveragePooling2D, MaxPooling2D, Dropout\nfrom keras.models import Model\n\nimport keras.backend as K\nfrom keras.models import Sequential\n\nimport warnings\nwarnings.simplefilter(\"ignore\", category=DeprecationWarning)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2cea35de3530cc898be5b85063b84e875401d092"},"cell_type":"code","source":"os.listdir(\"../input/\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"46a8839e13a14eb8d16ea6823de9927ea63d5001"},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/train.csv\")\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f46b24dbba74f22833cac6140e60348b15a8e047"},"cell_type":"code","source":"def prepareImages(data, m, dataset):\n    print(\"Preparing images\")\n    X_train = np.zeros((m, 100, 100, 3))\n    count = 0\n    \n    for fig in data['Image']:\n        #load images into images of size 100x100x3\n        img = image.load_img(\"../input/\"+dataset+\"/\"+fig, target_size=(100, 100, 3))\n        x = image.img_to_array(img)\n        x = preprocess_input(x)\n\n        X_train[count] = x\n        if (count%500 == 0):\n            print(\"Processing image: \", count+1, \", \", fig)\n        count += 1\n    \n    return X_train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6587a101b58af064af0f9c60a1070c6c8f52d45f"},"cell_type":"code","source":"def prepare_labels(y):\n    values = np.array(y)\n    label_encoder = LabelEncoder()\n    integer_encoded = label_encoder.fit_transform(values)\n    # print(integer_encoded)\n\n    onehot_encoder = OneHotEncoder(sparse=False)\n    integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)\n    onehot_encoded = onehot_encoder.fit_transform(integer_encoded)\n    # print(onehot_encoded)\n\n    y = onehot_encoded\n    # print(y.shape)\n    return y, label_encoder","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4afe4128a0cd6859848c8a80686208082d647c39"},"cell_type":"code","source":"X = prepareImages(train_df, train_df.shape[0], \"train\")\nX /= 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"675924f8863aef27cf90dc668e0a68cd609dfc1c"},"cell_type":"code","source":"y, label_encoder = prepare_labels(train_df['Id'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"14d243b19023e830b636bea16679e13bc40deae6"},"cell_type":"code","source":"y.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import applications\n\n# This will load the whole VGG16 network, including the top Dense layers.\n# Note: by specifying the shape of top layers, input tensor shape is forced\n# to be (224, 224, 3), therefore you can use it only on 224x224 images.\n#vgg_model = applications.VGG16(weights='imagenet', include_top=True)\n\n# If you are only interested in convolution filters. Note that by not\n# specifying the shape of top layers, the input tensor shape is (None, None, 3),\n# so you can use them for any size of images.\nvgg_model = applications.VGG16(weights='imagenet', include_top=False)\n\n# If you want to specify input tensor\nfrom keras.layers import Input\ninput_tensor = Input(shape=(100, 100, 3))\nvgg_model = applications.VGG16(weights='imagenet',\n                               include_top=False,\n                               input_tensor=input_tensor)\n\n# To see the models' architecture and layer names, run the following\nvgg_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vgg_model = applications.VGG16(weights='imagenet',\n                               include_top=False,\n                               input_shape=(100, 100, 3))\n\n# Creating dictionary that maps layer names to the layers\nlayer_dict = dict([(layer.name, layer) for layer in vgg_model.layers])\n\n# Getting output tensor of the last VGG layer that we want to include\nx = layer_dict['block5_pool'].output\n\n# Stacking a new simple convolutional network on top of it    \n\nx = Flatten()(x)\nx = Dense(1024, activation='relu')(x)\nx = Dropout(0.2)(x)\nx = Dense(y.shape[1], activation='softmax')(x)\n\n# Creating new model. Please note that this is NOT a Sequential() model.\nfrom keras.models import Model\nmodel = Model(input=vgg_model.input, output=x)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.layers[:-3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Make sure that the pre-trained bottom layers are not trainable\nfor layer in model.layers[:-4]:\n    layer.trainable = False\n    \nfrom keras import optimizers\n# Do not forget to compile it\nadam=optimizers.Adam(lr=0.001)\nmodel.compile(loss='categorical_crossentropy',\n                     optimizer=adam,\n                     metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Use 100 epoch or more. I used 10 only for fast commit"},{"metadata":{"trusted":true,"_uuid":"169f45e150c3a584e0f655a8eda523e0675da63a"},"cell_type":"code","source":"history = model.fit(X, y, epochs=10, batch_size=512, verbose=1, validation_split=0.2)\n#gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7bca48a1d0963cbf70685b75431435cef9499895"},"cell_type":"code","source":"plt.plot(history.history['acc'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(history.history['val_acc'])\nplt.title('Model accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"adam=optimizers.Adam(lr=0.0001)\nmodel.compile(loss='categorical_crossentropy',\n                     optimizer=adam,\n                     metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#model.load_weights()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X.shape, y.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(X, y, epochs=10, batch_size=64, verbose=1, validation_split=0.2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"debe961c93b72bef151d9aad3ca2cb500ee00aaa"},"cell_type":"code","source":"test = os.listdir(\"../input/test/\")\nprint(len(test))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"72ed8198f519f7b1ae3efbc688933c78d8cdd0e4"},"cell_type":"code","source":"col = ['Image']\ntest_df = pd.DataFrame(test, columns=col)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['Id'] = ''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"52262195fc0b8755cff78bf8c98e6116d50f79af"},"cell_type":"code","source":"X = prepareImages(test_df, test_df.shape[0], 'test')\nX /= 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"88c8d8ff98fbdb1df4218abb6bd51889e855a6fb"},"cell_type":"code","source":"predictions = model.predict(np.array(X), verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"66f0bdde31b8c7847916268aa82d9a1bdc9c0658"},"cell_type":"code","source":"for i, pred in enumerate(predictions):\n    test_df.loc[i, 'Id'] = ' '.join(label_encoder.inverse_transform(pred.argsort()[-5:][::-1]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"09d7c1eb9b554e4e580b0c3c7eb609c15636892d"},"cell_type":"code","source":"\ntest_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\n#os.chdir(r'kaggle/working')\n    \nfrom IPython.display import FileLink\nFileLink(r'submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save_weights('model_vgg_trans.hdf5')\nfrom IPython.display import FileLink\nFileLink(r'model_vgg_trans.hdf5')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}