[PYTHON] Try to infer using a linear regression model on android [PyTorch Mobile]

What to do this time

Create a linear regression model in python and use that model to ** infer ** on android. (It is not trained on android.)

This code is posted on github, so please refer to it as appropriate. (URL posted at the bottom)

The one I make this time ↓

・ Use ** PyTorch Mobile **

pytorch-mobile.png

Creating a model

First, we will create a linear model to run on android. If you don't have a python environment and want to read only Android users, skip to the heading ** Inference with Android ** and download the completed model.

The code posted this time is the one that was run on the jupyter notebook.

data set

For the dataset used this time, try using Red Wine Quality listed in kaggle.

It feels like predicting ** 10 levels of quality of wine ** from wine component data such as sourness, pH, and frequency. キャプチdfasdfadsffdvzscャ.PNG

This time, I just want to move the linear model on android, so I will use a simple linear multiple regression to see the 10-step quality as a continuous value and fit it with the linear model. There are 11 columns, but there is no L1 regularization in particular. (Hmm, the accuracy seems to get worse ...)

Data organization

View data, check for missing areas, and organize data.

Import data downloaded from kaggle

import torch 
from matplotlib import pyplot as plt
import pandas as pd
import seaborn as sns

wineQualityData = pd.read_csv('datas/winequality-red.csv')

For the time being, plot the correlation, check for defects ..

sns.pairplot(wineQualityData)

#Check for missing data
wineQualityData.isnull().sum()

cvahtr.PNG   yjktkj.PNG

Especially since it may be a missing value, we will create a data loader next

Creating a data loader

#Input and correct label
X = wineQualityData.drop(['quality'], 1)
y = wineQualityData['quality']

#8:Divide by 2
X_train = torch.tensor(X.values[0:int(len(X)*0.8)], dtype=torch.float32)
X_test = torch.tensor(X.values[int(len(X)*0.8):len(X)], dtype=torch.float32)

#8:Divide by 2
y_train = torch.tensor(y.values[0:int(len(y)*0.8)], dtype=torch.float32)
y_test = torch.tensor(y.values[int(len(y)*0.8):len(y)], dtype=torch.float32)

#Data loader creation
train = torch.utils.data.TensorDataset(X_train, y_train)
train_loader = torch.utils.data.DataLoader(train, batch_size=100, shuffle=True)
test = torch.utils.data.TensorDataset(X_test, y_test)
test_loader = torch.utils.data.DataLoader(test, batch_size=50, shuffle=False)

It's easy to have a method in pytorch that makes it easy to create a data loader. I'm making test data this time, but I won't use it this time.

Creating a model

Next, we will make a linear model.

from torch import nn, optim

#model
model = nn.Linear(in_features = 11, out_features=1, bias=True)
#Learning rate
lr = 0.01
#Square error
loss_fn=nn.MSELoss()
#Loss function log
losses_train= []
#Optimization function
optimizer = optim.Adam(model.parameters(), lr=lr)

Model learning

Train the created model

from tqdm import tqdm
for epoch in tqdm(range(100)):
    print("epoch:", epoch)

    for x,y in train_loader:
        #Zero the previous gradient
        optimizer.zero_grad()
        #Forecast
        y_pred = model(x)
        #Calculate the derivative by MSE loss and w
        loss = loss_fn(y_pred, y)
        if(epoch != 0):  #End when the error becomes small
            if abs(losses_train[-1] - loss.item()) < 1e-1:
                break
        loss.backward()
        optimizer.step()
        losses_train.append(loss.item())

    print("train_loss", loss.item())

Learning results

Transition of loss function

plt.plot(losses_train)

adsffgda.png It seems that it is converging for the time being.

Try a little model

for i in range(len(X_test)):
    print("Inference result:",model(X_test[i]).data, "Correct label:", y_test[i].data)
adsfjkasdf.PNG

Hmm? It doesn't fit at all. It's just a linear multiple regression, but I wonder if it doesn't fit so well. Looking at the data again, 56% of the quality was 5. In other words, I wonder if it has almost converged to a value of 5 so as to reduce the loss. In the first place, was it difficult to regard such data as a continuous value label and perform linear multiple regression? It might have been better to do it by classification.

However, this time it is not the main thing to ask for the accuracy of the model, so for the time being, let's say that the model is completed.

If you know that the code is bad here because of the poor accuracy this time, please let us know in the comments.

Save model

