あきらぼ

テック系ブログ

Python Tensorflow でcudart64_110.dll not found

PythonのTensorflowでプリグラムを実行しようとしたところ以下のようなエラーが出ました。

2022-04-24 20:52:29.885267: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'cudart64_110.dll'; dlerror: cudart64_110.dll not found
2022-04-24 20:52:29.885774: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.

単純にCUDAとcuDNNがインストールされていないためのエラーになります。

まずCUDAを以下からインストールします。
developer.nvidia.com

次に、cuDNNを以下のサイトからダウンロードします。
developer.nvidia.com

インストールのやり方は、単純にCUDAのインストール先に解凍したcuDNNの中のbin, includeファイル等をすべてコピーするだけです。
私の場合は以下のパスです。
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6

最後にパス通して完了です。

するとエラーが以下のように無くなりました。

2022-04-24 22:22:43.985293: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-04-24 22:22:44.743542: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 9633 MB memory:  -> device: 0, name: NVIDIA GeForce GTX 1080 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1

しかし、cuDNNとTensorflow, CUDA等には動かないバージョンの組み合わせがあるので気を付けてください。
私も他のところでバージョンによるエラーが生じました。

以下の記事参照。
aki-lab.hatenadiary.com

Tensorflowで「Loaded cuDNN version 8400」からのクラッシュ

Tensorflowでモデルを回そうとしたところEpoch一回目で、以下のメッセージがでて、その後クラッシュしてしまいました。

Epoch 1/10
2022-04-24 22:44:52.714618: I tensorflow/stream_executor/cuda/cuda_dnn.cc:368] Loaded cuDNN version 8400

cuDNNのバージョンミスマッチでしょうか。
cuDNNが v8.4
Tensorflow v2.8.0
Cudaのバージョンがv11.6になります。



Tensorflowのバージョンはpythonで以下のコードで確認することができます。

import tensorflow as tf
print(tf.__version__)

コマンドプロンプト上で以下のコマンドでCudaのバージョンを確認できます。

nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Tue_Mar__8_18:36:24_Pacific_Standard_Time_2022
Cuda compilation tools, release 11.6, V11.6.124
Build cuda_11.6.r11.6/compiler.31057947_0

cuDNNのバージョンはインストールされているディレクトリの
include/cudnn_version.h
のファイルに記載されています。

/**
 * \file: The master cuDNN version file.
 */

#ifndef CUDNN_VERSION_H_
#define CUDNN_VERSION_H_

#define CUDNN_MAJOR 8
#define CUDNN_MINOR 4
#define CUDNN_PATCHLEVEL 0

#define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL)

#endif /* CUDNN_VERSION_H */

とりあえず急ぎではないので以下の方法でGPU無効化してTensorflow自体は動くことは確認済みです。

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

回答はありませんが、同様のエラーの人もいるようですね。
https://forums.developer.nvidia.com/t/use-gpu-for-tensorflow-crashes/208849

追記

やはりcuDNNのバージョンによるものでした。
私の上記環境であれば、cuDNNのv8.2.4 for Cuda 11.4でTensorflowをGPUで動かすことできました。

ちなみにTensorflowの検証済み環境を使用するのが一番無難だとは思います。
www.tensorflow.org

IFTTTで在宅時間をモニターする

こんにちは。

今回はIFTTTを使って在宅時間のモニターシステムを作ってみようと思います。




背景

私は仕事の関係で出張と在宅勤務が非常に多いです。
そこで、出張が多い時は家の稼働率がどのぐらいなのか、在宅勤務時はどのくらい移動していないのかという参考にこちらのモニターを作ってみたいと思いました。
このデータをもとに、散歩や買い物に出かけるのも良し、自宅の稼働率があまりに低い様なら引っ越しなんかもアリかななんてことに使ってみたいです。

システム構成

今回のシステム構成はこんな感じです。

f:id:AKIRA_san:20220328224623p:plain

IFTTTの機能を使って家(周辺)の出入りをGoogleSpreadsheetに記載します。
次にサーバー上のPythonでこの家の出入り情報のSpreadsheetをダウンロードしてJSONに変換します。
最後にjavascript上でこのJSONにアクセスし、Chart.jsでグラフ表示します。

IFTTTの設定

今回はIFTTTで家周辺への出入りをSpreadsheetに書き込むというAppletと呼ばれるものを作成します。

以前IFTTTを使って家電リモコンの温湿度情報をSpreadsheetに書き込むことをやったので記事を載せておきます。
aki-lab.hatenadiary.com

