Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

機械学習による着座中か否か判定 part2

昨日学習結果を保存するまでの処理をまとめました。
elsammit-beginnerblg.hatenablog.com

今回はこちらの保存した学習データを用いてWeb上に着座中か否かの判定結果を表示させてみたいと思います!!
f:id:Elsammit:20210227105017p:plain



■学習結果を使用する

学習結果はpickleにて保存いたしました。
では、保存した結果を使用してみます。

使用する場合にはこちらのように、pickleファイルを読み出せば学習結果を利用することが出来ます。

    with open('model.pickle', mode='rb') as f:
        lr = pickle.load(f)
    ans = lr.predict(row_f.reshape(1, -1))

pickleを呼び出して使用する場合には、

import pickle
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

の通り、インポートをする必要があります。

■学習結果を用いて赤外線アレイセンサから予測する

では実際に保存した学習結果を用いて予測していきます。
構成はこちらを参照ください。
elsammit-beginnerblg.hatenablog.com

赤外線アレイセンサ値を収集して学習結果より予測するためのコードはこちら。

from flask import *
from flask import Flask, jsonify, make_response, request, Response
import time
import busio
import board
import adafruit_amg88xx
import numpy as np
from flask_cors import CORS
import csv
import pickle
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split

app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})

@app.route("/")
def main():
    return "Hello World"    

@app.route('/post', methods=['POST'])
def post_json():
    #赤外線アレイセンサ値取得.
    i2c_bus = busio.I2C(board.SCL, board.SDA)
    sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)
    time.sleep(.1)
    array = np.array(sensor.pixels)
    array1616 = array.repeat(2, axis=0).repeat(2, axis=1) 
    data = array1616.reshape(-1)
    llist = data.tolist()
    row_f = np.array(llist)
    
    #学習結果を呼び出し.
    with open('model.pickle', mode='rb') as f:
        lr = pickle.load(f)
    
    #学習結果を用いて赤外線アレイセンサ値から予測.
    ans = lr.predict(row_f.reshape(1, -1))
    Msg = ""
    if ans == 1:
        Msg = "Sit down"
    else:
        Msg = "None or Stand up"

    result = {
        "data": {
        "ret": Msg,
        "message":llist
        }
    }

    return jsonify(result)

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0',port=8888, threaded=True)

こちらのコードにてセンサ値を取得し、8x8 ⇒16x16に変換。
そして、list型からnumpy配列に変換。

    i2c_bus = busio.I2C(board.SCL, board.SDA)
    sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)
    time.sleep(.1)
    array = np.array(sensor.pixels)
    array1616 = array.repeat(2, axis=0).repeat(2, axis=1) 
    data = array1616.reshape(-1)
    llist = data.tolist()
    row_f = np.array(llist)

そして次に、先ほどの通り、学習結果を呼び出してその結果を用いて予測します。

    with open('model.pickle', mode='rb') as f:
        lr = pickle.load(f)
    ans = lr.predict(row_f.reshape(1, -1))

ansには予測結果が格納されています。
ansは、
 ・1:着座状態
 ・0:着座以外の状態
で返ってきます。
こちらの結果からWeb上に表示する文字列に変換しjson形式でresponseします。

webブラウザ上で予測結果表示

では次に表示側の修正です。
前回のブラウザ表示と異なる点はこちらです。

【HTML】

    <body>
        <link rel="stylesheet" href="heatmap.css">
        <div id="result"></div>
        <div style="height:800px; width:800px">
            <canvas id="heatMap" style="height:800px; width:800px"></canvas>
        </div>
        
        <script type="text/javascript" src="heatmap.js"></script>
    </body>

javascript

const interval = function(){
    var result = document.getElementById("result");
    $.post("ipアドレス")
    .always(function(data){
        datalist = data.data.message
        result.innerHTML = data.data.ret;
    })
    
    heatMap.data = {
        datasets: generateDatasets(),
        labels: generateLabels()
    }
    Chart.defaults.global.animation.duration = 0
    heatMap.update();
}
setInterval(interval, 1000);

css

#result{
    font-size: 52px;
    color:red;   
}

追加した部分が少し多いように見えますが、、、
実施していることはとても単純で、javascriptに記載した

    var result = document.getElementById("result");
    $.post("ipアドレス")
    .always(function(data){
        datalist = data.data.message
        result.innerHTML = data.data.ret;
    })

にてresponseされた結果をresultのinnerHTMLに表示。
このresultは、HTMLの

<div id="result"></div>

の部分に表示されます。
cssはこちらのresultに表示される文字サイズや文字色を変更しているのみです。

■結果表示

では実際に学習結果を用いてリアルタイムで予測・結果表示を行ってみます。
結果はこちら!!


着座⇒席を立ってみる⇒着座
の順で動いてみたのですが、リアルタイムに状態の表示が行えておりました!!
上出来、上出来!!

■最後に

機械学習を用いてみましたが精度高く実現できたのでうれしい!!
だけど、、、どういった判定を行って結果を出しているのでしょう🤔
機械学習ですと過程が分かりにくいのが難点ですね。。。