{"id":1563,"date":"2019-06-17T14:59:44","date_gmt":"2019-06-17T09:29:44","guid":{"rendered":"https:\/\/debuggercafe.com\/?p=1563"},"modified":"2023-01-08T16:19:43","modified_gmt":"2023-01-08T10:49:43","slug":"wild-cats-image-classification-using-deep-learning","status":"publish","type":"post","link":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/","title":{"rendered":"Wild Cats Image Classification using Deep Learning"},"content":{"rendered":"\n<p>Updated: April 8, 2020.<\/p>\n\n\n\n<p>You must have come across numerous tutorials to distinguish between cats and dogs using deep learning. Well, then this tutorial is going to be a bit different and a whole lot interesting. In this article, we too will be using deep learning with Keras and TensorFlow for image classification. But with one difference, we will be classifying between images of wild cats, namely, golden tigers, white tigers and, mountain lions.<\/p>\n\n\n\n<p>You can go ahead and download the project file. After extracting the file you will have the data, the pre-trained model and, also the original Jupyter Notebook.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline is-style-outline--1\"><a class=\"wp-block-button__link has-black-color has-luminous-vivid-orange-background-color has-text-color has-background\" href=\"https:\/\/drive.google.com\/file\/d\/12QbE3_3I6LyK6zE73lbIdHByPMuEMEs2\/view?usp=sharing\" target=\"_blank\" rel=\"noreferrer noopener\">Download Project and Trained Models<\/a><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Directory Structure <\/h2>\n\n\n\n<p>It is not mandatory that you should use the same data as provided here. You can use your own data and by the end of this post, you will have a personal project ready. Just make sure that the folder structure of the data should be the same as provided. The following is the tree structure of the project directory.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u251c\u2500\u2500\u2500.ipynb_checkpoints\n\u251c\u2500\u2500\u2500data\n\u2502   \u251c\u2500\u2500\u2500golden_tiger\n\u2502   \u251c\u2500\u2500\u2500mountain_lion\n\u2502   \u2514\u2500\u2500\u2500white_tiger\n\u251c\u2500\u2500\u2500images\n\u2514\u2500\u2500\u2500logs\n    \u251c\u2500\u2500\u2500wild-cats-1560494714\n    \u2514\u2500\u2500\u2500wild-cats-1560495009<\/pre>\n\n\n\n<p>We have the <code>data<\/code> directory and three sub-directories inside it. The sub-directories (<em>golden_tiger,&nbsp;mountain_lion,&nbsp;white_tiger<\/em>) contain the respective images of the wild cats. If you consider using your own data, then just replace the sub-directories with your own. The names of the sub-directories will act as labels. So, it will be better if you give intuitive names to those.<\/p>\n\n\n\n<p>The <code>images<\/code> directory contains the test images that we will use after the model has been trained.<\/p>\n\n\n\n<p>The <code>logs<\/code> directory contains the TensorBoard logs. We will be using TensorBoard to visualize the train and validation plots and also see the graph of the model. If you are going to use TensorBoard for the first time, then you may find <strong><a rel=\"noreferrer noopener\" aria-label=\"this (opens in a new tab)\" href=\"https:\/\/debuggercafe.com\/keras-deep-learning-with-tensorboard-visualization\/\" target=\"_blank\">this<\/a><\/strong> article useful. <\/p>\n\n\n\n<p>Moreover, if you want to download new images for this tutorial, then please refer to my previous article &#8211; <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/debuggercafe.com\/create-your-own-deep-learning-image-dataset\/\" target=\"_blank\"><strong>Create Your Own Deep Learning Image Dataset<\/strong><\/a>. Just one more thing. We will be using <code>tf.keras<\/code> module instead of the direct Keras API. If you find the model building codes too long, then feel free to use Keras directly. Okay, let&#8217;s start.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Loading Data and Preprocessing<\/h2>\n\n\n\n<p>The following block of code imports all the necessary packages.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># import packages\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport numpy as np\nimport random\nimport pickle\nimport time\nimport cv2\nimport os\n\nfrom sklearn.preprocessing import LabelBinarizer\nfrom sklearn.model_selection import train_test_split\nfrom imutils import paths<\/pre>\n\n\n\n<p>The above code is mostly self-explanatory. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>time<\/code> module will help us to get a different <strong>timestamp <\/strong>for each of the TensorBoard logs so that the previous ones do not get replaced.<\/li><li>Using <code>cv2<\/code> we will read the images, make necessary changes before feeding the image to the model and also <strong>visualize the predictions<\/strong>.<\/li><li>We will use <code>LabelBinarizer<\/code> from Scikit-Learn to <strong>get the image labels<\/strong>.<\/li><\/ul>\n\n\n\n<p>Moving on, let&#8217;s get the image paths:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># path to the images\ndata_path = 'data'\n\nimages = []\nimage_labels = []\n\n# get the image paths inside the `data` directory\nimage_paths = sorted(list(paths.list_images(data_path)))\n# for reproducibility\nrandom.seed(42)\n# shuffle the images\nrandom.shuffle(image_paths)<\/pre>\n\n\n\n<p>We initialize two lists, <code>images<\/code> and <code>image_labels<\/code> which will hold our images and the labels of the images respectively. For this project, we have three labels, <em>golden_tiger<\/em>, <em>white_tiger<\/em> and <em>mountain_lion<\/em>. Next, we use <code>random.seed()<\/code> for reproducibility, in case we need to run the code again. Finally, we shuffle all the images.<\/p>\n\n\n\n<p>Now, let&#8217;s read the images and resize them using <code>cv2<\/code>. We will also append each image to the <code>images<\/code> list and the labels to the <code>image_labels<\/code> list.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for image_path in image_paths:\n    # load and resize the images\n    image = cv2.imread(image_path)\n    image = cv2.resize(image, (128, 128))\n    images.append(image)\n    \n    # get the labels from the image paths and store in `image_labels`\n    image_label = image_path.split(os.path.sep)[-2]\n    image_labels.append(image_label)<\/pre>\n\n\n\n<p>It is a good idea to rescale the image pixels. Rescaling is a very important factor when considering the accuracy and performance of neural networks.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># rescale the image pixels \nimages = np.array(images, dtype='float') \/ 255.0\n# make `image_labels` as array\nimage_labels = np.array(image_labels)<\/pre>\n\n\n\n<p>Moving on, we will now split the data into train and validation test. We will be using 80% of the data for training and 20% for validation.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># divide the image data into train set and test set\n(train_X, test_X, train_y, test_y) = train_test_split(images, image_labels, \n                                                      test_size=0.2, \n                                                      random_state=42)<\/pre>\n\n\n\n<p>The <code>image_labels<\/code> is a list of strings. To use it properly during training and inference (prediction) we need to convert those into one-hot labels. <\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># one-hot encode the labels\nlb = LabelBinarizer()\ntrain_y = lb.fit_transform(train_y)\ntest_y = lb.fit_transform(test_y)<\/pre>\n\n\n\n<p>So, now for <em>golden_tiger<\/em>, we will have [1, 0, 0]. This means that the image is true for <em>golden_tiger<\/em> only (hence, the 1). Similarly, it will be [0, 1, 0], [0, 0, 1] for <em>mountain_lion<\/em> and <em>white_tiger<\/em> respectively.<\/p>\n\n\n\n<p>Next, we will insert the code image augmentation generator. This will provide our model with a lot of different cases to learn while training. Hopefully, this step will help in achieving better accuracy.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># generator for image augmentation\nimage_aug = tf.keras.preprocessing.image.ImageDataGenerator(rotation_range=30, shear_range=0.2, \n    zoom_range=0.2, height_shift_range=0.2, width_shift_range=0.2, \n    horizontal_flip=True, fill_mode='nearest')<\/pre>\n\n\n\n<p>For data augmentation, we are using the <code>ImageDataGenerator<\/code> from <code>tf.keras<\/code> module.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Building the Model<\/h2>\n\n\n\n<p>Now, its time to build our model. Frankly, the model does have a lot of layers. Let&#8217;s insert the code fist, then I will move on to explain the layers.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># build the model\nmodel = tf.keras.models.Sequential()\ninput_shape = (128, 128, 3)\n\nmodel.add(tf.keras.layers.Conv2D(32, (3, 3), padding='same', \n            activation='relu', input_shape=input_shape))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))      \nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\nmodel.add(tf.keras.layers.Dropout(0.2))\n        \nmodel.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same', \n                                 activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))\nmodel.add(tf.keras.layers.Conv2D(64, (3, 3), padding='same', \n                                 activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\nmodel.add(tf.keras.layers.Dropout(0.2))\n\nmodel.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', \n                                 activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))\nmodel.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', \n                                 activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))\nmodel.add(tf.keras.layers.Conv2D(128, (3, 3), padding='same', \n                                 activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization(axis=-1))\nmodel.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))\nmodel.add(tf.keras.layers.Dropout(0.2))\n\nmodel.add(tf.keras.layers.Flatten())\nmodel.add(tf.keras.layers.Dense(512, activation='relu'))\nmodel.add(tf.keras.layers.BatchNormalization())\nmodel.add(tf.keras.layers.Dropout(0.2))\n\nmodel.add(tf.keras.layers.Dense(len(lb.classes_), activation='softmax'))<\/pre>\n\n\n\n<p>First of all, we are using the <code>Sequntial()<\/code> API to build the model. Secondly, the we have given the input shape as <code>(128, 128, 3)<\/code> for the height, width and channels. So, it is a channels last input shape.<\/p>\n\n\n\n<p>Now, moving on to the actual layers, we are using <code>Conv2D<\/code> with <code>relu<\/code> activation function and <code>padding=same<\/code>. For the first convolutional layer we have given the output dimensionality as 32. Then we gradually increase it to 64 and 128. Each of the <code>Conv2D<\/code> layer is having its own <code>BatchNormalization<\/code> layer as well. The <code>axis<\/code> is -1 as we are using channels last. Then we have the <code>MaxPooling<\/code> layer with <code>pool_size=(2, 2)<\/code> and <code>Dropout<\/code> layer with a rate of 0.2.<\/p>\n\n\n\n<p>In the model, the only exceptions are the last hidden layer and the output layer. For the last hidden layer we are using <code>Dense<\/code> with 512 dimensionality. The output layer is using <code>softmax<\/code> activation function and the output dimensionality is <code>len(lb.classes)<\/code>. That would amount to 3 as we have 3 classes in total. <\/p>\n\n\n\n<p>Now, we are going to create a <a rel=\"noreferrer noopener\" aria-label=\"TensorBoard (opens in a new tab)\" href=\"https:\/\/debuggercafe.com\/keras-deep-learning-with-tensorboard-visualization\/\" target=\"_blank\"><strong>TensorBoard<\/strong><\/a> callback to save the training logs.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">NAME = 'wild-cats-{}'.format(int(time.time())) # to save different tensorboard logs each time\n \ntensorboard = tf.keras.callbacks.TensorBoard(log_dir='logs\/{}'.format(NAME))<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Compiling and Running the Model<\/h2>\n\n\n\n<p>In this part, we are going to define the optimizer, compile the model and train it using <code>fit_generator<\/code>. We will be using <code>fit_generator()<\/code> instead of <code>fit()<\/code> as we have an <code>ImageDataGenerator()<\/code> in the pipeline for augmenting the images.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">optimizer = tf.keras.optimizers.Adam(lr=0.01)\nmodel.compile(loss='categorical_crossentropy', optimizer=optimizer, \n              metrics=['accuracy'])\n\nhistory = model.fit_generator(image_aug.flow(train_X, train_y, \n                                             batch_size=32), \n                              validation_data=(test_X, test_y), \n                              steps_per_epoch=len(train_X) \/\/ 32, \n                              epochs=50, callbacks=[tensorboard])<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Saving the Model<\/h3>\n\n\n\n<p>It is always a good idea to save the model weights after training. Here, we will be saving the trained model as well as the labels as a <em>pickle<\/em> file.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">model.save('conv2d.model')\nf = open('conv2d_lb.pickle', 'wb')\nf.write(pickle.dumps(lb))\nf.close()<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Plotting and TensorBoard Visualization<\/h2>\n\n\n\n<p>Before we move on to the inference stage let&#8217;s see all the accuracies and losses in a single plot. That would help in comparing them in a better way.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">num_epochs = np.arange(0, 50)\nplt.figure(dpi=300)\nplt.plot(num_epochs, history.history['loss'], label='train_loss', c='red')\nplt.plot(num_epochs, history.history['val_loss'], \n    label='val_loss', c='orange')\nplt.plot(num_epochs, history.history['acc'], label='train_acc', c='green')\nplt.plot(num_epochs, history.history['val_acc'], \n    label='val_acc', c='blue')\nplt.title('Training Loss and Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Loss\/Accuracy')\nplt.legend()\nplt.savefig('plot.png')<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"667\" src=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/plot-e1560743463116.png\" alt=\"Graph plot for the trained model\" class=\"wp-image-1596\"\/><figcaption>Model Plot<\/figcaption><\/figure>\n\n\n\n<p>The validation loss does not look very stable. There can be numerous reasons for this. One of the reasons is the similarity between the images and also the small number of images. You can also get a TensorBoard visualization of the plots and the model graph as well. In the command line (in the project directory), type the following:<\/p>\n\n\n\n<p><code>tensorboard --logdir=logs\/ <\/code><\/p>\n\n\n\n<p>Then go to  <strong><a rel=\"noreferrer noopener\" href=\"http:\/\/localhost:6006\/#scalars\" target=\"_blank\">http:\/\/localhost:6006\/#scalars<\/a> <\/strong>.<\/p>\n\n\n\n<p>You can also click on the <strong>GRAPHS<\/strong> tab to see the model graph.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1460\" height=\"907\" src=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-plots-1.png\" alt=\"Image for tensorboard plot\" class=\"wp-image-1602\" srcset=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-plots-1.png 1460w, https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-plots-1-300x186.png 300w, https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-plots-1-768x477.png 768w\" sizes=\"auto, (max-width: 1460px) 100vw, 1460px\" \/><figcaption>Tensorboard plots<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1483\" height=\"889\" src=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-graph.png\" alt=\"Image for tensorboard graph\" class=\"wp-image-1603\" srcset=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-graph.png 1483w, https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-graph-300x180.png 300w, https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/Tensorboard-graph-768x460.png 768w\" sizes=\"auto, (max-width: 1483px) 100vw, 1483px\" \/><figcaption>Tensorboard graph<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Predicting<\/h2>\n\n\n\n<p>The code that follows can be run fully independently without running any of the previous code after you have completed the training part. So, you can always predict on new images only by executing the following code snippets. If you want, you can also save this part in a <code>predict.py<\/code> python file which you can run independently without opening the Jupyter Notebook.<\/p>\n\n\n\n<p>Let&#8217;s load one of the test images, scale the pixels and reshape it as well:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># load the test image\nimage = cv2.imread('images\/golden.jpg')\noutput = image.copy()\nimage = cv2.resize(image, (128, 128))\n\n# scale the pixels\nimage = image.astype('float') \/ 255.0\n\nimage = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))<\/pre>\n\n\n\n<p>Loading the model and the label binarizer.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">model = tf.keras.models.load_model('conv2d.model')\nlb = pickle.loads(open('conv2d_lb.pickle', 'rb').read())<\/pre>\n\n\n\n<p>Now, predicting and getting the class labels.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># predict\npreds = model.predict(image)\n\n# get the class label\nmax_label = preds.argmax(axis=1)[0]\nprint('PREDICTIONS: \\n', preds)\nprint('PREDICTION ARGMAX: ', max_label)\nlabel = lb.classes_[max_label]<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">PREDICTIONS: [[9.2370689e-01 2.5450445e-06 7.6290570e-02]] \nPREDICTION ARGMAX: 0<\/pre>\n\n\n\n<p>Finally, let&#8217;s see the predictions.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># class label along with the probability\ntext = '{}: {:.2f}%'.format(label, preds[0][max_label] * 100)\ncv2.putText(output, text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)\ncv2.imshow('image', output)\ncv2.waitKey(0)<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"311\" src=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/tiger-e1560756008126.png\" alt=\"Image predicted by the model\" class=\"wp-image-1608\"\/><figcaption>Prediction<\/figcaption><\/figure><\/div>\n\n\n\n<p>Our model is predicting the image as <em>golden_tiger<\/em> with 92.3% accuracy, which is fairly good. But when you predict for the other images, you may sometimes get wrong results. One reason is that our data set is fairly small (only about 350 images in total for each class). You can always try to find more images for better training.  Other times you may find that if white tiger image has a yellowish hue (maybe sunrise), then also the model is predicting the image as <em>golden_tiger<\/em> or maybe <em>mountain_lion<\/em>. Adding a variety of images covering different scenes appears to be the only solution here. You should surely try out these.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this tutorial, you learned how to build your own image classifier using TensorFlow and Keras. From here on, you can try training the model on different images. <\/p>\n\n\n\n<p>Again, you can download the files here: <\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-outline is-style-outline--2\"><a class=\"wp-block-button__link has-black-color has-luminous-vivid-orange-background-color has-text-color has-background\" href=\"https:\/\/drive.google.com\/file\/d\/12QbE3_3I6LyK6zE73lbIdHByPMuEMEs2\/view?usp=sharing\" target=\"_blank\" rel=\"noreferrer noopener\">Download Project and Trained Models<\/a><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Be sure to share your thoughts in the comment section and subscribe to the website as well. Don&#8217;t forget to give a Thumbs Up You can also follow me on <strong><a rel=\"noreferrer noopener\" aria-label=\"Twitter (opens in a new tab)\" href=\"https:\/\/twitter.com\/SovitRath5\" target=\"_blank\">Twitter<\/a><\/strong>, <strong><a rel=\"noreferrer noopener\" aria-label=\"Facebook (opens in a new tab)\" href=\"https:\/\/www.facebook.com\/profile.php?id=100013731104496\" target=\"_blank\">Facebook<\/a><\/strong>, and <strong><a rel=\"noreferrer noopener\" aria-label=\"LinkedIn (opens in a new tab)\" href=\"https:\/\/www.linkedin.com\/in\/sovit-rath-660712104\/\" target=\"_blank\">LinkedIn<\/a><\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated: April 8, 2020. You must have come across numerous tutorials to distinguish between cats and dogs using deep learning. Well, then this tutorial is going to be a bit different and a whole lot interesting. In this article, we too will be using deep learning with Keras and TensorFlow for image classification. But with [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1620,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76,113,59,119,67,17,57,54],"tags":[77,112,61,123,72,62],"class_list":["post-1563","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-computer-vision","category-convolutional-neural-networks","category-deep-learning","category-image-classification","category-keras","category-machine-learning","category-neural-networks","category-tensorflow","tag-computer-vision","tag-convolutional-neural-networks","tag-deep-learning","tag-image-classification","tag-keras-deep-learning","tag-neural-networks"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Wild Cats Image Classification using Deep Learning<\/title>\n<meta name=\"description\" content=\"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Wild Cats Image Classification using Deep Learning\" \/>\n<meta property=\"og:description\" content=\"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\" \/>\n<meta property=\"og:site_name\" content=\"DebuggerCafe\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/profile.php?id=100013731104496\" \/>\n<meta property=\"article:published_time\" content=\"2019-06-17T09:29:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-08T10:49:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Sovit Ranjan Rath\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@SovitRath5\" \/>\n<meta name=\"twitter:site\" content=\"@SovitRath5\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sovit Ranjan Rath\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\"},\"author\":{\"name\":\"Sovit Ranjan Rath\",\"@id\":\"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752\"},\"headline\":\"Wild Cats Image Classification using Deep Learning\",\"datePublished\":\"2019-06-17T09:29:44+00:00\",\"dateModified\":\"2023-01-08T10:49:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\"},\"wordCount\":1334,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg\",\"keywords\":[\"Computer Vision\",\"Convolutional Neural Networks\",\"Deep Learning\",\"Image Classification\",\"Keras Deep Learning\",\"Neural Networks\"],\"articleSection\":[\"Computer Vision\",\"Convolutional Neural Networks\",\"Deep Learning\",\"Image Classification\",\"Keras\",\"Machine Learning\",\"Neural Networks\",\"TensorFlow\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\",\"url\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\",\"name\":\"Wild Cats Image Classification using Deep Learning\",\"isPartOf\":{\"@id\":\"https:\/\/debuggercafe.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg\",\"datePublished\":\"2019-06-17T09:29:44+00:00\",\"dateModified\":\"2023-01-08T10:49:43+00:00\",\"author\":{\"@id\":\"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752\"},\"description\":\"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.\",\"breadcrumb\":{\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage\",\"url\":\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg\",\"contentUrl\":\"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg\",\"width\":1200,\"height\":675,\"caption\":\"Banner Image\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/debuggercafe.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Wild Cats Image Classification using Deep Learning\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/debuggercafe.com\/#website\",\"url\":\"https:\/\/debuggercafe.com\/\",\"name\":\"DebuggerCafe\",\"description\":\"Machine Learning and Deep Learning\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/debuggercafe.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752\",\"name\":\"Sovit Ranjan Rath\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/debuggercafe.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f71ca13ec56d630e7d8045e8b846396068791aa204936c3d74d721c6dd2b4d3c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f71ca13ec56d630e7d8045e8b846396068791aa204936c3d74d721c6dd2b4d3c?s=96&d=mm&r=g\",\"caption\":\"Sovit Ranjan Rath\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Wild Cats Image Classification using Deep Learning","description":"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/","og_locale":"en_US","og_type":"article","og_title":"Wild Cats Image Classification using Deep Learning","og_description":"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.","og_url":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/","og_site_name":"DebuggerCafe","article_publisher":"https:\/\/www.facebook.com\/profile.php?id=100013731104496","article_published_time":"2019-06-17T09:29:44+00:00","article_modified_time":"2023-01-08T10:49:43+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg","type":"image\/jpeg"}],"author":"Sovit Ranjan Rath","twitter_card":"summary_large_image","twitter_creator":"@SovitRath5","twitter_site":"@SovitRath5","twitter_misc":{"Written by":"Sovit Ranjan Rath","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#article","isPartOf":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/"},"author":{"name":"Sovit Ranjan Rath","@id":"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752"},"headline":"Wild Cats Image Classification using Deep Learning","datePublished":"2019-06-17T09:29:44+00:00","dateModified":"2023-01-08T10:49:43+00:00","mainEntityOfPage":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/"},"wordCount":1334,"commentCount":0,"image":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage"},"thumbnailUrl":"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg","keywords":["Computer Vision","Convolutional Neural Networks","Deep Learning","Image Classification","Keras Deep Learning","Neural Networks"],"articleSection":["Computer Vision","Convolutional Neural Networks","Deep Learning","Image Classification","Keras","Machine Learning","Neural Networks","TensorFlow"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/","url":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/","name":"Wild Cats Image Classification using Deep Learning","isPartOf":{"@id":"https:\/\/debuggercafe.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage"},"image":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage"},"thumbnailUrl":"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg","datePublished":"2019-06-17T09:29:44+00:00","dateModified":"2023-01-08T10:49:43+00:00","author":{"@id":"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752"},"description":"This article teaches how to build your own image classifier using Keras and Tensorflow. Deep Learning with Keras and TensorFlow for image classification.","breadcrumb":{"@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#primaryimage","url":"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg","contentUrl":"https:\/\/debuggercafe.com\/wp-content\/uploads\/2019\/06\/1-e1560761961746.jpg","width":1200,"height":675,"caption":"Banner Image"},{"@type":"BreadcrumbList","@id":"https:\/\/debuggercafe.com\/wild-cats-image-classification-using-deep-learning\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/debuggercafe.com\/"},{"@type":"ListItem","position":2,"name":"Wild Cats Image Classification using Deep Learning"}]},{"@type":"WebSite","@id":"https:\/\/debuggercafe.com\/#website","url":"https:\/\/debuggercafe.com\/","name":"DebuggerCafe","description":"Machine Learning and Deep Learning","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/debuggercafe.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/debuggercafe.com\/#\/schema\/person\/27719b14d930bd4a88ade40d18b0a752","name":"Sovit Ranjan Rath","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/debuggercafe.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/f71ca13ec56d630e7d8045e8b846396068791aa204936c3d74d721c6dd2b4d3c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f71ca13ec56d630e7d8045e8b846396068791aa204936c3d74d721c6dd2b4d3c?s=96&d=mm&r=g","caption":"Sovit Ranjan Rath"}}]}},"_links":{"self":[{"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/posts\/1563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/comments?post=1563"}],"version-history":[{"count":88,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/posts\/1563\/revisions"}],"predecessor-version":[{"id":28533,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/posts\/1563\/revisions\/28533"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/media\/1620"}],"wp:attachment":[{"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/media?parent=1563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/categories?post=1563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/debuggercafe.com\/wp-json\/wp\/v2\/tags?post=1563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}