fc2ブログ

OpenCV AI KITで遊ぶ(1)

 昨年の夏頃だったと思いますが、ネット記事OpenCV AI KIT(OAK)というクラウドファンディングで資金調達しているLuxonisという会社のプロジェクトがありましたので、投資しました。クラウドファンディングで投資をしたのは初めてでしたが、OpenCVは昔から使っていたこともあり、愛着もあったので、即断即決でした。
 世界中から投資が集まり、投資額は日に日に増加して行ったと思います。投資の際に完成品を安価に購入できるとのことで、OAK-1を99ドルでエントリしました。(最終的には送料が加算されて119ドル:約13,000円)。ちなみに現在の小売価格は199ドルでした。

 すっかりこの存在を忘れていた今月、DHLで届け物があり、確認すると、このOAK-1でした。中身はカメラ本体、USBケーブル、レンズ拭きとカード2枚のみ。カードの1枚にセットアップ方法のURLの案内がありました。OAK-1_210124.png 早速、URLの内容を元に、Macでセットアップを開始。年末に届いたM1チップのMacはまだ何かと問題がありそうなので、無難なIntelチップのMacBook Airで行いました・・・が、セットアップの時に、XcodeのCommand Line ToolsとHomebrewがエラーを吐き、結局これらを入れ直さないと正常にセットアップできませんでした・・。

 セットアップを終えて、デモプログラムを動かしてみました。車で近所に出かける予定がありましたので、早速MacBook AirとOAK-1を車の中に持ち込み、録画ON。あいにくの雨でしたが、車(特に横方向から)は動画でも正しく認識しているようでした。正面は認識が難しい感じ・・(さらに学習が必要?)。CarOK1_210124.pngCarOK2_210124.png車のワイパーが動くと、なぜかBoatと認識されます。このような画像が学習されているということなんでしょうね。BoatNG_210124.png実際に利用する際はそれなりの学習、チューニングが必要ですね。

休日に遊べるアイテムが増えました。マニュアルを読んで、何ができそうか、また調べてみようと思います。
スポンサーサイト



M1チップMacでVisual Studio 2019を動かす

 年末にM1チップのMac miniを勢いで購入しましたが、その後あまり使いこなせていませんでした。また、M1チップに対応していないアプリもあり、Rosettaを利用すれば従来のIntelプロセッサで動作するアプリも動かすことができるなど「これから感」が満載です。それを楽しんでいるディープなMacユーザも多いようですが・・。そういう中でネット上では次期のMacのM2チップの話題が出ています。ちょっと購入を急ぎ過ぎたかも知れません・・。

 日々良く利用するアプリのPythonやRはセットアップでき、問題なく動作しています。Dockerは対応途中でBootcampは今後なくなるような記事を見ました。理想は1台のPCで必要な時、気分を変えたい時にOSを切り替えて使いたいのですが直近は無理そうですね。

 使うアプリでたまに必要になるのは.NETのC#でVisual Studioを使いたくで、今はAzureにVMを立てて利用している状態です。頻度は少ないですが・・。今回、このMac miniに環境構築できないかなと思いながら情報を探していると、あるサイトにParallels Desktopというアプリを使ってWindows10のArm版を利用できることが分かりました。

 早速、試してみるとうまくいきました。ネットも普通につながりますし、フルスクリーンにするとMacが動いていたことも忘れそうです。デフォルトが英語版だったので日本語のパッチを当てました。起動したWindows10の仕様です。プロセッサは2個、実装メモリは3GBでした。ちなみに元々のMac miniは8コアでメモリ8GBです。M1_Win10_1_210116.pngM1_Win10_2_210116.pngM1_Win10_3_210116.png
Visual Studio2019も無事にインストールでき、プログラムも問題なく動作しました。M1-Mac_VS2019_210116.png このParallels Desktop、Bootcampよりはるかに便利ですね。しばらく遊んでみます。

ベイジアンネットワークを学ぶ(3)

 今回は前回前々回に手計算した内容をRで実装します。Pythonでも良かったのですが、Rの方が参考資料が多く、手っ取り早く実装できそうだったので選びました。
 実装したRのコードは以下の通りです。
library(bnlearn)

# Bayesian network
dag = model2network("[C][S|C][R|C][W|S:R]")
plot(dag)

