あきらぼ

テック系ブログ

RaspberryPiで計測した環境センサ情報をSQLデータベースに書き込む

こんにちは。

 

今回は先日RaspberryPiで計測した環境データをSQLデータベースサーバーにアップロードします。

 

 

 

前回はCCS811とBME280から疑似CO2濃度と気圧を取得するところまで行いました。

RaspberryPiでCO2センサーCCS811を動かす - あきらぼ

RaspberryPiでBME280で気圧測定 - あきらぼ

 

今回はここで取得した値をSQLデータベースにアップロードします。

実際のコードはこちらです。

IPアドレス等は伏せています。)

 

実際にcrontabで定期実行させたときのデータベースを確認します。

 

eCO2の値が飛んでいるのは要確認ですが、15分毎にデータがアップロードされていることが確認できます。

 

次回はデータベースの値を使ってWEBページ上でこれらの値を可視化してみようと思います。

 

今回の環境モニタシステムのコードの全体はこちらになります。

GitHub - Aki-R/RoomConditionMonitor

 

 

PyTorchをWindows環境にインストールしてPyCharmで使用する

こんにちは。

今回はPyCharmでYOLOv5を使用するためにPyTorchをインストールしようとしたところ、上手くいかなかったので備忘録として残しておきます。
まず、私の環境はAnaconda等の仮想環境を使っていません。仮想環境を使っている場合のインストール方法はすぐに見つかったのですが、Windowsに直接Pythonをインストールしている場合です。


まず、PyCharmが使用しているPythonのパスを確認します。
SettingのProject Interpreterから確認することができます。

私の場合はAppDataの中ですね。

次にコマンドプロンプトでインストールしてるCUDAのバージョンを確認します。
CUDAをインストールしていなければ以下を参考にしてください。
Python Tensorflow でcudart64_110.dll not found - あきらぼ

GPUを使用しないでPyTorchを使用する場合はインストール不要です。

CUDAのバージョン確認は以下のコマンドで行えます。

nvcc -V

私の場合はV11.6でした。

次にCUDAバージョンに合ったPyCharmをインストールします。
以下のサイトでインストールのコマンドをコピーします。
pytorch.org


今回はpipを使用してインストールするので以下になります。

こちらのインストールコマンドをコピーして、pipでインストールしていきます。
pipはPythonInterpreterと同ディレクトリのScriptというディレクトリにあります。

私の場合は以下です。
C:\Users\UserName\AppData\Local\Programs\Python\Python38\Scripts

今回はこのディレクトリのpip3.pyに対して先ほどのコマンドを使用します。
pip3.pyのあるディレクトリでコマンドプロンプトを使用して、私の場合は以下のようになります。

python pip3.py install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113

pip3ではなくpip3.pyに修正する必要があるのでご注意ください。
あとは勝手にPyTorchがインストールされます。

RaspberryPiでBME280で気圧測定

今回は気圧センサーであるBME280を使って気圧測定をしました。

 

最近梅雨入りしたせいで、ニュース等でも天気病などといって、気圧の低下に伴う体調不良が取り上げられるようになりました。
この天気病は気圧の絶対値ではなく、変化量が重要だと考えられています。

 

 

 

そこで、実際に時系列の自宅の気圧データを取得することで体調管理をしましょうというのが目的です。
完成形はこちらです。

 

 

さて、実際に実装に移っていきます。

BME280とRaspberryPiはI2Cで接続しています。

詳細はこちら

aki-lab.hatenadiary.com

 

今回使用した気圧センサーはドイツの自動車部品メーカーのボッシュ製のBME280になります。

ACEIRMC BME280搭載 温湿度 気圧センサーモジュール 5V用 SPI I2C Arduino対応 Raspberry Pi (1個)

 

データシートはこちらになります。

https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

 

基本的にはこちらのデータシートの指示通りにレジスタを叩いてデータを取得していきます。

 

まず、実際のコードがこちらになります。

 

基本的にはデータシート通りの実装なのですが、pythonで記述する際に、変数の型が明示的ではなかったので、Numpyを使用して明示的に型変換を行うことでデータシート通りの温度と気圧の補正を行っています。

 

実際に実行するとこんな感じです。

pi@raspberrypi: python3 BME280.py
Device ID is 0x60
BME280 is connected.
Temperature 26.88 degC
Pressure 998.76 hPa

