Erstellen Sie ein lineares Regressionsmodell in Python und verwenden Sie dieses Modell, um auf Android zu schließen. (Es ist nicht auf Android trainiert.)
Dieser Code wird auf github veröffentlicht. Bitte beziehen Sie sich auf ihn. (URL unten gepostet)
Die mache ich diesmal ↓
・ Verwenden Sie ** PyTorch Mobile **
Erstellen Sie zunächst ein lineares Modell für Android. Wenn Sie keine Python-Umgebung haben und nur Android-Benutzer lesen möchten, fahren Sie mit der Überschrift ** Inferenz mit Android ** fort und laden Sie das fertige Modell herunter.
Der diesmal veröffentlichte Code ist der Code, der auf dem Jupyter-Notebook ausgeführt wurde.
Verwenden Sie für den diesmal verwendeten Datensatz Rotweinqualität, der in kaggle aufgeführt ist.
Es fühlt sich an, als würde man aus Weinzutatendaten wie Säuregehalt, pH-Wert und Häufigkeit ** 10 Qualitätsstufen von Wein ** vorhersagen.
Dieses Mal möchte ich nur das lineare Modell auf Android verschieben, daher werde ich eine einfache lineare multiple Regression verwenden, um die 10-Stufen-Qualität als kontinuierlichen Wert zu sehen und sie an das lineare Modell anzupassen. Es gibt 11 Spalten, aber keine bestimmte L1-Regularisierung. (Hmm, die Genauigkeit scheint schlechter zu werden ...)
Zeigen Sie Daten an, suchen Sie nach fehlenden Bereichen und organisieren Sie Daten.
Importieren Sie die von kaggle heruntergeladenen Daten
import torch
from matplotlib import pyplot as plt
import pandas as pd
import seaborn as sns
wineQualityData = pd.read_csv('datas/winequality-red.csv')
Zeichnen Sie vorerst die Korrelation, überprüfen Sie sie auf Fehler.
sns.pairplot(wineQualityData)
#Auf fehlende Daten prüfen
wineQualityData.isnull().sum()
Insbesondere da es sich möglicherweise um einen fehlenden Wert handelt, erstellen wir als Nächstes einen Datenlader
#Eingabe und korrekte Beschriftung
X = wineQualityData.drop(['quality'], 1)
y = wineQualityData['quality']
#8:Teilen Sie durch 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:Teilen Sie durch 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)
#Erstellung des Datenladers
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)
Es ist einfach, eine Methode in pytorch zu haben, die es einfach macht, einen Datenlader zu erstellen. Dieses Mal mache ich Testdaten, aber diesmal werde ich sie nicht verwenden.
Als nächstes werden wir ein lineares Modell erstellen.
from torch import nn, optim
#Modell-
model = nn.Linear(in_features = 11, out_features=1, bias=True)
#Lernrate
lr = 0.01
#Quadratischer Fehler
loss_fn=nn.MSELoss()
#Verlustfunktionsprotokoll
losses_train= []
#Optimierungsfunktion
optimizer = optim.Adam(model.parameters(), lr=lr)
Trainiere das erstellte Modell
from tqdm import tqdm
for epoch in tqdm(range(100)):
print("epoch:", epoch)
for x,y in train_loader:
#Den vorherigen Gradienten auf Null setzen
optimizer.zero_grad()
#Prognose
y_pred = model(x)
#Berechnen Sie die Differenzierung nach MSE-Verlust und w
loss = loss_fn(y_pred, y)
if(epoch != 0): #Beenden Sie, wenn der Fehler klein wird
if abs(losses_train[-1] - loss.item()) < 1e-1:
break
loss.backward()
optimizer.step()
losses_train.append(loss.item())
print("train_loss", loss.item())
Übergang der Verlustfunktion
plt.plot(losses_train)
Es scheint, dass es vorerst konvergiert.
Probieren Sie ein kleines Modell
for i in range(len(X_test)):
print("Inferenzergebnis:",model(X_test[i]).data, "Richtiges Antwortetikett:", y_test[i].data)
Hmm? Es passt überhaupt nicht. Es ist nur eine lineare multiple Regression, aber ich frage mich, ob es nicht so gut passt. Bei erneuter Betrachtung der Daten waren 56% der Qualität 5. Mit anderen Worten, ich frage mich, ob es fast auf einen Wert von 5 konvergiert ist, um den Verlust zu verringern. War es überhaupt schwierig, solche Daten als kontinuierliche Wertelabelle zu betrachten und eine lineare multiple Regression durchzuführen? Es wäre vielleicht besser gewesen, dies durch Klassifizierung zu tun.
Diesmal ist es jedoch nicht die Hauptsache, nach der Genauigkeit des Modells zu fragen. Nehmen wir also vorerst an, dass das Modell fertiggestellt ist.
Wenn Sie wissen, dass der Code hier wegen der diesmal schlechten Genauigkeit schlecht ist, teilen Sie uns dies bitte in den Kommentaren mit.
Speichern Sie das Modell, um das Modell auf Android zu setzen
import torchvision
model.eval()
#Eingangstensorgröße
example = torch.rand(1,11)
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("wineModel.pt")
Wenn es erfolgreich ausgeführt werden kann, sollte eine pt-Datei im selben Ordner generiert werden.
Wenn Sie es übersprungen haben, laden Sie das trainierte Modell von [github] herunter (https://github.com/SY-BETA/Red-Wine-Quality-Linear-Regression/blob/master/wineModel.pt).
Von hier aus werden wir Android Studio verwenden.
Stand März 2020
build.gradle
dependencies {
implementation 'org.pytorch:pytorch_android:1.4.0'
implementation 'org.pytorch:pytorch_android_torchvision:1.4.0'
}
Fügen Sie das trainierte Modell (wineModel.pt) ein, das Sie zuvor in Android Studio heruntergeladen oder erstellt haben.
** Erstellen Sie zunächst einen Asset-Ordner ** (Sie können ihn erstellen, indem Sie mit der rechten Maustaste auf den res-Ordner oder einen geeigneten Speicherort klicken -> Neu-> Ordner-> Asset-Ordner). Kopieren Sie dort das trainierte Modell.
Erstellen Sie ein Layout, in dem die Inferenzergebnisse angezeigt werden. Ich habe jedoch gerade 3 Textansichten angeordnet.
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="Prognose der Rotweinqualität"
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>
Laden Sie das Modell, setzen Sie den Tensor und schließen Sie
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Weintestdaten
val inputArray = floatArrayOf(7.1f, 0.46f, 0.2f, 1.9f, 0.077f, 28f, 54f, 0.9956f, 3.37f, 0.64f, 10.4f)
//Tensol-Erzeugung:Streit(floatArray,Tensolgröße)
val inputTensor = Tensor.fromBlob(inputArray, longArrayOf(1,11))
//Modell laden
val module = Module.load(assetFilePath(this, "wineModel.pt"))
//Inferenz
val outputTensor = module.forward(IValue.from(inputTensor)).toTensor()
val scores = outputTensor.dataAsFloatArray
//Ergebnisse anzeigen
result.text ="Voraussichtlicher Wert: ${scores[0]}"
label.text = "Richtiges Antwortetikett: 6"
}
//Funktion zum Abrufen des Pfads aus dem Asset-Ordner
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
}
}
}
Komplett! !! Wenn Sie an diesen Punkt gelangen und ihn ausführen, sollte der Eröffnungsbildschirm angezeigt werden.
Das Bildsystem ist auch ein Tutorial, aber ich habe diesen Artikel geschrieben, weil es nicht viel über gewöhnliche Linearität gab. Die Genauigkeit des Modells war nicht gut, aber ich konnte das lineare Modell vorerst verschieben. Versuchen wir diesmal, diese zu klassifizieren.
Klicken Sie hier für diesen Code Python-Code Android Studio Code
Recommended Posts