今回は、家に出入りしたらその情報をSpreadSheetに書き込むというAppletを作成します。
新規のAppletをCreateから作成します。
f:id:AKIRA_san:20220328231141p:plain
If ThisにLocationを追加します。

f:id:AKIRA_san:20220328231221p:plainf:id:AKIRA_san:20220328232518p:plain

今回は入退出の両方を記録したいので、「You enter or exit an area」を選択します。
f:id:AKIRA_san:20220328232616p:plain

あとは自宅の場所を選択して、Triggerを作成します。
次に「Then That」を設定していきます。
入退出情報をGoogleSpreadsheetに出力したいのでGoogle SheetのAdd rowを選択します。


f:id:AKIRA_san:20220328233435p:plain
f:id:AKIRA_san:20220328233913p:plain
あとは以下のように設定すれば、入退出の時間と入場・退場の情報が記録されるようになります。
これにてIFTTTの設定は完了です。

Google APIの設定

次にサーバーからGoogleSpreadSheetへアクセスするためにAPIを使用するのですが、その準備をします。

本当は該当のIFTTTが記録するスプレッドシートを公開設定にしてこんな設定しなくて済むのですが、在宅情報は少し機密性の高い情報な気がするのでしっかりとAPIでアクセスします。

まず適当なプロジェクトを作ります。
私の場合はHomeAwayMonitorとしました。
f:id:AKIRA_san:20220412185016p:plain

次にGoogleDriveのAPIを設定します。


f:id:AKIRA_san:20220412193319p:plainf:id:AKIRA_san:20220412193641p:plain

次にサービスアカウントというものを作ります。
このアカウントを使ってデータにアクセスするのが最終的にやりたいことです。

まず、APIとサービスのメニューから認証情報を開きます。
そこで認証情報を作成からサービスアカウントを選んでサービスアカウントを作成します。

f:id:AKIRA_san:20220412194333p:plain

今回はHomeAwayMonitorAccountというアカウント名にしました。

f:id:AKIRA_san:20220412194725p:plain

次にこのアカウントをサーバー上で使用するための鍵を生成します。


f:id:AKIRA_san:20220412194842p:plain
f:id:AKIRA_san:20220412195001p:plain

このJSON鍵を使ってサーバープログラム上からGoogleDriveのファイルにアクセスします。

最後にこのサービスアカウントにIFTTTによって随時情報が追加されているエクセルのファイルを共有してあげます。

f:id:AKIRA_san:20220412195256p:plain

これにてAPIの準備は完了です。

