{"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":"markdown","source":"## Data Overview\n\nRefer to the competition page for details: https://www.kaggle.com/c/dog-breed-identification/overview","metadata":{}},{"cell_type":"markdown","source":"## Dependency","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nimport os\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport pandas as pd","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Global Variables","metadata":{}},{"cell_type":"code","source":"# Hyperparameters\nbatch_size = 128\nepochs = 10\nIMG_HEIGHT = 150\nIMG_WIDTH = 150\nvalidation_split=0.2\n\nrescale=1./255\nrotation_range=0\nwidth_shift_range=0\nheight_shift_range=0\nhorizontal_flip=True\nzoom_range=0","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load Data","metadata":{}},{"cell_type":"code","source":"# Load file-labels data\ntrain_dir = '../input/dog-breed-identification/train/'\ndf = pd.read_csv('../input/dog-breed-identification/labels.csv')\ndf['id']=df['id'].apply(lambda x: x+'.jpg')\nclass_names = np.array(sorted(df['breed'].unique()))\nnum_classes = class_names.shape[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create generator with augmentation\nimage_generator = ImageDataGenerator( rescale=rescale, \n                                      validation_split=validation_split,\n                                      rotation_range=rotation_range,\n                                      width_shift_range=width_shift_range,\n                                      height_shift_range=height_shift_range,\n                                      horizontal_flip=horizontal_flip,\n                                      zoom_range=zoom_range)\ntrain_data_gen = image_generator.flow_from_dataframe(dataframe=df,\n                                                     subset='training',\n                                                       batch_size=batch_size,\n                                                       x_col='id',\n                                                       y_col='breed',\n                                                       directory=train_dir,\n                                                       shuffle=True,\n                                                       target_size=(IMG_HEIGHT, IMG_WIDTH),\n                                                       class_mode='categorical')\nvalidation_data_gen = image_generator.flow_from_dataframe(dataframe=df,\n                                                          subset='validation',\n                                                           batch_size=batch_size,\n                                                           x_col='id',\n                                                           y_col='breed',\n                                                           directory=train_dir,\n                                                           shuffle=True,\n                                                           target_size=(IMG_HEIGHT, IMG_WIDTH),\n                                                           class_mode='categorical')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize sample training data\nsample_training_images, sample_training_labels = next(train_data_gen)\nsample_training_label_id = np.argmax(sample_training_labels, axis=-1)\nsample_training_labels = class_names[sample_training_label_id]\nplt.figure(figsize=(20,20))\nplt.subplots_adjust(hspace=.5)\nfor n in range(30):\n  plt.subplot(6,5,n+1)\n  plt.imshow(sample_training_images[n])\n  plt.title(sample_training_labels[n].title())\n  plt.axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build Model\n\nWe are implementing a transfer learning by leveraging tensorflow pre-trained NN weights. The framework below can be applied to different models. An alternative is to use tf.hub (e.g. https://www.tensorflow.org/tutorials/images/transfer_learning_with_hub) ","metadata":{}},{"cell_type":"code","source":"# Create the base model from the pre-trained model\n'''base_model = tf.keras.applications.MobileNetV2(input_shape=(IMG_HEIGHT,IMG_WIDTH,3),\n                                              include_top=False,\n                                             weights='imagenet')'''\n\nbase_model = tf.keras.applications.VGG16(input_shape=(IMG_HEIGHT,IMG_WIDTH,3),\n                                               include_top=False,\n                                               weights='imagenet')\n\n# Freeze the convolutional base\nbase_model.trainable = False\n\nbase_model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Add classification head\nmodel = tf.keras.Sequential([\n  base_model,\n  layers.GlobalAveragePooling2D(),\n  layers.Dense(num_classes, activation='softmax')\n])\n\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train Model","metadata":{}},{"cell_type":"code","source":"# Complile the model\nmodel.compile(\n  optimizer=tf.keras.optimizers.Adam(),\n  loss='categorical_crossentropy',\n  metrics=['acc'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Start training\nsteps_per_epoch = np.ceil(train_data_gen.samples/train_data_gen.batch_size)\nvalidation_steps = np.ceil(validation_data_gen.samples/validation_data_gen.batch_size)\n\nhistory = model.fit_generator(\n    train_data_gen,\n    steps_per_epoch=steps_per_epoch,\n    epochs=epochs,\n    validation_data=validation_data_gen,\n    validation_steps=validation_steps\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize the learning curve\nacc = history.history['acc']\nval_acc = history.history['val_acc']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nplt.figure(figsize=(8, 8))\nplt.subplot(2, 1, 1)\nplt.plot(acc, label='Training Accuracy')\nplt.plot(val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.ylabel('Accuracy')\nplt.ylim([min(plt.ylim()),1])\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(2, 1, 2)\nplt.plot(loss, label='Training Loss')\nplt.plot(val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.ylabel('Cross Entropy')\nplt.title('Training and Validation Loss')\nplt.xlabel('epoch')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}