こちらの温度は気圧センサ補正に使用しているのでセンサーの温度です。

なので、室温よりは少し高い値になっているので単純な環境センサ値としては使えなさそうです。

 

あまり、レジスタ直叩きで使用している記事を見なかったので参考になればと思います。

 

実際に使用してみると、天気とは関係なく気圧が変動していることや、気密性の高いマンションだと換気扇を使うことで圧力が下がってしまうことです。

次回、頭が痛くなったときは値を確認してみようと思います。

 

コードの全体はこちらになります。

GitHub - Aki-R/CCS811_BME280_RPi: Upload CCS811 and BME280 measurement to database by using RaspberryPi

 

 

RaspberryPiでCO2センサーCCS811を動かす

こんにちは。

 

今回はRaspberryPiでCCS811を動かしました。

 

 

 

前回はRaspberryPiへの接続まで完了していました。

aki-lab.hatenadiary.com

 

KEYESTUDIO DC 5V CCS811 CO2 二酸化炭素 TVOC 大気質 センサー モジュール for Arduino アルドゥイーノ アルディーノ 電子工作

 

そして今回は実際に値を読み取るところまでを行います。

しかし、基本的なI2Cのフローは前回STM32で行った場合と同じになります。

aki-lab.hatenadiary.com

 

同じことをRaspberryPiで実装した形になります。

なので詳細は省きます。

 

今回のコードはこちらになります。

 

このまま実行します。

pi@raspberrypi: python3 CCS811_RPi.py
Device ID is 0x81
CCS811 is connected.
Application mode is in active.
Measure Mode is set to Mode1.
eCO2: 405
eTVOC: 0

 

二酸化炭素換算量が問題なく取得できました。

 

あとはこのデータをデータベースにアップロードして部屋環境モニターで使用する予定です。

 

コード全文はこちらに保存しています。

GitHub - Aki-R/CCS811_BME280_RPi: Upload CCS811 and BME280 measurement to database by using RaspberryPi

 

 

【Tensorflow】【Keras】CNNでHololiveメンバーの識別をしてみる

こんにちは。

今回は先日のモデルに引き続き、ざっくりと最初のHololiveメンバー識別機を作ってみたのでそのことを書こうと思います。


まず今回作った識別機がどのように動くかの動画がこちらになります。

youtu.be

 

 

 

 

背景

今回識別器を作った理由としては最近流行っているHololiveのメンバーがどんどん増えていって覚えきれません。

しかし、サムネイル等には出てくるし、いちいち調べるのも面倒。

そこでAIを使って判定させてしまおうというのが今回作った動機になります。

 

今回参考にしたのはこちらの本です。実際のKerasのコードまで書いてあって分かりやすかったです。

Pythonによるディープラーニング (Compass Booksシリーズ) 単行本(ソフトカバー)

 

教師データ収集

まず、教師データ集めです。

今回はGoogle検索を使ってHololiveメンバー58名分のデータをを集めました。

メンバー一覧はこちら。

所属タレント一覧 | hololive(ホロライブ)公式サイト

 

画像収集方法はこちらです。

aki-lab.hatenadiary.com

 

全部で集まった画像データは24254枚、平均一人あたり約400万になります。

しかし、インドネシア勢とはまだ画像データが少なく、あまり検出できていませんでした。

例えば、こぼ・かなえるはデータ数が少なく、集めたデータも本に以外のデータばかりだったので正しく識別できていませんでした。

 

 

そこで、後でYoutubeのサムネイル等から画像を集めて、正しいデータだけを残すようにすればまた精度が上がると思います。

 

識別CNNモデル

次に今回のモデルにはKerasに既に用意されている識別でよく使われるVGG16モデルをベースに使用します。

入力画像サイズは256×256です。

 

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 rescaling (Rescaling)       (None, 256, 256, 3)       0         
                                                                 
 random_rotation (RandomRota  (None, 256, 256, 3)      0         
 tion)                                                           
                                                                 
 random_zoom (RandomZoom)    (None, 256, 256, 3)       0         
                                                                 
 random_flip (RandomFlip)    (None, 256, 256, 3)       0         
                                                                 
 random_translation (RandomT  (None, 256, 256, 3)      0         
 ranslation)                                                     
                                                                 
 vgg16 (Functional)          (None, None, None, 512)   14714688  
                                                                 
 flatten (Flatten)           (None, 32768)             0         
                                                                 
 dense (Dense)               (None, 512)               16777728  
                                                                 
 dropout (Dropout)           (None, 512)               0         
                                                                 
 dense_1 (Dense)             (None, 58)                29754     
                                                                 