# Probability
C.lv = c("F", "T")
C.prob = array(c(0.50, 0.50), dim = 2, dimnames = list(C = C.lv))
S.lv = c("F", "T")
S.prob = array(c(0.50, 0.50, 0.90, 0.10), dim = c(2, 2), dimnames = list(S = S.lv, C = C.lv))
R.lv = c("F", "T")
R.prob = array(c(0.80, 0.20, 0.20, 0.80), dim = c(2, 2), dimnames = list(R = R.lv, C = C.lv))
W.lv = c("F", "T")
W.prob = array(c(1.00, 0.00, 0.10, 0.90, 0.10, 0.90, 0.01, 0.99), dim = c(2, 2, 2), dimnames = list(W = W.lv, S = S.lv, R = R.lv))
cpt = list(C = C.prob, S = S.prob, R = R.prob, W = W.prob)

# Model fit
survey = custom.fit(dag, cpt)

# Prediction
N = 2000
temp = array(0,N)

# P(C=T|W=T)
for (i in 1:N) {
temp[i] = cpquery(survey, event = (C == "T"), evidence = (W == "T"))
}
print(paste("P(C=T|W=T) =", mean(temp)))

# P(C=T|R=T)
for (i in 1:N) {
temp[i] = cpquery(survey, event = (C == "T"), evidence = (R == "T"))
}
print(paste("P(C=T|R=T) =", mean(temp)))

# P(S=T|R=T)
for (i in 1:N) {
temp[i] = cpquery(survey, event = (S == "T"), evidence = (R == "T"))
}
print(paste("P(S=T|R=T) =", mean(temp)))

# P(W=T|R=T)
for (i in 1:N) {
temp[i] = cpquery(survey, event = (W == "T"), evidence = (R == "T"))
}
print(paste("P(W=T|R=T) =", mean(temp)))
 実行結果は以下の通り。
 5行目のプロットはこんな感じになりました。線がクロスしていますが、前回、前々回と議論してきたモデルです。BayesianNetwork_Grass_R_plot_210111.png 8〜16行目は、確率の値を代入し、19行目でモデルフィットを行っています。22行目以降は手計算で行った条件付き確率を求めています。計算はcpquery関数を使っていますが、この関数は以下の注意点がマニュアルにありましたので、2,000回計算させて、平均値を求めました。

「cpqueryとcpdistの両方ともモンテカルロ粒子フィルタに基づいているため,シミュレーションのノイズの影響で,実行によってはわずかに異なる値を返す可能性があることに注意してください.」
P(C=T|W=T) = 0.575912086190798(手計算:0.5758)
P(C=T|R=T) = 0.799937096528357(手計算:0.8)
P(S=T|R=T) = 0.179835101789838(手計算:0.18)
P(W=T|R=T) = 0.916275204803596(手計算:0.9162)
 簡単に条件付き確率を求めることができたので、拍子抜けした感がありますが、変数(ノード)が増えると、さすがに手計算では無理ですね。Rで簡単に実装できることが分かりましたので、何か別のテーマを検討してみようと思います。

ベイジアンネットワークを学ぶ(2)

 前回の続きで芝生が濡れているかの事例で、雨が降ったというエビデンスがある場合を考えます。はネット上にあった情報を参照させていただきました。BayesianNetwork_Grass1_210111.png
 まず、①の矢印の逆の「雨が降ったというエビデンス」のある時の雲が出る確率P(C=T|R=T)を以下の式から求めます。
 P(C=T|R=T) = P(C=T, R=T) / P(R=T)
