{"cells":[{"metadata":{},"cell_type":"markdown","source":"# End to end multi class dog breed classification \nthis notebook builds the multiclass classification using the tensorflow's latest version which is 2.4.1 \nand tensorflow hub \n\n## problem \nIdentify the breeds of the dogs given an image of the dog \n## data \ndata is imported from the kaggle competition \n\n## evalutation \n    evaluation is the file with the prediction probabilities of each dog breed of the test images \n\n## features\nsome info about data \n* we are dealing with the images (120) breeds of the dogs \n* we are using the deep learning/ trnasfer learning ( this is the multiclass classification ) \n* there are around the 10000 + images in the training set and 10000 in the test set \n* training set images are having the labels but the testing dataset are not having any labels \n"},{"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 20GB 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":{"trusted":true},"cell_type":"code","source":"data = pd.read_csv('../input/dog-breed-identification/labels.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# importing the data and getting the workspace ready \nimport tensorflow as tf \nprint('tf version ',tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow_hub as hub\nprint('tf_hub version' , hub.__version__)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('GPU available ' if tf.config.list_physical_devices('GPU') else print('its not avail'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nimport tensorflow as tf\nimport timeit\n\ndevice_name = tf.test.gpu_device_name()\nif device_name != '/device:GPU:0':\n  print(\n      '\\n\\nThis error most likely means that this notebook is not '\n      'configured to use a GPU.  Change this in Notebook Settings via the '\n      'command palette (cmd/ctrl-shift-P) or the Edit menu.\\n\\n')\n  raise SystemError('GPU device not found')\n\ndef cpu():\n  with tf.device('/cpu:0'):\n    random_image_cpu = tf.random.normal((100, 100, 100, 3))\n    net_cpu = tf.keras.layers.Conv2D(32, 7)(random_image_cpu)\n    return tf.math.reduce_sum(net_cpu)\n\ndef gpu():\n  with tf.device('/device:GPU:0'):\n    random_image_gpu = tf.random.normal((100, 100, 100, 3))\n    net_gpu = tf.keras.layers.Conv2D(32, 7)(random_image_gpu)\n    return tf.math.reduce_sum(net_gpu)\n  \n# We run each op once to warm up; see: https://stackoverflow.com/a/45067900\ncpu()\ngpu()\n\n# Run the op several times.\nprint('Time (s) to convolve 32x7x7x3 filter over random 100x100x100x3 images '\n      '(batch x height x width x channel). Sum of ten runs.')\nprint('CPU (s):')\ncpu_time = timeit.timeit('cpu()', number=10, setup=\"from __main__ import cpu\")\nprint(cpu_time)\nprint('GPU (s):')\ngpu_time = timeit.timeit('gpu()', number=10, setup=\"from __main__ import gpu\")\nprint(gpu_time)\nprint('GPU speedup over CPU: {}x'.format(int(cpu_time/gpu_time)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# if we do get the runtime disconnected model restart with runnning all the cells \n#  getting the data ready (converting the images into tensor's ) \ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['breed'].value_counts().plot.bar(figsize=(20,10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['breed'].value_counts().median()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# viewing the images inside the notebook\nfrom IPython.display import Image\nImage('../input/dog-breed-identification/train/001513dfcb2ffafc82cccf4d8bbaba97.jpg')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### getting the images and their labels \ngetting the list of the image file pathnames \n"},{"metadata":{"trusted":true},"cell_type":"code","source":"data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating the pathnames from image id's\nfilenames = ['../input/dog-breed-identification/train/'+fname+'.jpg' for fname in data['id'] ]\nfilenames","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Image(filenames[-1:][0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os \nif len(os.listdir('../input/dog-breed-identification/train/')) == len(filenames):\n    print('filenames match the actual amount ')\nelse : \n    print('filenames do not match the actual amt ')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Image(filenames[9000])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['breed'][9000]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# let's prepare the lables \nlabels = np.array(data.breed)\nlabels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if len(labels) == len(filenames):\n    print('all the data can be mapped ')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"unique_breeds = np.unique(labels)\nlen(unique_breeds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(labels[0])\nlabels[0] == unique_breeds ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# turning the labels into a boolean array \nboolean_labels =  [label == unique_breeds for label in labels ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(boolean_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# turnign the boolean array into the integers \nprint(labels[0])\nprint(np.where(unique_breeds == labels[0])) # index where the label occurs \nprint(boolean_labels[0].argmax()) # index where label occurs in boolean array \nprint(boolean_labels[0].astype(int)) # there will be 1 where the sample occurs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating our own validation set \nx = filenames\ny = boolean_labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# setting the number of images for experimenting \nNUM_IMAGES = 1000  #@param {type:'slider',min:1000,max:10000,step:1000}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# splitting the data into train and validation \nfrom sklearn.model_selection import train_test_split\n# splitting the data into 2 different sets \nx_train,x_val, y_train,y_val = train_test_split(x[:1000],y[:1000],test_size = 0.2,random_state = 42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(x_train), len(x_val), len(y_train), len(y_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train[:5],y_train[:2]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# preprocessing images turning the images into the tensor's\n# using the filepath as input \n\n# conver the image into the numpy array with importing the image \nfrom matplotlib.pyplot import imread \nimage = imread(filenames[42])\nimage.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tf.constant(image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# writing the function to turn the image into tensors tensors are execute faster with gpu's \nIMG_SIZE = 224 \ndef process_image(image_path,img_size = IMG_SIZE):\n    image = tf.io.read_file(image_path)\n    # turning the jpeg image into numberical tensor in 3 color channels \n    image = tf.image.decode_jpeg(image,channels=3)\n    # converting the color channel values from 0-255 to 0-1 values \n    image = tf.image.convert_image_dtype(image,tf.float32)\n    # resizing the image into the specified 224 \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":"# turnign the data into the batches of 32 tensorflow executes batches more efficiently cause all the 1000 image might not fit into the memory \n# create a simple function to get the label \ndef get_image_label(image_path,label):\n    image  = process_image(image_path)\n    return image,label\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# turning the images into the batches \nBATCH_SIZE = 32 \n# creating the function to turn data into batches \ndef create_data_batches(x,y=None,batch_size = BATCH_SIZE,valid_data = False,test_data = False):\n    #if the data is the data is the test data set then we don't have the labels \n    if test_data : \n        print('creating the test data batches')\n        data = tf.data.Dataset.from_tensor_slices((tf.constant(x))) # only file paths no labels \n        data_batch = data.map(process_image).batch(batch_size)\n        return data_batch \n    # if the data is the validation dataset we don't need to shuffle the validation data set \n    elif valid_data:\n        print('creating the validation dataset batches ')\n        data = tf.data.Dataset.from_tensor_slices((tf.constant(x),tf.constant(y)))# file paths and labels \n        data_batch = data.map(get_image_label).batch(batch_size)\n        return data_batch\n    else:\n        print('creating the training databatches')\n        # turning the file path and label's into tensors \n        data = tf.data.Dataset.from_tensor_slices((tf.constant(x),tf.constant(y)))\n        # shuffling pathnames and labels before mapping images to the processor function is faster than shuffling images\n        data = data.shuffle(buffer_size=len(x))\n        data = data.map(get_image_label)\n        #turning the training data into batches \n        data_batch = data.batch(batch_size)\n        return data_batch\n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating the training data and the validation data batches \ntrain_data = create_data_batches(x_train,y_train)\nval_data = create_data_batches(x_val,y_val,valid_data=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" train_data.element_spec,val_data.element_spec ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# visualizing the data batches \n#  data is now in the batches but it's hard to understand let's visualize them \n\nimport matplotlib.pyplot as plt \n#  creating the function of viewing the images in the data batch \ndef show_25_images(images,labels):\n    plt.figure(figsize = (10,10))\n    # loop through the 25 images \n    for i in range(25):\n        # creating the subplots 5 rows and 5 cols \n        ax = plt.subplot( 5,  5 , i+1)\n        plt.imshow(images[i]) #showing the ith image \n        plt.title(unique_breeds[labels[i].argmax()])\n        plt.axis('off') # turning the gridlines off \n        ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images,train_labels = next(train_data.as_numpy_iterator())\nlen(train_images), len(train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# let's visualize the data in the training batch \nshow_25_images(train_images,train_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# let's visualize the validation data \nval_images, val_labels = next(val_data.as_numpy_iterator())\nshow_25_images(val_images,val_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# building the model \n# before we build a model there are few things which we need to define \n# the input shape in the form of the tensors to our model \n#  the output shape image, labels in the form of the tensors \n# URL of the model which we want to use \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# setting up the input shape to the model \nINPUT_SHAPE = [None,IMG_SIZE,IMG_SIZE,3 ] # batch , height width and the color channels \n\nOUTPUT_SHAPE = len(unique_breeds)\n\n# SETTING  the model url with the tensorflow hub \nMODEL_URL = 'https://tfhub.dev/google/imagenet/mobilenet_v2_130_224/classification/4' # we get the model from tensorflow hub ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating the ML model function let's put them together into keras deep learning model \n#  getting the functional into line by line \n# the func takes the input shape, output shape and the model we choosen as parameters and defines the layers in keras in sequential model \n# compiles the model (how it should be evaluated/ improved )\n# builds the model tells the input shape which it's getting \n#  returns the model all the steps can be referred to keras overview in tensorflow website ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef create_model(input_shape=INPUT_SHAPE,output_shape = OUTPUT_SHAPE,model_url = MODEL_URL):\n    print('building the model with ' + model_url)\n    # setting up the layers \n    model = tf.keras.Sequential([\n        hub.KerasLayer(model_url),# layer 1 input layer \n        tf.keras.layers.Dense(units=output_shape,activation='softmax') # layer 2 output layer \n        \n    ])\n    #compile the model \n    model.compile(\n    loss = tf.keras.losses.CategoricalCrossentropy(),\n        optimizer=tf.keras.optimizers.Adam(),\n        metrics = ['accuracy']\n    )\n    model.build(input_shape)\n    return model ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs = np.ones(shape=(1,1,200))\noutputs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#  creating the callback's \n# callbacks are the helper function which in runtime helps the model to save it's progress , check it's progress, stop training early if the model stops \n# we are creating 2 callback's one for the tensorboard for checking the progress and one for the early stopping which will prevent the model for running too long \n# tensorboard callback \n# Load Tensorboard notebook extension \n%load_ext tensorboard ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# to set up the tensorboard callback we will need to do 3 things \n1. loading the tensorboard notebook extension \n2. creating the tensorboard callbacks which will save the logs to the directory \n    passign the model to the fit function\n3. visualizing the model's training log with tensorboard magic function "},{"metadata":{"trusted":true},"cell_type":"code","source":"import datetime\n# creating the function to build a tensorboard call back  \ndef create_tensorboard_callback():\n    logdir = os.path.join(\"./logs\",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":"# training the model \n#  the first model is gonna train on the thousand images to making sure everything is working fine \nearly_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_accuracy',patience=3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NO_EPOCHS = 100 \n# checking to make sure we are working on the gpu \nprint('GPU Avail YAYYYYYYYYYYYY' if tf.config.list_physical_devices('GPU') else print(\"NA\"))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# creating the function to train the model \nsetting up the tensorboard using create_tensorboard_callback \ncalling the fit function for training data , val data, no of epochs  adn the callbacks which will help the func"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Build the function to train and return the trained model \ndef train_model():\n    model = create_model()\n    # creating the new tensorboard sessoin everytime we create the model \n    tensorboard = create_tensorboard_callback()\n    # fitting the model to the data passing the callbacks we created \n    model.fit(x=train_data,\n             epochs = NO_EPOCHS,\n             validation_data = val_data,\n             validation_freq=1,\n             callbacks=[tensorboard,early_stopping])\n    #returning the fitted model \n    return model ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":" #fitting the model to the data \nmodel =train_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# checking the tensorboard logs \n#  %tensorboard used to access the data \n%tensorboard --logdir ./logs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# making and evaluating the predictions with the trained model \nval_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions = model.predict(val_data,verbose=1)\npredictions","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(y_val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(unique_breeds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(predictions[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def predict_probas(index):\n    print(predictions[index])\n    print(f'max prediction is : {np.max(predictions[0])}')\n    print('sum', np.sum(predictions[0]))\n    print('max Index : ', np.argmax(predictions[index]))\n    print('predicted label ;',unique_breeds[np.argmax(predictions[index])])\n    print('actual label ' )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict_probas(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in range(10):\n    predict_probas(i)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# prediction probabilities are the confidence levels \ndef get_predict_label(predict ):\n    return unique_breeds[np.argmax(predict)]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"get_predict_label(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# we will have to unbatch the data to get our actual validation predictions \nimages = []\nlabels = []\n\nfor image, label in val_data.unbatch().as_numpy_iterator():\n    images.append(image)\n    labels.append(label)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from matplotlib.pyplot import imshow\nimshow(images[0]),get_predict_label(labels[0]),get_predict_label(predictions[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def unbatch_data(data):\n    images = []\n    labels = []\n    \n    \n    \n    for image,label in data.unbatch().as_numpy_iterator():\n        images.append(image)\n        labels.append(labels)\n    return images, labels\nval_images, val_labels = unbatch_data(val_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# i = 1 \n# plt.subplot(1,1,i)\n# plt.imshow(images[i])\n# plt.title('predicted:' + str(get_predict_label(predictions[i])) + 'actual :' + str(get_predict_label(val_labels[i])) )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_pred(predictions_probabilities , labels, images,n=1):\n    pred_prob,true_label,image = predictions_probabilities[1],labels[1],images[1]\n    # get the pred lables \n    pred_label = get_predict_label(pred_prob)\n#     plt.imshow(image)\n#     plt.xticks([])\n#     plt.yticks([])\n    \n    print(str(pred_label)+str(np.max(pred_prob)*100)+str(unique_breeds[np.argmax(true_label)]))\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_pred(predictions_probabilities=predictions,labels=val_labels,images=images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"% timeit \nprint('hello world ')","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}