=================================================================
Total params: 31,522,170
Trainable params: 23,886,906
Non-trainable params: 7,635,264
_________________________________________________________________

 

上流のRandom層は過学習対策になります。

最初からこの層を追加した状態で学習のハイパーパラメータ等設定していたので少し沼ってしまいました。

詳細はこちら。

 

aki-lab.hatenadiary.com

 

また、VGG16の内、下流側4層のみをパラメータ学習可能としています。

 

学習

まず、学習にあたって集まったデータの80%を学習用、20%を検証用としてランダムに分割します。

学習・最適化は以下のようにしています。

  • Optimizer:Adam
  • 損失:Categorical Crossentropy
  • 学習率:1.0e-4
  • バッチサイズ:128

 実際に学習を始めると、すぐに過学習に入ります。

 

10エポックを過ぎたあたりで過学習が始まっています。

最大精度で60%を少し超えるぐらいでした。

そこで最大精度のものを使用したのが動画で使用しているモデルになります。

 

識別器

最後にモデルを学習してそれで終わりでは、全く役に立たないので、実際にYotubeや画像で範囲を選択すると判定してくれるようなアプリを作ってみました。

 

今回はTkinterを使用して簡単なGUIの識別器を作りました。

詳細な説明はここではしませんが、ウィンドウを透明の256X256ピクセルのサイズにすることで、そこの表示を読み取ってモデルで判定させています。

 

一番確度(そうである可能性)の高いメンバー名を表示するようにしています。

詳しくはソースコードをご参照ください。

 

問題点

実際使ってみた問題点として、256x256のウィンドウサイズだと、二人以上のメンバーが同時にウィンドウ内に入ってしまうケースが多く、どちらを検出しているのか分かりません。

そこで領域も検出できるようにすると便利さ増すかなと思っています。

そのあたりも使える方法がないか調べて実装してみようと思います。

 

 

 

今回使用したコードは以下になります。(適宜アップデートするかもしれませんが。)

GitHub - Aki-R/Hololive_Categorizer: CNN categorizer for VTuber Holilive members

 

また、識別対象を増やしたり、精度改善も暇な時にでもしていこうと思います。

(人力で画像データ集めと振り分けが少し必要そう。こういう仕事をアノテーターというらしいです(笑))

 

 

Tensorflowの画像分類器の学習設定で損失が減らずハマった話

こんにちは。

現在、VTuberアイドルグループであるHololiveの画像分類器を作成しているのですが、CNNのモデル設定でハマったのでそのことを書こうと思います。

ちなみにHololiveはこんなグループです。
所属タレント一覧 | hololive(ホロライブ)公式サイト




前提条件

まず、前提条件としては学習データとしてはホロライブメンバーのうち9人分の画像データをGoogle画像検索で集めました。
以下の方法です。
aki-lab.hatenadiary.com

そこで一人当たり400-500枚、計4175枚の画像になります。
これらのデータの内8割を学習データ、2割を検証データとします。

分類モデルとしては有名なvgg16を転移学習させる形でモデルを組みました。
最後に全結合層で512個のニューロンを追加しています。

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 rescaling (Rescaling)       (None, 256, 256, 3)       0         
                                                                 
 random_rotation (RandomRota  (None, 256, 256, 3)      0         
 tion)                                                           
                                                                 
 random_zoom (RandomZoom)    (None, 256, 256, 3)       0         
                                                                 
 random_flip (RandomFlip)    (None, 256, 256, 3)       0         
                                                                 
 random_translation (RandomT  (None, 256, 256, 3)      0         
 ranslation)                                                     
                                                                 
 vgg16 (Functional)          (None, None, None, 512)   14714688  
                                                                 
 flatten (Flatten)           (None, 32768)             0         
                                                                 
 dense (Dense)               (None, 512)               16777728  
                                                                 
 dropout (Dropout)           (None, 512)               0         
                                                                 
 dense_1 (Dense)             (None, 9)                 4617      
                                                                 
=================================================================
Total params: 31,497,033
Trainable params: 23,861,769
Non-trainable params: 7,635,264
_________________________________________________________________