前回と同じ方法で求めましたが、計算式を書くのが面倒なので表計算ソフトで計算させました。BayesianNetwork_Grass2_210111.png結果(事後確率)は80%となり、事前確率の50%よりも大きくなりました。

 次に、②の矢印の方向で「雨が降ったというエビデンス」のある時のスプリンクラーが動作する確率P(S=T|R=T)を以下の式から求めます。
 P(S=T|R=T) = P(S=T, R=T) / P(R=T)BayesianNetwork_Grass3_210111.png元々のスプリンクラーが動作する確率(事前確率)P(S=T)は以下の通り30%なので、BayesianNetwork_Grass4_210111.png雨が降ったというエビデンスにより、確率は30%から18%に減少します。

 最後に③の矢印の方向で「雨が降ったというエビデンス」のある時の芝生が濡れている確率P(W=T|R=T)を以下の式から求めます。
 P(W=T|R=T) = P(W=T, R=T) / P(R=T)BayesianNetwork_Grass5_210111.png元々の芝生が濡れている確率(事前確率)P(W=T)は以下の通り65%なので、BayesianNetwork_Grass6_210111.png雨が降ったというエビデンスにより、確率は92%に増加します。

 芝生が濡れているかという結果の主要因を推論する上で、原因候補の中からエビデンスが得られた場合、それを利用して結果の裏付けにアプローチできる点でベイジアンネットワークは有効な手段なのかもしれません。

 次回はこの芝生が濡れているかのモデルと推論計算をRで実装したいと思います。

ベイジアンネットワークを学ぶ(1)

 因果分析を調べている中で「ベイジアンネットワーク」に行き当たりました。
名前は聞いたことがあったのですが、詳しく知らなかったのでネット情報を元に勉強しました。その備忘録です。

 まず、Wikipediaによると、ベイジアンネットワーク(Bayesian network)は、以下の通り説明されています。
  ① 因果関係を確率により記述するグラフィカルモデルの1つ。
  ② 複雑な因果関係の推論を有向非巡回グラフ構造により表す。
  ③ 個々の変数の関係を条件つき確率で表す確率推論のモデル。
グラフィカルモデルとベイジアンネットワークは因果の有無、有向か無向の違いによるもので、以下の図のイメージです。BayesianNetwork1_210111.pngまた、因果関係は「条件付き確率」を用いて以下の通りに表します。BayesianNetwork2_210111.pngさらに、条件付き確率の式からは、ベイズの定理(ベイズルール)が導き出せます。BayesianNetwork3__210111.png以上は、教科書やネット上に書いてある内容ですが、いまいちピンとこなかったので、具体例を探すことにしました。

 ベイジアンネットワークの有名な例で「芝生は濡れているか」がありましたので、ネット情報を元に考えてみました。BayesianNetwork4_210111.pngこの図は芝生が濡れているか(結果)に対して、「原因」としてのスプリンクラーの動作有無、雨の有無を考えたものです。また、スプリンクラー、雨の「結果」には、雲が出ているか否かの「原因」が影響を与えていることを示しています。
 このような原因・結果の関係の中で、原因から結果への流れは頭にスムーズに入ってきますが、例えば「芝生が濡れていた時に雲が出ていた確率は?」と聞かれた場合は、結果から原因の方に思考転換をしなくてはなりません。その解法を与えてくれるのが、ベイジアンネットワークです。

 早速、この問題について、手計算で解いてみようと思います。
計算は単純ですが、変数(ノード)が増えると面倒ですね。manual_calc1_210111.pngmanual_calc2_210111.png最終的に、芝生が濡れていたというエビデンスがある時の雲が出ていた確率は58%となります。芝生が濡れていたというエビデンスがない時は50%なので確率が大きくなったということですね。
 次回もこの芝生の例を使って計算をしてみます。

M5StickCとGPSユニットで遊ぶ

 先日のブログでお話した現実逃避グッズのM5StickCM5Stack用GPSユニットAT6558を接続して遊んでみました。
 M5StickC本体とGPSユニットは4心のGroveケーブルで接続しました。GPSunit_210110.pngArduinoのコードはネット上にあるものを一部修正して利用しました。センサとの通信はUARTです。
#include <M5StickC.h>
#include <TinyGPS++.h>

HardwareSerial GPSRaw(2);
TinyGPSPlus gps;

int cnt=0;

void setup() {
M5.begin();
M5.Lcd.setRotation(3);
GPSRaw.begin(9600, SERIAL_8N1, 33, 32);
}

