{"id":10719,"date":"2023-12-26T07:10:09","date_gmt":"2023-12-26T07:10:09","guid":{"rendered":"https:\/\/mdr.foobrdigital.com\/?p=10719"},"modified":"2023-12-26T07:10:09","modified_gmt":"2023-12-26T07:10:09","slug":"image-classification-using-pre-trained-model","status":"publish","type":"post","link":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/2023\/12\/26\/image-classification-using-pre-trained-model\/","title":{"rendered":"Image Classification Using Pre-Trained Model"},"content":{"rendered":"\n<p>In this lesson, you will learn to use a pre-trained model to detect objects in a given image. You will use&nbsp;<strong>squeezenet<\/strong>&nbsp;pre-trained module that detects and classifies the objects in a given image with a great accuracy.<\/p>\n\n\n\n<p>Open a new&nbsp;<strong>Juypter notebook<\/strong>&nbsp;and follow the steps to develop this image classification application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Importing Libraries<\/h2>\n\n\n\n<p>First, we import the required packages using the below code \u2212from caffe2.proto import caffe2_pb2 from caffe2.python import core, workspace, models import numpy as np import skimage.io import skimage.transform from matplotlib import pyplot import os import urllib.request as urllib2 import operator<\/p>\n\n\n\n<p>Next, we set up a few&nbsp;<strong>variables<\/strong>&nbsp;\u2212INPUT_IMAGE_SIZE = 227 mean = 128<\/p>\n\n\n\n<p>The images used for training will obviously be of varied sizes. All these images must be converted into a fixed size for accurate training. Likewise, the test images and the image which you want to predict in the production environment must also be converted to the size, the same as the one used during training. Thus, we create a variable above called&nbsp;<strong>INPUT_IMAGE_SIZE<\/strong>&nbsp;having value&nbsp;<strong>227<\/strong>. Hence, we will convert all our images to the size&nbsp;<strong>227&#215;227<\/strong>&nbsp;before using it in our classifier.<\/p>\n\n\n\n<p>We also declare a variable called&nbsp;<strong>mean<\/strong>&nbsp;having value&nbsp;<strong>128<\/strong>, which is used later for improving the classification results.<\/p>\n\n\n\n<p>Next, we will develop two functions for processing the image.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Image Processing<\/h2>\n\n\n\n<p>The image processing consists of two steps. First one is to resize the image, and the second one is to centrally crop the image. For these two steps, we will write two functions for resizing and cropping.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Image Resizing<\/h3>\n\n\n\n<p>First, we will write a function for resizing the image. As said earlier, we will resize the image to&nbsp;<strong>227&#215;227<\/strong>. So let us define the function&nbsp;<strong>resize<\/strong>&nbsp;as follows \u2212def resize(img, input_height, input_width):<\/p>\n\n\n\n<p>We obtain the aspect ratio of the image by dividing the width by the height.original_aspect = img.shape[1]\/float(img.shape[0])<\/p>\n\n\n\n<p>If the aspect ratio is greater than 1, it indicates that the image is wide, that to say it is in the landscape mode. We now adjust the image height and return the resized image using the following code \u2212if(original_aspect&gt;1): new_height = int(original_aspect * input_height) return skimage.transform.resize(img, (input_width, new_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None)<\/p>\n\n\n\n<p>If the aspect ratio is&nbsp;<strong>less than 1<\/strong>, it indicates the&nbsp;<strong>portrait mode<\/strong>. We now adjust the width using the following code \u2212if(original_aspect&lt;1): new_width = int(input_width\/original_aspect) return skimage.transform.resize(img, (new_width, input_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None)<\/p>\n\n\n\n<p>If the aspect ratio equals&nbsp;<strong>1<\/strong>, we do not make any height\/width adjustments.if(original_aspect == 1): return skimage.transform.resize(img, (input_width, input_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None)<\/p>\n\n\n\n<p>The full function code is given below for your quick reference \u2212def resize(img, input_height, input_width): original_aspect = img.shape[1]\/float(img.shape[0]) if(original_aspect&gt;1): new_height = int(original_aspect * input_height) return skimage.transform.resize(img, (input_width, new_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None) if(original_aspect&lt;1): new_width = int(input_width\/original_aspect) return skimage.transform.resize(img, (new_width, input_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None) if(original_aspect == 1): return skimage.transform.resize(img, (input_width, input_height), mode=&#8217;constant&#8217;, anti_aliasing=True, anti_aliasing_sigma=None)<\/p>\n\n\n\n<p>We will now write a function for cropping the image around its center.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Image Cropping<\/h3>\n\n\n\n<p>We declare the&nbsp;<strong>crop_image<\/strong>&nbsp;function as follows \u2212def crop_image(img,cropx,cropy):<\/p>\n\n\n\n<p>We extract the dimensions of the image using the following statement \u2212y,x,c = img.shape<\/p>\n\n\n\n<p>We create a new starting point for the image using the following two lines of code \u2212startx = x\/\/2-(cropx\/\/2) starty = y\/\/2-(cropy\/\/2)<\/p>\n\n\n\n<p>Finally, we return the cropped image by creating an image object with the new dimensions \u2212return img[starty:starty+cropy,startx:startx+cropx]<\/p>\n\n\n\n<p>The entire function code is given below for your quick reference \u2212def crop_image(img,cropx,cropy): y,x,c = img.shape startx = x\/\/2-(cropx\/\/2) starty = y\/\/2-(cropy\/\/2) return img[starty:starty+cropy,startx:startx+cropx]<\/p>\n\n\n\n<p>Now, we will write code to test these functions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Processing Image<\/h2>\n\n\n\n<p>Firstly, copy an image file into&nbsp;<strong>images<\/strong>&nbsp;subfolder within your project directory.&nbsp;<strong>tree.jpg<\/strong>&nbsp;file is copied in the project. The following Python code loads the image and displays it on the console \u2212img = skimage.img_as_float(skimage.io.imread(&#8220;images\/tree.jpg&#8221;)).astype(np.float32) print(&#8220;Original Image Shape: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Original image&#8217;)<\/p>\n\n\n\n<p>The output is as follows \u2212<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.tutorialspoint.com\/caffe2\/images\/processing_image.jpg\" alt=\"Processing Image\"\/><\/figure>\n\n\n\n<p>Note that size of the original image is&nbsp;<strong>600 x 960<\/strong>. We need to resize this to our specification of&nbsp;<strong>227 x 227<\/strong>. Calling our earlier-defined&nbsp;<strong>resize<\/strong>function does this job.img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print(&#8220;Image Shape after resizing: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Resized image&#8217;)<\/p>\n\n\n\n<p>The output is as given below \u2212<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.tutorialspoint.com\/caffe2\/images\/original_image.jpg\" alt=\"Original Image\"\/><\/figure>\n\n\n\n<p>Note that now the image size is&nbsp;<strong>227 x 363<\/strong>. We need to crop this to&nbsp;<strong>227 x 227<\/strong>&nbsp;for the final feed to our algorithm. We call the previously-defined crop function for this purpose.img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print(&#8220;Image Shape after cropping: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Center Cropped&#8217;)<\/p>\n\n\n\n<p>Below mentioned is the output of the code \u2212<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.tutorialspoint.com\/caffe2\/images\/cropping_image.jpg\" alt=\"Cropping Image\"\/><\/figure>\n\n\n\n<p>At this point, the image is of size&nbsp;<strong>227 x 227<\/strong>&nbsp;and is ready for further processing. We now swap the image axes to extract the three colours into three different zones.img = img.swapaxes(1, 2).swapaxes(0, 1) print(&#8220;CHW Image Shape: &#8221; , img.shape)<\/p>\n\n\n\n<p>Given below is the output \u2212CHW Image Shape: (3, 227, 227)<\/p>\n\n\n\n<p>Note that the last axis has now become the first dimension in the array. We will now plot the three channels using the following code \u2212pyplot.figure() for i in range(3): pyplot.subplot(1, 3, i+1) pyplot.imshow(img[i]) pyplot.axis(&#8216;off&#8217;) pyplot.title(&#8216;RGB channel %d&#8217; % (i+1))<\/p>\n\n\n\n<p>The output is stated below \u2212<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.tutorialspoint.com\/caffe2\/images\/dimension.jpg\" alt=\"Dimension\"\/><\/figure>\n\n\n\n<p>Finally, we do some additional processing on the image such as converting&nbsp;<strong>Red Green Blue<\/strong>&nbsp;to&nbsp;<strong>Blue Green Red (RGB to BGR)<\/strong>, removing mean for better results and adding batch size axis using the following three lines of code \u2212# convert RGB &#8211;&gt; BGR img = img[(2, 1, 0), :, :] # remove mean img = img * 255 &#8211; mean # add batch size axis img = img[np.newaxis, :, :, :].astype(np.float32)<\/p>\n\n\n\n<p>At this point, your image is in&nbsp;<strong>NCHW format<\/strong>&nbsp;and is ready for feeding into our network. Next, we will load our pre-trained model files and feed the above image into it for prediction.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Predicting Objects in Processed Image<\/h2>\n\n\n\n<p>We first setup the paths for the&nbsp;<strong>init<\/strong>&nbsp;and&nbsp;<strong>predict<\/strong>&nbsp;networks defined in the pre-trained models of Caffe.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting Model File Paths<\/h3>\n\n\n\n<p>Remember from our earlier discussion, all the pre-trained models are installed in the&nbsp;<strong>models<\/strong>&nbsp;folder. We set up the path to this folder as follows \u2212CAFFE_MODELS = os.path.expanduser(&#8220;\/anaconda3\/lib\/python3.7\/site-packages\/caffe2\/python\/models&#8221;)<\/p>\n\n\n\n<p>We set up the path to the&nbsp;<strong>init_net<\/strong>&nbsp;protobuf file of the&nbsp;<strong>squeezenet<\/strong>&nbsp;model as follows \u2212INIT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;init_net.pb&#8217;)<\/p>\n\n\n\n<p>Likewise, we set up the path to the&nbsp;<strong>predict_net<\/strong>&nbsp;protobuf as follows \u2212PREDICT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;predict_net.pb&#8217;)<\/p>\n\n\n\n<p>We print the two paths for diagnosis purpose \u2212print(INIT_NET) print(PREDICT_NET)<\/p>\n\n\n\n<p>The above code along with the output is given here for your quick reference \u2212CAFFE_MODELS = os.path.expanduser(&#8220;\/anaconda3\/lib\/python3.7\/site-packages\/caffe2\/python\/models&#8221;) INIT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;init_net.pb&#8217;) PREDICT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;predict_net.pb&#8217;) print(INIT_NET) print(PREDICT_NET)<\/p>\n\n\n\n<p>The output is mentioned below \u2212\/anaconda3\/lib\/python3.7\/site-packages\/caffe2\/python\/models\/squeezenet\/init_net.pb \/anaconda3\/lib\/python3.7\/site-packages\/caffe2\/python\/models\/squeezenet\/predict_net.pb<\/p>\n\n\n\n<p>Next, we will create a predictor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating Predictor<\/h3>\n\n\n\n<p>We read the model files using the following two statements \u2212with open(INIT_NET, &#8220;rb&#8221;) as f: init_net = f.read() with open(PREDICT_NET, &#8220;rb&#8221;) as f: predict_net = f.read()<\/p>\n\n\n\n<p>The predictor is created by passing pointers to the two files as parameters to the&nbsp;<strong>Predictor<\/strong>&nbsp;function.p = workspace.Predictor(init_net, predict_net)<\/p>\n\n\n\n<p>The&nbsp;<strong>p<\/strong>&nbsp;object is the predictor, which is used for predicting the objects in any given image. Note that each input image must be in NCHW format as what we have done earlier to our&nbsp;<strong>tree.jpg<\/strong>&nbsp;file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Predicting Objects<\/h3>\n\n\n\n<p>To predict the objects in a given image is trivial &#8211; just executing a single line of command. We call&nbsp;<strong>run<\/strong>&nbsp;method on the&nbsp;<strong>predictor<\/strong>&nbsp;object for an object detection in a given image.results = p.run({&#8216;data&#8217;: img})<\/p>\n\n\n\n<p>The prediction results are now available in the&nbsp;<strong>results<\/strong>&nbsp;object, which we convert to an array for our readability.results = np.asarray(results)<\/p>\n\n\n\n<p>Print the dimensions of the array for your understanding using the following statement \u2212print(&#8220;results shape: &#8220;, results.shape)<\/p>\n\n\n\n<p>The output is as shown below \u2212results shape: (1, 1, 1000, 1, 1)<\/p>\n\n\n\n<p>We will now remove the unnecessary axis \u2212preds = np.squeeze(results)<\/p>\n\n\n\n<p>The topmost predication can now be retrieved by taking the&nbsp;<strong>max<\/strong>&nbsp;value in the&nbsp;<strong>preds<\/strong>&nbsp;array.curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1)) print(&#8220;Prediction: &#8220;, curr_pred) print(&#8220;Confidence: &#8220;, curr_conf)<\/p>\n\n\n\n<p>The output is as follows \u2212Prediction: 984 Confidence: 0.89235985<\/p>\n\n\n\n<p>As you see the model has predicted an object with an index value&nbsp;<strong>984<\/strong>&nbsp;with&nbsp;<strong>89%<\/strong>&nbsp;confidence. The index of 984 does not make much sense to us in understanding what kind of object is detected. We need to get the stringified name for the object using its index value. The kind of objects that the model recognizes along with their corresponding index values are available on a github repository.<\/p>\n\n\n\n<p>Now, we will see how to retrieve the name for our object having index value of 984.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Stringifying Result<\/h2>\n\n\n\n<p>We create a URL object to the github repository as follows \u2212codes = &#8220;https:\/\/gist.githubusercontent.com\/aaronmarkham\/cd3a6b6ac0 71eca6f7b4a6e40e6038aa\/raw\/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b\/alexnet_codes&#8221;<\/p>\n\n\n\n<p>We read the contents of the URL \u2212response = urllib2.urlopen(codes)<\/p>\n\n\n\n<p>The response will contain a list of all codes and its descriptions. Few lines of the response are shown below for your understanding of what it contains \u22125: &#8216;electric ray, crampfish, numbfish, torpedo&#8217;, 6: &#8216;stingray&#8217;, 7: &#8216;cock&#8217;, 8: &#8216;hen&#8217;, 9: &#8216;ostrich, Struthio camelus&#8217;, 10: &#8216;brambling, Fringilla montifringilla&#8217;,<\/p>\n\n\n\n<p>We now iterate the entire array to locate our desired code of 984 using a&nbsp;<strong>for<\/strong>&nbsp;loop as follows \u2212for line in response: mystring = line.decode(&#8216;ascii&#8217;) code, result = mystring.partition(&#8220;:&#8221;)[::2] code = code.strip() result = result.replace(&#8220;&#8216;&#8221;, &#8220;&#8221;) if (code == str(curr_pred)): name = result.split(&#8220;,&#8221;)[0][1:] print(&#8220;Model predicts&#8221;, name, &#8220;with&#8221;, curr_conf, &#8220;confidence&#8221;)<\/p>\n\n\n\n<p>When you run the code, you will see the following output \u2212Model predicts rapeseed with 0.89235985 confidence<\/p>\n\n\n\n<p>You may now try the model on another image.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Predicting a Different Image<\/h2>\n\n\n\n<p>To predict another image, simply copy the image file into the&nbsp;<strong>images<\/strong>&nbsp;folder of your project directory. This is the directory in which our earlier&nbsp;<strong>tree.jpg<\/strong>&nbsp;file is stored. Change the name of the image file in the code. Only one change is required as shown belowimg = skimage.img_as_float(skimage.io.imread(&#8220;images\/pretzel.jpg&#8221;)).astype(np.float32)<\/p>\n\n\n\n<p>The original picture and the prediction result are shown below \u2212<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.tutorialspoint.com\/caffe2\/images\/predicting_image.jpg\" alt=\"Predicting Image\"\/><\/figure>\n\n\n\n<p>The output is mentioned below \u2212Model predicts pretzel with 0.99999976 confidence<\/p>\n\n\n\n<p>As you see the pre-trained model is able to detect objects in a given image with a great amount of accuracy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Full Source<\/h2>\n\n\n\n<p>The full source for the above code that uses a pre-trained model for object detection in a given image is mentioned here for your quick reference \u2212def crop_image(img,cropx,cropy): y,x,c = img.shape startx = x\/\/2-(cropx\/\/2) starty = y\/\/2-(cropy\/\/2) return img[starty:starty+cropy,startx:startx+cropx] img = skimage.img_as_float(skimage.io.imread(&#8220;images\/pretzel.jpg&#8221;)).astype(np.float32) print(&#8220;Original Image Shape: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Original image&#8217;) img = resize(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print(&#8220;Image Shape after resizing: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Resized image&#8217;) img = crop_image(img, INPUT_IMAGE_SIZE, INPUT_IMAGE_SIZE) print(&#8220;Image Shape after cropping: &#8221; , img.shape) pyplot.figure() pyplot.imshow(img) pyplot.title(&#8216;Center Cropped&#8217;) img = img.swapaxes(1, 2).swapaxes(0, 1) print(&#8220;CHW Image Shape: &#8221; , img.shape) pyplot.figure() for i in range(3): pyplot.subplot(1, 3, i+1) pyplot.imshow(img[i]) pyplot.axis(&#8216;off&#8217;) pyplot.title(&#8216;RGB channel %d&#8217; % (i+1)) # convert RGB &#8211;&gt; BGR img = img[(2, 1, 0), :, :] # remove mean img = img * 255 &#8211; mean # add batch size axis img = img[np.newaxis, :, :, :].astype(np.float32) CAFFE_MODELS = os.path.expanduser(&#8220;\/anaconda3\/lib\/python3.7\/site-packages\/caffe2\/python\/models&#8221;) INIT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;init_net.pb&#8217;) PREDICT_NET = os.path.join(CAFFE_MODELS, &#8216;squeezenet&#8217;, &#8216;predict_net.pb&#8217;) print(INIT_NET) print(PREDICT_NET) with open(INIT_NET, &#8220;rb&#8221;) as f: init_net = f.read() with open(PREDICT_NET, &#8220;rb&#8221;) as f: predict_net = f.read() p = workspace.Predictor(init_net, predict_net) results = p.run({&#8216;data&#8217;: img}) results = np.asarray(results) print(&#8220;results shape: &#8220;, results.shape) preds = np.squeeze(results) curr_pred, curr_conf = max(enumerate(preds), key=operator.itemgetter(1)) print(&#8220;Prediction: &#8220;, curr_pred) print(&#8220;Confidence: &#8220;, curr_conf) codes = &#8220;https:\/\/gist.githubusercontent.com\/aaronmarkham\/cd3a6b6ac071eca6f7b4a6e40e6038aa\/raw\/9edb4038a37da6b5a44c3b5bc52e448ff09bfe5b\/alexnet_codes&#8221; response = urllib2.urlopen(codes) for line in response: mystring = line.decode(&#8216;ascii&#8217;) code, result = mystring.partition(&#8220;:&#8221;)[::2] code = code.strip() result = result.replace(&#8220;&#8216;&#8221;, &#8220;&#8221;) if (code == str(curr_pred)): name = result.split(&#8220;,&#8221;)[0][1:] print(&#8220;Model predicts&#8221;, name, &#8220;with&#8221;, curr_conf, &#8220;confidence&#8221;)<\/p>\n\n\n\n<p>By this time, you know how to use a pre-trained model for doing the predictions on your dataset.<\/p>\n\n\n\n<p>What\u2019s next is to learn how to define your&nbsp;<strong>neural network (NN)<\/strong>&nbsp;architectures in&nbsp;<strong>Caffe2<\/strong>&nbsp;and train them on your dataset. We will now learn how to create a trivial single layer NN.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this lesson, you will learn to use a pre-trained model to detect objects in a given image. You will use&nbsp;squeezenet&nbsp;pre-trained module that detects and classifies the objects in a given image with a great accuracy. Open a new&nbsp;Juypter notebook&nbsp;and follow the steps to develop this image classification application. Importing Libraries First, we import the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[861],"tags":[],"_links":{"self":[{"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/posts\/10719"}],"collection":[{"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/comments?post=10719"}],"version-history":[{"count":0,"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/posts\/10719\/revisions"}],"wp:attachment":[{"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/media?parent=10719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/categories?post=10719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mudassirbackup.infinitycodestudio.com\/index.php\/wp-json\/wp\/v2\/tags?post=10719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}