{"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 PIL import Image\nimport tensorflow as tf\nimport os\nimport cv2\nimport seaborn as sns","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:15:32.258603Z","iopub.execute_input":"2022-06-04T01:15:32.258912Z","iopub.status.idle":"2022-06-04T01:15:32.616345Z","shell.execute_reply.started":"2022-06-04T01:15:32.258878Z","shell.execute_reply":"2022-06-04T01:15:32.615472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:11:17.069769Z","iopub.execute_input":"2022-06-04T01:11:17.070027Z","iopub.status.idle":"2022-06-04T01:11:17.075276Z","shell.execute_reply.started":"2022-06-04T01:11:17.069993Z","shell.execute_reply":"2022-06-04T01:11:17.073631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:11:17.076657Z","iopub.execute_input":"2022-06-04T01:11:17.076909Z","iopub.status.idle":"2022-06-04T01:11:17.981484Z","shell.execute_reply.started":"2022-06-04T01:11:17.076874Z","shell.execute_reply":"2022-06-04T01:11:17.980754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.resnet_v2 import ResNet50V2\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.applications.resnet_v2 import preprocess_input, decode_predictions\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.layers import Input, Add, Dense, Activation, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D\nfrom tensorflow.keras.models import Model, load_model\n\nfrom tensorflow.keras.initializers import random_uniform, glorot_uniform, constant, identity\nfrom tensorflow.python.framework.ops import EagerTensor\nfrom matplotlib.pyplot import imshow","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:11:17.985016Z","iopub.execute_input":"2022-06-04T01:11:17.985215Z","iopub.status.idle":"2022-06-04T01:11:17.996212Z","shell.execute_reply.started":"2022-06-04T01:11:17.985191Z","shell.execute_reply":"2022-06-04T01:11:17.994792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path= '/kaggle/input/dog-breed-identification/'\nos.chdir(path)\ndata_folder= os.listdir(path)\ndf = pd.read_csv(path + '/labels.csv')","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:11:17.999916Z","iopub.execute_input":"2022-06-04T01:11:18.000095Z","iopub.status.idle":"2022-06-04T01:11:18.042061Z","shell.execute_reply.started":"2022-06-04T01:11:18.000073Z","shell.execute_reply":"2022-06-04T01:11:18.041378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:11:18.043353Z","iopub.execute_input":"2022-06-04T01:11:18.043617Z","iopub.status.idle":"2022-06-04T01:11:18.062288Z","shell.execute_reply.started":"2022-06-04T01:11:18.043581Z","shell.execute_reply":"2022-06-04T01:11:18.061558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df['breed'].value_counts())","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:13:13.073203Z","iopub.execute_input":"2022-06-04T01:13:13.073542Z","iopub.status.idle":"2022-06-04T01:13:13.089035Z","shell.execute_reply.started":"2022-06-04T01:13:13.073486Z","shell.execute_reply":"2022-06-04T01:13:13.088208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize= (120,20))\nplt.subplot(1,2,1)\nsns.countplot(df['breed'])","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:16:32.357781Z","iopub.execute_input":"2022-06-04T01:16:32.358043Z","iopub.status.idle":"2022-06-04T01:16:34.456199Z","shell.execute_reply.started":"2022-06-04T01:16:32.358016Z","shell.execute_reply":"2022-06-04T01:16:34.45548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = \"/kaggle/input/dog-breed-identification/train/\"\nfilenames = [train_path + fname + \".jpg\" for fname in df[\"id\"]]","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:03.741658Z","iopub.execute_input":"2022-06-04T01:43:03.741923Z","iopub.status.idle":"2022-06-04T01:43:03.749986Z","shell.execute_reply.started":"2022-06-04T01:43:03.741895Z","shell.execute_reply":"2022-06-04T01:43:03.749291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(filenames)","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:04.095323Z","iopub.execute_input":"2022-06-04T01:43:04.095719Z","iopub.status.idle":"2022-06-04T01:43:04.101243Z","shell.execute_reply.started":"2022-06-04T01:43:04.095684Z","shell.execute_reply":"2022-06-04T01:43:04.100411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check whether number of filenames matches number of actual image files\nimport os\nif len(os.listdir(train_path)) == len(filenames):\n  print(\"Filenames match actual amount of files!\")\nelse:\n  print(\"Filenames do not match actual amount of files, check the target directory.\")","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:04.40016Z","iopub.execute_input":"2022-06-04T01:43:04.400409Z","iopub.status.idle":"2022-06-04T01:43:04.734977Z","shell.execute_reply.started":"2022-06-04T01:43:04.40038Z","shell.execute_reply":"2022-06-04T01:43:04.734229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = df[\"breed\"].to_numpy() # convert labels column to NumPy array\nlen(labels)","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:10.523494Z","iopub.execute_input":"2022-06-04T01:43:10.523905Z","iopub.status.idle":"2022-06-04T01:43:10.535811Z","shell.execute_reply.started":"2022-06-04T01:43:10.523864Z","shell.execute_reply":"2022-06-04T01:43:10.535082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# See if number of labels matches the number of filenames\nif len(labels) == len(filenames):\n  print(\"Number of labels matches number of filenames!\")\nelse:\n  print(\"Number of labels does not match number of filenames, check data directories.\")","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:12.529824Z","iopub.execute_input":"2022-06-04T01:43:12.530081Z","iopub.status.idle":"2022-06-04T01:43:12.535079Z","shell.execute_reply.started":"2022-06-04T01:43:12.530053Z","shell.execute_reply":"2022-06-04T01:43:12.534303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Tìm số lượng class, loại bỏ những labels trùng nhau\nunique_breeds = np.unique(labels)\nlen(unique_breeds)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-04T01:43:15.77819Z","iopub.execute_input":"2022-06-04T01:43:15.778629Z","iopub.status.idle":"2022-06-04T01:43:15.793033Z","shell.execute_reply.started":"2022-06-04T01:43:15.778595Z","shell.execute_reply":"2022-06-04T01:43:15.792343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure()\nax = fig.add_axes([2,2,2,2])\nax.axis('equal')\nlangs = ['Train', 'Valid']\nstudents = [80,20]\nax.pie(students, labels = langs,autopct='%1.2f%%')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-06-04T02:40:57.419328Z","iopub.execute_input":"2022-06-04T02:40:57.419624Z","iopub.status.idle":"2022-06-04T02:40:57.553884Z","shell.execute_reply.started":"2022-06-04T02:40:57.419588Z","shell.execute_reply":"2022-06-04T02:40:57.553022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# one_hot_encoding\nboolean_labels = [label == np.array(unique_breeds) for label in labels]\n","metadata":{"execution":{"iopub.status.busy":"2022-06-04T02:36:06.109249Z","iopub.execute_input":"2022-06-04T02:36:06.109505Z","iopub.status.idle":"2022-06-04T02:36:06.196833Z","shell.execute_reply.started":"2022-06-04T02:36:06.109476Z","shell.execute_reply":"2022-06-04T02:36:06.196107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Tạo tập train và tập value\nX = filenames\ny = boolean_labels\n\n\n# Import train_test_split from Scikit-Learn\nfrom sklearn.model_selection import train_test_split\n\n# Split them into training and validation using NUM_IMAGES \nX_train, X_val, y_train, y_val = train_test_split(X,\n                                                  y, \n                                                  test_size=0.2,\n                                                  random_state=42)\n\nlen(X_train), len(y_train), len(X_val), len(y_val)\nprint(f\"Number of training images: {len(X_train)}\")\nprint(f\"Number of validation images: {len(X_val)}\")","metadata":{"execution":{"iopub.status.busy":"2022-06-04T02:37:01.932831Z","iopub.execute_input":"2022-06-04T02:37:01.93309Z","iopub.status.idle":"2022-06-04T02:37:01.948704Z","shell.execute_reply.started":"2022-06-04T02:37:01.933062Z","shell.execute_reply":"2022-06-04T02:37:01.948005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 224\n\ndef process_image(image_path):\n  \"\"\"\n  Takes an image file path and turns it into a Tensor.\n  \"\"\"\n  # Read in image file\n  image = tf.io.read_file(image_path)\n  # Turn the jpeg image into numerical Tensor with 3 colour channels (Red, Green, Blue)\n  image = tf.image.decode_jpeg(image, channels=3)\n  # Convert the colour channel values from 0-225 values to 0-1 values\n  image = tf.image.convert_image_dtype(image, tf.float32)\n  # Resize the image to our desired size (224, 244)\n  image = tf.image.resize(image, size=[IMG_SIZE, IMG_SIZE])\n  return image","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:12.450395Z","iopub.execute_input":"2022-05-09T14:23:12.450801Z","iopub.status.idle":"2022-05-09T14:23:12.457759Z","shell.execute_reply.started":"2022-05-09T14:23:12.450758Z","shell.execute_reply":"2022-05-09T14:23:12.456857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_image_label(image_path, label):\n  \"\"\"\n  Takes an image file path name and the associated label,\n  processes the image and returns a tuple of (image, label).\n  \"\"\"\n  image = process_image(image_path)\n  return image, label","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:12.459628Z","iopub.execute_input":"2022-05-09T14:23:12.459826Z","iopub.status.idle":"2022-05-09T14:23:12.467437Z","shell.execute_reply.started":"2022-05-09T14:23:12.45979Z","shell.execute_reply":"2022-05-09T14:23:12.466462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the batch size, 32 is a good default\nBATCH_SIZE = 32\n\n# Create a function to turn data into batches\ndef create_data_batches(x, y=None, batch_size=BATCH_SIZE, valid_data=False, test_data=False):\n  \"\"\"\n  Creates batches of data out of image (x) and label (y) pairs.\n  Shuffles the data if it's training data but doesn't shuffle it if it's validation data.\n  Also accepts test data as input (no labels).\n  \"\"\"\n  # If the data is a test dataset, we probably don't have labels\n  if test_data:\n    print(\"Creating test data batches...\")\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x))) # only filepaths\n    data_batch = data.map(process_image).batch(BATCH_SIZE)\n    return data_batch\n  \n  # If the data if a valid dataset, we don't need to shuffle it\n  elif valid_data:\n    print(\"Creating validation data batches...\")\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x), # filepaths\n                                               tf.constant(y))) # labels\n    data_batch = data.map(get_image_label).batch(BATCH_SIZE)\n    return data_batch\n\n  else:\n    # If the data is a training dataset, we shuffle it\n    print(\"Creating training data batches...\")\n    # Turn filepaths and labels into Tensors\n    data = tf.data.Dataset.from_tensor_slices((tf.constant(x), # filepaths\n                                              tf.constant(y))) # labels\n    \n    # Shuffling pathnames and labels before mapping image processor function is faster than shuffling images\n    data = data.shuffle(buffer_size=len(x))\n\n    # Create (image, label) tuples (this also turns the image path into a preprocessed image)\n    data = data.map(get_image_label)\n\n    # Turn the data into batches\n    data_batch = data.batch(BATCH_SIZE)\n  return data_batch","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:12.469404Z","iopub.execute_input":"2022-05-09T14:23:12.469921Z","iopub.status.idle":"2022-05-09T14:23:12.483557Z","shell.execute_reply.started":"2022-05-09T14:23:12.469879Z","shell.execute_reply":"2022-05-09T14:23:12.482758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = create_data_batches(X_train, y_train)\nval_data = create_data_batches(X_val, y_val, valid_data=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:12.48508Z","iopub.execute_input":"2022-05-09T14:23:12.48535Z","iopub.status.idle":"2022-05-09T14:23:14.9964Z","shell.execute_reply.started":"2022-05-09T14:23:12.485317Z","shell.execute_reply":"2022-05-09T14:23:14.9951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow_hub as hub","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:14.997649Z","iopub.execute_input":"2022-05-09T14:23:14.997878Z","iopub.status.idle":"2022-05-09T14:23:15.283666Z","shell.execute_reply.started":"2022-05-09T14:23:14.997845Z","shell.execute_reply":"2022-05-09T14:23:15.282957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Setup input shape to the model\nINPUT_SHAPE = [None, IMG_SIZE, IMG_SIZE, 3] # batch, height, width, colour channels\n\n# Setup output shape of the model\nOUTPUT_SHAPE = len(unique_breeds) # number of unique labels\n\n# Setup model URL from TensorFlow Hub\nMODEL_URL = \"https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/4\"","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:15.284835Z","iopub.execute_input":"2022-05-09T14:23:15.285119Z","iopub.status.idle":"2022-05-09T14:23:15.291692Z","shell.execute_reply.started":"2022-05-09T14:23:15.285081Z","shell.execute_reply":"2022-05-09T14:23:15.289941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a function which builds a Keras model\ndef create_model(input_shape=INPUT_SHAPE, output_shape=OUTPUT_SHAPE, model_url=MODEL_URL):\n  print(\"Building model with:\", MODEL_URL)\n\n  # Setup the model layers\n  model = tf.keras.Sequential([\n    hub.KerasLayer(MODEL_URL), # Layer 1 (input layer), TensorFlow Hub layer, requires Kaggle internet setting turned on\n    tf.keras.layers.Dense(units=OUTPUT_SHAPE, \n                          activation=\"softmax\") # Layer 2 (output layer)\n  ])\n\n  # Compile the model\n  model.compile(\n      loss=tf.keras.losses.CategoricalCrossentropy(), # Our model wants to reduce this (how wrong its guesses are)\n      optimizer=tf.keras.optimizers.Adam(), # A friend telling our model how to improve its guesses\n      metrics=[\"accuracy\"] # We'd like this to go up\n  )\n\n  # Build the model\n  model.build(INPUT_SHAPE) # Let the model know what kind of inputs it'll be getting\n  \n  return model","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:15.292954Z","iopub.execute_input":"2022-05-09T14:23:15.29336Z","iopub.status.idle":"2022-05-09T14:23:15.305644Z","shell.execute_reply.started":"2022-05-09T14:23:15.293326Z","shell.execute_reply":"2022-05-09T14:23:15.304707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a model and check its details\nmodel = create_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:15.306808Z","iopub.execute_input":"2022-05-09T14:23:15.307224Z","iopub.status.idle":"2022-05-09T14:23:18.486477Z","shell.execute_reply.started":"2022-05-09T14:23:15.307186Z","shell.execute_reply":"2022-05-09T14:23:18.485724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the TensorBoard notebook extension\n%load_ext tensorboard","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:18.487572Z","iopub.execute_input":"2022-05-09T14:23:18.487807Z","iopub.status.idle":"2022-05-09T14:23:18.501845Z","shell.execute_reply.started":"2022-05-09T14:23:18.487772Z","shell.execute_reply":"2022-05-09T14:23:18.501076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import datetime\n\n# Create a function to build a TensorBoard callback\ndef create_tensorboard_callback():\n  # Create a log directory for storing TensorBoard logs\n  logdir = os.path.join(\"logs\",\n                        # Make it so the logs get tracked whenever we run an experiment\n                        datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n  return tf.keras.callbacks.TensorBoard(logdir)","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:18.502922Z","iopub.execute_input":"2022-05-09T14:23:18.503299Z","iopub.status.idle":"2022-05-09T14:23:18.510182Z","shell.execute_reply.started":"2022-05-09T14:23:18.503261Z","shell.execute_reply":"2022-05-09T14:23:18.509327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create early stopping (once our model stops improving, stop training)\nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\",\n                                                  patience=3) # stops after 3 rounds of no improvements","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:18.511386Z","iopub.execute_input":"2022-05-09T14:23:18.511993Z","iopub.status.idle":"2022-05-09T14:23:18.518521Z","shell.execute_reply.started":"2022-05-09T14:23:18.511952Z","shell.execute_reply":"2022-05-09T14:23:18.517772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# How many rounds should we get the model to look through the data?\nNUM_EPOCHS = 100","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:23:18.52058Z","iopub.execute_input":"2022-05-09T14:23:18.520829Z","iopub.status.idle":"2022-05-09T14:23:18.529237Z","shell.execute_reply.started":"2022-05-09T14:23:18.520803Z","shell.execute_reply":"2022-05-09T14:23:18.528384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build a function to train and return a trained model\ndef train_model():\n  \"\"\"\n  Trains a given model and returns the trained version.\n  \"\"\"\n  # Create a model\n  model = create_model()\n\n  # Create new TensorBoard session everytime we train a model\n  tensorboard = create_tensorboard_callback()\n\n  # Fit the model to the data passing it the callbacks we created\n  model.fit(x=train_data,\n            epochs=NUM_EPOCHS,\n            validation_data=val_data,\n            validation_freq=1, # check validation metrics every epoch\n            callbacks=[early_stopping])\n  \n  return model","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:24:38.759253Z","iopub.execute_input":"2022-05-09T14:24:38.759906Z","iopub.status.idle":"2022-05-09T14:24:38.771593Z","shell.execute_reply.started":"2022-05-09T14:24:38.759869Z","shell.execute_reply":"2022-05-09T14:24:38.770805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fit the model to the data\nmodel = train_model()","metadata":{"execution":{"iopub.status.busy":"2022-05-09T14:24:40.196833Z","iopub.execute_input":"2022-05-09T14:24:40.197103Z","iopub.status.idle":"2022-05-09T14:30:14.85533Z","shell.execute_reply.started":"2022-05-09T14:24:40.197072Z","shell.execute_reply":"2022-05-09T14:30:14.854504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}