Warning
This page is located in archive. Go to the latest version of this course pages. Go the latest version of this page.

8. Strojové učení

Cíle cvičení

Další zdroje

Rozpoznání náklonu z akcelerometru

Cílem této úlohy je natrénovat SVM klasifikátor tak, aby rozpoznal přibližné naklonění akcelerometru. Abychom toho mohli dosáhnout, je třeba projít těmito kroky:

  1. Získání trénovacích dat
  2. Označení trénovacích dat (štítky)
  3. Natrénování modelu
  4. Predikce pomocí v reálném čase

Získání trénovacích dat

Thunderboard

Program pro Thunderboard čte data z IMU a posílá je do PC po rozhraní. Jedná se o data typu float, takže je nutné promyslet, jak data přenést. Dobrým nápadem je přenášet data ve struktuře, můžete se inspirovat tímto kódem.

Zamyslete se nad význemem dat (a datových typech), potřebou přesností, ale také nad rychlostí, kterou budete data snímat a přenášet.

PC - příjem a uložení

Na straně PC je třeba datat dekódovat a uložit do souboru s jednoduše editovatelným formátem, případně zobrazit. Lze vycházet např. z kódu na gitlabu, nebo použít následující:

import struct
import numpy as np
#
points = []
# cteni ze serioveho portu
byte = ser.read(24)
points.append(struct.unpack('6f', byte))

Pro offline analýzu uložte data do souboru ve formátu CSV. To lze udělat např. pomocí modulu csv.

import csv
 
header = ['acc_x', 'acc_y', 'acc_z', 'gyr_x', 'gyr_y', 'gyr_z']
data = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
 
 
with open('data.csv', 'w', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)
 
    # write the header
    writer.writerow(header)
 
    # write the data
    writer.writerow(data) 

Přiřazení štíků

Rozpoznání náklonu akcelerometru je velmi jednoduchá klasifikační úloha. Hledané třídě (náklonu) odpovídá kombinace diskrétní hodnot, získaných z IMU. Nasbíraná data rozdělíme do tříd tak, že do jednotlivých řádků doplníme jednoznačný štítek, např. takto

  • 0 - vodorovně
  • 1 - náklon dopředu
  • 2 - náklon dozadu

Štítky nemusí být číselné, může to být i textový řetězec. Příklad výsledného souboru:

acc_x,acc_y,acc_z,gyr_x,gyr_y,gyr_z,class
0.076416015625,-0.04150390625,1.00341796875,0.030517578125,6.591796875,0.9307861328125,0
0.1044921875,-0.04052734375,0.851318359375,-2.95257568359375,9.6435546875,-0.38909912109375,0
...
0.173583984375,0.426513671875,0.89892578125,2.99072265625,10.36834716796875,1.8768310546875,1
0.146728515625,0.327392578125,0.689697265625,3.692626953125,4.31060791015625,4.6844482421875,1
...
-0.076904296875,-0.660888671875,0.782958984375,5.767822265625,2.02178955078125,2.4566650390625,2
-0.1162109375,-0.67138671875,0.619384765625,6.44683837890625,-15.106201171875,-0.61798095703125,2

Trénování klasifikátoru

Uložená data použijeme jako trénovací (70% dat) a testovací (30% dat) množinu pro získání klasifikátoru.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import svm
import pickle
 
dataset = pd.read_csv('data.csv')
X = dataset.iloc[:, [0, 1, 2, 3, 4, 5]].values
y = dataset.iloc[:, [6]].values
 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.30, random_state = 0)
 
clf = svm.SVC(kernel='linear')
clf.fit(X_train, np.ravel(y_train))

Klasifikátor je možné uložit pro pozdější použití např. pomocí modulu pickle.

filename = 'model.sav'
pickle.dump(clf, open(filename, 'wb'))

Predikce

Pokud máme k dispozici model, je možné použít předikci z dat, které v reálném čase získáváme z Thunderboardu:

clf = pickle.load(open('model.sav', 'rb'))
# ziskani dat
D = [[data.acc_x, data.acc_y, data.acc_z, data.gyr_x, data.gyr_y, data.gyr_z]]
# predikce
print(clf.predict(D))

Rozpoznání gesta

Projekt je inspirován tímto tutoriálem.

K rozpoznání gest je třeba si nejprve připravit trénovací data. Zkusíme rozpoznat následující pohyby:

  • bez pohybu (důležité)
  • pohyb vodorovný
  • pohyb svislý
  • pohyb krouživý
  • vlnovka

Pro každý z těchto pohybů nasbírejte data do textového souboru. Následující kód slouží pro přípravu trénovací množiny.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
 
if __name__ == '__main__':
    # assume you saved your recordings into a "data" folder
    rest = pd.read_csv("data/0-rest.csv")
    vert = pd.read_csv('data/1-vertical.csv')
    hori = pd.read_csv('data/2-horizontal.csv')
    circ = pd.read_csv('data/3-circle.csv')
    shak = pd.read_csv('data/4-shake.csv')
 
    rest.plot(title='Rest')
    vert.plot(title='Verticla')
    hori.plot(title='Horizontal')
    circ.plot(title='Circle')
    shak.plot(title='Shake')
    plt.show()
 
    # X is the array of features to train the model on
    # y is the array of labels
    X = np.vstack([
        rest.to_numpy(),
        vert.to_numpy(),
        hori.to_numpy(),
        circ.to_numpy(),
        shak.to_numpy()
    ])
 
    y = np.concatenate([
        0 * np.ones(len(rest)),
        1 * np.ones(len(vert)),
        2 * np.ones(len(hori)),
        3 * np.ones(len(circ)),
        4 * np.ones(len(shak)),
    ])
 
    print("X.shape", X.shape)
    print("y.shape", y.shape)

courses/b0b37nsi/tutorials/08.txt · Last modified: 2022/04/25 15:31 by viteks