back to index

Lesson 2: Practical Deep Learning for Coders 2022


Chapters

0:0 Introduction
0:55 Reminder to use the fastai book as a companion to the course
2:6 aiquizzes.com for quizzes on the book
2:36 Reminder to use fastai forums for links, notebooks, questions, etc.
3:42 How to efficiently read the forum with summarizations
4:13 Showing what students have made since last week
6:45 Putting models into production
8:10 Jupyter Notebook extensions
9:49 Gathering images with the Bing/DuckDuckGo
11:10 How to find information & source code on Python/fastai functions
12:45 Cleaning the data that we gathered by training a model
13:37 Explaining various resizing methods
14:50 RandomResizedCrop explanation
15:50 Data augmentation
16:57 Question: Does fastai's data augmentation copy the image multiple times?
18:30 Training a model so you can clean your data
19:0 Confusion matrix explanation
20:33 plot_top_losses explanation
22:10 ImageClassifierCleaner demonstration
25:28 CPU RAM vs GPU RAM (VRAM)
27:18 Putting your model into production
30:20 Git & Github desktop
31:30 For Windows users
37:0 Deploying your deep learning model
37:38 Dog/cat classifier on Kaggle
38:55 Exporting your model with learn.export
39:40 Downloading your model on Kaggle
41:30 How to take a model you trained to make predictions
43:30 learn.predict and timing
44:22 Shaping the data to deploy to Gradio
45:47 Creating a Gradio interface
48:25 Creating a Python script from your notebook with #|export
50:47 Hugging Face deployed model
52:12 How many epochs do you train for?
53:16 How to export and download your model in Google Colab
54:25 Getting Python, Jupyter notebooks, and fastai running on your local machine
60:50 Comparing deployment platforms: Hugging Face, Gradio, Streamlit
62:13 Hugging Face API
65:0 Jeremy's deployed website example - tinypets
68:23 Get to know your pet example by aabdalla
69:44 Source code explanation
71:8 Github Pages

Whisper Transcript | Transcript Only Page