void loop() {
M5.Lcd.setCursor(0, 0, 2);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.printf("### GPS TEST %d\n", cnt++);
while(GPSRaw.available()>0) {
if(gps.encode(GPSRaw.read())) {
break;
}
}
if(gps.location.isValid()) {
M5.Lcd.printf("LAT:%.6f\n", gps.location.lat() );
M5.Lcd.printf("LNG:%.6f\n", gps.location.lng() );
M5.Lcd.printf("ALT:%.2f\n", gps.altitude.meters() );
} else {
M5.Lcd.printf("INVALID\n");
}
delay(5000);
}
 M5StickCにコードを書き込んで、プログラムは動き出すのですが、正常に緯度、経度、標高がLCD画面に出力されるまで結構時間がかかりました。ずっと「INVALID」が出ているので、故障しているのではないかと疑うほどです。忘れた頃にGPSユニット本体のLEDが点滅し始めて、あれっと思った後に、画面表示されて、一安心。

 それでは、休日の散歩に一緒に出かけることにしましょう。最近はかなり寒い日(朝は氷点下)が続きますが、昼間はまだマシです。測定値を本当はSDカードに常時書き込みしたかったのですが、M5StickCにはSDカードのユニットがついていないので、面倒ですが、散歩ルートの要所要所で携帯カメラで撮影して値を記録することにしました。

 測定された緯度・経度のマップへのプロットはfoliumライブラリを用いました。
import folium
import pandas as pd

positions = pd.DataFrame({
'position': ['1', '2', '3', '4', '5', '6', '7', '8', '9'],
'latitude': [35.xxx, 35.xxx, 35.xxx, 35.xxx, 35.xxx, 35.xxx, 35.xxx, 35.xxx, 35.xxx],
'longtude': [136.xxx, 136.xxx, 136.xxx, 136.xxx, 136.xxx, 136.xxx, 136.xxx, 136.xxx, 136.xxx],
})

map = folium.Map(location=[35.xxx,136.xxx], zoom_start=16)

for i, r in positions.iterrows():
folium.Marker(location=[r['latitude'], r['longtude']], popup=r['position']).add_to(map)

map.save("map_position.html")
 結果がhtmlファイルで出力されます。そのキャプチャ画像は以下の通りで、散歩コースと完全一致。結構いい精度で測定できるようです。map_210110.png 今度は、SDカードが付いているM5Stack Core2でデータ保存しながら散歩しようと思います。

Mac miniを買う

 大晦日もあっと言う間に過ぎ、年が変わってしまいました。
新年明けましておめでとうございます。今年もよろしくお願い申し上げます。

 昨日(12/31)は休暇とは言え、自宅で仕事をせざるを得ない状況で、気分も冴えない状態でした。ただ、この1年なんとか頑張って来れた自分へのご褒美に購入した「Mac mini」が届きました。1/8の納品予定でしたが速い到着でした。在庫があったのかな??
 今日も正月とは言え、午前中は仕事をやっていたので、午後からようやく箱を開けることができました。

 段ボールの箱を開けると、いつものAppleの箱で「Mac mini」の文字を確認。Mac_mini1_210101.png購入したのは、新しいM1チップタイプのメモリ8GBのモデルで72,800円(税別)のもの。Intelチップのものもありましたが、価格が割高でスペックもイマイチと思いました。また、新しいものを試してみたいこともあったのでM1チップタイプを購入しました。

 サイズは19.7cm角で厚みは3.6cm。コンパクトな筐体です。重さも1.2kgで軽いです。Mac_mini2_210101.png裏面はこんな感じで、Mac_mini3_210101.pngサイドはこんな感じです。Mac_mini4_210101.pngEthernet-1口、USB-2口、Thunderbolt/USB4-2口、接続可能です。ディスプレイはHDMIで接続します。

初期セットアップを終え、起動後、スペックの確認です。OSは先日のブログでケチがついた「macOS Big Sur」です。BigSur1_210101.pngチップは確かに「Apple M1チップ」と記載されています。BigSur2_210101.pngメモリは8GBでコア数は8個です。確かにサクサクと動きます。今まで使っていた5年戦士のMacBook Airのスペックがそんなに良くなかったので、なおさら速く感じました。

 macOS Big Surは何かとまだまだ不具合がありそうなので、早急に11.1にUpdateして、通常利用するソフトウェアをセットアップした後に、即Time Machineでバックアップしました。これで、万が一の時に元に戻せますね。BigSur3_210101.png
 パソコンが速いせいか、セットアップはすぐに終わりました。今後、ハイスペックを味わうために、負荷の多い処理をバリバリ行い、使いこなしていこうと思います。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: