{"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":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom matplotlib import gridspec\nimport seaborn as sns\n\nimport os\nimport os, warnings\nimport PIL\nimport PIL.Image\n\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing import image_dataset_from_directory\nimport tensorflow_datasets as tfds\nfrom keras.models import Sequential\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom sklearn import preprocessing\n\nimport sys\n\nif not sys.warnoptions:\n    import warnings\n    warnings.simplefilter(\"ignore\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## HappyWhale - Whale and Dolphin Classification","metadata":{}},{"cell_type":"code","source":"df_train=pd.read_csv('../input/happy-whale-and-dolphin/train.csv')\ndf_train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.info()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train['individual_id'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Distribution Species","metadata":{}},{"cell_type":"code","source":"df_train.species.unique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classe_names=['melon_headed_whale', 'humpback_whale', 'false_killer_whale',\n       'bottlenose_dolphin', 'beluga', 'minke_whale', 'fin_whale',\n       'blue_whale', 'gray_whale', 'southern_right_whale',\n       'common_dolphin', 'kiler_whale', 'pilot_whale', 'dusky_dolphin',\n       'killer_whale', 'long_finned_pilot_whale', 'sei_whale',\n       'spinner_dolphin', 'bottlenose_dolpin', 'cuviers_beaked_whale',\n       'spotted_dolphin', 'globis', 'brydes_whale', 'commersons_dolphin',\n       'white_sided_dolphin', 'short_finned_pilot_whale',\n       'rough_toothed_dolphin', 'pantropic_spotted_dolphin',\n       'pygmy_killer_whale', 'frasiers_dolphin']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(classe_names)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"species_view=pd.DataFrame(df_train['species'].value_counts())\nspecies_view\n\nplt.figure(figsize=(14,7))\nlabel=[species_view['species']]\nsns.set_theme(style=\"whitegrid\")\nax=sns.histplot(df_train, x=\"species\",color='#0B606F', kde = True)\nfor rect in ax.patches:\n    height = rect.get_height()\n    ax.annotate(f'{int(height)}', xy=(rect.get_x()+rect.get_width()/2, height), \n                xytext=(0, 5), textcoords='offset points', ha='center', va='bottom') \nplt.xticks(rotation=90)\nax.set_title('Species count', x=0.54, y=1.1, fontsize=30)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocessing VGG16","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:49:08.189357Z","iopub.execute_input":"2022-03-09T14:49:08.189658Z","iopub.status.idle":"2022-03-09T14:49:08.19382Z","shell.execute_reply.started":"2022-03-09T14:49:08.189629Z","shell.execute_reply":"2022-03-09T14:49:08.192824Z"}}},{"cell_type":"code","source":"datagen=ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input,rotation_range=20,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    horizontal_flip=True,\n    validation_split=0.25)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator=datagen.flow_from_dataframe(\n    df_train,\n    directory='../input/happy-whale-and-dolphin/train_images',\n    x_col='image',\n    y_col='species',\n    subset=\"training\",\n    target_size=(224,224),\n    batch_size=32,\n    rescale=1.0/255,\n    seed=1042,\n    shuffle=True,\n    classes=classe_names,\n    class_mode=\"categorical\",)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_generator=datagen.flow_from_dataframe(\n    df_train,\n    directory='../input/happy-whale-and-dolphin/train_images',\n    x_col='image',\n    y_col='species',\n    subset=\"validation\",\n    target_size=(224,224),\n    batch_size=32,\n    rescale=1.0/255,\n    seed=1042,\n    shuffle=True,\n    classes=classe_names,\n    class_mode=\"categorical\",)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(nrows=1, ncols=4, figsize=(15,15))\n\nfor i in range(4):\n    image, label = valid_generator.next()\n    ax[i].imshow(image[0])\n    ax[i].axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission=pd.read_csv('../input/happy-whale-and-dolphin/sample_submission.csv')\ndf_submission.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen=ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input)\ntest_generator=test_datagen.flow_from_dataframe(\n    df_submission,\n    directory='../input/happy-whale-and-dolphin/test_images',\n    x_col='image',\n    y_col=None,\n    target_size=(224,224),\n    batch_size=32,\n    rescale=1.0/255,\n    seed=2020,\n    shuffle=False,\n    class_mode=None,)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## The VGG16 preprocessing can be use to make a better approche for knucles, dorsal humps scars and pigmentation\n## useful to identification of species","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(nrows=1, ncols=4, figsize=(15,15))\n\nfor i in range(4):\n    image = next(test_generator)[0].astype('uint8')\n    image = np.squeeze(image)\n    ax[i].imshow(image)\n    ax[i].axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\nfrom tensorflow.keras import layers\nfrom keras.layers import Dense, Activation, Flatten, Dropout, BatchNormalization\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras import regularizers\nfrom tensorflow.keras import optimizers\nfrom keras.layers import Dense, Conv2D , MaxPool2D , Flatten , Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom keras.callbacks import ReduceLROnPlateau\nfrom tensorflow.keras.optimizers import SGD\nfrom keras.regularizers import l2\nimport tensorflow_hub as hub\nimport tensorflow_addons as tfa\nfrom tensorflow.keras.models import Model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##################################################################","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.vgg16 import VGG16","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = [224, 224]\nvgg = VGG16(input_shape=IMAGE_SIZE + [3], weights='imagenet', include_top=False) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model=Sequential()\nfor layer in vgg.layers[:-1]:\n    model.add(layer)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def count_params(model):\n    non_trainable_params=np.sum([np.prod(v.get_shape().as_list()) for v in model.non_trainable_weights])\n    trainable_params=np.sum([np.prod(v.get_shape().as_list()) for v in model.trainable_weights])\n    return {'non_trainable_params': non_trainable_params, 'trainable_params': trainable_params}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable=False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = Flatten()(vgg.output)\nprediction=Dense(units=30, activation='softmax')(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Model(inputs=vgg.input, outputs=prediction)\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer=Adam(learning_rate=0.01), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size=64","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(x=train_generator, validation_data=valid_generator, steps_per_epoch=50,validation_steps=100,epochs=2,)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -U tensorflow-addons","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"####################################################################","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(64, (3, 3), activation='relu', padding='same', name='conv_1', input_shape=(224, 224,3)))\nmodel.add(MaxPooling2D((2, 2), strides=(1,1),name='maxpool_1'))\nmodel.add(Conv2D(64, (3, 3), activation='relu', padding='same',name='conv_2'))\nmodel.add(MaxPooling2D((2, 2), strides=(2,2),name='maxpool_2'))\nmodel.add(Conv2D(128, (3, 3), activation='relu', padding='same',name='conv_3'))\nmodel.add(MaxPooling2D((2, 2),strides=(1,1),name='maxpool_3'))\nmodel.add(Conv2D(128, (3, 3), activation='relu', padding='same',name='conv_4'))\nmodel.add(MaxPooling2D((2, 2),strides=(2,2), name='maxpool_4'))\n\n\nmodel.add(Conv2D(256, (3, 3), activation='relu', padding='same',name='conv_5'))\nmodel.add(Conv2D(256, (2, 2), activation='relu', padding='same',name='conv_6'))\nmodel.add(Flatten())\nmodel.add(Dropout(0.5))\n\n\nmodel.add(Dense(512, activation='relu', name='dense_1'))\nmodel.add(Dense(256, activation='relu', name='dense_2'))\nmodel.add(BatchNormalization())\nmodel.add(Dense(30, activation='softmax', name='output'))\n\n#optimizer = tf.keras.optimizers.Adam(learning_rate=0.01,\n#    beta_1=0.9,\n#    beta_2=0.999,\n#    epsilon=1e-07,\n#    amsgrad=False,\n#    name=\"Adam\",)\n#opt = tfa.optimizers.Lookahead(optimizer)\n#model.compile(optimizer='Adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n  optimizer=tf.keras.optimizers.Adam(learning_rate=0.005), \n  loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True, label_smoothing=0.1),\n  metrics=['accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    layer.trainable=False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE=32","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size=len(train_generator)\nvalid_size=len(valid_generator)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"steps_per_epoch = train_size // BATCH_SIZE\nvalidation_steps = valid_size // BATCH_SIZE\nhist = model.fit(\n    train_generator,\n    epochs=5, steps_per_epoch=steps_per_epoch,\n    validation_data=valid_generator,\n    validation_steps=validation_steps).history","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure()\nplt.ylabel(\"Loss (training and validation)\")\nplt.xlabel(\"Training Steps\")\nplt.ylim([0,2])\nplt.plot(hist[\"loss\"])\nplt.plot(hist[\"val_loss\"])\n\nplt.figure()\nplt.ylabel(\"Accuracy (training and validation)\")\nplt.xlabel(\"Training Steps\")\nplt.ylim([0,1])\nplt.plot(hist[\"accuracy\"])\nplt.plot(hist[\"val_accuracy\"])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rlrp = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, min_delta=1E-7,verbose=1)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit_generator(train_generator, steps_per_epoch=4000//batch_size, epochs=4,\n                              validation_data=valid_generator, validation_steps=800//batch_size,verbose=1, validation_freq=1,callbacks=[rlrp]) ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_frame = pd.DataFrame(history.history)\nhistory_frame.loc[:, ['loss', 'val_loss']].plot()\nhistory_frame.loc[:, ['accuracy', 'val_accuracy']].plot();","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#########################################################################################################","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_model = Sequential()\nmy_model.add(Conv2D(64, kernel_size=4, strides=1, activation='relu',input_shape=(224, 224, 3)))\nmy_model.add(Conv2D(64, kernel_size=4, strides=2, activation='relu'))\nmy_model.add(Dropout(0.5))\nmy_model.add(Conv2D(128, kernel_size=4, strides=1, activation='relu'))\nmy_model.add(Conv2D(128, kernel_size=4, strides=2, activation='relu'))\nmy_model.add(Dropout(0.5))\nmy_model.add(Conv2D(256, kernel_size=4, strides=1, activation='relu'))\nmy_model.add(Conv2D(256, kernel_size=4, strides=2, activation='relu'))\nmy_model.add(Flatten())\nmy_model.add(Dropout(0.5))\nmy_model.add(Dense(512, activation='relu'))\nmy_model.add(Dense(30, activation='softmax'))\n\nmy_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=[\"accuracy\"])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_model.fit_generator(train_generator, epochs=5, validation_data=val_generator)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history_frame = pd.DataFrame(history.history)\nhistory_frame.loc[:, ['loss', 'val_loss']].plot()\nhistory_frame.loc[:, ['accuracy', 'val_accuracy']].plot();","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Save model","metadata":{}},{"cell_type":"code","source":"\nmodel.save('model.h5')\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load model","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.models import load_model\nnew_model=load_model('../input/model-happywhale/model.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probability_model = tf.keras.Sequential([model, tf.keras.layers.Softmax()])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = probability_model.predict_generator(test_generator[0])\nprediction2 = probability_model.predict_generator(test_generator[10])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_generator[0])\nprediction2 = model.predict(test_generator[10])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.argmax(predictions[0])\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.argmax(prediction2[0])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator.class_indices","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.image as mpimg\nimg = mpimg.imread('../input/happy-whale-and-dolphin/test_images/000110707af0ba.jpg')\nimgplot = plt.imshow(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = mpimg.imread('../input/happy-whale-and-dolphin/test_images/00150406ce5395.jpg')\nimgplot = plt.imshow(img)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"desired_batch_size=32\nfilenames = test_generator.filenames\nnb_samples = len(filenames)\n\npredict = probability_model.predict_generator(test_generator,steps = np.ceil(nb_samples/desired_batch_size))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nfrom tqdm import tqdm\nimport itertools\n\ndesired_batch_size=10000\nfilenames = test_generator.filenames\nnb_samples = len(filenames)\npred=[]\nfor row in tqdm(itertools.islice(test_generator, 27956)):\n    pred.append(probability_model.predict_generator(row,steps =  np.ceil(nb_samples/desired_batch_size)))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission[\"predictions\"] = pred\ndf_submission.to_csv(\"submission.csv\", index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}