AI Custom Drawings Classifier with Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is going on guys welcome back in this video today we're going to build a custom drawing classifier in Python so an application it uses machine learning to classify your drawings as one of three customly defined classes so we're going to start up the application we're going to provide three Uh custom categories or classes so for example circle triangle square and then we're going to provide sample drawings to train the model and the goal is to then use that model to make predictions on new drawings so we're going to draw a triangle we're going to draw a circle then we're going to press on predict and we're going to hopefully get triangle Circle whatever we have drawn onto the canvas that's the basic idea and the good thing about the tool that we're going to write today is that it works with all different classes that come to mind so you can do cars you can do headphones you can do books you can do animals whatever you want you can just provide that category name you can provide sample drawings and you can train them all to recognize this specific type of drawing and this is a somewhat Advanced or at least intermediate project so we're going to write a lot of code we're going to use machine learning we're going to build a graphical user interface so if you're a complete python beginner that might be a little bit too much for you however you can still follow along but I think this is a video more targeted towards intermediate python programmers so let us get right into it again [Music] all right now before we get into the actual tutorial I would like to show you what we're going to end up with here as a motivational preview up front so I'm going to run the application that I have already prepared and the first thing we can do here is we can specify a project name so let's call this shapes and then let's define three classes I'm going to call them triangle where is it now triangle Circle and square and then we have this graphical user interface here with a canvas I can just draw on here I can clear the canvas I can increase the brush size I can decrease the brush size like this and then I can provide samples for the three different classes triangle circles where they have their own button so I can just go ahead now and draw a basic triangle I can click on triangle I can draw another triangle and of course to make this somewhat accurate we would have to provide a couple of training samples so not just five or something but for the preview now I'm not going to provide a ton of examples I'm just going to write to to draw five triangles five circles like this and then five squares this will probably not be entirely accurate because squares and circles can be quite similar and if we just have five examples per class it will probably not be a perfect model however once we have the training examples what we can do is we can just click on train model and then it says model successfully trained and then hopefully this works now if I provide a triangle and click on predict it tells me it is probably a triangle let's try if it does the same thing for a circle so as a triangle maybe because I draw it I drew the circles like this there you go drawing is probably a circle and hopefully it recognizes a square yeah probably a square um somewhat accurate at least and we also have a couple of different options here so for example I can change the model you can see right now I'm using a linear support Vector classifier I can also use a k neighbors classifier I can use a logistic regression I can use decision tree classifier random forest classifier and uh gaussian naive Bass so let's see random Force classified train the model and let's see if that also performs somewhat somewhat well triangle Circle and Circle okay we would have to add more training data but we can also save the model load the model we can uh save everything so the whole project also when I'm closing here it asks me if I want to save my work um and this is what we're going to build in this video today it's quite comprehensive we're going to have to write a lot of code but this is a very good project for intermediate python programmers all right so we can now get started with the coding and the first thing we need to do is we need to open up a command line and we need to install a couple of external python packages by saying pip install and we're going to install here numpy we're going to install pillow we're going to install opencv Dash Python and we're going to install scikit Dash learn numpy is what we're going to use to just work with arrays efficiently pillow and open CVR for working with images and scikit-learn is for the machine learning part so just install those packages in my case they're already installed and then you can import them in the script now for this video we're going to write a lot of lines of code in the prepared code on my second screen I have 283 lines so it's going to be quite comprehensive however this time this might surprise you the code will be probably available on GitHub I already have a repository called Drawing classifier it's quite old and after I'm done with the video I'm probably going to update this file to be the code of this video tutorial so you can check out the link in the description down below you will probably find a link to the repository where you can just copy the code or at least copy sections of the code however if you want to learn something I recommend you type everything from scratch without copy pasting so let's get started by opening up a new python file calling it main.py and we're going to import a couple of things here we're going to start by importing pickle which is a core python module we're also going to import os.path we're going to import um numpy SNP we're going to import pill pil in capital letters for pillow we're going to then also um import cv2scv so I'm going to structure it like that uh then we're going to import a bunch of TK inter uh stuff so we're going to first say or actually let's just go ahead for the sake of Simplicity and let's say from TK enter import everything now as always this is not a good practice if you're building an actual application that is used by people that is something that works um in production that is something that's actually not just a tutorial you should not use wildcard Imports you should always say from TK enter import file dialog simple dialog button whatever but for the sake of Simplicity I'm just going to import everything here but this is not a good practice we're also going to explicitly import uh down below or actually yeah above is better import TK enter Dot message box um and I think that's it for the graphical user interface Imports we're then going to also say from sklearn dot svm we're going to import the linear support Vector classifier from sklearn dot naivebase we're going to import uh gaussian naive base we're going to save from sklearn uh Dot three we're going to import a decision tree classifier from sklearn dot neighbors we're going to import a k neighbors classifier and from SQ learn dot Ensemble we're going to import a random Forest classifier now you can add as many classifiers as you want you can also just use one you can remove one that you don't like you can also use neural networks with tensorflow if you want to those are just models that we can use we're going to have the same training data we're going to have the same mechanism of predicting we're going to have the same graphical user interface adding and removing models is quite simple so you can do that if you want to but we're going to use those here for the video so once we have that we're going to now create a new class which we're going to call drawing classifier and we're going to have a simple init method and the init method will basically only be used for defining attributes we're going to set all of them to none but we're going to talk about um what these attributes basically are there for so we're going to say self.class1 self.class 2 and self.class three are going to be equal uh delete bookmark are going to be equal to none none and none basically those are going to just be the class name so Triangle Square Circle for example we're going to then also have self class one counter self Class 2 counter and self class three counter we're going to set those to none as well and basically those are going to just keep track of how many instances of sample drawings we already have for the respective classes so when I add a triangle if class 1 is a triangle I'm going to have one here 0 here 0 here I'm going to use that to basically choose the file names because we're going to store the samples in a directory with um with the name of the file being the number of the sample and it's going to be in a directory for that respective class that's the basic idea then we're going to say self-classifier equals none we're going to say self.project name is going to be equal to none we're going to have self.root being equal to none and we're going to have self.image uh one I think I call it image one because image is a keyword not necessarily a keyword but uh image probably a used image somewhere else so we're going to call this image one maybe we can change that later on uh basically the classifier is just a model that we're going to use for the actual prediction and for the training the project name is just the name of the directory that we're going to store all this stuff in the root is going to be the root TK enter window and image one is going to be something that we use to take the canvas turn it into an image store it feed it into the machine learning models and umpire array and stuff like that then we're going to say self dot status label this is just important because we're going to change the status label uh this is going to just be a label in TK enter or from TK intro because we're going to keep track of which model is being used at the moment then we're going to say the canvas also has to be a class attribute here or an object attribute here and then self draw is equal to none uh draw is going to be an image draw object from pillow so pill dot image draw so that we can draw on the actual image and then we're going to say self.brush width is going to be 15 this is just going to be the default brush size um and then we're going to say self dot uh we're going to Define here two methods the first one is going to be classes prompt and the second one is going to be initialize graphical user interface so init GUI and we're going to call those two functions those two methods directly in the Constructor so self.classes prompt and self dot initialize graphical user interface that's the basic idea so those are just the attributes we don't do anything with them we just Define them here because it's a good practice to Define them in the init method and then you can set them later on in the other functions uh we Define a default brush size and then we just ask for the classes this is the text box or the text boxes that you saw in the preview where we have project name class one class two class three and then we initialize the graphical user interface um so for the classes prompt uh this is going to be quite simple we're just going to say that the message is going to be TK so a TK instance we're going to say that message with we want to withdraw the message window so we just want to have a window that we can work with but we don't want to necessarily display a window and then we're going to say self.project name so the project name is going to be equal to simple dialog um and I think can we not use that from TK enter directly do I have to save from TK enter import simple dialog probably I have to do it explicitly so simple dialog dot ask string and then the title is going to be project name the text is going to be please enter your project name down below and the parent this is why we need that the parent of that whole thing is going to be the message TK instance so we need to have a parent this is why we Define mess G equal to TK we then withdraw and then we just have this prompt that has the parent message then what we're going to do once we get that project name we're going to check if that directory already exists and if yes we're going to try to load a pickle file a serialized file with all the information of the project because that is something that we're going to implement later on we're going to be able to store everything meaning all the classes all the samples all the models we can store them um as a file and if that file exists we want to load it so what we're going to do is we're going to say if OS path exists and we want to check if uh self.project name exists because the directory of the project is going to be the project name or the directory name is going to be the project name and uh then we're going to just try to open up here the following file fstring uh and here we want to have self project name slash and then again self project name underscore data dot pickle we're going to open this as reading in Reading binary mode and then we're going to say data equals pickle dot lot and we're going to load the file that we open up here as f Asic idea is you specify a project name if that directory exists we're going to load this pickle file otherwise we're going to create uh we're going to create a new uh instance we're going to create a new directory with new classes and everything is going to be set up from scratch however if we have this data we need to First extract all the information so we're going to say self.class1 is going to be equal to data and we're going to have the key C1 later on all of this will be defined when we save the project but we're going to now just uh Define the structure here we're going to say that in this pickle file we're going to have a dictionary and this dictionary will have key value Pairs and the key C1 C2 C3 leads to class 1 Class 2 class 3. then we also have self.class1counter that is going to be equal to data and the key is going to be c1c and here we're going to have C2 see 3C C2C like that then the classifier will be also part of that dictionary we're going to just get clf here and the project name obviously will also be part of that we're going to call it P name of that dictionary otherwise if we don't have this directory already existing we're going to just create a new class one two and three we're going to say class one is simple dialogue dot ask string and we're going to ask here for a class one what is the first class called question mark parent is going to be message we're going to copy that three times we're going to say Class 2 class 3. Class 2 class 3 and then we need the second class the third class um and then we're going to initialize the counters being equal to one we're going to set them to one even though we have zero instances because we want the first instance to be called image one and not image zero so we're going to say self class one counter is going to be equal to one I'm going to copy that I'm going to set Class 2 counter class 3 counter to one as well then we're going to initialize a new classifier so self uh self.clf is going to be a linear support vector classifier by default we can of course change that by rotating the classifier later on but the default is going to be a linear support vector classifier and then we're going to just say OS dot make directory self dot project name so this creates a new directory we then go into that directory and we create the class directories inside of that directory so we go OS change directory self dot project name and then we copy this here this make directory and we just replace this by class one class two class three and then we go back so OS change directory up one directory by using two dots and that basically creates the project structure so this alone already creates the project directory with three directories for the different classes with the class counters initialized all being equal to one and with a new machine learning model that is not trained on anything yet that is the setup and then we also need to display the graphical user interface now this might be a little bit tedious it's not too complicated what we're going to do here but it's going to be quite repetitive we just set oh we we just create a root element and then we add UI elements to that root element but we need to go through it so we're going to just do it here we're going to specify the width being equal to 500 the height being equal to 500 of course feel free to change those values if you want to and we're going to define the color white being equal to 255 255 255 this is just an RGB triple then we're going to say self root equals TK and self-root title is going to be neural 9 drawing classifier uh Alpha since the one that's on GitHub right now is 0.1 I'm going to call this now 0.2 uh and we're going to make this an F string actually because we also want to display the project name so self dot project name is going to be here as well in the title then we want to add the canvas this is the most important thing so self.canvas is going to be equal to a new canvas object and we're going to say this is part of self dot root the width of the canvas is going to be the width and the height is going to be the height um or actually since the whole window is going to be that size we're just going to say -10 minus 10. in the background is going to be white like this I'm not sure if we're going to need that I'm just going to keep it here because I have it in my prepared code and I think it's not there for no reason but maybe we're not going to use it so self.canvas dot pack we're going to use pack to actually pack this into the graphical user interface and then we're going to add a bunch of new um a bunch of additional elements so first of all we're going to have self image one this is what we defined up here already where is it there you go this is going to be just a pillow image so we're going to say self image one is going to be equal to pill image dot new and I think we need to explicitly import um pill image right and I think also pill image draw so pillow dot Image new we're going to say RGB width height and I think this is why we need white because here we need to pass the RGB triple and then we're going to say self.draw we also have this in the Constructor already is going to be image draw or pill dot image draw dot draw self image one uh yeah so that's it and then we're going to say self dot canvas dot pack I mean actually I think I can replace this with that so self canvas pack uh expand is going to be uh yes so TK intro yes and Phil is going to be both those are constants from TK intro we have them because we said from TK enter import everything uh and then we're going to say South canvas dot bind and we want to bind the event of moves moving the mouse when the left Mouse button is clicked we want to bind that to a certain method that we don't have yet and how we do that is we say B1 Dash motion so button one is clicked and you move the mouse this event of moving the mouse while you have the mouse button clicked shall be bind to the function shall we bound to the function um self dot paint and we don't have that function yet or this method yet so we're going to just Define it we're going to Define it later on but we just bind this now to that particular function meaning every time we click the left Mouse button and we move the mouse this is going to trigger that function with the event so we also pass your an event um we're going to take care of that later on but that's what we're going to do here then we want to create a button frame so BTN frame is going to be equal to TK enter frame which is going to be part of self root we want to say button frame dot pack we want to say fill on the x-axis so X basically um and side is going to be TK enter or actually we don't need to say TK enter we can just say bottom since we import everything from TK enter and then what we want to do is we want to configure The Columns so we want to have three columns because we're going to have three buttons for the classes and then we're going to have buttons below that and what I want to do here is we want to say button frame dot column configure zero weight equals one and I'm going to copy that one two so we have these columns now that are equally weighted and then we can add the buttons so we're going to say class 1 button is going to be a new button with which is going to be part of the button frame the text of this button not the text variable the text of this button is going to be self.class one the command of this button so what happens when you click on the button is going to be a Lambda expression which is going to call a function called self.safe with the parameter one this is why we want to have a Lambda expression because we want to pass the value 1 to that function because whatever is on the canvas will be saved for class one now the save function does not exist yet so we're going to create itself I always keep saying function it's actually a method since we're in a class uh but we just pass one here as a parameter um and then what we do is we say class one button dot grid because now we have a grid um layout so we're going to use grid not pack we're going to place this as uh at row 0 column equals zero and we're going to make it sticky meaning it's going to be West plus East now what's the problem here with the one unexpected argument ah because we don't get a class number here um we can copy this now we can paste this and replace one with two and here as well and here as well rest should stay the same other than the fact that the column is one we can copy this again we can change this to class three class three column is going to be 2. class 3 and save three those are the three class buttons that we use to take a drawing and add it as a sample as a training data sample for a respective class the functionality will be implemented down here after that we need to also have a brush minus in a brush plus size uh button so we're going to change the brush size with one button we're going to increase the brush size with one button we're going to decrease it with another one so BM underscore button for brush minus button is going to be a button part of the button frame with a text that is going to be brush minus the command for that will be self dot brush minus and then we're going to just I can copy this here change BM button we can say Row 1 column zero sticky is going to stay the same um and actually I think the rest is quite similar now I can paste this now two times uh the one down below here is going to be BP button for brush Plus like this brush plus we need to add these methods again um we're going to place this at column two and here we're going to have another button it's going to be the clear underscore button so clear underscore button it's going to be clear and the function is going to be self.clear and the column is going to be a one again a method that does not exist yet so we're going to add them here and Implement them later on brush minus pass brush Plus and then clear all right um and then we have I think two more rows so we're going to have here maybe I can copy this still so three times we're going to just change the text and the function so we're going to have a train button so that we can actually take the images that we already have a sample data and we can train the model on those images so train model self dot train underscore model again a method that we need to implement train button second row First Column as I said this will be a little bit tedious because it's quite repetitive but we need to have the graphical user interface hopefully you will find timestamps in the video so if you want to script skip the graphical user interface part you can just do that [Music] um but then we're going to also have a save button which is going to be for uh saving the model and it's going to call the function safe model not the function safe button uh this is going to be your Row 2 column one and then we're going to have obviously a load Button as well close button load model load model load button and Row 2 column two and now we have one last row we're going to have the change button so we're going to be able to rotate the model we're going to be able to make predictions and we're going to be able to save absolutely everything so I'm going to just copy this here I'm going to paste it down below we're going to have a change button change button and it's going to be with the text change model rotate model is going to be the function because rotate is actually a proper term here because we're going to go full circle all the time we're going to have this in Row 3 column 0. we're going to have this in row three column one and Row three column two here we're going to say this is the predict button it will have the text predict and the function is going to be predict and we're going to say predict button and finally we're going to have the safe underscore everything button which will have the text save everything meaning the model the classes the instances everything and it's going to be save underscore everything [Music] um yeah save everything button all right and the last thing that we need here as a UI element is going to be a status label so we're going to say status label is equal to label part of the button frame the text is going to be an F string it's going to say current model will be whatever the current model is so self or actually we need to do type self.classifier and we want to get the name so unscore underscore name underscore underscore this will give us for example linear SVC random force classifier and uh whatever and then we're going to say self dot status label dot config we want to change the font a little bit we want to say that the font is equal to Ariel 10 and then self.status label grit it will be Row 4 column one so that it's somewhat centered uh and it's going to be also sticky to West plus East uh and now to finalize everything we say self dot root protocol protocol meaning uh we want to associate a function with the following event uh when we delete the window so when the window is being closed we want to call a function on closing so that we can ask the user if they want to save self.root attributes we're going to set uh top most being equal to true so that it always stays on top now this is optional if it annoys you you can just remove it and self.root Main Loop not like this self.root main Loop starts the whole process all right that is the graphical user interface now we have all these functions or methods that we need to implement so we're going to just Define them down here train model was one then predict was one uh rotate model was one what else did we have we had a safe model load model and save everything and on closing okay save model load model save underscore everything and on closing maybe we're going to change the order here uh what we're going to do first now is we're going to do some basic functions that are easy to implement so we're going to do the clear function the brush plus and the brush minus function that's quite simple so the clear function just says uh self.canvas dot delete all basically clears the full canvas South dot draw dot rectangle we're going to draw a rectangle from zero zero to a thousand one thousand which is going to be filled with white why are we doing that because just because the canvas is clear doesn't mean that the image that we're drawing that we're actually keeping track off that we defined where did we Define it here this also needs to be cleared so we're just going to write to draw a fully white rectangle over it that's the basic idea and now for the brush plus and minus um for the minus we have to make the check if the brush width is above one if that's the case we can decrease it so we can say self.brush width minus equals one and for the plus it doesn't really matter we can go infinitely large so we can say self dot brush width is just plus equal one uh all right so that's that uh what else are we going to do we're going to train the model but maybe before we train them all we should take care of saving the instances so let's do the save function first which is this one here the save function is quite simple what we want to do here is we want to take the class number which is passed here in the command one two three uh and we want to save that respective image that we currently have in the canvas or that is currently being drawn you want to save it into a file and want to take that file and put it into the directory of the respective class with the respective counter so we're going to say here the file name for briefly storing the image so that we can resize it um we're going to say this is temporary.png self.image1 dot save so we're going to save this image um actually we're not going to use file name we're going to just use temp PNG directly we're going to save that image into a temporary file we're going to then load this image directly so we're going to say uh image equals pill dot image dot open temp.png image.thumpmail 50 times 50 so we're going to scale it down to that size we're going to use anti-aliasing so pillow image anti-alias and then we're going to determine the class number we're going to get the class number if it's one we're going to save it in the following path image dot safe fstring self.project name slash self dot class one slash and the name of the actual file should be then the class counter so class 1 counter in this case dot PNG that is the file path and the file type should be PNG and then of course in this case we want to increase the counter for by one so that the next file is not saved under the same name and then we can copy this here we can change this to LF equals to 2 oh no plus one actually but here we need to change one to two uh and here we also need to change one to two and here as well and then we can copy this paste this LF class number is three then we want to use class 3. that is that and of course what we want to do every time when we save we want to clear the canvas because otherwise we need to click too much so we just save something and then it's gone um that's a basic save function logic here now painting is also quite simple all we need to do for painting is we need to get remember painting is bound to uh what wants to the movement of the mouse when button one is clicked when the left Mouse button is clicked so what we need to do now is we need to say get the event X1 y1 is event dot x minus one event dot y minus one so we're just getting the current we're just drawing a rectangle essentially from X1 y1 to X2 Y2 and that's just going to be um plus one and plus one here and then we just say self.canvas dot create rectangle rectangle X1 y1 X2 Y2 we're going to fill it with black color and the width is self Dot brush width and then we say self.draw we also need to draw it on the actual image that we're saving self draw rectangle X1 y1 X2 plus plus uh self dot brush width and then Y2 plus self dot brush width and then fill is equal to Black and a width is again equal to self Dot brush with all right so that is the pain function um do we already have everything that we need to store the images let me just see we have train model this is something else something else yeah everything else should be related to just training the model and using the models let's just go ahead and try to create an instance of a drawing classifier to see if we can already start creating some images so let's just call this project whatever and let's call the first class here a second one b and this third one C now we have this directory structure here A B C and now I can provide some samples so a is going to be that a is going to be that then B is going to be that b is going to be that c is that c is that and we should have these samples now one PNG two PNG uh and this is what they look like okay so this works everything's fine um and now we can go into the machine learning part so now we have already a program that can draw images and store them here in the respective class directories that's awesome so we can now delete this directory again and now we want to train them all on the training data so we take the data from these directories and we just need to train whatever classifier we're currently using on that data so we're going to say here first thing image underscore list is going to be a numpy array an empty numpy array class list is going to be also an empty numpy array those are basically the X and Y values so the image the the image array here the image list array is going to be just a numpy array full of numpy arrays being the image pixels and the class this is going to be a numpara wave array full of the labels one two three that's the basic idea and what we do here is we say 4X in range one up until self.class one counter so we started one and go up until the amount of um instances that we already have image equals CV Emirate and we're going to use an F string here we want to have self.project name self dot class name so class 1 in this case and we don't want to use here now um the class counter but we want to use x because X is so we're iterating over the images so we're just getting X um and then what we want to do is we want to get the result we want to read that image dot PNG by the way and we want to get here just one dimension I want to get the actual image data the actual Channel that's that we want to have here um so this is how you load the image then we want to reshape it by saying image dot reshape 2 500. image equals image reshape and then the image list is going to be NP a pinned numpy append to the current image list the image in a list so that the shape is compatible and class list is going to be NP append class list one since we're adding for class one and I can copy this now two times and we can just replace uh this one is not something that we should replace but here we can replace class 1 to class 2. and here one to two I think that's actually it and of course your class one counter is class 2 counter here class three class three three and that should be it so we go through all the directories we collect the samples we add them to the image list we add the respective class labels and that is our training data and now what we can do here is we can say image list is image list dot reshape self.class one counter -1 plus self dot class to counter minus one plus self dot class 3 counter minus one and we want to have 2500 as the dimension so we just get the amount of different images and this is the shape of the images here that we provided because it's 50 times 50. and then we have self.classifier fit the image list in the class list and now the model is trained after this step so we can say we don't want to print we want to just say TK enter Dot message box show info neural 9 drawing classifier as a title and then models successfully trained the parents of this message box is going to be self.root all right so now we have them all trained now we just need to use it for predictions how do we make predictions quite simple we get a new uh we get the file from the canvas we store it into a temporary file again we shape it we reshape it so that it's compatible with the model shape and then we just essentially do the prediction and display it so what we do is we say here self dot image one dot safe I want to save it again is temp dot PNG want to then say um image equals pillow dot image dot open temp PNG and then want to say image thumbnail to resize it again to 50 times 50. you want to do anti-aliasing image safe uh and then we're going to save this as predicted or let's call it predict shape dot PNG as a PNG file and then we're going to load this with opencv again to have an Umpire array so we want to say image equals CV image by the way I'm not claiming that this is the most efficient way probably can do it in a better way without storing and loading all the time but this is just how I did it here probably this can be optimized um so we're going to to read this predict shape.png file now we're going to get again only the channel that we're interested in and then we're going to reshape it to 2500 again and then we're going to say the prediction for that respective image is self.classifier.predict the image and then we want to say if the prediction index 0 is equal to one um actually I did it in a not very efficient way here so I'm going to do it now differently than in my prepared code because in my prepared code I basically said if the prediction is one print that if the prediction is two print that if the prediction is three print that but I think we can also just say here TK enter Dot message box show info um or actually no we cannot do that because we cannot no okay I have to do it like that so I'm going to say if prediction equals if prediction zero equals one we're going to say TK enter Dot message box show info neural 9 drawing classifier uh the drawing is probably a and now I'm going to use an S string here and we're going to just say whatever class one is so whatever the self class one name is we're going to print that we're going to show that in the message box we're going to see here parents is equal to self dot root uh and that's what we want to do here now we can say let me copy this let me paste this let me add an alif here and let me say that this is equal to two then we just need to print class two and now we can copy this again we can say alif it's three we're going to say it's class 3. the reason we have to do it with an if else here is because I cannot just say class plus whatever it is because this is an attribute name so I just have to do it like that um that's the predict method now the rest of the methods here are quite simple we need to rotate them all we need to save them all load them all it's quite simple for rotating it's uh very simple we just need to define a um a circular structure here so we need to say if is instance self.classifier if it's currently a linear support Vector machine if that's the case we're going to say self.classifier equals next one is going to be a k neighbors classifier and we're going to then say alif if the instance is a safe uh if the classifier is a k neighbors classifier would want to do is want to say the classifier now is going to be a logistic regression um logistic regression didn't I import that oh no I forgot to mount the logistic regression so from is this part of the linear model I think so isn't it yeah there you go um and then you can continue to do that in this way so we can say okay if it's a logistic regression we're going to jump to the decision tree classifier if it's a decision tree classifier we're going to jump to um a random Forest classifier then we can copy this two more times I think if it's a random Force classifier what we want to do is want to jump to a gaussian knife base and if it's a gaussian naive base we want to jump back to a linear support Vector machine or support Vector classifier that's basically it and we can change the status label to display what the current model is so self dot status label dot config we're going to change the text to an F string current model is self Dot uh or actually type self dot clf underscore name or underscore underscore name underscore underscore uh and that then displays the model so saving and loading is also quite simple what we're going to do here is we're going to say the file path that we want to save them all at is going to be file dialog dot ask and I think this needs to be imported again uh like this file dialog dot ask save as file name default extension is going to be pickle with open that file path in writing bytes mode s f we're going to just say pickle dot dump .classifier into the file and we're going to say TK enter message box dot show info neural 9 drawing classifier model successfully saved the parent of this message box again is self dot root now for loading them all we're going to do something similar we're going to say file path is going to be file dialog but this time open ask open file name and with open the file path as reading bytes SF we're going to say self.classifier is pickle load whatever is in the file and then we're going to just take this message box and print Mall successfully load it all right and this leaves us with the last two functions save everything and on closing save everything is going to be quite simple we're going to define a dictionary where we're going to have key value pairs of some identifier and what we're trying to save so we're going to say as we defined up in the Constructor here I think there you go C1 C2 C3 and stuff like that we're going to use those again down here we're going to say C1 points to self.class1 C2 points to self dot class two C3 points to self.class 3. then c 1 C points to self dot class one counter C2C points to self.class 2 counter c3c points to self Dot class 3 counter and then we also want to have of course the classifier which is going to be self.clf and the pname is going to be the self Dot project name um so we take this dictionary and then we say with open and we want to store it at the following file path no why don't I see anything it's going to be self.project name slash um self.project name underscore data dot pickle which is exactly what we loaded up at the top so if I go back up this is where we loaded this from so I'm going to store it there um and we want to open this as writing bytes SF and want to say now pickle dark dump this dictionary here this data into the file and then we can again display a message box show info project successfully saved and finally what we want to do here on closing is we want to say answer equals I want to check if we want to save answer equals TK enter message box ask yes no cancel quit question mark do you do you want to save your work question mark parent equals self dot root and then we say if answer is not none so if it's not canceled and if the answer is yes so if answer then self.save everything otherwise if the answer is not none but it's no basically we say self dot root dot destroy and exit just to make sure that everything is closed and that's basically the full code of the drawing classifier now let's see if we did any mistakes we need to test it first um maybe I made some mistakes but let's try and do again shapes let's go and say we have a triangle shape we have a square shape we have a circle shape uh and now I want to provide some examples so triangle there you go triangle triangle triangle those are not beautiful triangles so it's probably going to be a pretty shitty classifier let's go with square let's try Square two square three oh boy those are not beautiful shapes and then Circle Circle Circle and circle and let's see now if I can train the model linear support Vector classifies train let's see if it can recognize a triangle predict it's a triangle let's see if it can recognize a circle it's a circle oh there you go so let's change K neighbor's classifier train them all again predict this shape here it's a triangle okay change the model train it does it recognize as a triangle it does okay change the model decision tree classifier predict triangle okay great change the model train predict okay works and then we can change a couple more times we can now save the model on the desktop for example or I can actually save it here at neural 9 python current so I can just store it as my model I can save it I'm all successfully saved I can also load the model now from here I'm all successfully loaded or I can just save everything and then I can close you can say I don't want to save my work then I should have here now in shapes this shapes data pickle and when I now open this up so when I restart the program hopefully if I now type shapes it should find that project and already know that this is a triangle okay no we need to fit still train model predict it's a triangle okay um and Square I think we only needed to fit them all because the last time I saved so let's try save everything again let's close let's run this again let's type shapes let's see if this works right out of the box there you go all right so this is how you build a drawing classifier that customize uh that classifies your custom drawings in Python all right so that's it for today's video I hope you enjoyed it and hope you learned something if so let me know by hitting a like button and leaving a comment in the comment section down below and of course don't forget to subscribe to this Channel and hit the notification Bell to not miss a single future video for free other than that thank you much for watching see you next video and bye foreign [Music]
Info
Channel: NeuralNine
Views: 7,344
Rating: undefined out of 5
Keywords: python, machine learning, artificial intelligence, python ML, python machine learning, drawing classifier, drawing recognition, scikit-learn, machine learning project, advanced machine learning project, intermediate machine learning project, advanced python project, intermediate python project, drawing classifier machine learning, paint python, opencv, opencv python
Id: cwwqDn57LUk
Channel Id: undefined
Length: 57min 8sec (3428 seconds)
Published: Wed Mar 15 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.