狠狠撸

狠狠撸Share a Scribd company logo
1
第一回 AI Code Review
日程:2018年04月24日(火)19:30~21:30
協賛:forkwell(株式会社grooves様)、テモナ株式会社様
2
人工知能のコードを読んで
ハックして遊びます
目的
? 人工知能(パターン認識/機械学習)のソースコードの解読方法を学び、
共有する
? プログラムの改良や新しい応用を検討する
? 知的好奇心/探究心を追求して楽しむ
3
AI Code Review
目的
? 人工知能(パターン認識/機械学習)のソースコードのレビューを楽しむ
ルール
? 「サンドバッグ枠」の登壇者はソースコードの内容を発表?説明する
? 「ハッカー枠」のレビュアーは発表内容に関して質問する
? 「コメンテータ枠」のコメンテータは第三者視点でコメント?解説する
? 「観客枠」の来場者は、レビューの様子を観戦する
4
タイムテーブル
5
スポンサー
forkwell(株式会社grooves様) テモナ株式会社様
https://forkwell.com/ https://temona.co.jp/
6
ジェスチャー認識?予測プログラム
2018年04月24日(火)
神 谷 亮 平
7
自己紹介
▼開発経験
?アルゴリズム/ライブラリ開発(C / C++、Python)
?組み込みソフトウェア開発(C)
?WEBアプリケーション開発(Java、 PHP 、JavaScript、 Python、Go)
?Windowsデスクトップアプリケーション開発(C#)
株式会社LABBIZ 代表取締役
ソフトウェアエンジニア
▼略歴
時計メーカー研究開発職 ? データ分析会社新規事業開発職
? IoTスタートアップ研究開発職 ? 創業
神谷 亮平
▼その他
AI Code Hackers(人工知能のコードをハックする会)主催者
8
【一般的な意味】
ジェスチャーとは、他の人に何かを伝えるために
する身振り手振りのこと(Wikipedia日本語版より)。
【今回の定義】
連続性のある2次元平面上の一連の動き。
一筆書きの軌跡のこと。
ジェスチャーとは
9
ようするに......
10
または......
センサデータ ?(変換)? 二次元点列 ?(認識)? アクション
11
ジェスチャー予測?認識
プログラムの開発
12
ジェスチャー予測?認識プログラム
13
LSTMで16点先まで予測し、MLPで認識。
ジェスチャー予測?認識
14
①データを用意する
②予測?認識器を作る
③予測?認識器を使う
開発の流れ
15
①データを用意する
16
データセットの作成
1. ジェスチャーパターンを入力?記録するプログラム
gesture_painter.py
2. ジェスチャーパターンをデータ拡張?整形するプログラム
make_datafiles.py
3. 各データの索引を作るプログラム
make-points-dataset.sh
make-spoints-dataset.sh
1 => 2 => 3 の順に実行
17
②予測?認識器を作る
18
予測器?認識器の学習
1. 予測器(LSTM)の学習?評価用プログラム
lstm_with_baseshift.py
2. 認識器(MLP)の学習?評価用プログラム
mlp.py
データセットを指定して学習
19
③予測?認識器を使う
20
アプリケーション実行
1. ジェスチャー予測?認識プログラム
gesture_recognizer.py
学習した予測器?認識器を指定して実行
21
コードレビュー
22
gesute_recognizer.py
376. def run(self):
377. self._recognizer = GestureRecognizer(self._config)
378. self._window.mainloop()
379.
380.if __name__ == '__main__':
381. args = get_args()
382. GesturePainter(args).run()
383. sys.exit(0)
GestureRecognizerを
設定して入力待機
コマンドラインオプションを
GesturePainterに渡してrun()実行
23
280.class GesturePainter:
333. def _on_canvas_released(self, event):
334. result_label, _ = self._recognizer.infer(self._points)
335. if result_label is not None:
336. self._result_txt.set("You drew " + result_label)
359. def _on_canvas_dragged(self, event):
360. if self._minx <= event.x and event.x <= self._maxx:
361. if self._miny <= event.y and event.y <= self._maxy:
362. p0 = [self._x, self._y]
363. p1 = [event.x, event.y]
364. points = self._fulfill_interpolation([p0, p1])[:-1]
365. self._points.extend(points)
366. self._x = event.x
367. self._y = event.y
368. if self._recognizer.get_network_type() == 'mlp-with-lstm':
369. self._show_prediction()
370. self._draw_line(p0, p1, color="black", width=2)
gesute_recognizer.py
マウスドラッグを検
知し、軌跡を予測?
描画
マウスリリース時に
ジェスチャー認識
24
gesute_recognizer.py
82. class GestureRecognizer:
254. # recognize a gesture
255. def infer(self, points, stroke_terminal=True):
256. result_label = None
257. result_points = []
268. if not stroke_terminal :
269. tmp_points = self.predict(points)
270. result_points = tmp_points[len(points):]
271. points = tmp_points
272. self._points_buf.set_points(points)
273. self._points_buf.adjust()
274. points = self._points_buf.get_points()
275. result_label = self._mlp.infer(np.asarray(points))
276. if self._labels is not None and result_label is not None:
277. result_label = self._labels[result_label]
278. return (result_label, result_points)
ジェスチャー軌跡予測
ジェスチャー認識
25
gesute_recognizer.py
82. class GestureRecognizer:
254. # predict next points
255. def predict(self, points):
256. tmp_points = self._standardize(points)
257. for i in range(0, self._config.x_input_length, self._config.x_split_step):
258. xin = self._subtract_point_from_points(
259. tmp_points[-self._config.x_input_length:],
260. tmp_points[-1])
261. xout = self._lstm.infer(np.asarray(xin)).tolist()
262. pred = self._add_point_to_points(xout, tmp_points[-1])
263. tmp_points.extend(pred)
264. return self._unstandardize(tmp_points)
点列予測
入力点列の原点移動
出力点列の原点移動
26
何か質問ある?
27
補足①データセット作成
28
ジェスチャーパターンの入力?記録
$ python3 gesture_painter.py
SAVE
A列:X座標 (0 ~ 255)
B列:Y座標 (0 ~ 255)
CSVファイル
(画像はExcelでオープンしたところ)
29
実際に入力?記録したデータ
クラス数:26クラス
パターン数/クラス:10パターン
30
記録データの整理
ORIGINAL_POINTS_DIR/
a/
b/
y/
z/
0-1517153926.csv
0-1517154074.csv
0-1517154217.csv
1-1517153930.csv
1-1517154080.csv
1-1517154219.csv
クラスごとにディレクトリを作り、
パターンを保存
31
データ拡張?整形
$ python3 make_datafiles.py ORIGINAL_POINTS_DIR DATASET_DIR
ORIGINAL_POINTS_DIR/
a/
b/
c/
x/
y/
z/
0-1517153926.csv
0-1517154074.csv
0-1517154217.csv
DATASET_DIR/
0-1517153926-0000.csv
0-1517153926-0001.csv
0-1517153926-0002.csv
a/
points/
sampled_points/
image/
0-1517153926-0000.csv
0-1517153926-0001.csv
0-1517153926-0002.csv
a/
0-1517153926-0000.png
0-1517153926-0001.png
0-1517153926-0002.png
a/
プログラム実行
32
データ拡張?整形
DATASET_DIR/
0-1517153926-0000.csv
0-1517153926-0001.csv
0-1517153926-0002.csv
a/
points/
sampled_points/
image/
0-1517153926-0000.csv
0-1517153926-0001.csv
0-1517153926-0002.csv
a/
0-1517153926-0000.png
0-1517153926-0001.png
0-1517153926-0002.png
a/
点列データ
64点にサンプリングされた
点列データ
画像データ
33
DATASET_DIR/points/以下の点列データ
? 隣接点間の関係の正規化
? 点と点の間を1ピクセル単位で補間 : p[ i + 1 ] = ( p[i].x ± 1, p[i].y ± 1 )
? その後、スケールを右記の通り変更 : -1.0 ≦ x ≦ 1.0, -1.0 ≦ y ≦ 1.0
p[ i – 1 ]
p[ i ]
p[ i + 1 ]
1.0 / 128.0 = 0.0078125
1.0 / 128.0 = 0.0078125
拡大
34
DATASET_DIR/sampled_points/以下の点列データ
? 点列の長さの正規化
? DATASET_DIR/points/以下の点列データを64点にサンプリング
0.192157 -0.57647
0.176471 -0.57647
0.176471 -0.60784
0.07451 -0.6549
-0.00392 -0.6549
-0.03529 -0.67059
-0.26275 -0.67059
-0.29412 -0.6549
-0.35686 -0.59216
-0.38039 -0.57647
-0.41961 -0.52157
-0.45098 -0.48235
-0.50588 -0.39608
-0.55294 -0.38039
-0.56863 -0.34902
-0.60784 -0.3098
-0.64706 -0.23922
-0.69412 -0.15294
-0.69412 0.003922
-0.7098 0.035294
-0.7098 0.294118
-0.67843 0.32549
-0.67843 0.34902
-0.62353 0.403922
-0.60784 0.403922
-0.55294 0.435294
-0.53726 0.435294
-0.48235 0.466667
-0.19216 0.466667
-0.16863 0.45098
-0.12157 0.435294
-0.10588 0.403922
-0.06667 0.380392
-0.05098 0.34902
-0.00392 0.294118
0.011765 0.262745
0.058824 0.239216
0.105882 0.192157
0.152941 0.105882
0.192157 0.05098
0.223529 0.019608
0.247059 -0.01177
0.278431 -0.12157
0.278431 -0.3098
0.294118 -0.33333
0.294118 -0.38039
0.317647 -0.39608
0.317647 -0.22353
0.333333 -0.15294
0.34902 -0.0902
0.411765 0.035294
0.427451 0.082353
0.458824 0.105882
0.47451 0.160784
0.521569 0.223529
0.537255 0.262745
0.584314 0.294118
0.607843 0.364706
0.678431 0.388235
0.709804 0.419608
0.72549 0.45098
0.811765 0.498039
0.866667 0.498039
0.866667 0.482353
64行2列
の点列
データ
ジェスチャー
開始点
ジェスチャー
終了点
サンプリング
長さ不定
の点列
データ
ジェスチャー
開始点
ジェスチャー
終了点
35
? スケールを変えて画像化
? DATASET_DIR/points/以下の点列データのスケールを下記の通り変更して画像化
? 0 ≦ x ≦ 27, 0 ≦ y ≦ 27 (その後、28 pix × 28 pix の画像として保存)
DATASET_DIR/image/以下の画像データ
画像化
点列
データ
ジェスチャー
開始点
ジェスチャー
終了点 0 ≦ x ≦ 27
0 ≦ x ≦ 27
36
データ拡張方法
? 非線形の幾何的な複合変換(以降、データ拡張変換と呼ぶ)を適用
① Gaussianによる空間歪曲
② Homography変換(射影変換)による空間歪曲
Gaussianの中心点をランダムに選択して歪曲
4隅の点を(制限された範囲で)ランダムに移動
① ? ②の順に
各々を適用
37
データ拡張方法
データ拡張変換未適用
1回適用
2回適用
38
データセット索引作成
DATASET_DIR $ ./make-points-dataset.sh
DATASET_DIR $ ./make-spoints-dataset.sh
点列データのデータセット索引ファイルを作成
サンプリングされた点列データのデータセット
索引ファイルを作成
39
点列データセット索引ファイル
? Lサイズデータセット
? grd-points-training-l.csv
? grd-points-validation-l.csv
? grd-points-test-l.csv
? Mサイズデータセット
? grd-points-training-m.csv
? grd-points-validation-m.csv
? grd-points-test-m.csv
? Sサイズデータセット
? grd-points-training-s.csv
? grd-points-validation-s.csv
? grd-points-test-s.csv
A列:点列データファイル
B列:正解クラス番号(a = 0, b = 1, ..., z = 25)
40
サンプリング点列データセット索引ファイル
? Lサイズデータセット
? grd-sampled_points-training-l.csv
? grd-sampled_points-validation-l.csv
? grd-sampled_points-test-l.csv
? Mサイズデータセット
? grd-sampled_points-training-m.csv
? grd-sampled_points-validation-m.csv
? grd-sampled_points-test-m.csv
? Sサイズデータセット
? grd-sampled_points-training-s.csv
? grd-sampled_points-validation-s.csv
? grd-sampled_points-test-s.csv
A列:サンプリング点列データファイル
B列:正解クラス番号(a = 0, b = 1, ..., z = 25)
41
各データセットのサイズ
? 全体サイズ
? 1クラスあたり
? データ拡張変換未適用データ:10パターン
? データ拡張変換1回適用データ:80パターン
? データ拡張変換2回適用データ:640パターン
? 全部(26クラス)で18980パターン
? Lサイズデータセットサイズ
? 学習用データセット:全体サイズの7割
? 検証用データセット:全体サイズの2割
? 評価用データセット:全体サイズの1割
? Mサイズデータセットサイズ
? Lサイズデータセットの半分
? Sサイズデータセットサイズ
? Mサイズデータセットの半分
クラスごとに730パターン
42
補足②予測器の学習?評価
43
入出力データ
? 入力データ
? 現時刻の点の座標を(0, 0)とした、直近の(過去の)
N個の点列の相対位置の時系列データ
? 出力データ
? 次の(未来の)1点の現時刻の点からの相対位置
44
入出力データ
(0, 0)
(0, 0)
マウスのポインタの位置が
常に原点になるように平行移動
45
入出力データ
直近のN点(青色の点列)から
未来の1点(緑色の点)を予測
46
入出力データ
直近のN-1点(青色の点列)と未来の1点(緑色の点)
から、さらに次の未来の1点(黄色の点)を予測
47
入出力データ
N点先まで実行
48
LSTMの学習
直近の64点から次の1点の相対位置を学習
(点列を1点ずつずらして入力)
49
予測精度評価
入力点数 平均二乗誤差
ピクセル単位換算
誤差
16 1.115419×10^-5 0.427493
64 1.079881×10^-5 0.420628
直近の64点から次の1点の相対位置予測を評価
(点列を1点ずつずらして入力)
誤差は1ピクセル以下。
隣接8ピクセルからランダムに選択する
場合の誤差(≒1.54)よりも小さい。

More Related Content

第一回 AI Code Review