
Machine learning (ML) and data science are the fastest-growing technology areas. However, machine learning engineers need faster ways to expose their models as web applications without knowledge of web backend or frontend technologies such as Flask, React, and Javascript.
This process is also very time-consuming, more so if the goal is to deploy the model on the web as a prototype. For such scenarios, Streamlit is a perfect solution that can be easily scaled if the load on the application increases.
Streamlit is a free, open-source framework to quickly build and share interactive machine learning and data science web apps. It is a Python-based library specifically designed for data scientists and machine learning engineers.
In the following tutorial, you will train a deep learning model on an image dataset as a multi-classification problem. Although our code is designed to work on both CPU and GPU instances, it is recommended that you use a GPU instance to save time and increase accuracy. After evaluating the prediction metric for the trained model, you will deploy the model in production as a web application using Streamlit and tmux.
Before you begin this tutorial, you need the following:
A Vultr server with a freshly installed Ubuntu (22.04) instance, preferably a GPU instance.
A local Mac, Windows (with Putty installed), or a Linux system. This guide focuses on Windows, but the procedures are similar for any Linux control node.
A previously generated private SSH Key for the Vultr host; the SSH public key should already be installed for the root user.
A text editor that supports Python syntax highlighting, such as Atom, Visual Studio Code, or Sublime Text. These editors are available on Windows, macOS, and Linux.
Familiarity with Python programming and pip
Familiarity with Machine Learning concepts such as training, testing, evaluation
Familiarity with data science tools such as Numpy, Pandas, Sci-kit-learn, Kera, and TensorFlow.
Connect to your freshly installed Vultr server with your private SSH keys as a non-root user.
Also note that by default, you will connect with the Vultr instance terminal shell, which does not show the host and current directory you are in, and does not have an autocompletion feature. Type bash on the terminal if you are used to working with Bash shell:
Machine learning tasks involve using various Python libraries (non-standard), which are most common in data science. To install the required libraries to follow this tutorial:
Also, install the recursive directory listing program tree:
In this guide, you will be training your model on an image dataset, and therefore it is advantageous to use a vultr GPU instance instead of a normal CPU instance which can accelerate the training phase substantially. This is known as GPU acceleration. Vultr uses Nvidia GPUs (from NVIDIA A100 and A100 series), and it provides computing GPUs at a very cost-effective price which are not shared with other customers.
To check the availability of GPU on the remote machine, launch a python session:
And type the following in the python session:
You will receive an output that indicates GPUs are available:
If your server is not equipped with GPU, Num GPUs Available will be 0.
Leave the Python interpreter by typing Ctrl+D.
In this step, we will ensure that our GPU device is available, and we will make a comparative performance analysis of the GPU versus the CPU.
Create a project folder named satellite and enter into it:
When in your project folder, create a new file called comparison.py:
Add the following lines of python code to the comparison.py file:
Save your comparison.py file, then run the code in a terminal session:
If your machine has a GPU device, you will receive an output response similar to this:
Otherwise, you will get an error (if GPU is not there on your machine).
Your speedup may be different depending on your GPU capability. So it is a clear indication that GPUs are highly advantageous if machine learning task involves heavy number crunching, such as in image processing (which the current guide deals with) or natural language processing (NLP).
Now for the current guide, you will train a machine-learning model using image datasets from Kaggle. This dataset has four different classes mixed from Sensors and Google map snapshots. The trained model can recognize a satellite image belonging to a particular class of the four classes. Instead of downloading the data to your local machine, you will download the Kaggle image dataset directly to your server. This trick will be handy when you process a big Kaggle dataset that can run from ~100 MBs to a few GBs.
For this step, you need an account on Kaggle, as you will need the Kaggle API token. Create a Kaggle account if you don't have one already. To download the Kaggle API token, go to your profile on the Kaggle website from your browser, click on the Account tab, and in the menu ribbon, go to the Account tab as shown below:
Click on the Create New API Token button. This will download a kaggle.json file to your local machine. Open the JSON file via any text editor on your local machine to view its content which will be similar to:
Note the values for the username and key keys.
Now create a kaggle_json.py file in the project folder satellite:
And add the following code to it
Modify the username and key values as previously noted from your downloaded kaggle.json file in the above code.
Run the python script:
This python script will create a kaggle.json file on your remote server and grant it the necessary permission.
To download Kaggle datasets, you need to install the Kaggle CLI tool:
Run the following command to download your required Kaggle dataset:
This command downloads the image data as a zip file from the Kaggle website.
Unzip the downloaded zip file:
This will unzip the image data to a newly created data folder. Check the content of the data folder.
You will see four folders:
These folders correspond to the four classes of images.
You can check the contents of the folder with tree command:
You will notice that these four directories contain 5631 jpeg images. Also, download the few images from the Kaggle website to your local machine to upload once you run your Streamlit application in the later steps of this tutorial.
Clear the terminal screen.
Now you will prepare the image for machine learning.
Now create a dataPreparation.py file:
And add the following code to this file:
In this python script, you create an empty Pandas dataframe data, and define a python dictionary labels with keys as the path information of folders containing images, and corresponding values as strings in line with folders' names. Then you run a for-loop to populate the dataframe data. Then you save this data to a CSV file image_dataset.csv. In the next step, you read the CSV file to a Pandas dataframe df. Then, you divide the images dataset into train and test sets in the 80 by 20 ratio respectively. As an important preprocessing step, you numericise the image pixels because machine learning frameworks can only process numerical arrays. For this purpose, you employ ImageDataGenerator class imported from keras.preprocessing.image, and create train_datagen and test_datagen object instances from this class with suitable parameter values. During the training, machine learning frameworks typically process the data objects in batches. You set the batch size depending on the type of server, whether CPU or GPU. Finally, you invoke a method flow_from_dataframe of the object with the value of parameter dataframe equal to train_df, and assign this object to the variable train_generator. Similarly, test_generator is created with test_df.
Now, let us run the python script:
You will get the output similar to as below:
After preprocessing the dataset, dividing them into training and testing sets, and saving them into variables, we move on to the next step of setting up your machine learning model.
In this step, we will build our deep learning model. Create a modelBuild.py file:
And add the following code to it:
Here, for your model, you use convolutional neural network (CNN) using Sequential class from keras.models. The code above will build model with 4 CNN layers, with the final layer activated with softmax for multi-output classification. In the last step, you compile the model with the appropriate optimizer, loss, and metric parameters, as well.
Now create a file trainModel.py:
Add the following code to the trainModel.py file:
To train the model for predetermined iterations, you need to set the value of epoch parameter depending upon the availability of GPU on your server; it is set to 20 for the GPU server and 1 for the server with CPU only. For the determined epochs, you train the model by invoking the fit_generator method of the CNN model, and the progress of the training is saved in the history variable for future analysis of how the training proceeded. In the end, you save the trained model as Model.h5 file.
Run the script:
Although the code has been designed and tested to run on the single CPU-only server as well, if the RAM and other computing resources do not match up, you may encounter the Resource Exhausted error as well:
If you face this error, try reducing the batch size from 8 to 4 or 2, and run the training script again. Alternatively, you can launch a GPU instance.
If the training is successfully completed, you will see similar output:
Typically the training time will vary between 5 to 20 minutes with GPU for 20 epochs of training. You can do an experiment with epoch numbers yourself and reach the optimal number by trial and error.
In this step, you will make an inference using the trained model. For that, create a file prediction.py
And add the following code to it:
In the code above, you input an image from the green_area folder to the trained model to infer the label. The image is converted to a numerical array and reshaped before inputting it into the trained model. During the training phase, the conversion to numerical array and reshaping was done by ImageDataGenerator implicitly. Run the python script:
If the code runs successfully, you will see a similar output at the bottom:
In this instance, the model inferred correctly. However, your image prediction may be different depending on the accuracy of your trained model and the image you provide.
Before we code the Streamlit application, it is to be noted that by default, on a freshly installed Vultr server, the standard Linux firewall blocks ports for security reasons. Therefore, you will open the required port. Streamlit uses port numbers starting from 8501 onwards. Now to check the firewall status, type in the terminal:
You will observe a similar response:
Now open port 8501 to listen to the incoming requests:
Ensure that port 8501 is open now by checking the status:
You will get the output:
So you can confirm that port 8501 is open, and can listen to HTTP requests from any network (IP address). You should open other ports in line 8500 if needed.
Note: Streamlit does not give any warning even if port 8501 is closed. So be sure about the port used by Streamlit is open before you deploy the Streamlit application.
In this step, you will deploy your trained model as a web application using Streamlit. It will generate all the necessary endpoints on the back-end server and necessary client-side code (HTML and javascript) to be rendered by the browser. Moreover, the application generated will be responsive, i.e., it will work perfectly on mobile as well as desktop screens.
The web application will upload the test image on the browser by the front-end code. The image will be sent back to the server, and the model will make an inference and send back the inferred result to the front-end.
Create a file main.py:
And add the following code to it:
Here we have turned the previous code from prediction.py into a function predict_label. And button and write method of streamlit is used to create the input and output widget.
Now run the python script through Streamlit:
You will see the following output:
Go to your browser and type in the External URL to view your Streamlit application. Depending on the settings of your server, Network URL External URL might be different as well. The screenshot of the app is here.
You can play with it by uploading an image out of the previously saved images from the Kaggle dataset on your local machine.
This is all good, but as soon as you close the SSH terminal window or log off, the process will stop, causing your application to stop as well. To overcome this problem, you need to launch the process as a background application.
Stop your application by typing Ctrl+:key_c.
Tmux is a terminal multiplexer, and Tmux sessions are persistent, which means that programs running in Tmux session will continue to run even if you get disconnected from the terminal. Tmux is already installed in Vultr server(ubuntu image). In case tmux is not installed, install it by:
Start a new Tmux session with a session name, say sts:
See the session name at the left bottom of the console window in a green highlighted info line at the bottom of the terminal window. Start running the Streamlit application in the tmux session:
You will be able to view your application at the External URL as in the previous step. Now detach your Tmux session so that it continues running in the background even when you leave the SSH shell. Now to detach your TMUX session, press Ctrl+B and then D (Don't press Ctrl while pressing D). Be careful not to press Ctrl+C while detaching.
After detaching, you will come back to the SSH console, indicated by no green highlighted line at the bottom. You can now safely close your SSH session, but the application will keep running at the External URL.
Remember if you want to stop the Streamlit application running via a Tmux session, you need to kill the process as follows.
Watch all the Tmux sessions running:
Attach to the session in which you have started the Streamlit application:
While in Tmux session, press Ctrl+C to stop the application and then detach by pressing Ctrl+B and then D. Mind it, as the previous step will stop the application.
Note: If you enter into the Tmux session as a root user, you will land in the home folder of root even if you were in your project folder before. Enter into the project folder before running the Streamlit command.
In this tutorial, you trained a machine learning model with image recognition capability, which you subsequently deployed using Streamlit and Tmux. As part of the next actions, you can train machine learning models for NLP and business datasets apart from other image datasets. For inputs to these models, you will use the other input widgets of Streamlit, such as textbox, radio button, and slider. Further as an exercise, you can try to code logic to take care of the error arising in this application if you press Recognise button without first uploading a photo.
0 Comments
Be the first to comment and share your perspective with the community.