0:00 what do you want to learn baby today?
0:04 Well I understand baby Yoda's language
0:06 what he's saying is he wants to learn
0:09 TF serving and fast API today and he
0:12 wants to go through some mlops concepts.
0:14 In first two videos we
0:16 trained a model
0:18 we exported it on a disk. In this video
0:20 we will be writing a fast API server
0:23 around that model and will have a
0:25 working http server ready which we'll use
0:28 to for the deployment in the production
0:31 and this is how the big companies do the
0:33 deployment. So you'll learn a lot of
0:34 practical useful tips today so make sure
0:37 you watch till then. Couple of
0:38 prerequisites for this video. You need to
0:40 know about fast API.I made a very simple
0:44 fast API tutorial that even a high
0:46 school student can understand it easily.
0:48 So you need to watch that the second
0:50 prerequisite is.
0:52 I made a simple video on TF serving, like
0:54 what's the purpose of tf serving, how it
0:56 is useful in ML ops. You need to watch
0:59 that as well and obviously this is part
1:02 three of this project series. So I'm
1:03 assuming you have watched the part one
1:06 and part two. So let's get started in our
1:09 last video. We exported models to a
1:12 models directory
1:14 which is this particular directory and
1:16 I'm going to rename it to saved model
1:19 because that I feel is an appropriate
1:21 name
1:22 and I'm going to create
1:24 an API folder here and in this API
1:28 folder. We are going to write our fast
1:31 API based server. Now let's install some
1:36 prerequisites, some modules
1:38 to write this API server. So if you go
1:40 to my github page on potato this is
1:43 classification go to API directory and
1:45 requirement.txt file. You can either get
1:48 clone it or
1:50 you can right click here.
1:53 Create
1:55 requirements dot txt
1:58 and
1:59 once you have that file
2:02 I will just
2:03 copy paste this here
2:09 so requirement.txt is used to list down
2:12 all your Python dependencies
2:14 and then you can go to command prompt
2:18 here.
2:19 go to API directory. API directory I see
2:22 the
2:24 requirements.txt file. See
2:27 actually I need to save it so I have
2:29 saved this now
2:31 and it has all these requirements and I
2:34 can simply run pip install
2:37 hyphen r requirements dot txt and it
2:40 will install
2:42 all these modules. You can install them
2:44 in the individually but this approach
2:47 is a little better. So now all our
2:49 modules are installed.
2:51 I'm into Pyjam here
2:53 in API folder. I will go right click
2:56 create a file called
2:58 main.pi and here
3:00 first thing I'll do is I'll go in a zen
3:03 mode. I will start meditating now
3:06 and from
3:08 fast API
3:10 import
3:12 if you've seen my first API tutorial
3:15 these are like
3:16 this like bare bone that you need so
3:19 here you will create an app
3:22 which will be an instance of
3:24 fast api and let's write a very simple
3:28 you know ping type of routine so you
3:31 will say async
3:33 def
3:34 ping
3:35 okay and
3:36 you can just return
3:39 hello I am alive. I am writing this
3:42 routine
3:43 just to make sure that my server is
3:45 alive you know we can call this ping
3:47 method and make sure our server is alive
3:49 it's not crashed or it is not stopped
3:51 and here you can say app.get
3:55 and this is how you specify an endpoint
3:59 and I will say ping you can say hello hi
4:02 whatever
4:05 so this is
4:07 barebone fast API ping server ready so
4:09 let's test this now
4:11 to run this server you can use uicon
4:14 command based on my fast API tutorial.
4:17 you can say main because that's the name
4:19 of the file right? Main dot pi so you'll
4:21 see main column app which is this
4:24 variable here app
4:26 and
4:27 reload. You can run it this way but I'm
4:30 going to run it in a little different
4:32 way and that way is this- I will import
4:36 uvicon
4:38 as a module
4:39 and you can
4:40 say if
4:42 your standard Python way you know if
4:44 name is equal to main
4:47 uvcon
4:48 dot run
4:50 and here
4:52 you will specify your app, your port the
4:56 support is
4:58 let's say 8 000 you know
5:00 and your host
5:03 your host is
5:05 let's say localhost
5:08 and I can right click run it
5:11 okay?
5:13 Oh this there is a syntax error
5:16 so I can run it the server is ready to
5:18 run and now
5:20 I can go to my browser
5:24 and type in
5:26 localhost 8000
5:29 ping
5:30 when applying say I get this- hello I am
5:32 alive which means my server is ready you
5:35 can also look at docs
5:37 and that will give you all the
5:39 documentation so I have ping method
5:42 you can say try it out execute and that
5:45 is another way of testing your server.
5:47 See I just got this response- hello I am
5:50 alive so my basic bare bone is set up.
5:54 now I am going to write my actual
5:56 predict method so let me just
5:59 copy paste here
6:02 and instead of get this will be a post
6:06 a
6:06 record and trying to get something
6:09 you are doing model prediction
6:12 and probably post is an appropriate
6:14 method for that.
6:16 You will call this entry point predict
6:18 and this one also predict by the way
6:20 these two functions.
6:22 These two can be different you know. I
6:23 can do like predict foo as well they
6:27 don't have to be same really.
6:29 Now,
6:30 what will be the argument of this. Okay,
6:33 let's think about that.
6:36 So this will be a file
6:38 sent by your mobile application or
6:40 website. It will be an image of a potato
6:43 plant leaf
6:46 and that image since fast API provides
6:49 inbuilt validation. If you use an upload
6:53 file as a data type and let's do some
6:57 Google search on what upload file really
7:00 is. So if you do
7:02 fast API upload file you find this
7:06 documentation
7:09 and you can read through it. But the idea
7:11 is when you use something like this
7:14 the
7:15 fast API will make sure
7:17 that whoever is calling this predict
7:19 method
7:20 they have to send the
7:23 image or the file as an input. If you
7:26 send let's say an integer or a string as
7:28 an input it's not going to work. So I'm
7:30 just going to copy paste
7:33 this thing here.
7:39 Usually in Python you have syntax scene.
7:41 Syntax like this you just give a
7:43 variable name but when you do colon
7:46 it is type hint. It is this is a data
7:48 type basically. You are saying upload
7:50 file is my data type and when you say
7:52 equal to this it means this is your
7:54 default
7:56 value okay.
7:58 So now right click
8:00 run it.
8:01 I will show you what happens, okay. File
8:04 is not defined because I need to import
8:08 and upload file
8:10 here and I can run it so now this is
8:15 running. It is ready.
8:16 Let me just stop it here. Actually I will
8:19 put a break point at
8:22 each
8:23 stage and I will show you in the
8:25 debugger how it looks. So this is how you
8:26 put a break point right click debug
8:32 and I will go to
8:38 okay what I will do is
8:40 now
8:42 localhost see my documentation shows
8:45 this and I can use
8:48 this web UI to post the actual request
8:51 now see fast API is telling that my
8:53 input has to be a file so you need to
8:55 choose a file here. So this is one way
8:58 of testing your
9:00 API
9:01 the other better way which I like is
9:04 using postman. So
9:06 go to Google and just say download
9:08 postman you find this website
9:11 download the app based on what OS you
9:14 have and once you have that
9:16 app installed you can go here and run
9:20 postman. okay.
9:21 I have this postman running here
9:24 and I'm going to use a post method so
9:26 here
9:27 select post
9:28 and type in
9:30 http
9:32 localhost predict
9:35 Okay so local host
9:39 because it's running on 8 000 and I'm
9:40 calling a predict method
9:42 and it is expecting
9:45 file as a parameter. So here I will go to
9:49 body
9:51 and I will say form data because we are
9:52 sending a form data when UI sends a data
9:55 it will send a form data here and this
9:58 will be file.
9:59 This is file because this is also file.
10:01 If this is let's say x y z then this
10:04 will also be
10:06 xyz. You get the point right?
10:09 So that's why this is file.
10:13 and
10:15 here you select the file. So I'm
10:18 putting let's say
10:19 late blight image here.
10:22 Okay and when you say send since I have
10:25 this server running in debugger mode it
10:28 has now stopped here and you can see the
10:30 data type of files. This file in the
10:32 variable pan here it says it's an upload
10:37 file.
10:37 Beautiful!
10:39 So
10:40 fast API is good in this sense if you
10:43 were writing a flash server you'll have
10:44 to do lot of manual validation. So fast
10:47 API is much better. Okay now I have this
10:49 upload file I need to convert it to a
10:52 numpy array or a tensor so that my model
10:55 can do prediction. So my next step
10:57 naturally is going to be how do I
11:00 convert this file
11:03 into numpy array. Well first what I need
11:06 to do is
11:08 let me just stop this here.
11:11 I need to do file read I need to read
11:14 the files you know because that way I
11:17 get my bytes back
11:19 okay? As simple as that.
11:21 And you can read the documentation of
11:23 this on fast API.
11:25 Now this is an async routine so I will
11:29 call await. The benefit of doing await is
11:31 that if 100 callers are calling your
11:34 server let's say you have one server
11:35 running and there are 100 mobile
11:37 applications. You know 100 farmers are
11:39 using your mobile application they all
11:42 are sending
11:44 predict requests and they're attaching a
11:46 huge file. Now let's say to read the file
11:49 it takes two seconds. If I don't have
11:52 async here let's say and if I don't have
11:54 a weight here what's gonna happen is
11:57 my first request let's say it takes two
11:59 seconds to read my other request will be
12:01 waiting
12:02 but if I do
12:03 await an async
12:05 while
12:07 my first request takes two seconds to
12:09 read the file, it will put this function
12:12 in a suspend suspend mode and my second
12:15 request can be served. You can go to
12:18 youtube and watch some tutorials on
12:20 async io so you will get an
12:22 understanding of
12:23 why we are using async and oh wait so I
12:27 will put a breakpoint here again I
12:30 always run it in debug mode and once I
12:33 run it in debug mode I go to postman
12:35 send it here
12:37 and you see bytes
12:40 I love breakpoints and debugging because
12:42 that way I can evolve my program step by
12:44 step. So now I have all the content of
12:47 the file read as bytes and I need to
12:50 convert these bytes into numpy array.
12:53 Let me write
12:55 a simple function
12:57 called read file as image
13:00 and that returns me.
13:02 Basically image is nothing but a numpy
13:04 array.
13:06 Here this will be a regular Python
13:08 function which takes data which is
13:10 basically bytes as an input and it
13:13 returns np dot nd array
13:16 as an
13:17 output, okay?
13:19 Now here I need to import numpy
13:24 as
13:25 np
13:28 and then
13:31 I will also import couple of things so
13:34 this data that that's coming in
13:37 is bytes
13:38 and you can use bytes IO Python module.
13:43 Let me import that python model here
13:46 and when you do bytes IO
13:49 like this
13:51 you can supply this thing to
13:53 [Music]
13:55 pil directory so pll sorry pi mod model
13:59 pillow module is a model that is used to
14:02 read images
14:04 in Python and from below module I have
14:06 imported image class and when you do
14:08 this
14:09 image
14:11 dot open
14:14 it will
14:16 open
14:18 it will read those bytes as an image
14:20 as a pillow image and to convert pillow
14:23 image into numpy array you can just say
14:27 np array
14:29 like this
14:31 and that will be your numpy array which
14:33 you can return as an image
14:36 and that's it. So now let's put a
14:40 breakpoint again.
14:41 So I put a breakpoint here
14:43 again
14:44 clicking on my bug icon
14:46 and again sending a request so now let's
14:50 see what do I have an image? Hooray
14:53 party!
14:54 India rate 256 by 256 that's my x and y
14:58 of image and 3 is for rgb each of these
15:01 values are between 0 to 255 range so my
15:04 nd array is ready.
15:06 Now I need to
15:07 load my saved tensorflow model
15:12 so to say load my tensorflow model first
15:16 I need to import
15:19 tensorflow
15:20 and then I will create a global variable
15:24 you know let's call it model
15:26 and tf dot
15:29 keras dot
15:30 models
15:32 dot load model.
15:34 So that will load the model. Now, let's
15:37 give our directory path of this model. If
15:40 you look at my
15:42 directory structure I'm here okay in API.
15:45 I have to go to a parent directory then
15:48 go to saved model and I will load any
15:51 model these three models are same
15:53 in practical situation you might have
15:55 different versions of model with you
15:57 know different accuracy or
16:00 you know they will have different
16:01 metadata but I will use this one model.
16:03 So to go to parent directory you see you
16:06 will have to do dot dot then you will do
16:09 saved models
16:10 then you will do one I'm just you know
16:13 using version one. We will also look into
16:16 using a tensorflow serving by which we
16:19 can dynamically
16:21 load version 1 2 and so on. But right now
16:24 I'm just keeping things simple.
16:26 I'm also going to create
16:28 a variable not called class names which
16:31 will have all these three class name. Now
16:33 these three need to be consistent with
16:35 what you had in your notebook when you
16:37 were training the model. Now here I will
16:41 do model dot predict
16:45 image
16:46 but
16:47 this image it doesn't accept a single
16:50 image it has to be a batch image and you
16:54 can
16:55 basically.. I have see
16:57 I have this image okay 256 by 256x3
17:02 this predict function doesn't take
17:04 single image as an input. It takes
17:06 multiple images so it has to be
17:09 like this.
17:10 Okay and the way you can do that is by
17:12 doing
17:14 np
17:15 dot expand dims
17:19 and you can give image
17:21 and zero.
17:22 So if you read the documentation of this
17:24 thing
17:26 cnp expand dims. What it is doing? It's a
17:30 simple
17:31 APi friends. Nothing confusing. See you
17:33 have one dimensional array when you do
17:35 expand this, it is just adding one more
17:38 dimension. That's it. It's making it two
17:40 dimensional and if the axis is one it
17:42 will add that dimension at a column
17:44 level. So read the documentation is
17:47 super duper
17:49 easy
17:50 API.
17:55 So I will
17:57 call this
17:58 an image batch
18:02 and that image badge goes to predict
18:06 as an input
18:07 and what you get as a return is
18:10 predictions.
18:13 Okay I'll stop here and I'll again run
18:15 it and see what happens.
18:18 So I clicked on debug icon here
18:21 now model is loading. So it will take
18:23 some time. So have some patience
18:25 and you need to see a prompt here which
18:27 will say
18:28 uv con running on this then only you can
18:31 run your postman. You send it
18:34 and now see this is also taking time
18:35 because prediction is a little bit time
18:38 consuming. See my predictions are
18:41 one by three so it's an array
18:43 because my batch has only one image
18:46 so the second dimension
18:48 is
18:49 my actual prediction and if you look at
18:51 this prediction
18:54 you know the second one is
18:56 see it has three values. Let me just show
18:58 you
19:02 point twenty nine e raised to minus nine
19:04 so this is very
19:06 very small number. Zero point zero zero
19:07 something
19:08 nine point nine. So this is almost 0.99
19:11 and this is again you see e raised to
19:13 minus 0 6.
19:15 So I have three classes. So the first
19:18 number corresponds to early blight
19:20 second number corresponds to late blight
19:22 third one is healthy. So looks like this
19:24 is late blight because the second number
19:26 is a highest value.
19:28 So you what you have to do here
19:31 is
19:33 you have to always take
19:37 So I will call this predictions and in
19:39 this prediction you need to take
19:41 zeroth prediction because it's a batch.
19:44 And in batch you have given only one
19:45 image so
19:47 take zeroth prediction
19:49 and
19:50 the class. The class name okay class name
19:54 would be
19:55 whoever is the maximum value.
19:59 So what np dot argmax will do is this
20:04 see I had three values, correct?
20:07 I had zero point zero zero something
20:09 then I had zero point nine nine
20:11 something and I had zero point again
20:13 zero zero something.
20:15 So when you do rp np dot arg max it will
20:17 look for maximum value. Maximum value is
20:19 this what is the index of this index is
20:23 So this is 0 1 2 so the index is 1 so it
20:27 will return
20:28 1
20:29 if my value here is let's say something
20:31 like this
20:33 then it will return to-
20:34 Okay so that's my np dot argmax function
20:37 and this index when you give it
20:40 to
20:41 this particular array it will tell you
20:43 the actual class name
20:46 Okay so here I will say predicted
20:50 class is equal to whatever is this index
20:53 and
20:54 class name you just give it as an index
20:58 to this
21:00 then the confidence will be the np dot
21:03 max so
21:06 prediction zero.
21:10 Okay so np dot max again
21:12 I'll just show you
21:16 you have a value like this
21:18 you know
21:22 then what is the maximum value 0.99. So
21:25 this function returns point
21:29 99 it is as simple as that and that I
21:32 will store in a variable called
21:34 confidence
21:37 and you can just
21:39 return
21:40 these two
21:41 in a simple dictionary. So let's run this
21:44 and see what happens. So I'm going to run
21:46 this
21:47 and whenever it's ready
21:53 postman send it
21:57 see late blight now you can
21:59 easily
22:01 taste it this is lead blood okay let's
22:02 taste healthy
22:04 healthy leaves and it says healthy with
22:07 98 percent
22:10 confidence. So you can try different
22:12 images you know
22:14 like early blight for example
22:16 early blight. Let's say this one
22:20 I'll leave let's see the score the
22:22 confidence is very high and my
22:24 model is perfect perfectly predicting
22:27 the accurate class for each of these
22:29 images.
22:31 Now
22:32 loading the model from one specific
22:35 saved version might work okay for demo
22:38 applications but in real life in big
22:40 corporate companies you have new
22:42 versions of these models being built all
22:45 the time.
22:47 And let's say
22:48 version number one is a production model
22:50 it is stable but then you come up with
22:52 version number two which is beta model
22:55 which view you want to try it out on
22:57 your beta users.
22:58 So now you are running kind of
23:00 a b testing scenario where you're
23:03 comparing the performance of version one
23:05 with version two and you want to
23:07 dynamically route the traffic to
23:10 some traffic. Let's say 10 traffic to
23:12 beta users and remaining traffic to
23:15 your production users now you can do all
23:17 of that in this core you can just maybe
23:19 call it like a broad model
23:22 and you can call
23:24 let's say
23:26 version two a beta model and dynamically
23:28 you
23:29 use one or the other based on the user
23:31 type
23:32 but there is a better way to handle this
23:35 situation and that better way is using
23:37 tf serving. If you go to Youtube code
23:40 basics TF serving you'll find my video I
23:42 highly recommend you watch it because
23:43 I'm not going to cover all the concepts
23:46 behind TF serving but just to give you a
23:48 gist of it you can have
23:51 in your UI code or client code you can
23:55 have this type of urls or endpoints for
23:59 your TF serving you can say prod URL is
24:02 labels you know you can use labels. You
24:04 don't need to use specific version you
24:06 can say
24:07 my tf serving endpoint label is prod
24:10 versus beta and the corresponding config
24:14 file might look this like
24:16 this is prod actually because this is
24:19 production
24:20 versus prod. But this is broad and this
24:23 should be broad
24:24 so that prod is pointing to specific
24:27 version and things get dynamically
24:30 loaded version management becomes very
24:32 very easy
24:34 if you want to.
24:36 Let's build a new version let's say
24:38 version 3
24:39 and point that to beta all you need to
24:41 do is just change this config file. You
24:44 don't need to change your code when you
24:45 change a code you have to do a lot of
24:47 testing. It might break things. It's risky
24:50 but if you change config file
24:52 it's little safer
24:54 again I
24:55 friends you have to watch this video to
24:58 get an understanding of TF serving
25:01 now we are going to change our
25:03 architecture a little bit and we are
25:05 going to do this.
25:06 What we are going to do is
25:08 our
25:09 UI website or right now we are using
25:11 postman we have not built this website
25:13 yet but the postman will call fast API
25:15 server. fast API will do
25:18 maybe numpy conversion and all those
25:20 things but for actual prediction it will
25:23 call a TF serving
25:25 server which is running on localhost
25:27 8501
25:30 to run tf serving. I will start windows
25:33 powershell because I like to run it that
25:36 way
25:36 and I will use this command so I'll
25:38 explain
25:40 okay let me
25:42 if you have seen. By the way if you've
25:43 seen my tf serving video you will get an
25:46 idea you need to install docker and you
25:49 need to get a docker image for TF
25:52 serving. That's why if you watch
25:54 this video code basics TF serving
25:58 you would get all the understanding on
26:00 how what to install and you know how
26:02 different concepts work. So now we are
26:04 running docker run we are saying
26:07 port 8501 on my host system maps to
26:10 eight five zero one on my docker
26:11 container image.
26:12 And my directory is c code potato
26:16 disease that is mapping to slash potato
26:19 dishes directory inside my docker
26:22 This is the name of the container. So I'm
26:24 running tensorflow serving
26:26 my rest API port is eight five zero one.
26:28 So if you look at this image see eight
26:30 five zero one that's where my TF serving
26:32 is running and my model config file is
26:35 potato. This is dot config okay. So potato
26:38 disease model dot config. So here this is
26:42 how the file looks like I'm saying okay
26:44 run all the versions which are available
26:47 so I will run all the versions and when
26:49 you do
26:51 prediction by default. It will use latest
26:54 version which version 3 but you can
26:55 explicitly specify version as well this
26:58 way if you
27:00 you know build a new version 4 it will
27:02 automatically use that for version. I'm
27:04 using a very simple models config file
27:07 but
27:07 you can use
27:09 this kind of fancy file where
27:11 you know you have different versions for
27:13 production beta and so on
27:16 all right
27:19 So now
27:20 here I will say end point let me
27:23 let me go into meditation. I love
27:27 meditation okay point end point what is
27:30 my endpoint?
27:32 You have any guess?
27:36 See this is how you will use version two
27:39 but I don't really want to use version
27:41 two. I want to use
27:44 latest version so this way
27:47 it will use latest
27:49 version basically.
27:53 So if I build a version 4 it will use
27:55 version 4. If I build a version 5 it
27:57 will use version 5. So it's dynamically
27:59 loaded or loading.
28:01 All those things okay
28:05 All right! What did I do okay? Let me make
28:09 you know let me make a new
28:12 file actually.
28:14 I will keep this so that you have a
28:16 reference
28:22 this was a model
28:24 and I will copy with ctrl c, ctrl v
28:27 and I will call it
28:29 main
28:30 TF serving dot pi
28:34 and in here
28:35 I will
28:37 make those changes. So my
28:40 endpoint is this
28:44 of course I'm not using any specific
28:46 version
28:47 [Music]
28:48 and
28:49 now
28:51 here
28:52 [Music]
28:54 okay?
28:55 So we'll use a request module so I will
28:58 import request model to make that http
29:02 call
29:03 and in this request so instead of
29:07 model.predict. You are using request.post
29:13 request dot post
29:15 and in that post
29:16 you are specifying your end point you
29:21 the
29:22 in json here. You need to specify json
29:24 data. Okay what is my json data by the
29:26 way?
29:27 This is my actual request okay? How does
29:29 my actual request look like?
29:31 If you have seen my TF serving video. You
29:34 know that
29:36 the weightiest learning works? Is it will
29:39 expect instances. You know as a
29:42 dictionary key and here you need to
29:45 supply
29:47 your image batch.
29:49 You can say image batch to list just
29:51 convert it to list this is the format
29:53 that it expects basically.
29:56 And what you get as a result is your
30:00 response. So let's do just this much-
30:02 Let's set a breakpoint and once again
30:05 test everything from the postman. So I'll
30:08 set a breakpoint here
30:11 I will stop everything. I will
30:14 do debugging I'll start debugging here
30:18 and once the prompt comes up when it
30:20 says local host this is ready I go to my
30:25 postman sender request
30:27 and in the response
30:30 say 200
30:32 http request 200 response 200 minutes
30:36 everything is fine
30:37 and
30:38 it has predictions here.
30:41 So you need to
30:42 [Music]
30:43 use
30:45 I think json here okay so predictions
30:47 looks okay so our request everything
30:49 worked fine. So let's further enhance
30:52 this code and kind of
30:54 complete it so here
30:56 the response dot json will contain the
30:59 actual response in that
31:02 there was an element called predictions
31:08 in that.
31:09 I want to look at the zeroth image see
31:11 we are supplying a batch of images but
31:14 actually we have a batch of only one
31:16 image. So zeroth location is your first
31:20 response. Okay so I will say I will call
31:23 it prediction not predictions
31:26 singular because zeroth image. Okay now
31:30 here
31:31 we already saw previously that if you do
31:33 np dot arg max on prediction
31:36 and np dot max
31:38 on prediction there are two two type of
31:40 things. What do you get?
31:42 Well you have already seen this video
31:44 right? Here you get the confidence
31:48 and here you get
31:50 the predicted
31:52 class
31:55 and this is something you return back
31:58 as a
32:01 dictionary.
32:02 So predicted class is
32:05 this one here
32:07 and confidence is
32:10 this guy here
32:14 this is pretty much it. I can
32:16 just run the server now
32:19 my server is running okay
32:21 send a request internal server error
32:25 I think I'm realizing the problem the
32:27 predictions here. I think I need to do
32:30 this np dot array
32:33 so I need to convert this into a np.
32:36 Otherwise I can't call this npr
32:38 arg max function you know
32:41 I converted it to that
32:44 run it again
32:46 stop and run
32:56 just set a breakpoint. Here I'm trying to
32:57 see where exactly that error is
32:59 occurring so until this point is okay
33:02 see my response looks good
33:06 and here
33:08 if I do response.js
33:10 let's load that step by step
33:13 so response.json
33:16 see
33:17 response.json also looks good
33:21 and now let's do
33:28 not able to edit this
33:30 so response.json is a dictionary and in
33:32 that dictionary you are saying
33:34 predictions from my spelling is most
33:37 likely okay
33:38 and zeroth prediction
33:41 and you're doing np dot alright so I
33:43 think that should work okay.
33:44 Oh so that that worked okay? Actually
33:48 okay.
33:49 Now
33:51 dot arg max let's see if that works
33:56 Okay that works. Okay confidence also
33:58 worked okay
34:00 So yes giving
34:02 these two back
34:14 what happened was
34:16 I previously had a session running on
34:18 zero 8501 port
34:20 for my docker tensorflow survey. So I'm
34:22 now running it on eight five zero two so
34:24 I change eight five zero to s five zero
34:26 to here eight five zero two
34:28 and I will
34:30 just
34:34 this and see this is now running
34:36 it says this is running okay
34:38 and here
34:40 I'm just changing my port
34:43 8502
34:47 I'm not sure if this is what is the
34:49 cause for the error but
34:51 i'll run it anyway.
34:56 Okay that wasn't
34:59 that wasn't a cause okay. Oh I'm not
35:02 supplying the file okay let me just
35:04 apply the file.
35:06 Now I got the same error
35:12 Let me try different file
35:20 Okay I'm realizing the error here I have
35:23 to use class name actually
35:27 because it was a numpy number numpy is
35:31 data type is not supported by first api
35:33 that's why so this is the
35:36 you know actual class name so now when I
35:38 run this
35:41 hopefully let's see if it works
35:45 correct. See it worked only blight you
35:47 can
35:50 attach an image of a healthy potato
35:52 plant send it not say healthy so things
35:54 are working just perfectly okay right
35:58 now so just to go over it again.
36:00 We sent a request here using request
36:03 module
36:05 and went to localhost 8502 for TF
36:08 serving okay and that returned us a
36:11 response which we are returning back to
36:13 the UI
36:15 we have for today in the next video we
36:18 will build a website in React.js where
36:20 you can drag and drop potato plant leaf
36:23 image and it will call fast EPS server
36:26 that we wrote today
36:28 for the prediction.
36:30 Check video description below I have
36:31 provided all the useful link including
36:34 the link of this playlist and I have the
36:36 by the way same series available in
36:37 hindi. So if you have issues with English
36:40 you can also watch this series in Hindi.
36:42 Thank you.