{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#Import necessary tools\nimport tensorflow as tf\nprint(\"Tensor Flow version:\", tf.__version__)\nimport tensorflow_hub as hub\nprint(\"Tensor Flow Hub version:\", hub.__version__)\n\n#Check for GPU availability\nprint(\"GPU\",\"available (YESS!!)\" if tf.config.list_physical_devices(\"GPU\") else \"not available\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#check out the labels of our data\nimport pandas as pd\nlabels_csv=pd.read_csv(\"/kaggle/input/dog-breed-identification/labels.csv\")\nprint(labels_csv.describe())\nprint(labels_csv.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#How many images of each breed?\nlabels_csv[\"breed\"].value_counts().plot.bar(figsize=(20,10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Lets view an image \nfrom IPython.display import Image\nImage(\"/kaggle/input/dog-breed-identification/train/000bec180eb18c7604dcecc8fe0dba07.jpg\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Getting images and their labels\n\nSince we've got the image ID's and their labels in a DataFrame (`labels_csv`), we'll use it to create:\n* A list a filepaths to training images\n* An array of all labels\n* An array of all unique labels\n\nWe'll only create a list of filepaths to images rather than importing them all to begin with. This is because working with filepaths (strings) is much efficient than working with images.\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"filenames= [\"/kaggle/input/dog-breed-identification/train/\"+ fname + \".jpg\" for fname in labels_csv[\"id\"]]\n# Check the first 10 filenames\nfilenames[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nlabels= labels_csv[\"breed\"].to_numpy()\nprint(labels[:10])\nlen(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Find the unique label values\nunique_breeds = np.unique(labels)\nlen(unique_breeds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Turn one label into an array of booleans\nprint(labels[0])\nlabels[0] == unique_breeds # use comparison operator to create boolean array","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Turn every label into boolean labels\nboolean_labels=[label==np.array(unique_breeds) for label in labels]\nboolean_labels[:2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Example: Turning a boolean array into integers\nprint(labels[0]) # original label\nprint(np.where(unique_breeds == labels[0])[0][0]) # index where label occurs\nprint(boolean_labels[0].argmax()) # index where label occurs in boolean array\nprint(boolean_labels[0].astype(int)) # there will be a 1 where the sample label occurs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Setup X & y variables\nX = filenames\ny = boolean_labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# now lets make a function to preprocess the image\n\n# Define the size\nIMG_SIZE=224\n\n#Create a function for preprocess images\ndef process_image(image_path):\n  \"\"\"\n  Take image file path and turn it into 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,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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Create a function to return a tuple\ndef 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","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Define batch size 32 is default\nBATCH_SIZE=32\n\n#Create a function to turn data to 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\n  #If 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  # 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    \n    return data_batch\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    # 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 ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n#Create a function for viewing images in a data batch\ndef show_25_images(images,labels):\n  \"\"\"\n  Displays 25 images from a data batch.\n  \"\"\"\n  #Setup the figure\n  plt.figure(figsize=(10,10))\n\n  #loop through 25 for 25 images\n  for i in range(25):\n    #Create a subplot 5 rows and 5 columns\n    ax=plt.subplot(5,5,i+1)\n    #Display an image\n    plt.imshow(images[i])\n    # Add the image label as the title\n    plt.title(unique_breeds[labels[i].argmax()])\n    # Turn gird lines off\n    plt.axis(\"off\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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_140_224/classification/4\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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)\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 tells our model how to improve its guesses\n      metrics=[\"accuracy\"]\n  )\n\n  #Build the model\n  model.build(input_shape)\n\n  return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create a model and check its details\nmodel = create_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load tensoboard notebook extension\n%load_ext tensorboard","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import datetime\n\n#Create a function to build a Tensorboard callback\ndef create_tensorboard_callback():\n  #Create a dir for storing Tensorboard logs\n  logdir=os.path.join(\"/kaggle/input/dog-breed-identification/logs\",\n                      #MAke it so that logs can be tracked whenever twe ran an experiment\n                      datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\"))\n  return tf.keras.callbacks.TensorBoard(logdir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create early stopping callback(once our model stop improving, stop training)\nearly_stopping=tf.keras.callbacks.EarlyStopping(monitor=\"val_accuracy\",\n                                                patience=3) #stops after 3 rounds of no improvements","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# How many rounds should we get the model to look through the data?\nNUM_EPOCHS = 100 #@param {type:\"slider\", min:10, max:100, step:10}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Build a function for training a model\ndef train_model():\n  \"\"\"\n  Trains a given model and returned a trained version\n  \"\"\"\n  #Create a model\n  model = create_model()\n\n  #tensorboard session evertime we train a model. For call backs\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,\n            callbacks=[tensorboard,early_stopping])\n  \n  return model\n  \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create a data batch with the full data set\nfull_data = create_data_batches(X, y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Remind ourselves of the size of the full dataset\nlen(X), len(y)\nX[:10]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"full_model=create_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Create full model callbacks\nfull_model_tensorboard=create_tensorboard_callback()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#no validation set when training on all the data, so we cant model val accuracy\nfull_model_early_stopping=tf.keras.callbacks.EarlyStopping(monitor=\"accuracy\", patience=3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Fit the full model to the full data\nfull_model.fit(x=full_data,\n               epochs=NUM_EPOCHS,\n               callbacks=full_model_early_stopping)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load test image filenames\ntest_path = \"/kaggle/input/dog-breed-identification/test/\"\ntest_filenames = [test_path + fname for fname in os.listdir(test_path)]\ntest_filenames[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(test_filenames)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Create test data batch\ntest_data = create_data_batches(test_filenames, test_data=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Make predictions on test data . will take an hour for 10000+ images\ntest_predictions=full_model.predict(test_data,verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_predictions.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_df=pd.DataFrame(columns=[\"id\"]+list(unique_breeds))\npreds_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Append test image ID's to predictions DataFrame\ntest_ids=[os.path.splitext(path)[0] for path in os.listdir(test_path)]\npreds_df[\"id\"] = test_ids","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Add the prediction probabilities to each dog breed column\npreds_df[list(unique_breeds)] = test_predictions\npreds_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}