サーバー上でのCSVデータ変換(python

今回のサーバー上のコードの構成としては

  • GoogleDriveからのSpreadSheetの取得(CSV形式)
  • PandasでCSVからデータ変換してJSONとして出力

となっています。

20行目でhomeawaymonitor_APIKey.jsonというファイルを参照していますが、こちらがサービスアカウントで作成した秘密鍵になります。
なのでセキュリティ上安全なDirectoryでこのコードからアクセスできる場所に置いておきましょう。

データ変換内容としてはIFTTTからのデータフォーマットはEnter/Exitの出入りを記録しています。
しかし、私が確認したいのは「どのぐらい家にいるか」なので家にいる状態かどうかが重要です。

そこで、Enter/Exitの時間にステップ的に在宅状態(Home)と外出状態(Away)が切り替わるようにしています。(実際は一秒)
なので状態量としてはEnemurationとしてAway/Homeといた値を使用しています。

あとはこのコードをCrontabで定期的に実行しておけば勝手に変換されたJSONを吐いてくれるのでそれをJavascrptで呼び出してグラフ表示するだけです。

パッケージは私はgoogle-api-python-clientをpipで追加しました。(Pandas等は以前インストールしていたので)




Chart.jsでの在宅状況表示

最後に変換したJSONファイルをJavaScriptでChart.jsを使用してグラフ化します。
基本的には前回の温度モニターと同様の処理になりますが、追加でx軸の変更機能も過去記事同様に実装しています。

aki-lab.hatenadiary.com

特筆するような内容はないのですが、今回は表示する値が数値ではなくHome/AwayといったEnemuration値なのでその設定を37、38行目で行っています。
typeを「category」、labelsを「'Home',''Away'」とすることでEnemuration値を扱うことができます。

実際の表示画面はこんな感じになります。

f:id:AKIRA_san:20220412211956p:plain

ちょっと見づらい気もしますね。(笑)
在宅率とかにした方がいいのか、、、、

今後改善していこうと思います。

せっかくAPI使ってデータをとってきてはいますが、このページ自体にはアクセス制限はかけていないので今後それも設定していこうと思います。

以上で在宅時間モニター作成でした。

実際のコードもこちらに置いておきます。
GitHub - Aki-R/HomeAwayMonitorIFTTT: Monitor your presence in your home by IFTTT.

スマート家電リモコンで自室の温度湿度モニター

今回は私が持っているラトックシステムのスマート家電を使って温度湿度モニターを作りました。

最近在宅勤務が増えて、何かと温湿度の変化を気にする場面が増えました。 ラトックシステムのスマート家電でも温湿度をアプリから確認することができますが、その時の温湿度しか分かりません。 そこで時系列の変化がどうなっているかをグラフでモニターできるようにしたいと思います。

追記

残念ながら、ラトックでのIFTTTのサービス提供が終了します。

aki-lab.hatenadiary.com

システム概要

今回は以下のような流れでグラフ化しています。

  1. 家電リモコンからIFTTTでGoogleスプレッドシートに出力

  2. サーバーで30分おきにスプレッドシートからJSONファイルにPythonで変換出力

  3. WEBページ上でChart.jsを使ってJSONファイルを可視化

Javascriptから直接csvダウンロードできると思うのですが、javascriptは今回初めて書いたので、簡単にできるように一度JSONに変換しています。

家電リモコンからIFTTTでGoogleスプレッドシートに出力

今回使用しているスマート家電リモコンは以下のラトックシステムの家電リモコンになります。

こちらの家電リモコンはIFTTTというサービスが利用できます。

IFTTTとは様々なWEBサービスやアプリ等々をコードを書くことなく簡単に連動させることができます。 このIFTTTが「IF This Then That」が示している通り、あるサービスのある条件をトリガーにして他のサービスを動かすことができます。 結構色々なWEBサービスと連携できるので様々なことができます。

ifttt.com

今回はラトックの家電リモコン専用のAppletをそのまま使用してセンサー情報をスプレッドシートへ出力します。 ExploreでRatocで検索すると簡単に出てきます。 その中から「センサー情報をスプレッドシートへ記録」を使用します。

あとは指示に従えば簡単にスプレッドシートへ出力することができます。 スプレッドシートのフォーマットは左から 日付、時間、温度、湿度、照度となっています。

大して個人情報でもないので公開設定にしてリンクを知っていればだれでもアクセスできるようにします。 こうすると後でアクセスるときにスプレッドシートAPI等使わずに済むので簡単なので。

サーバーで30分おきにスプレッドシートからJSONファイルにPythonで変換出力

つぎにスプレッドシートをCSVで取得してJSONファイルに変換します。 今回はサーバー上でpythonスクリプトをcrontabで30分おきに実行して変換します。

変換するPythonスクリプトは以下です。

まずCSVでダウンロードするために、スプレッドシートのURLの最後に「export?gid=0&format=csv」を追加します。 こうすることでCSVでダウンロードすることができます。

今回はPandasのライブラリを使って変換、及び、JSONで出力しています。

時間はこのコードではエポックミリ秒で出力されます。

次にこのPythonスクリプトをCrontabで30分おきに実行します。 以下のコマンドをターミナルで実行してcrontabの設定を編集します。

sudo crontab -e

以下の文を追加します。

*/30 * * * * python3 /(PATH)/RoomConditionMonitor/RoomConditionMonitor.py

これで30分おきに実行されます。

WEBページ上でChart.jsを使ってJSONファイルを可視化

最後にWEBページで表示できるようにします。

今回はパッとググって出てきたChart.jsというライブラリを使用します。

www.chartjs.org

サンプルプログラムを参考に、表示するためのJavascriptのコードを書きました。

今回はJSONの読み込みのためにJQueryのライブラリ、 グラフ表示のためのChart.jsのライブラリ、 今回は時系列のデータをx軸に使用しているため、正しく表示するためにMoment系のライブラリ等を読み込みこんでいます。

<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@^3"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@^2"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>

これですべて完了です。

実際に設置したページにアクセスしてみると、以下のようになっています。

時系列で温湿度が分かるので、寝ている間やエアコンのつけ始め、加湿器を起動したとき等の影響が手に取るように分かります。 このデータを参考にエアコンの設定を変えたり、加湿器をつけるタイミング等を快適に過ごせるように活用していこうと思います。

今度はCO2センサーも追加して換気や外出タイミングの参考にしたいですね。 あと、気圧計もあると低気圧頭痛等の判断に使えるので便利そうですよね。

以上、自室の温湿度モニターづくりでした。

ARKサーバーを自動監視し再起動できるようにPythonでスクリプトを書く。

追記

ARKサーバーは最終的にはLinuxのサービス化させて自動監視・再起動できるようにしました。
以下の記事参照。
aki-lab.hatenadiary.com




こんにちは。

最近レンタルVPSを借りてリモートのサーバーでARKをプレイしているのですが、時々メモリ不足かなにかでARKサーバーが勝手に落ちてしまうことがありました。

時々確認してARKサーバーソフト再起動してをいたのですが面倒くさいので自動で定期的に監視して実行するようにPythonスクリプトとCrontabを使います。

作ったPythonスクリプトはこちら。

基本的にはsubprocessを使ってシステムコマンドをpythonから実行してARKの状態を監視、及び、再起動しています。

11行目のtop -n 1で現時点のプロセス一覧を取得。
その一覧にARKのプロセスであるShooterGamesの文字列があるかどうかを確認します。

なぜかプロセス取得時にプロセス名が一部分しか取得できなかったので「Shoot」の文字列だけで確認しています。

あとはプロセスの実行状態に合わせて、実行されていなければ再起動用のシェルスクリプトを実行して再起動します。

ここでのシェルスクリプト相対パスではなく絶対パスで定義しておくとcrontabで実行してもちゃんと動いてくれます。

次にcrontabで定期的にこのpythonスクリプトを実行するように設定します。
以下のコマンドでcrontabの設定を変更します。

crontab -e

勝手にテキストエディタが起動して編集できるので15分ごとに実行するように以下のように設定します。
作ったpythonスクリプトのパスを指定してください。

*/15 * * * * python3 /home/user/python/ARK_Server_Monitor/ARK_ServerMonitor.py

これであとは勝手に定期的に実行されるのでなにかの事情でARKが落ちても勝手に再起動してくれます。

Raspberry Pi で30分毎にPythonスクリプトを実行してMySQLに書き込む

先日、IPhoneがLANに接続されているかを確認し、状態をMySQLデータベースに書き込むコードを作りました。
Raspberry Pi でLAN内のIPhoneを監視して在宅・外出の状態をSQLサーバーにアップロード - あきらぼ

今回はこのコードを30分毎に自動的に実行されるようにします。
そのためにLinuxにおいて定期的にコマンドを実行するためのcrontabを使用します。
crontab - Wikipedia

crontabで実行するコマンドと時間をスケジュールするためには以下のコマンドを使用します。

crontab -e

するとテキストエディタでスケジューリングとコマンドの設定ファイルが開かれます。
初期設定では恐らくすべて「#」でコメントアウトされていると思うのですが、ここに以下の二行を追加します。

0 */1 * * * python /home/pi/Python/HomeAwayMonitor/homeaway.py
30 */1 * * * python /home/pi/Python/HomeAwayMonitor/homeawa.py

一行目が毎時0分に指定のコマンド(Pythonコード)を実行
二行目が毎時30分に指定のコマンドを実行
という意味合いになっており、結果30分おき、0分と30分に指定したPythonコードが実行されるという設定です。

実際に指定したコードが30分おきに実行され、データベース書き込まれているか確認してみます。

+----+---------------------+-------+
| id | date                | state |
+----+---------------------+-------+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 70 | 2022-01-04 04:00:07 | Home  |
| 71 | 2022-01-04 04:30:07 | Home  |
| 72 | 2022-01-04 05:00:08 | Away  |
| 73 | 2022-01-04 05:30:07 | Home  |
| 74 | 2022-01-04 06:00:07 | Away  |
| 75 | 2022-01-04 06:30:07 | Away  |
| 76 | 2022-01-04 07:00:07 | Away  |
| 77 | 2022-01-04 07:30:08 | Home  |
| 78 | 2022-01-04 08:00:07 | Away  |
| 79 | 2022-01-04 08:30:08 | Home  |
| 80 | 2022-01-04 09:00:08 | Away  |
+----+---------------------+-------+

問題なく、30分おきに実行されています。
しかし、ここで家にいるはずなのにいないと判定されてしまっています。
これはIPhoneがスリープ状態になるとpingすら通さなく、ARPコマンドにも応答しないのが原因のようです。
どうやらhping3でUDPでパケットを送るといiPhoneを起こせるようなので、今度試してみようと思います。

Raspberry Pi でLAN内のIPhoneを監視して在宅・外出の状態をSQLサーバーにアップロード

最近、仕事やら出張やら旅行やら遊びやらで一体どれくらい自宅が稼働しているのかを把握するために、Raspberry Piで在宅/外出をモニタするシステムを作ろうと思います。
使用しているIPhoneがLANに接続されているかどうかで在宅・外出を判断するシステムとします。
今回は前回セットアップしたSQLサーバーにIPhoneがLAN内に接続されているかどうか(在宅中か外出中か)の状態をアップロードするコードをPythonで書きます。

まず、SQLサーバーのセットアップはこちらの記事を参照。
RaspberryPiでSQLサーバー構築 - あきらぼ

また前準備として、今回はLAN内にIPhoneがいるかどうか確認するのにarp-scanコマンドを使用するのでインストールする必要があります。(下記記事参照)
Raspberry Pi でLAN内のIPアドレス一覧表示 - あきらぼ

次に今回Pythonからデータベースへの書き込みをするのでPythonのMySQLdbのパッケージをインストールする必要があります。(下記記事参照)
Raspberry Pi でPythonのMySQLClientをインストール - あきらぼ

そして今回のコードになります。

# -*- coding: utf-8 -*-

import MySQLdb
import time
from enum import Enum
import subprocess

class State(Enum):
    Home = 0
    Away = 1

if __name__ == "__main__":

    # Get LAN State to check existence of IPhone
    arp_result = subprocess.getoutput('sudo arp-scan -I eth0 -l')
    # Show arp-scan result
    print(arp_result)
    # Check if IPhone MAX adress is in LAN
    MacMatch = arp_result.find('xx:xx:xx:xx:xx:xx')
    if MacMatch == -1:
        CurrentState = State.Away
    else:
        CurrentState = State.Home
    
    # Connect to MySQL server
    connector = MySQLdb.connect(host="localhost", db="homeaway", user="user_homeaway", passwd="pass_homeaway", charset="utf8")
    cursor = connector.cursor()
    
    sql = u"insert into homeaway_table(`id`,`date`,`state`) values(0,now(),'%s')" % CurrentState.name 
    cursor.execute(sql)
    connector.commit()
    
    cursor.close()
    connector.close()
    
    #Show Current State
    print(CurrentState.name)

基本的にはarp-scanの結果から該当するMACアドレスがあるかを参照してそれに応じてHome(在宅)、Away(外出)をデータベースに送るようにしています。
今回はSQLサーバーもPython実行もRaspberry Pi になるので、localhostとなっています。

コードはGitHubにも置いてあります。
GitHub - Aki-R/HomeAwayMonitor: Monitor existence of certain device in LAN and send the status to SQL.


実際にSSH経由で実行してみます。

python homeaway.py

f:id:AKIRA_san:20220102125836p:plain

実行は問題ありません。
実際にデーターベースの書き込んだTableを見てみます。

MariaDB [homeaway]> SELECT * FROM homeaway_table;
+----+---------------------+-------+
| id | date                | state |
+----+---------------------+-------+
|  1 | 2022-01-02 12:10:19 | Away  |
|  2 | 2022-01-02 12:50:37 | Home  |
+----+---------------------+-------+
2 rows in set (0.003 sec)

問題なく書き込まれていますね。

今回はこれで終了です。

次はこのコードを一定期間(30分毎)に実行するのとデータベース上の情報をHTTPサーバー上で可視化しようと思います。

2021/01/06 追記
こちらIPhoneはスリープ(画面オフ)の状態になってしまうとWiFiをスタンバイ状態にしてしまい、ARPにも応じないようです。
スタンバイ状態でもBonjour用のポート(5353)が開いておりそこにUDPでパケット送るとWiFiが復帰するという記事を見つけたのですが、毎回復帰してくれるわけではないようです。

参考までにやり方ですが、hping3のパッケージを使用します。
デフォルトではインストールされていないので、まずこれをインストールします。

sudo apt intall hping3

次にUDPで5353ポートに3パケットを送ります。

sudo hping3 -2 -c 3 -p 5353 -i u1  (iPhoneのIPアドレス)

これでiPhoneWiFiが起きるはずなのですが、私の場合はうまくいきませんでした。

次回、WiFiではなくBluetoothで在宅モニターを行ってみようと思います。