Save the model to put the model on android

import torchvision

model.eval()
#Input tensor size
example = torch.rand(1,11) 
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("wineModel.pt")

If it can be executed successfully, a pt file should be generated in the same folder.

Inference on android

If you skipped it, please download the trained model from github.

From here, we will use Android Studio.

Dependencies

As of March 2020

build.gradle


dependencies {
    implementation 'org.pytorch:pytorch_android:1.4.0'
    implementation 'org.pytorch:pytorch_android_torchvision:1.4.0'
}

Put the model

Put the trained model (wineModel.pt) you downloaded or created earlier in Android Studio.

First, create an asset folder ** (you can create it by right-clicking on the res folder or a suitable location-> new-> folder-> asset folder) Copy the trained model there. jkjjkl.PNG

Layout

Create a layout that displays the inference results. However, I just arranged 3 textViews.

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/label" />

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="30sp"
        app:layout_constraintBottom_toTopOf="@+id/result"
        app:layout_constraintEnd_toEndOf="@+id/result"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="@+id/result"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Red wine quality forecast"
        android:textSize="30sp"
        app:layout_constraintBottom_toTopOf="@+id/label"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

inference

Load the model, put the tensor and infer

MainActivity.kt


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Wine test data
        val inputArray = floatArrayOf(7.1f, 0.46f, 0.2f, 1.9f, 0.077f, 28f, 54f, 0.9956f, 3.37f, 0.64f, 10.4f)
        //Generation of tensor:argument(floatArray,Tensor size)
        val inputTensor = Tensor.fromBlob(inputArray, longArrayOf(1,11))
        //Model loading
        val module = Module.load(assetFilePath(this, "wineModel.pt"))
        //inference
        val outputTensor = module.forward(IValue.from(inputTensor)).toTensor()
        val scores = outputTensor.dataAsFloatArray
        //View results
        result.text ="Predicted value: ${scores[0]}"
        label.text = "Correct label: 6"
    }

    //Function to get the path from the asset folder
    fun assetFilePath(context: Context, assetName: String): String {
        val file = File(context.filesDir, assetName)
        if (file.exists() && file.length() > 0) {
            return file.absolutePath
        }
        context.assets.open(assetName).use { inputStream ->
            FileOutputStream(file).use { outputStream ->
                val buffer = ByteArray(4 * 1024)
                var read: Int
                while (inputStream.read(buffer).also { read = it } != -1) {
                    outputStream.write(buffer, 0, read)
                }
                outputStream.flush()
            }
            return file.absolutePath
        }
    }
}

Complete! !! If you come to this point and execute it, the opening screen should appear.

end

The image system is also a tutorial, but I wrote this article because there wasn't much about ordinary linearity. The accuracy of the model was not good, but I was able to move the linear model for the time being. Let's try to classify this time.

Click here for this code python code android studio code

Recommended Posts

Try to infer using a linear regression model on android [PyTorch Mobile]
Try to implement linear regression using Pytorch with Google Colaboratory
Try to model a multimodal distribution using the EM algorithm
Try to edit a new image using the trained StyleGAN2 model
[kotlin] Image classification on android (Pytorch Mobile)
A addictive story when using tensorflow on Android
Predict hot summers with a linear regression model
Try to create a new command on linux
[PyTorch] Sample ⑧ ~ How to build a complex model ~
(Python) Try to develop a web application using Django
I tried hosting a Pytorch sample model using TorchServe
PyTorch Learning Note 2 (I tried using a pre-trained model)
Regression with linear model
Try to evaluate the performance of machine learning / regression model
How to run a trained transformer model locally on CloudTPU
SSH connection to a private server using a bastion server on EC2
I made a VGG16 model using TensorFlow (on the way)
Try clustering with a mixed Gaussian model on a Jupyter Notebook
[Introduction to Tensorflow] Understand Tensorflow properly and try to make a model
Try using OpenCV on Windows
Notes on optimization using Pytorch
Linear regression method using Numpy
Try to select a language
I tried to implement anomaly detection using a hidden Markov model
I just wrote a script to build Android on another machine
How to build a Python environment using Virtualenv on Ubuntu 18.04 LTS
Evaluate the performance of a simple regression model using LeaveOneOut cross-validation
Try to log in to Netflix automatically using python on your PC
Call dlm from python to run a time-varying coefficient regression model
Set up a node to do MNIST on ROS using Tensorflow