00:00:00.000 | Hi everybody, welcome to lesson two.
00:00:04.200 | Thanks for coming back.
00:00:07.000 | Slight change of environment here.
00:00:08.120 | We had a bit of an administrative issue at our university.
00:00:11.920 | Somebody booked our room, so I'm doing this from the study at home, so sorry about the
00:00:21.640 | lack of decorations behind me.
00:00:25.800 | I'm actually really, really pumped about this lesson.
00:00:29.320 | It feels like going back to what things were like in the very early days, because we're
00:00:34.760 | doing like some really new, really cool stuff, which, you know, stuff that hasn't really
00:00:42.360 | been in courses like this before, so I'm super, super excited.
00:00:48.160 | So thanks a lot for coming back after lesson one, and I hope it's worth you coming back.
00:00:52.600 | I think you're going to love it.
00:00:54.240 | I am, yeah, I'm really excited about this.
00:00:57.960 | Now remember that the course goes with the book, so be sure that you're not following
00:01:04.480 | along in the book because we're covering similar things in different directions, but read the
00:01:09.040 | book as well.
00:01:10.160 | And remember, the book is entirely available for free as well.
00:01:14.000 | You can go to the Fast.ai Fastbook repo to see the notebooks, or through course.fast.ai.
00:01:20.080 | You can read it there, for example, through Colab.
00:01:23.360 | And also, remember that the book, I mean, the book's got a lot of stuff that we didn't
00:01:33.920 | cover in the course, like, you know, stuff I find pretty interesting about the history
00:01:37.200 | of neural networks, some of which has some really interesting personal stories, actually,
00:01:44.640 | as you'll read here.
00:01:46.160 | And at the end of each chapter, there is a quiz.
00:01:49.360 | And remember, it's not a bad idea before you watch the video to read the quiz, so if you
00:01:55.400 | want to read the chapter 2 quiz, you know, and then come back, that's not a bad idea.
00:02:00.560 | And then make sure that you can do the quiz after you've watched the video and you've
00:02:04.000 | read chapter 2 of the book.
00:02:07.840 | Something I didn't mention last week is there's also a very cool thing that Radak, who I mentioned
00:02:11.720 | last week, has written called aikwizzes.com, which is a site specifically for quizzes about
00:02:19.720 | the book.
00:02:20.720 | And it actually uses repetitive space learning techniques to make sure that you never forget.
00:02:24.500 | So do check out aikwizzes.com, it's all brand new questions, they're different to the ones
00:02:29.960 | in the book.
00:02:31.640 | And they're really nicely curated and put together, so check out aikwizzes.com as well.
00:02:39.440 | However, as well as course.fast.ai, there's also forums.fast.ai.
00:02:45.040 | So course.fast.ai is where you want to go to get links to all the notebooks and Kaggle
00:02:52.200 | stuff and all that stuff.
00:02:55.600 | You'll also find on forums.fast.ai, every lesson has an official topic, you know, with
00:03:01.520 | all the information you'll need.
00:03:04.520 | Generally there'll be a bit more info on the forums.
00:03:07.040 | We try to keep the course lean and mean, and the forums are a bit more detailed.
00:03:14.020 | So if you find, in this case, you'd want to look at the Lesson 2 official topic, but here's
00:03:18.600 | the Lesson 1 official topic so far.
00:03:25.000 | So from the Lesson 1 official topic, already after just a few days since I recorded it,
00:03:32.640 | we haven't even launched the course, so it's just the people doing it live, there's already
00:03:36.240 | a lot of replies, and that can get pretty overwhelming.
00:03:40.280 | So be aware that there's a button at the bottom of my post that says summarize this topic.
00:03:48.440 | And if you hit that, then you'll just see the most upvoted replies, and that's a really
00:03:54.140 | good way to just make sure that you hit on the main stuff.
00:03:58.800 | So there's the button, and here's what it looks like after you hit it, you'll just get
00:04:02.840 | the upvoted stuff from fast.ai legends like Sanyam and Tanishk.
00:04:09.800 | So hopefully you'll find that a useful way to use the forum.
00:04:14.680 | So one of the cool things about this week is I, as promised, put up the Show Us What
00:04:21.280 | You've Made post, and already a lot of people have posted.
00:04:27.600 | I took the screenshot a few days ago, it's way above 39 replies already, if I remember
00:04:32.800 | correctly.
00:04:34.160 | I had a lot of trouble deciding which ones to share, because they're also good.
00:04:39.240 | So I've actually decided to kind of, you know, went the easy route, and I just picked the
00:04:46.320 | first.
00:04:47.320 | So I'm just going to show you the first ones that were posted, because they're also good.
00:04:50.960 | So the very, very first one to be posted is a damaged car classifier.
00:04:58.560 | So that worked out pretty well, it looks like.
00:05:00.880 | And I really liked what Matt the creator said about this is that, you know, wow, it's a bit
00:05:07.640 | uncomfortable to run this code, I don't really understand yet, but I'm just doing it.
00:05:12.060 | And so I'm like, yeah, good on you, Matt, for just for just doing it.
00:05:16.000 | That's the way to get started.
00:05:17.000 | It's all going to make sense, don't worry.
00:05:20.760 | Very nice to see that the next one posted was actually a blog post in fast pages, very
00:05:26.480 | nice to see.
00:05:27.480 | They were describing some stuff, some experiments that they ran over the week.
00:05:31.280 | And what did they find?
00:05:33.640 | Next one was the amazing beard detector, which if I understand correctly, was mainly because
00:05:38.080 | it's very easy to get from bird to beard by just changing one letter to two.
00:05:42.800 | And this is doing a very good job of finding gentlemen with beards.
00:05:46.760 | So very nice.
00:05:49.040 | And then this one is another level again, it's a whole in production web app to classify
00:05:56.160 | food, which is kind of like extra credit.
00:06:00.080 | Apparently we're up to 80 replies now in that thread.
00:06:03.080 | Thank you, Sanyam.
00:06:06.640 | Very cool.
00:06:10.800 | So you know, obviously, so this was actually created by Suvash, who's been doing the courses
00:06:19.920 | for a few years now, I believe.
00:06:23.840 | And so, you know, one day you too might be able to create your very own web app and put
00:06:29.320 | it in production.
00:06:30.320 | And when I say one day, more specifically today, I'm actually going to show you how
00:06:35.640 | to do this right now.
00:06:37.620 | So it's actually quite lucky coincidence that Suvash put this up there because it's exactly
00:06:42.520 | the topic that we're going to pick today.
00:06:46.160 | So how do we go about putting a model in production?
00:06:51.760 | Step one is, well, you've kind of done step one, right?
00:06:57.120 | Step one is step one, two, three, four is figure out what problem you want to solve,
00:07:03.160 | figure out how to find the data for it, gather some data and so forth.
00:07:08.720 | So what's the kind of first step after you've got your data?
00:07:13.640 | The next step is data cleaning.
00:07:15.840 | And if you go to chapter two of the book, which I'm going to go ahead and open up now.
00:07:24.060 | So here is the book, so you can open it in CoLab directly from the course, or if you've
00:07:31.280 | cloned it to your computer or whatever, you can do it there.
00:07:34.640 | So remember, course.fast.ai will run you through exactly how to run these notebooks.
00:07:40.400 | And so you can see chapter two is all about putting stuff in production.
00:07:44.560 | And so here is chapter two.
00:07:46.180 | All right.
00:07:47.180 | And so remember, we hit Shift+Enter to run cells, okay, to execute them.
00:07:53.880 | And so we're going to go to the part of the book where we start cleaning the data.
00:07:59.880 | So I'll click on navigate, and we'll go down here, gathering data, there we are.
00:08:08.400 | So we could do a quick bit of revision first.
00:08:10.840 | So by the way, I will mention a lot of people ask me what are the little tricks I use for
00:08:16.440 | getting around Jupyter Notebook so quickly and easily.
00:08:20.760 | One of the really nice ones, as you'll see, is this navigate menu, which actually doesn't
00:08:23.840 | appear by default.
00:08:25.920 | So if you install something called Jupyter Notebook Extensions, Jupyter Notebook Extensions,
00:08:37.200 | and so you just pip install them, follow the instructions.
00:08:46.120 | And then restart Jupyter, obviously, Colab already has a table of contents, by the way.
00:08:52.560 | This is just if you're using something local, for example.
00:08:56.480 | Then you'll see here that this nb extension thing will appear.
00:09:00.000 | And if you click on table of contents two, that gets you this handy navigation bar.
00:09:05.480 | The other thing I really like is this one here called collapsible headings.
00:09:11.760 | And that's the one which gives me these nice little things here to close and open up.
00:09:19.280 | And actually, that's not even the best part.
00:09:20.720 | The best part for me is if I hit right arrow, it goes to the end of a section.
00:09:26.040 | And if I hit left arrow, it goes to the start of a section.
00:09:29.620 | So it's like if I want to move around sections, I just press up left, down right, down right.
00:09:34.920 | Very handy.
00:09:35.920 | And if you hit left again, when you're here, it'll close it up.
00:09:38.560 | Hit right again here.
00:09:39.560 | Open it up.
00:09:40.560 | So that's collapsible headings.
00:09:41.560 | Anyway, a couple of really handy things.
00:09:43.240 | And we'll be talking a lot more about getting your notebook set up today at the moment.
00:09:49.200 | Okay.
00:09:50.200 | So one thing you'll notice is in the book, we use the Bing API for searching images.
00:09:57.920 | I've just gone ahead and replaced Bing with DDG because the Bing API requires getting
00:10:04.160 | an SDK key, which honestly, it's like the hardest thing in deep learning is figuring
00:10:09.700 | out that the Bing Azure website and getting that sorted out, DDG doesn't.
00:10:14.720 | So it's basically exactly the same.
00:10:20.100 | And you can, I'll share this notebook as well on the course website and the forum.
00:10:25.840 | But all I've basically done is I've replaced Bing with DDG and got rid of the key.
00:10:30.280 | So then just like we did last week, we can search for things.
00:10:35.000 | And so in the book, we did a bear detector because at the time I wrote it, my then toddler
00:10:41.060 | was very interested in me helping identify teddy bears.
00:10:45.760 | And I certainly didn't want her accidentally cuddling a grizzly bear.
00:10:50.460 | So we show here how we can search for grizzly bears just like last week, something that
00:10:56.820 | loops through grizzly bears, black bears and teddy bears, just like last week, get rid
00:11:02.680 | of the ones that failed just like last week.
00:11:06.880 | And one thing a few people have asked on the forum is how do I find out more information
00:11:14.100 | about basically any Python or fast AI or PyTorch thing?
00:11:20.560 | There's a few tips here in the book.
00:11:24.240 | One is that if you put a double question mark next to any function name, you'll actually
00:11:29.260 | get the whole source code for it.
00:11:32.120 | And by the same token, if you put a single question mark, you'll get a brief, a little
00:11:42.400 | bit of information.
00:11:44.620 | If you've got nbdev installed, I think it's nbdev you need, then you can type doc and
00:11:55.740 | that'll give you, perhaps most importantly, a link straight to the documentation where
00:12:03.480 | you can find out more information.
00:12:06.660 | And generally there'll be examples as well.
00:12:09.840 | And also a link here to the source code, if you want to, let's do that with a control.
00:12:15.580 | A link to the source code and that way you can jump around.
00:12:19.840 | Notice that in GitHub in the source code you can click on things and jump to their definition,
00:12:24.840 | so it's kind of a nice way of skipping around to understand exactly what's going on.
00:12:32.980 | Okay, so lots of great ways of getting help.
00:12:42.200 | But what I promised you is that we're going to now clean the data.
00:12:46.520 | So I'm going to tell you something that you might find really surprising.
00:12:51.880 | Before you clean the data, you train a model.
00:12:55.440 | Now I know that's going to sound really backwards to what you've probably heard a thousand times,
00:13:00.680 | which is that first you train, you plane your data and then you train your model.
00:13:06.680 | But I'm going to show you something really amazing.
00:13:08.840 | First we're going to train a model and you'll see why in a moment.
00:13:11.480 | So to train a model, just like before, we use a data block to grab our data loaders.
00:13:17.240 | There's lots of information here in the book about what's going on here.
00:13:20.200 | There we go.
00:13:27.800 | And so then we can call show batch to see them as per usual.
00:13:31.600 | There's a little sidebar here in the book I'll quickly mention, which is about the different
00:13:37.720 | ways we can resize.
00:13:39.360 | I think we briefly mentioned it last week.
00:13:41.360 | We can squish.
00:13:44.400 | Last week I used a string.
00:13:45.400 | You can use a string or this kind of enum-like thing that we have.
00:13:48.720 | You can see with a squish, you can end up with some very thin bears.
00:13:53.400 | Right?
00:13:54.400 | So this is the real site that's the shape of the bear.
00:13:56.440 | Here it's become thin.
00:13:57.440 | You can see now we've got all of its cubs.
00:13:59.960 | Are they called cubs?
00:14:01.320 | Yeah, bear cubs.
00:14:02.860 | So it squished it to make sure we can see the whole picture.
00:14:05.240 | Same one here.
00:14:06.240 | This one was out of the picture.
00:14:07.240 | We squished it.
00:14:08.240 | This guy now looks weirdly thin, but we can see the whole thing.
00:14:11.800 | So that's squishing.
00:14:12.800 | Whereas this one here is cropping.
00:14:14.360 | It's cropped out just the center of the image, so we get a better aspect ratio, but we lose
00:14:18.040 | some stuff.
00:14:19.040 | This is so we can get square images.
00:14:21.560 | And the other approach is we can use pad.
00:14:24.740 | And so you can pad with various different things if you pad with zeros, which is black.
00:14:28.600 | You can see here now we've got the whole image and the correct aspect ratio.
00:14:33.480 | So that's another way we can do it.
00:14:34.920 | And you know, different situations, you know, result in different quality models.
00:14:41.440 | You can try them all.
00:14:42.440 | It doesn't normally make too big a difference, so I wouldn't worry about it too much.
00:14:47.220 | I'll tell you one though that is very interesting is random resized crop.
00:14:52.140 | So instead of saying resize, we can say random resized crop.
00:14:58.660 | And if we do that, you'll see we get a different bit of an image every time.
00:15:04.400 | So during the week, this week, somebody asked on the forum, I'm trying to, this is a really
00:15:10.280 | interesting idea, which it turned out worked slightly, was they wanted to recognize pictures
00:15:17.920 | of French and German texts.
00:15:22.760 | So obviously this is not the normal way you would do that, but just for a bit of experiment.
00:15:26.400 | And I love experiments.
00:15:27.800 | So they had very big scans of documents and they wanted to figure out whether it was French
00:15:32.620 | or German just by looking at images.
00:15:34.640 | And they said the pictures were too big.
00:15:36.080 | What should I do?
00:15:37.080 | I said, use random resized crop and that way you would grab different bits of the image.
00:15:41.680 | And this is very nice because you could run lots and lots of epochs and get slightly different
00:15:46.400 | pictures each time.
00:15:49.700 | So this is a very good technique.
00:15:51.760 | And this idea of getting different pictures each time from the same image is called data
00:15:56.160 | augmentation.
00:15:57.160 | And again, I'm not going to go into too much detail about data augmentation because it's
00:16:05.920 | in the book.
00:16:06.920 | But I'll just quickly point out here that if you use this thing called aug transforms,
00:16:12.120 | so augmentation transforms, and here I have multiplied them by two.
00:16:17.000 | So I've made them super big so you can see them more easily.
00:16:19.840 | You can see that these teddies are getting turned and squished and warped and recolored
00:16:27.200 | and saturated, all this stuff to make every picture different.
00:16:31.800 | And generally speaking, if you're training for more than about five or 10 epochs, which
00:16:37.560 | you'll probably want to do most of the time, unless you've got a super easy problem to
00:16:41.600 | solve, you'll probably want to use random resized crop and these orb transforms.
00:16:48.520 | Don't put them all equals two, just leave that empty.
00:16:50.840 | I'm just putting it there so you can see them more clearly.
00:16:56.920 | So I've got an interesting question here from Alex in our audience, which is, is this copying
00:17:05.200 | the image multiple times, doing something like this or something like this?
00:17:11.340 | And the answer is no, we're not copying the image.
00:17:16.200 | What happens is that image, so each epoch, every image gets rid.
00:17:21.560 | And what happens here is though, is kind of in memory, in RAM, this, the image is being
00:17:27.480 | warped, right?
00:17:29.220 | It's being, we're cropping it and recoloring it and so forth.
00:17:32.240 | So it's a real time process that's happening during model training.
00:17:37.080 | So there's no copies being stored on your computer, but effectively it's almost like
00:17:41.800 | there's infinitely slightly different copies, because that's what the model ends up seeing.
00:17:47.120 | So I hope that makes sense, Alex and everybody else.
00:17:53.160 | That's a great question.
00:17:54.880 | Okay, so we've got, we're going to use random resized crop, we're going to use augmentation
00:18:00.120 | transforms so that we can get a data loaders from that and then we can go ahead and train
00:18:05.880 | our model.
00:18:06.880 | We've got about a minute.
00:18:08.520 | In this case, we only did four epochs of fine-tuning.
00:18:13.040 | We'll talk about why there's five here later in the course, but four main epochs of fine-tuning.
00:18:18.540 | So we probably didn't really need random resized crop and aug transforms because there's so
00:18:23.240 | few epochs, but you know, if you want to run more epochs, this is a good approach.
00:18:29.200 | Under 3% error, that's good.
00:18:31.160 | Okay, so remember I said we're going to train a model before we clean.
00:18:37.040 | Okay so let's go ahead and train it.
00:18:46.560 | So while that's training, so it's running on my laptop, which only has a 4 gigabyte GPU,
00:18:53.760 | it's pretty basic, but it's enough to get started.
00:18:56.760 | While that's training, we'll take a look at the next one.
00:18:59.560 | So the first thing we're going to look at is the confusion matrix and the confusion matrix
00:19:04.080 | is something that it only is meaningful for when your labels are categories, right?
00:19:09.680 | And what it says is how, what category errors are you making?
00:19:13.580 | And so this is showing that the model that we've got at this point, there was two times
00:19:19.660 | when there was actually a grizzly bear and it thought it was a black bear.
00:19:24.920 | And there was two times when there was actually a black bear and it thought it was a grizzly
00:19:28.320 | bear.
00:19:29.320 | And there was no times that it got teddies wrong, which makes sense, right?
00:19:32.160 | Because teddies do look quite different than both.
00:19:39.240 | In a lot of situations, when you look at this, it'll kind of give you a real sense of like,
00:19:43.760 | okay, well, what are the hard ones, right?
00:19:45.600 | So for example, if you use the pets dataset that we quite often play within the book in
00:19:50.160 | the course, this classification metric matrix for different breeds of pet, you know, really
00:19:56.880 | shows you which ones are difficult to identify.
00:19:59.800 | And I've actually gone in and like read Wikipedia pages and pet breeding reports about how to
00:20:06.400 | identify these particular types because they're so difficult and even experts find it difficult.
00:20:11.120 | And one of the things I've learned from doing the course actually is black bears and grizzly
00:20:14.880 | bears are much harder to pick apart than I had realized.
00:20:19.360 | So I'm not even going to try.
00:20:22.160 | But I'll show you the really interesting thing we can do with this model is that now we've
00:20:25.680 | created this classification interpretation object, which we use for confusion metrics.
00:20:33.720 | We can say plot top losses.
00:20:42.600 | We can say plot top losses.
00:20:45.600 | And this is very interesting.
00:20:47.560 | What it does is it tells us the places where the loss is the highest.
00:20:53.720 | Now, if you remember from the last lesson, the loss is that measurement of how good our
00:21:00.580 | model is that we take after each time we run through an item of data.
00:21:05.880 | A loss will be bad if we predict wrongly and we're very confident about that prediction.
00:21:13.360 | So here's an example where we predicted, here's the order here, prediction, actual loss probability,
00:21:19.000 | where we predicted grizzly and it was actually a black.
00:21:23.160 | And we were 96 percent sure, our model was, that it's a grizzly.
00:21:29.120 | Now I don't know enough about bears to know whether the model made a mistake or whether
00:21:34.280 | this actually is a picture of a grizzly bear.
00:21:38.560 | But so an expert would obviously go back and check those out.
00:21:43.000 | Now you'll notice a couple here, it's got grizzly, grizzly, teddy, teddy.
00:21:48.240 | They're actually correct.
00:21:50.160 | So why is this loss bad when it's correct?
00:21:52.360 | And the reason is because it wasn't very confident, it was only 66 percent confident, right?
00:21:57.880 | So here's a teddy, it's only 72 percent confident, right?
00:22:01.440 | So you can have a bad loss either by being wrong and confident or being right and unconfident.
00:22:08.000 | Now the reason that's really helpful is that now we can use something called the FastAI
00:22:15.040 | image classifier cleaner to clean up the ones that are wrongly labeled in our data set.
00:22:25.120 | So when we use the image classifier cleaner, it actually runs our models, that's why we
00:22:29.800 | pass it learn, right?
00:22:32.040 | And I mentioned that I don't know much about black bears and grizzly bears, but I do know
00:22:36.920 | a lot about teddy bears, so I picked teddy bears.
00:22:41.280 | And if I click teddy bears, it's now showing me all the things in the training set - you
00:22:45.360 | can pick training or valid - that were marked as teddy bears.
00:22:48.640 | And here's what's really important, they're ordered by loss.
00:22:52.640 | So they're ordered by confidence, right?
00:22:55.000 | So I can scroll through just the first few and check they're correct, right?
00:22:59.440 | And oh, here's a mistake, right?
00:23:02.360 | So when I find one that was wrongly gathered, I can either put it if it's in the wrong category,
00:23:07.400 | I can choose the correct category, or if it shouldn't be there at all, I click delete.
00:23:11.520 | So here I'll go ahead and click delete, right?
00:23:14.280 | So you can see some reasons that some of these are hard, like, for example, here's two teddies,
00:23:17.800 | which is just, I guess, confusing, so it doesn't see that often.
00:23:20.880 | This one here is a bit weird looking, it looks almost like a wombat.
00:23:26.800 | This is an awful lot of teddies.
00:23:32.160 | This one maybe is just a bit hard to see from the background, but these other ways they
00:23:35.760 | are fine.
00:23:37.440 | Fine.
00:23:38.440 | So we just looked through the first few, and if you don't see any problem or problems in
00:23:41.000 | the first few, you're probably fine.
00:23:42.880 | So that's cleaned up our training set.
00:23:44.840 | Let's clean up our validation set as well.
00:23:48.320 | So here's that one it had trouble with, I don't know why it had trouble with that one,
00:23:53.320 | but so be it, and we'll have a quick scroll through.
00:23:57.840 | Okay, I'm not really sure that's a bear, so I'm just going to go ahead and delete it.
00:24:04.240 | So teddy something, but you know, it's a problem.
00:24:09.880 | Okay, that's not a teddy either.
00:24:15.520 | So you see the idea, right?
00:24:16.920 | So after we've done that, what that does is the cleaner has now stored a list of the ones
00:24:23.480 | that we changed and a list of the ones we deleted.
00:24:26.240 | So we can now go ahead and run this cell, and so that's going to go through a list of
00:24:31.600 | all of the indexes that we said to delete, and it will delete those files, and it'll
00:24:37.000 | go through all the ones we said to change, and it will move them to the new folder.
00:24:41.440 | There we go, done.
00:24:45.520 | So this is like not just something for image models, it's just, it's actually a really
00:24:50.360 | powerful technique that almost nobody knows about and uses, which is before you start
00:24:55.160 | data cleaning, always build a model to find out what things are difficult to recognize
00:25:01.880 | in your data, and to find the things that the model can help you find data problems.
00:25:06.880 | And then as you see them, you'll kind of say, okay, I see the kinds of problems we're having,
00:25:10.720 | and you might find better ways to gather the next data set, or you might find ways to kind
00:25:15.440 | of automate some of the cleaning and so forth.
00:25:21.080 | Okay, so that is data cleaning, and since I only have a four gigabyte GPU, it's very
00:25:30.880 | important for me to close and halt, because that will free up the memory.
00:25:34.880 | So it's important to know on your computer, your normal RAM doesn't really get filled
00:25:43.640 | up, because if you use up too much RAM, what will happen is that instead your computer
00:25:51.960 | will start, it's called swapping, which is basically to save that RAM onto the hard disk
00:25:56.440 | to use it later.
00:25:57.800 | GPUs can't swap, GPUs when they run out of RAM, that's it, you're done.
00:26:04.200 | So you need to make sure that you close any notebooks that are using the GPU that you're
00:26:08.840 | not using, and really only use it one thing at a time on the GPU, otherwise you'll almost
00:26:14.680 | certainly run out of memory.
00:26:16.200 | So we've got the first few reds starting to appear, so remember to ask.
00:26:22.440 | And in terms of the yellows, it's important to know, as you watch the video, I'm not asking
00:26:28.280 | you to run all this code, okay?
00:26:31.360 | The idea is to kind of watch it, and then go back and pause, you know, as you go along,
00:26:36.640 | or you can just stop, try, stop, try.
00:26:40.880 | The approach I really like and a lot of students really like for watching these videos is to
00:26:44.800 | actually watch the entire thing without touching the keyboard to get a sense of what the video
00:26:52.080 | is about, and then go back to the start, and watch it again, and follow along.
00:26:58.440 | That way, at every point, you know what it is you're doing, you know what's going to
00:27:01.600 | happen next, that can actually save you some time.
00:27:04.120 | It's a bit of an unusual way, because obviously, like, real life lectures, you can't do that,
00:27:10.880 | you can't rewind the professor and get them to say it again, but it's a good way to do
00:27:16.000 | it here.
00:27:18.840 | So now that we've cleaned our data, how are we going to put it into production?
00:27:22.120 | Well, in the book, we use something called Voila.
00:27:26.000 | And it's pretty good, but there's actually something that I think most of you are probably
00:27:32.400 | going to find a lot more useful nowadays, which is something called Hugging Face Spaces,
00:27:38.200 | and there's a couple of things you can use with that.
00:27:40.160 | We're going to look at something called Gradio today.
00:27:43.080 | And there isn't a chapter about this in the book, but that doesn't matter, because Tanishk
00:27:49.640 | Abraham, who's actually one of the TAs in the course, has written a fantastic blog post
00:27:55.000 | about really everything we're going to cover today.
00:27:58.840 | So there's a link to that from the forum and from the course page.
00:28:03.880 | So this is like the equivalent of the chapter of the book, if you like.
00:28:07.860 | And I would be remiss if I didn't stop for a moment and call out Tanishk in a big way
00:28:13.200 | for two reasons.
00:28:14.200 | The first is, he is one of the most helpful people in the FAST AI community.
00:28:19.480 | He's been around quite a few years, incredibly tenacious, thoughtful, and patient.
00:28:25.080 | And also, because I have this fantastic picture of him a few years ago with Conan when he
00:28:30.880 | was a famous child prodigy.
00:28:32.700 | So now you know what happens to famous child prodigies when they grow up.
00:28:35.760 | They became even more famous FAST AI community members and declining experts.
00:28:41.520 | So you should definitely check out this video of him telling jokes to Conan.
00:28:45.720 | I think he's still only 18, actually.
00:28:47.560 | This is probably not that many years ago.
00:28:50.240 | So thank you very much, Tanishk, for all your help in the community.
00:28:54.200 | And sorry if you're embarrassing you with that picture of you as a nine-year-old.
00:28:57.880 | I'm not really.
00:28:59.280 | Haha.
00:29:00.280 | Okay.
00:29:01.280 | Now, the thing is, for doing radio and hugging-face spaces, well, it's easy enough to start.
00:29:07.160 | Okay.
00:29:08.160 | We start over here on the hugging-face spaces page, which we've linked to from the forum
00:29:11.960 | in the course.
00:29:14.560 | And we're going to put a model in production where we're going to take the model we trained.
00:29:19.880 | And we are going to basically copy it to this hugging-face spaces server and write a user
00:29:25.400 | interface for it.
00:29:28.520 | So, start, let's go.
00:29:32.280 | Create new space.
00:29:33.480 | Okay.
00:29:34.480 | So you can just go ahead and say, all right, so obviously you sign up.
00:29:38.240 | The whole thing's free.
00:29:39.240 | And basically everything I'm showing you in this entire course you can do for free.
00:29:44.960 | That's the good news.
00:29:45.960 | Okay.
00:29:46.960 | So give it a name, just create something minimal.
00:29:50.600 | I always use the Apache license because it means other people can use your work really
00:29:55.120 | easily, but you don't have to worry too much about patents.
00:29:57.600 | As I say, there's a few different products you can use with it.
00:30:00.880 | We're going to use radio, also free.
00:30:04.760 | If you make it public, then you can share it, which is always a good idea when you're
00:30:08.020 | a student, particularly to really be building up that portfolio.
00:30:12.120 | Okay.
00:30:13.280 | So we're done.
00:30:14.280 | We've created a space.
00:30:17.920 | Now what do we do next?
00:30:19.480 | Well, spaces works through Git.
00:30:23.000 | Now most software developers will be very familiar with Git.
00:30:27.680 | Some data scientists might not be.
00:30:29.760 | And so Git's a very, very useful tool.
00:30:32.240 | I'm not going to talk about it in detail, but let's kind of quickly learn about how
00:30:39.000 | to use it, right?
00:30:41.160 | Now Git, you can use it through something called GitHub Desktop, which is actually pretty
00:30:47.960 | great.
00:30:48.960 | And even people who use Git through the console should probably be considering using GitHub
00:30:54.680 | Desktop as well, because something's just much faster and easier in it.
00:30:58.740 | In fact, I was talking to my friend Hamill today and I was like, "Oh, help.
00:31:02.880 | I've accidentally committed this two things by mistake.
00:31:05.960 | What's the easiest way to revert it?"
00:31:07.720 | And he used to work at GitHub, and I thought he was going to have some fancy console command
00:31:12.040 | and he was like, "Oh, you should use GitHub Desktop."
00:31:14.080 | And you can just click on it and say, "Oh, that's a great idea."
00:31:18.120 | So that's useful.
00:31:19.120 | But most of the time we do use Git from the console, from the terminal.
00:31:25.120 | If you're a Linux user or a Mac user, you've already got a terminal.
00:31:28.700 | Very straightforward.
00:31:29.700 | No worries.
00:31:30.700 | If you're a Windows user, I've got good news.
00:31:33.000 | Nowadays, Windows has a terrific terminal.
00:31:35.920 | It's called Windows Terminal.
00:31:37.240 | You get it from the Microsoft Store.
00:31:40.000 | So in fact, every time you see me using a terminal, I'm actually using that Windows
00:31:45.680 | Terminal.
00:31:46.680 | It works very well.
00:31:47.680 | God knows why I'd want it to have all these ridiculous colors, but there you go.
00:31:54.280 | Now what do you want to be running inside your terminal?
00:31:57.160 | Obviously, if you're in Linux or Mac, you've already got a shell set up.
00:32:01.900 | In Windows, you almost certainly want to use Ubuntu.
00:32:06.240 | So Windows, believe it or not, can actually run a full Linux environment.
00:32:11.800 | And to do it is typing a single line, which is this.
00:32:17.240 | So if you go to just Google for WSL install, run PowerShell as administrator, paste that
00:32:27.320 | command, wait about five minutes, reboot, you're done.
00:32:30.680 | You now have a complete Linux environment.
00:32:32.560 | Now, one of the reasons I'm mentioning this is I'm going to show you how to do stuff on
00:32:37.920 | your own machine now.
00:32:41.160 | And so this is like going to a bit of an extra level of geekery, which some data scientists
00:32:48.320 | may be less familiar with.
00:32:50.360 | So don't be worried about the terminal.
00:32:52.440 | I think you're going to find it really helpful and much less scary than you expect.
00:32:59.600 | And I particularly say like for me, I choose to use Windows and that's because I get all
00:33:07.200 | the nice Windows GUI apps and I can draw on my screen and do presentations.
00:33:11.360 | And I have a complete Linux environment as well.
00:33:14.980 | And that Linux environment uses my GPU and everything.
00:33:17.680 | So for me, my first choice is to use Windows.
00:33:21.960 | My second choice, not very much, really like it, would be to use Linux.
00:33:26.320 | Mac is a little bit harder, but it's still usable.
00:33:34.120 | So some things are a little bit trickier on Mac, but you should be fine.
00:33:37.800 | Okay.
00:33:38.960 | So whatever you've got at this point, you've now got a terminal available.
00:33:44.980 | And so in your terminal, one of the really nice things about using a terminal is you
00:33:48.280 | don't have to follow lots of instructions about click here, click here, click here.
00:33:51.860 | You just copy and paste things.
00:33:53.360 | So I'm just going to, you just copy this and you go over to your terminal and you paste
00:33:57.920 | it in and you run it.
00:34:00.480 | And after you do that, you'll find that you've now got a directory.
00:34:07.260 | And so that new directory initially is empty and they tell you, okay, go ahead and create
00:34:13.960 | a file with this in it.
00:34:16.160 | Okay.
00:34:17.160 | So how do you create a file with that in it when we're in here in our Linux environment
00:34:23.920 | on Windows or in the terminal on Mac or whatever?
00:34:26.840 | Well, all you do in Windows, if you just type explorer.exe dot, it'll open up explorer here,
00:34:34.120 | or better still on either Mac or Linux or Windows.
00:34:42.460 | So yeah, so regardless of what computer type of computer on, you can just type code dot
00:34:50.080 | and it will pop up official studio code and open up your folder.
00:34:56.600 | And so then you can just go ahead and if you haven't used VS code before, it's really well
00:35:01.760 | worth taking a few minutes to read the some tutorials.
00:35:05.960 | It's a really great IDE and so you can go ahead and create an app dot py file like they tell
00:35:13.960 | you to, app dot py file containing what they told you to put in it.
00:35:19.560 | Here it is here.
00:35:21.560 | All right, we're nearly there.
00:35:26.240 | So you can now go ahead and save that and then you need to commit it to a radio.
00:35:35.200 | It's a radio to hugging face bases.
00:35:37.480 | So one really easy way is just in Visual Studio itself.
00:35:40.760 | You can just click here and that'll give you a place where you type a message and you hit
00:35:45.680 | tick and it'll send it off to hacking face bases for you.
00:35:50.560 | So once you've done that, you can then go to back to the exact same website you run
00:35:58.560 | before, hugging space bases, JPHO minimal, and what you'll find now is that it'll take
00:36:06.280 | about a minute to build your website and the website it's building is going to have a radio
00:36:19.960 | interface with a text input, a text output, and it's going to run a function called greet
00:36:29.800 | on the input and my function called greet will return hello name.
00:36:36.160 | So that's what it's going to do.
00:36:38.920 | There it goes.
00:36:41.520 | Let's try it.
00:36:42.520 | We'll say hello to Tanishk.
00:36:44.800 | I'm not always very good at remembering how to spell his name.
00:36:47.720 | I think it's like that.
00:36:50.600 | And there you go.
00:36:51.600 | So you can see it's put the output for our input.
00:36:53.700 | So not a very exciting app, but we now have, to be fair, an app running in production.
00:37:00.480 | Now I told you we'd have a deep learning model running in production.
00:37:05.200 | So now we have to take the next step, which is to turn this into a deep learning model.
00:37:10.320 | All right, so first we're going to need a deep learning model, and there's a few different
00:37:18.640 | ways we can get ourselves a deep learning model, but basically we're going to have to
00:37:23.520 | train one.
00:37:25.400 | So I've got a couple of examples.
00:37:29.040 | I've got a Kaggle example and a Colab example.
00:37:31.900 | Maybe I'll quickly show you both.
00:37:34.120 | They're going to do the same thing.
00:37:35.120 | And I'm just going to create a dog or a cat classifier.
00:37:38.640 | Okay, so here's our Kaggle model.
00:37:41.920 | I'll click on edit so you can actually see what it looks like in edit view.
00:37:52.240 | Now Kaggle already has fast.ai installed, but I always put this first just to make sure
00:37:56.320 | we've got the latest version.
00:37:58.800 | And obviously import stuff.
00:38:00.740 | So we're going to grab the pets data set, a function to check whether it's a cat.
00:38:06.800 | That's our labeling function for our image data loaders.
00:38:09.000 | Remember, this is just another way of doing data blocks.
00:38:11.320 | It's like a little shorthand.
00:38:14.040 | And we create our learner and we fine-tune it.
00:38:16.640 | Okay, so that's all stuff we've seen before.
00:38:22.320 | So in Kaggle, every notebook has an edit view, which is what you just saw, and a reader view.
00:38:27.620 | And so you can share your notebook if you want to, and then anybody can read the reader
00:38:35.480 | view as you see.
00:38:37.440 | And so here you can see it shows you what happened when I ran it.
00:38:42.840 | And so I trained it, it took, you know, so that the GPUs on Kaggle are a bit slower than
00:38:48.040 | most modern GPUs, but this tool fast enough.
00:38:50.360 | I mean, it takes five minutes.
00:38:54.480 | And there's one bit at the end here, which you haven't seen before, which is I go learn.export
00:38:59.720 | and I give it a name.
00:39:02.840 | Now that's going to create a file containing our trained model.
00:39:08.120 | And that's the only thing, creating this file is the only thing you need a GPU for, right?
00:39:12.920 | So you do that on Kaggle or on Colab.
00:39:17.280 | So here's exactly the same thing on Colab.
00:39:18.960 | You can see pip install, here's cat, entire data, image data loaders.
00:39:24.080 | So I've got to show batch here as well just for fun, create my learner and then export.
00:39:31.800 | So while we wait, I might go ahead and just run that.
00:39:36.840 | One nice thing about Kaggle is once you've run it and saved it, you can then go to the
00:39:41.080 | data tab.
00:39:44.280 | And here is basically anything you've saved.
00:39:46.680 | It's going to appear here.
00:39:47.920 | And here it is model.pickle, right?
00:39:51.720 | So now I can go ahead and download that.
00:39:55.840 | And that will then be downloaded to my downloads folder.
00:40:01.800 | And then I need to copy it into the same directory that my Hugging Face Spaces apps in.
00:40:07.480 | Now my Hugging Face Spaces app is currently open in my terminal.
00:40:13.640 | On Mac you can type open. or in Windows you can type explorer.exe.
00:40:21.720 | And that'll bring up your finder or explorer in that directory.
00:40:29.160 | And so then you can just paste that thing you downloaded into this directory.
00:40:36.160 | Something by the way in Windows I do, which I find really helpful, is I actually grab
00:40:40.120 | my home directory in Linux and I pin it to my Quick Access.
00:40:46.640 | And that way I can always jump in Windows straight to my Linux files.
00:40:51.880 | Not really something you have to worry about on Mac because it's all kind of integrated.
00:40:55.840 | But on Windows they're like, kind of like two separate machines.
00:41:01.000 | Okay so let's do, so I created a space called testing and I downloaded my model.pickle and
00:41:12.520 | I pasted it into testing.
00:41:15.320 | So now we need to know how do we do predictions on a saved model.
00:41:23.680 | So we've got a notebook for that.
00:41:27.200 | Okay so we've got a notebook for that.
00:41:30.600 | And so I'm going to take you through how we use a model that we've trained to make predictions.
00:41:37.160 | There's a few funny things with hash pipe which I'll explain in a moment, just ignore
00:41:41.320 | those for now.
00:41:42.920 | So we import fast.ai as usual, we import radio as we did before, and we copy in the exact
00:41:50.360 | same iscat definition we had before.
00:41:53.400 | That's important.
00:41:54.400 | Any external functions that you used in your labeling need to be included here as well
00:42:00.520 | because that learner refers to those functions.
00:42:03.840 | It saves, that learner's saved everything about your model, but it doesn't have the
00:42:08.320 | source code to the function so you need to keep those with you.
00:42:12.440 | So let's try running this.
00:42:14.680 | So for example, I just grabbed, as you might have seen in my explorer, I just popped a
00:42:22.640 | dog picture there.
00:42:27.520 | And so we can create a Python image library image from that dog, turn it into a slightly
00:42:34.560 | smaller one so it doesn't overwhelm our whole screen and there's a picture of a dog.
00:42:38.680 | So how do we make predictions of whether that's a dog or a cat?
00:42:41.400 | Well, it's very simple.
00:42:42.560 | All we do is instead of training a learner, we use load_learner.
00:42:48.080 | We pass in the file name that we saved and that returns a learner.
00:42:52.340 | This learner is exactly the same as the learner you get when you finish training.
00:42:58.220 | So here we are, here's Colab, right, we've just been training a learner.
00:43:02.120 | So at the end of that, there's a learner that's been trained.
00:43:05.260 | And so we kind of froze it in time, something called a pickle file, which is a Python concept.
00:43:13.520 | It's like a frozen object.
00:43:15.600 | We saved it to disk, we transferred it to our computer and we've now loaded it and we've
00:43:20.440 | now un-throughthought it.
00:43:23.200 | Here's our unpickled learner.
00:43:24.960 | And we can now do whatever we like with that.
00:43:26.420 | So one of the things that the, one of the methods that a learner has is a .predict method.
00:43:34.720 | So if I run it, you can see even on my laptop, it's basically instance, instant.
00:43:39.160 | In fact, we can see how long it took.
00:43:42.960 | If you, in Jupyter, things that start with percent are called magics, they're special
00:43:47.480 | Jupyter things.
00:43:48.480 | So for example, there's a thing to see how long something takes.
00:43:51.360 | There you go.
00:43:52.720 | Okay, so it took 54 milliseconds to figure out that this is not a cat.
00:44:02.280 | So it's returning two things.
00:44:03.280 | Is it a cat as a string?
00:44:07.280 | Is it a cat as a zero or a one?
00:44:09.720 | And then the probability that it's a dog and the probability that it's a cat.
00:44:15.480 | So the probability of zero, false, and one, true of is it a cat?
00:44:20.400 | So definitely a dog.
00:44:22.280 | So we now want to create a Gradio interface, which basically has this information.
00:44:28.320 | So Gradio requires us to give it a function that it's going to call, so here's our function.
00:44:35.580 | So we're going to call predict, and that returns, as we said, three things.
00:44:39.160 | The prediction is a string, the index of that, and the probabilities of whether it's a dog
00:44:45.640 | or a cat.
00:44:47.440 | And what Gradio wants is it wants to get back a dictionary containing each of the possible
00:44:53.680 | categories, which in this case is dog or cat, and the probability of each one.
00:44:59.380 | So if you haven't done much Python before, a dict of a zip may be something you haven't
00:45:04.240 | seen.
00:45:05.240 | Very handy little idiom.
00:45:06.840 | Well worth checking out.
00:45:07.840 | Ditto if you haven't seen map before.
00:45:10.480 | Anyway, here it is.
00:45:13.160 | One slightly annoying thing about Gradio at the moment is that it doesn't handle PyTorch
00:45:20.120 | tensors.
00:45:21.120 | As you can see here, PyTorch is not returning normal numbers, it's returning tensors, it's
00:45:24.920 | not even returning NumPy arrays.
00:45:26.440 | In fact, Gradio can't handle NumPy either, so we have to change everything just to a
00:45:30.480 | normal float.
00:45:31.480 | So that's all that this is doing, is changing each one to a float.
00:45:34.560 | So for example, if I now call classify image with our doggy image, we get back a dictionary
00:45:41.080 | of a dog.
00:45:42.080 | Yes, definitely cat, definitely not.
00:45:45.420 | So now we've got all that, we can go ahead and create a Gradio interface.
00:45:51.320 | So Gradio interface is something where we say, well, what function do you call to get the
00:45:55.360 | output?
00:45:57.040 | What is the input?
00:45:58.040 | In this case, we say, oh, the input is an image.
00:46:01.020 | And so check out the Gradio dots, it can be all kinds of things like a webcam picture
00:46:04.680 | or a text or, you know, all kinds of things, give it a shape that it's going to put it
00:46:10.160 | into.
00:46:11.160 | The output's just going to be a label.
00:46:12.160 | So we're going to create very, very simple interface.
00:46:16.960 | And we can also provide some examples.
00:46:19.240 | And so there's a dog, a cat and a don't know, which I'll talk about in a moment, which you'll
00:46:24.120 | see here, there's a dog and a cat and a don't know.
00:46:27.800 | So once they launch it, it says, okay, that's now running on this URL.
00:46:31.620 | So if I open that up, you can see now we have just like a Sousvash, we have our own, not
00:46:39.680 | yet in production, but running on our own box, Classifier.
00:46:44.440 | So let's check, dog.
00:46:45.860 | So you can click and upload one or just choose the examples.
00:46:49.540 | Yeah, yeah, so it's running on my own laptop, basically instant.
00:46:55.480 | And I really have to tell you the story about this guy here.
00:47:00.240 | This is the don't know, submit, wait, why is it saying a hundred?
00:47:04.920 | Normally this says like 50/50.
00:47:05.920 | That's a bummer.
00:47:06.920 | This model's got messed up my whole story.
00:47:09.720 | So last time I trained this model and I ran it on the don't know, it said, it said like,
00:47:14.880 | it's almost exactly 50/50.
00:47:18.400 | And the way we found this picture is I showed my six year old daughter, she was like, what
00:47:23.720 | are you doing, dad?
00:47:24.720 | Like I'm coding.
00:47:25.720 | What are you coding?
00:47:26.720 | Oh, you know, dog cat classifier.
00:47:28.360 | She checks it out.
00:47:29.360 | And the first question is, can I take your keyboard for a moment?
00:47:32.480 | And she goes to Google and she's like, what is a dog mixed with a cat called?
00:47:37.440 | Like, there's no such thing as a dog mix of the cat.
00:47:40.280 | Anyway, she goes to the images tab and finds this picture and she's like, look, there's
00:47:44.840 | a dog mixed with a cat.
00:47:46.560 | She said, run it on that, dad, run it on that.
00:47:49.800 | And I ran it and it was like 50/50, it had no idea if it was a dog or a cat.
00:47:55.500 | Now this model I just retrained today, now I'm sure it's a cat.
00:47:59.520 | So there you go.
00:48:00.520 | I think I used a slightly different training schedule or something or gave it an extra
00:48:03.600 | epoch.
00:48:04.600 | Anyway, so that's a dog cat, but apparently it's a cat.
00:48:10.360 | I guess it is a cat.
00:48:12.680 | It's probably right.
00:48:13.680 | Shouldn't have trained it for as long.
00:48:16.160 | Okay, so there's our interface.
00:48:17.940 | Now that's actually running.
00:48:19.280 | So you actually have to click the stop button to stop it running.
00:48:21.740 | So otherwise you won't be able to do anything else in your notebook.
00:48:27.000 | Okay.
00:48:29.000 | So now we have to turn that into a Python script.
00:48:33.900 | So one way to turn it into a Python script would be to copy and paste into a Python script
00:48:38.520 | all the things that you need.
00:48:40.560 | It would be to copy and paste into a Python script all the parts of this that you need.
00:48:46.000 | So for example, we wouldn't need this, it's just to check something out.
00:48:49.160 | We wouldn't need this, it was just experimenting.
00:48:51.960 | This was just experimenting, we'd need this, right?
00:48:55.240 | So what I did is I went through and I wrote hash pipe export at the top of each cell that
00:49:02.640 | contains information that I'm going to need in my final script.
00:49:07.180 | And then, so there are the steps, right?
00:49:10.280 | And then at the very bottom here, I've imported something called notebook to script from nbdev.
00:49:16.960 | And if I run that and pass in the name of this notebook, that creates a file for me
00:49:25.720 | called app.py containing that script.
00:49:31.520 | So this is a nice, easy way to like when you're working with stuff that's expecting a script
00:49:35.800 | and not a notebook, like hugging face spaces does.
00:49:39.920 | It's fine to just copy and paste into a text file if you like, but I really like this way
00:49:43.320 | of doing it because that way I can do all of my experimentation in a notebook.
00:49:48.800 | And when I'm done, I just have a cell at the bottom, I just run and export it.
00:49:54.240 | How does it know to call it app.py?
00:49:56.620 | That's because there's a special thing at the top, default export, default x, which
00:50:01.240 | says what Python file name to create.
00:50:04.120 | So that's just a little trick that I use.
00:50:09.000 | So now we've got an app.py, we need to upload this to Gradio.
00:50:16.240 | How do we do that?
00:50:18.200 | You just push it to get.
00:50:19.640 | So you can either do it with Visual Studio Code or you can type git commit and then git
00:50:28.680 | push.
00:50:29.760 | And once you've done that, if we change minimal to testing, I think this hopefully might still
00:50:41.960 | be running my previous model because I didn't push it and that way we can see our crazy
00:50:46.240 | dog cat.
00:50:47.240 | All right.
00:50:48.240 | So here it is.
00:50:49.240 | You can see it running in production.
00:50:51.560 | So now this is something that anybody can, if you set it to public, anybody can go here
00:50:55.040 | and check out your model and so they can upload it.
00:50:58.440 | And so here's my doggy, yep, definitely a dog cat.
00:51:04.280 | Yeah, I think I might have trained this for Epoch or two less, so it's less confident.
00:51:08.560 | Yeah, definitely a cat, dog cat, hey, dog cat, hmm, still thinks it's definitely a cat.
00:51:22.720 | Oh, well, so be it.
00:51:25.600 | Okay, so that is, okay, so that is an example of getting a simple model in production.
00:51:43.200 | There's a couple of questions from the forum from the community.
00:51:48.200 | Okay, so one person's asking, what's the difference between a PyTorch model and a fast AI learner?
00:51:56.920 | Okay, that's fine.
00:51:57.920 | We will get to that shortly.
00:51:58.920 | Don't know if it'll be this lesson, it might be this lesson or the next lesson.
00:52:10.320 | And then somebody else asked, basically is asking, how many Epochs do we train for?
00:52:14.880 | So as you train a model, your error rate, as you can see, it improves.
00:52:22.280 | And so the question is, should I run more?
00:52:24.200 | Should I increase the number of Epochs?
00:52:26.600 | This is doing three Epochs, right?
00:52:28.040 | Here's my three Epochs plus one to get started.
00:52:31.880 | Look, it's up to you, right?
00:52:34.240 | I mean, this is here saying there's a 1% error, I'm okay with the 1% error.
00:52:39.440 | You know, if you want it to be better, then you could use more data augmentation and you
00:52:43.200 | could train it for longer.
00:52:46.220 | If you train for long enough, as we'll learn about soon and then maybe the next lesson,
00:52:52.200 | if you train for long enough, your error rate actually starts getting worse.
00:52:57.400 | And you'll see, we'll learn about why.
00:52:59.600 | So basically, yeah, you can train until it's good enough or until you've run out of patience
00:53:04.760 | or time or run out of compute, or until the error rate starts getting worse.
00:53:14.160 | Okay.
00:53:15.160 | Oh, and then in Colab, how do you grab your model?
00:53:21.160 | All you need to do in Colab is after you've exported it, is if you go into their file
00:53:29.080 | browser, you'll actually see it here, right?
00:53:33.060 | And you can click download.
00:53:36.440 | It's a bit weird.
00:53:39.640 | It doesn't like pop up a box saying, where do you want to download it to?
00:53:42.840 | But instead, this kind of progress circle thing pops up.
00:53:47.000 | And so depending on how big it is and so forth, it can take a few minutes.
00:53:51.320 | And once that circle fills up, then the browser thing will finally pop up and say, okay, you
00:53:55.680 | can save it.
00:53:56.680 | Okay.
00:53:57.680 | So that's how you actually grab your model.
00:53:59.380 | So as you can see that the step where you actually need a GPU, you can use these totally
00:54:03.520 | free resources, Colab, Kaggle, there are other ones we'll talk about in future lessons.
00:54:10.440 | And then you can do everything else on your own computer, including the predictions.
00:54:13.600 | The predictions are fast, right?
00:54:15.460 | So you really don't need to use a GPU for that unless you're doing thousands of them.
00:54:20.040 | Okay.
00:54:21.040 | Here we go.
00:54:22.040 | So now it's asking me to save it.
00:54:25.280 | Okay. So now one big issue is we needed to run it on our computer.
00:54:32.980 | We needed Python and Jupyter notebooks running on our computer.
00:54:36.880 | So how do you do that?
00:54:42.000 | Because this is where often people get in all kinds of trouble.
00:54:46.560 | I'm trying to figure out how to get this all working.
00:54:49.520 | So the good news is we've actually got something that makes it very, very straightforward.
00:54:54.480 | It's called fast setup.
00:54:55.600 | There's really only just one part of it you need.
00:54:58.000 | So let me show you.
00:55:00.120 | It's actually a Git repository on GitHub.
00:55:03.160 | GitHub's the place where most Git repositories live.
00:55:06.920 | So if you go to GitHub fast.ai/fastsetup, you'll see it.
00:55:10.520 | And so what you can do is you can now grab this whole repository just by clicking here
00:55:17.340 | on code.
00:55:18.720 | And if you've got GitHub Desktop installed, click on open with GitHub Desktop.
00:55:26.160 | And as you'll see, it brings this up saying, okay, I'm ready to save this for you.
00:55:29.560 | So I click clone, so it's making a copy of it.
00:55:34.920 | There we go.
00:55:40.040 | So basically once you've cloned it, you'll then find there's a file in there called setup-conda.sh,
00:55:54.240 | which you know, the details don't really matter, it's pretty short.
00:55:56.600 | But that's the thing that's going to install Python for you.
00:55:59.880 | So at that point, you can just run ./setup-conda and it'll run this installer.
00:56:05.760 | Now if you've got Linux or Mac, you've already got Python on your machine.
00:56:12.960 | Don't use that Python.
00:56:14.440 | And the reason is because that Python, it's called the system Python, it's used by your
00:56:18.920 | computer to do computer-y stuff, right?
00:56:21.080 | It's actually needed.
00:56:22.640 | You don't want to be messing with it, I promise you.
00:56:28.080 | It always leads to disaster, always.
00:56:31.880 | You want your own development version of Python.
00:56:34.320 | It's also going to make sure you've got the latest version and all the libraries you want.
00:56:38.900 | And by far the best one for you is almost certainly going to be these Conda-based Python
00:56:46.520 | distributions.
00:56:47.520 | So if you run setup-conda, you'll get the one that we recommend.
00:56:50.520 | And the one we recommend at the moment is something called MambaForge.
00:56:57.560 | So basically once you run it, you'll find that you've now, and you close your terminal
00:57:02.120 | and reopen it, you'll find you've now got one extra command, which is called Mamba.
00:57:07.520 | And Mamba lets you install stuff.
00:57:11.160 | So once you've run it, you'll be able to go Mamba, install fast.ai.
00:57:17.960 | And that's going to, actually we should probably, I should mention there's actually more, bit
00:57:23.440 | more detail about how to install it correctly.
00:57:27.360 | If we go to docs.fast.ai, installing, yeah, okay, we actually want to do conda install
00:57:35.480 | minus C fast-chain fast-ai, so let's just copy and paste.
00:57:39.600 | Oh, sorry, not actually.
00:57:41.880 | And then the other thing I'll say is instead of using conda, replace conda with Mamba, because
00:57:45.760 | nowadays it's much faster, so Mamba install minus C fast-chain fast-ai.
00:57:52.440 | Now this is going to install everything you need.
00:57:57.160 | It's going to install PyTorch, it's going to install NumPy, it's going to install fast-ai,
00:58:04.320 | and so forth, right?
00:58:06.680 | And so obviously I've already got it.
00:58:11.440 | And then the other thing you'll want to do is install nbdev, so you can do exactly the
00:58:19.960 | same thing for nbdev.
00:58:21.280 | You don't have to, right?
00:58:22.280 | It's just, but that'll install Jupyter for you, amongst other things.
00:58:28.760 | And so at that point you can now use Jupyter.
00:58:33.040 | And so the way Jupyter works is, you can see it over here, this is my, I'll go ahead and
00:58:40.520 | close it so we can start again.
00:58:42.880 | So basically to use Jupyter, you just type Jupyter notebook, okay?
00:58:51.580 | And when you run it, it'll say, okay, we're now running a server for you.
00:58:55.360 | And so if you click on that hyperlink, it'll pop up this, okay, which is exactly what you
00:59:03.480 | see me use all the time.
00:59:06.160 | Okay, so that hopefully is enough to kind of get you started with Python and with Jupyter
00:59:13.600 | notebook.
00:59:17.920 | The other way people tend to install software is using something called pip instead of mamba.
00:59:26.960 | Pretty much anything you can do with mamba, you can also do with pip.
00:59:29.500 | But if you've got a GPU, pip isn't going to install things generally so that it works
00:59:34.380 | on your GPU.
00:59:35.380 | You have to install lots of other stuff, which is annoying.
00:59:38.420 | So that's why I kind of tell people to use mamba, but you can use pip otherwise.
00:59:47.240 | Oh, a little bit of red.
00:59:48.520 | Please let us know how we can help you, gang.
00:59:52.920 | Okay, so let's see, how are we going with our steps?
00:59:56.760 | I forgot I had these steps here to remind myself.
00:59:59.080 | We created a space tick, we created a basic interface tick.
01:00:03.120 | Okay, we got get set up, we got condor and set up or mamba.
01:00:07.800 | So mamba and condor are the same thing, mamba is just a much faster version.
01:00:12.880 | And we'll keep some notes on the course website, because at the moment, they're actually working
01:00:17.600 | on including the speed ups from mamba into condor.
01:00:20.540 | So at some point, maybe it'll be fine to use condor again.
01:00:23.520 | At the moment, condor is way too slow, so don't use it.
01:00:26.200 | Okay, we've done dogs versus cats, no problem.
01:00:33.240 | Yeah, so we could also look at pet breeds, well, yeah, we'll briefly look at that.
01:00:43.200 | Okay, we've used exported learner, no problem, we've used nbdev, no problem, oh, okay, try
01:00:47.580 | the API.
01:00:48.580 | All right, this is interesting.
01:00:50.480 | So I think we can all agree, hopefully, that this is pretty cool that we can provide to
01:00:58.360 | anybody who wants to use it for free, a real working model and, you know, with Gradio, there's
01:01:09.280 | actually, you know, a reasonable amount of flexibility around like how you can make your
01:01:16.960 | your website look, you know, using these various different widgets.
01:01:23.200 | It's not amazingly flexible, but it's flexible enough to kind of, it really just for prototyping.
01:01:31.000 | So Gradio has lots of widgets and things that you can use.
01:01:36.520 | The other main platform at the moment that Hugging for Spaces supports is called Streamlit.
01:01:44.280 | Streamlit is more flexible, I would say, than Gradio.
01:01:50.280 | Not quite as easy to get started with, but, you know, it's kind of that nice in-between,
01:01:55.680 | I guess.
01:01:56.680 | So also a very good thing, again, mainly for kind of building prototypes, but at some point
01:02:02.160 | you're going to want to build more than a prototype, you want to build an app, right?
01:02:07.280 | And one of the things I really like about Gradio in Hugging for Spaces is there's a button
01:02:12.160 | down here, view the API.
01:02:15.560 | So we can actually create any app we want, and the key point is that the thing that does
01:02:28.400 | the actual model predictions for us is going to be handled by Hugging for Spaces, Gradio.
01:02:35.760 | And then we can write a JavaScript application that then talks to that.
01:02:41.680 | Now there's going to be two reactions here.
01:02:45.880 | Anybody who's done some front-end engineering is going to be like, "Oh, great.
01:02:49.440 | I can now literally create anything in the world because I just write any code and I
01:02:54.960 | can do it."
01:02:55.960 | And they'll be excited.
01:02:57.520 | And a lot of data scientists might be going, "Uh-oh, I have no idea how to use JavaScript.
01:03:03.480 | It's not in my, you know, inventory."
01:03:07.560 | So this is, again, where I'm going to say, "Look, don't be too afraid of JavaScript.
01:03:10.360 | I mean, obviously one option here is just to kind of say, 'Hey, I've got a model.
01:03:14.320 | Throw it over the wall to your mate who does know JavaScript and so please create a JavaScript
01:03:18.880 | interface for me.'"
01:03:20.280 | But let me just give you a sense of like how really not hard this actually is.
01:03:27.400 | So there's an endpoint.
01:03:31.160 | There's now a URL that's running with our model on it.
01:03:36.040 | And if you pass it some data, some image data to this URL, it's going to return back the
01:03:46.960 | dictionary.
01:03:47.960 | So it's going to do exactly the same thing that this UI does, but as an API, as a function
01:03:56.520 | we can call.
01:03:58.640 | And so it's got like examples here of how to call it.
01:04:01.660 | So for example, I can actually, let me show you the API as an example using that minimal
01:04:08.920 | interface we had, because it's just going to be a bit simpler.
01:04:13.160 | So if I click curl, and I copy that, copy that, and paste.
01:04:25.560 | So you can see there, oh, that's not a great example passing in "Hello, world."
01:04:28.760 | But if I pass in "Tanishk" again, let's see how I'm going with his name, Tanishk.
01:04:35.760 | Hey, it returns back "Hello, Tanishk."
01:04:40.360 | So this is how these APIs work, right?
01:04:43.880 | So we can use JavaScript to call the API, and we've got some examples.
01:04:56.320 | So I've created a website, and here is my website, Tiny Pets.
01:05:04.840 | And on this website, as you can see, it's not the most amazingly beautiful thing, but it's
01:05:09.240 | a website, it's a start, right?
01:05:11.680 | And up here, I've got some examples, here you go, single file, click, choose file, click.
01:05:22.960 | And in this example, I'm actually doing full pet classification, so I actually trained
01:05:27.680 | a model to classify breed, which we'll talk about more next week, rather than just dog
01:05:33.120 | versus cat.
01:05:34.120 | So let's pick a particular breed, and we run it.
01:05:39.120 | Oh, and there it is.
01:05:44.080 | Now, not very amazing, right?
01:05:47.760 | But the fact is that this is now a JavaScript app, means we have no restrictions about what
01:05:53.440 | we can do.
01:05:54.680 | And let's take a look at that HTML.
01:05:59.960 | That's it.
01:06:01.200 | It easily fits in a screen, right?
01:06:04.340 | And the basic steps are not crazy, right?
01:06:09.360 | It's basically we create an import for our photo, we add an event listener that says
01:06:17.040 | when you change the photo, call the read function.
01:06:19.800 | The read function says create a file reader, read the file.
01:06:27.720 | And when you finished loading, call loaded, and then loaded says fetch that.
01:06:33.840 | Now that path there is that path there, right, except we're doing the full pets one.
01:06:44.720 | So this is basically just copied and pasted from their sample.
01:06:53.840 | And then grab the JSON, and then grab from the data, the first thing, the confidences,
01:07:01.640 | the label, and then set the HTML.
01:07:05.640 | So as you can see, it's like, okay, if you haven't used JavaScript before, these are
01:07:08.640 | all new things, right?
01:07:09.920 | But they're not, it's not harder than Python, right?
01:07:12.600 | It's just another, it's just another language to learn.
01:07:16.600 | And so from here you can start to build up, right?
01:07:20.640 | So for example, we've created a multi-file version.
01:07:26.520 | So with the multi-file version, let me show you, multi-file, choose, so we can now click
01:07:33.200 | a few, so we've got a new fee, a rag doll, a basset hound, and some kind of cat.
01:07:40.840 | I'm not much of a cat person.
01:07:42.740 | So we chose four files, and bang, they've all been classified, apparently it's a Bengal,
01:07:50.080 | I wouldn't know.
01:07:51.080 | There's our new found one.
01:07:53.120 | So there's the multi-file version.
01:07:54.640 | And if you look at the code, it's not much more, right?
01:07:58.040 | It's now just doing, it's getting all the files and mapping them to read, and now appending
01:08:04.280 | each one.
01:08:05.280 | So not much more code at all.
01:08:10.080 | And as you might have seen on our site here, there's a few more examples, which is some
01:08:16.160 | of the community during the week has created their own versions.
01:08:21.600 | So this one here is, I think this is the, yeah, this is from one of the gradio guys.
01:08:30.600 | They called it get to know your pet.
01:08:33.800 | So if I choose a pet, I kind of, I really like this because it actually combines two models.
01:08:39.640 | So first of all, it says, oh, it's a basset hound, and then it lets me type in and ask
01:08:43.600 | things about it.
01:08:44.600 | So I could say, oh, what kind of tail does it have?
01:08:51.960 | Search.
01:08:52.960 | And so that's now going to call an NLP model, which asks about this, oh, it's a curved saber
01:09:00.680 | tail.
01:09:01.680 | So what maintenance does it need?
01:09:11.760 | So again, like here, you can kind of see how, oh, basset hounds ears must be cleaned inside
01:09:17.000 | it out frequently.
01:09:19.080 | So this is like combining models.
01:09:20.600 | So you can see this is something that you couldn't do with just a kind of a ready to
01:09:25.880 | go interface.
01:09:29.560 | And so the next thing I wanted to point out is, how did we create the website that showed
01:09:36.680 | you how to create an HTML file, but like, how do you create those and how do you make
01:09:41.800 | a website out of them?
01:09:43.640 | Well, watch this, let's, here's, here's, here's a, here's the source code to our most basic
01:09:54.640 | version.
01:09:55.640 | Okay.
01:09:56.640 | So I could just save this.
01:10:01.160 | There we go.
01:10:06.960 | Okay.
01:10:09.960 | So we could open that with Visual Studio Code.
01:10:20.440 | And what we could actually do is we could just use an explorer or Mac and finder.
01:10:25.160 | I could just double click on it and here it is, it's a working app.
01:10:30.600 | So you can see I don't need any software installed on my computer to use a JavaScript app, right?
01:10:38.480 | It's a single file.
01:10:40.240 | I just run it in a browser.
01:10:41.240 | A browser is our complete execution environment.
01:10:44.720 | It's a, it's got a debugger.
01:10:46.000 | It's got the whole thing.
01:10:47.080 | So here you can, you know, here you can see it's, it's just calling out to this external
01:10:51.400 | hugging faces endpoint.
01:10:52.720 | So I can do it all sitting here on my computer.
01:10:54.960 | So once I've got my HTML file that's working fine on my computer in VS code, how do I then
01:11:02.960 | put it on the web so that other people can use it?
01:11:06.280 | Again, the whole thing's free.
01:11:09.000 | There's a really cool thing called GitHub Pages, which basically will host your website
01:11:14.400 | for you.
01:11:15.440 | And because it's just JavaScript, it'll, it'll all work just fine.
01:11:23.160 | The easiest way to create a GitHub Pages site, in my opinion, is to use something called
01:11:28.080 | Fast Pages, which is a fast AI thing.
01:11:33.320 | And basically all you do is you follow the setup process.
01:11:43.600 | So first it, let's just go through it.
01:11:45.760 | So it says generate a copy by clicking on this link.
01:11:47.960 | So I click the link.
01:11:50.000 | All right.
01:11:52.400 | Okay, give it a name.
01:11:57.480 | I try to make everything public.
01:12:01.680 | I always think it's good, good practice.
01:12:03.520 | You don't have to create repo generating.
01:12:07.760 | Okay.
01:12:08.760 | And then there's basically two more steps takes about five minutes.
01:12:13.600 | We don't have five minutes.
01:12:14.600 | So I'll show you the one that I've already built, which is fast AI slash tiny pets.
01:12:22.280 | And so once it's done, you'll basically end up with this empty site, which again, you
01:12:30.000 | just go code, open with GitHub desktop or open with Visual Studio, whatever.
01:12:36.160 | So open with GitHub desktop, or you can copy and paste this to your terminal.
01:12:40.680 | And so any one of those is going to get you this whole thing on your computer.
01:12:44.120 | You can save your HTML files there, push it back up to GitHub.
01:12:49.360 | And what you'll find is fast pages will show you the link to the website that is created
01:12:55.800 | for you.
01:12:57.060 | Now the website that's created for you, you can make it look however you want using something
01:13:03.960 | called a theme.
01:13:04.960 | So you'll see it's created a file called config.yaml where you can pick a theme.
01:13:10.640 | So in this case, I picked a theme called alembic for no particular reason.
01:13:18.360 | So GitHub pages uses something called Jekyll.
01:13:21.720 | And so any Jekyll theme will basically work.
01:13:25.120 | So I picked out this theme.
01:13:27.160 | And so as a result, when I now save things into this repo, they will automatically appear
01:13:33.800 | in this website.
01:13:35.640 | And the files automatically appear up here in this list.
01:13:39.720 | So if you look at my index, that's the homepage, the entire file is just this.
01:13:48.960 | The only slightly weird thing is at the top of every GitHub page's file, you have to have
01:13:54.680 | three dashes, title and layout, and three dashes, it's called front-matter.
01:14:02.240 | And so once you do that and save it, it will appear in your website.
01:14:09.240 | So something else I did then I was like, okay, well, that's all very well that Fast.ai has
01:14:14.120 | created this website, but I don't really like what it looks like.
01:14:16.920 | I would have created a different version.
01:14:19.000 | No worries.
01:14:20.000 | You can go to Fast.ai Tiny Pets and click fork.
01:14:24.280 | And when you click fork, it's going to create your own copy.
01:14:27.760 | So I did that under my personal account, which is jph00.
01:14:34.360 | And look, now I've got my own version of it.
01:14:36.640 | And now I can make changes here.
01:14:38.400 | So I made a few changes.
01:14:39.560 | One change I made was I went to config.yaml and I changed the theme to pages themes hacker.
01:14:48.040 | So once you fork, one thing you have to do, which normally Fast pages does for you is
01:14:52.640 | you do have to go to settings and click pages and actually enable GitHub pages.
01:14:58.800 | So you basically have to, by default it's turned off.
01:15:01.560 | So here you'll just have to turn it on.
01:15:03.120 | So use the master branch, root, save, and then it'll say, no worries.
01:15:07.440 | It's ready to be published.
01:15:09.520 | And so I changed the config.yaml file to point at a different theme.
01:15:12.720 | And so if you look at now the jph's tiny pets, it's different.
01:15:17.880 | Okay.
01:15:18.880 | So it's got the same info, but it's much more hackerish because jph00 is a serious hacker,
01:15:25.360 | as you can tell from his website.
01:15:30.160 | So anyway, look, it's a very brief taste of this kind of world of JavaScript and websites
01:15:37.400 | and so forth.
01:15:38.680 | But I wanted to give you a sense of like, you know, you don't need any money.
01:15:45.680 | You don't need any IDEs, you know, you don't really need much code to get started with
01:15:54.720 | writing your own web apps.
01:15:56.880 | And thanks to hugging face spaces, you know, they'll even host your model for you.
01:16:01.360 | And all you need to do is just have the magic string as a thing to call.
01:16:06.280 | Okay.
01:16:07.400 | So signing out hacker Jeremy Howard, thanks very much for watching.
01:16:14.400 | And in the next lesson, we're going to be digging into some natural language processing.
01:16:18.200 | We're going to be doing some of the same stuff, but we're going to be doing it with language
01:16:22.000 | rather than pictures, and we're going to be diving under the hood to see how these models
01:16:28.160 | actually work.
01:16:29.160 | We're going to learn about things like stochastic gradient descent, and we might even be having
01:16:33.520 | to brush off a little bit of calculus.
01:16:36.160 | I hope I haven't put you off by saying the C word.
01:16:38.840 | I will see you next time.
01:16:40.440 | Thanks all.