--- title: Blog 001 tags: blog, medium, fastai --- # Lesson 1 fast.ai - Currency Classifier App <img src="https://media.christinas.vn/uploads/2017/06/vietnamese-dong-12.jpg" alt="Vietnamese Currency" width="50%"/> I have heard about fast.ai from many friends, and eventually, I gave it a try last week. The lecturer was [Jeremy Howard](https://en.wikipedia.org/wiki/Jeremy_Howard_(entrepreneur)). In the first lesson, he talked about the learning style **top-down**, which is different than the traditional **bottom-up**. He taught us about how to build a deep learning model and **deploy it in production** at the beginning. This was a bit overwhelming, but this was exactly what I was looking for. So I was super excited. After finishing the first lesson, I started building an app to classify the Vietnamese currency. The idea was to help foreigner to get familiar with our money. The main feature is capturing a photo on the web app using the webcam and recognizing the note before exchanging it into US Dollar (for example). I began with a plan and listed down some technical issues: * **Project Baseline 1**: Collect data and build a model to classify Vietnamese currency using fastai. * How to collect data? * How to train the model with the data? * How to export the model that can be used in production? * **Project Baseline 2**: Create a [Flask](https://www.fullstackpython.com/flask.html) app that user can take a photo from the webcam and upload it to the backend server. * How to access webcam and capture photos on the browser? * How to upload the photo to the server? * **Project Baseline 3**: Integrate the model from step one into the app and show the result to the user. * How to import the model into the app? * How to classify the image and return results? It sounded like a good plan. Then here we go. ### How to collect data? Follow the instructions in the lesson; I used the tool [Google Image Download](https://github.com/hardikvasa/google-images-download). It was straightforward, and I downloaded hundreds of images of Vietnamese currency automatically. Here below are some examples: ![](https://i.imgur.com/P7M7qUZ.jpg) As you can see, I wrote a short script to rename the files to a pattern `className_index.jpg`. So that it could match with the data Jeremy used in the first lesson. ### Training the model I followed the [lesson 1 notebook](https://github.com/fastai/course-v3/blob/master/nbs/dl1/lesson1-pets.ipynb) to import the data. The only change is the pattern of filename: ```python pat = r'/([^/]+)_\d+.jpg$' data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs ).normalize(imagenet_stats) data.show_batch(rows=3, figsize=(7,6)) ``` ![](https://i.imgur.com/aqD69Z2.png) Then I built a model using Resnet34 architecture, as does the course, and trained it with four epochs (1 epoch = looking at all images at once). I had around 28% error rate. ![](https://i.imgur.com/JZMnfLD.png) Continue following the lesson; I have fine-tuned the learning rate and chosen the range around $10^{-4}$ up to $10^{-3}$. Then I trained an unfrozen model with 20 epochs: ![](https://i.imgur.com/ZK4NoOq.png) Then I got only around 6.5% error rate, which was out of my expectation. There were a lot of things to improve the model and data, but I skipped it for a moment to move on building the web app. So I exported the model to a file `export.pkl` and finished my work on [Google Colab](https://colab.research.google.com). ```python # This will create a file named 'export.pkl' in the directory # where we were working that contains everything we need # to deploy our model learn.export() ``` ### Building the Flask app Luckily I have found this [tutorial](https://www.youtube.com/watch?v=gA_HJMd7uvQ) on Youtube. One thing to note was the deprecation of the function `createObjectURL()` in the tutorial. You should use `video.srcObject=stream`. I changed the UI a bit using [Bulma](https://bulma.io/), a free, light, and open-source CSS framework without Javascript. Then I wrapped the HTML page with a simple Flask app and moved on looking for a tool to upload the image which is captured by the user. The chosen one was [Filepond](https://pqina.nl/filepond/docs/print-version/#filepond-instance). Filepond's documentation is excellent. Literally, you can find everything you need there. This part of the project contained the most time-consuming tasks, tedious debugging issues, and endless researching on Google or [Stack Overflow](https://stackoverflow.com/). So I'm not going to bore you with now. To summarize, it took me 10 hours to come to this point: ![](https://i.imgur.com/9UAQq1C.png) ### Conclusion It turned out that the model performed poorly in my application, even the accuracy was 94% on the Jupyter Notebook. I came up with the two most important reasons, in my opinion: * The distribution of the trained data is different from the image user takes on the web. * The trained data was too small. So I need more data that's taken by users on webcam. And that brought me to part 2 of this project considering a brief overview: * Deploy the app (on [Google Cloud](https://cloud.google.com/), because I'm learning it) * Store the uploaded images ([Cloud Storage](https://cloud.google.com/storage/)) * If the model classifies wrong, give the user a way to correct it (Database needed, [FileStore](https://cloud.google.com/firestore/) may be good for this) Despite that the app didn't work perfectly, I was amazed by the results and look forward to work on part 2.