VGG16のパラメータの内、下流4層だけ学習可能にしています。
このうちrandom_rotation、random_zoom、random_flip、 random_translationはデータ強化層
dropoutは過学習対策の層となります。

今回は学習データが少ないので、データ強化層を4層入れています。
データ強化方法は、データ強化層を追加する方法以外に、そもそも元の学習データを事前に水増しする方法があります。(openCVやPillowを使って)

学習

ここから実際に学習をさせていきます。
パラメータ最適化方法としてはAdamを使用しました。

そして、バッチサイズや学習率を変化させて学習するようにします。
実際には全結合層の数や最適化手法も変更して色々試したのですが、なかなか教師データに対する損失(Loss)が減らずに悩んでいました。
結論から言うと、過学習対策を入れたままモデル検証していたからでした。

一例として過学習対策有りと無しで学習率の変化の影響がどう出るのか例を載せます。

過学習対策あり

以下は過学習対策ありのまま学習率を変化させた場合です。

確かに学習率を小さくして改善しているようですが、精度が低いままです。
これは過学習対策が教師データを各エピックで変更してしまっているために教師データに対しての精度も損失もあまり改善していないように見えてしまいます。

この状態だとモデルの表現力が分類に必要なだけあるかどうかも判断がつきづらいです。
エポック数を増やせば判断は付きますが、時間がかかってしまうのでモデル選定のトライ&エラーが大変になってしまします。

過学習対策なし

次に同じモデルで過学習対策を抜いた場合を見てましょう。

実際に過学習対策を抜いたモデルがこちら。

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 rescaling (Rescaling)       (None, 256, 256, 3)       0         
                                                                 
 vgg16 (Functional)          (None, None, None, 512)   14714688  
                                                                 
 flatten (Flatten)           (None, 32768)             0         
                                                                 
 dense (Dense)               (None, 512)               16777728  
                                                                 
 dense_1 (Dense)             (None, 9)                 4617      
                                                                 
=================================================================
Total params: 31,497,033
Trainable params: 23,861,769
Non-trainable params: 7,635,264
_________________________________________________________________

このモデルで同様に学習率違いを見てみましょう。

こちらの場合は学習率を小さくすることで学習が大きく改善され、損失が落ちて行っていることが一目で分かります。
もちろん、過学習対策を入れていないので、検証用データに対する損失と精度は悪いままですが、過学習対策を入れれば改善されます。

実際にこの学習率で過学習対策を入れてエポック数を増やせばかなり精度が上がります。

結論

今回の結果から過学習対策はモデル選定の段階では入れない方が良いということが分かりました。
過学習対策なしの状態で教師データに対して十分最適化され、精度が上がる状態で過学習対策を順次実装していく必要があります。

順番でいうとこんな感じ。

  1. 過学習対策なしでモデル選定・最適化パラメータ調整
  2. 教師データに十分フィッティングできる(低損失高精度)モデルであることを確認
  3. 過学習対策を追加

実際に過学習対策なしでフィッティングが進んだモデルでエポック数を増やしていくと以下のように精度が上がりました。

現状の分類器はこちら。

github.com

このような分類器作成の参考になる本がこちら。Keras、Tensorflowによるモデル作り方が分かりやすく解説されています。

引き続き分類器の作成を続けていこうと思います。

Python:grobでフォルダ内の大量の画像すべてを一括で読み込む

こんにちは。


今回は先日落としてきた大量の画像データの読み込みに関してメモがてら書こうと思います。


先日は画像分類器のために画像を大量にダウンロードしてきました。


aki-lab.hatenadiary.com


すると格納フォルダはこんなことになっています。



一応画像はナンバリングされているのですが、関係ない画像等を抜いたりもしているので、連番ではありません。
簡単に一括で処理できる方法がないかと調べてみたらgrabというパッケージがありました。


簡単な例を以下に書きます。



すると以下のような結果を返します。

./Train_Data/pekora\pekora002.jpg
./Train_Data/pekora\pekora003.jpg
./Train_Data/pekora\pekora004.jpg
(省略)
./Train_Data/pekora\pekora499.jpg
./Train_Data/pekora\pekora500.jpg
./Train_Data/pekora\pekora501.jpg


このように参照ディレクトリの内部ファイルのパスを全て返してくれます。





実際に画像分類器で使用したときは以下のようにして使用していました。



こうすることでImagesとnamesが教師データとして使用できます。


分類器全体はこちら
github.com