佐藤さとる

佐藤さとる

梶研 [伊達巻成功 & GCN, ST-GCN完全に理解した]

2024年04月16日

伊達巻成功 & GCN, ST-GCN完全に理解した

出席率

スケジュール

短期的な予定

長期的な予定

進捗報告

目的

料理中の動作を mocopi を使ってセンシングする。

このデータから最終的に位置推定を行う。

センシングした

完璧でした

生産者の顔

IMG_6565.jpg (988.8 kB)

フライパン買ってください

横幅がもう少し広いフライパンが欲しい

動作認識

動画からではないサンプルコードが欲しい

https://colab.research.google.com/github/machine-perception-robotics-group/MPRGDeepLearningLectureNotebook/blob/master/15gcn/03actionrecognitionST_GCN.ipynb

よく分からないけど学習が進んだ

# Epoch: 1 | Loss: 0.0359 | Accuracy: 15.0500
# Epoch: 2 | Loss: 0.0345 | Accuracy: 20.2500
# Epoch: 3 | Loss: 0.0338 | Accuracy: 22.5000
# Epoch: 4 | Loss: 0.0327 | Accuracy: 26.2500
# Epoch: 5 | Loss: 0.0312 | Accuracy: 29.1500
# Epoch: 6 | Loss: 0.0298 | Accuracy: 32.5500
# Epoch: 7 | Loss: 0.0285 | Accuracy: 36.1500
# Epoch: 8 | Loss: 0.0265 | Accuracy: 41.6000
# Epoch: 9 | Loss: 0.0237 | Accuracy: 49.0500
...

とても時間がかかったので10回目で止めた

グラフを表示してくれた

斜め (縦と横の軸が同じところ) が濃いほど正確ぽい

image.png (35.3 kB)

何をしているか追ってみる

追ってみたけど全く分かりませんでした.

一旦GCNの理解を頑張る

image.png (10.8 kB)

入力値を生成

仮でランダムに生成する

X = np.random.randn(num_node, in_channels) + 1

TODO: 動作認識ではこの入力値がどう変わるのか

隣接行列を生成

E = [[0, 1], [0, 2], [0, 4], [1, 2], [2, 3]]
# 向きを考慮しないために逆行列を足す
reversed_E = [[j, i] for [i, j] in E]
new_E = E + reversed_E
A = edge2mat(new_E, num_node)

畳み込み

$$

[1,1,1,0,1]

\left[

\begin{array}{c}

v_1 \\\\

v_2 \\\\

v_3 \\\\

v_4 \\\\

v_5 \\\\

\end{array}

\right]

= v1 + v2 + v3 + v5

$$

隣接している部分だけ取り出すみたいな

その結果が右側

(左の X はランダムのため変化しています)

image.png (11.6 kB)

ノードによる偏りがある

TODO: なぜ偏りが良くないのか

偏りの解消

平均を使うと多少解消される

$$

\tilde{\mathbf{D}}^{-1}\tilde{\mathbf{A}}\mathbf{X}

$$

image.png (11.6 kB)

実際は正規化するべき

$$

\tilde{\mathbf{D}}^{-\frac{1}{2}}\tilde{\mathbf{A}}\tilde{\mathbf{D}}^{-\frac{1}{2}}\mathbf{X}

$$

もっと調べる

畳み込みは 特定のノード に隣接するノード間でいい感じに計算するぽい

だから 隣接行列 を作って掛け算していた

動作認識において 隣接行列 は 関節間 の接続を入れればいいぽい

入力は...

difference_of_cnn_and_gcn.png (102.9 kB)

https://disassemble-channel.com/deep-learning-gcn/

↓ をみた感じ、人を正面から見た時の各関節の座標を持っているぽい

fig, ax = plt.subplots(2, 3, figsize=(16.0, 6.0) )
for i in range(6):
    r = i // 3
    c = i % 3
    # エッジを描画
    for e in E:
        ax[r,c].plot([X[i, e[0], 0], X[i, e[1], 0]], [X[i, e[0], 1], X[i, e[1], 1]], "c")
    # ノードを描画
    ax[r,c].scatter(X[i, :, 0], X[i, :, 1], s=7)
    # その他設定
    ax[r,c].set_xlim([0, width])
    ax[r,c].set_ylim([0, height])
    ax[r,c].set_aspect('equal', 'box')
    ax[r,c].set_xticks([])
    ax[r,c].set_yticks([])
    ax[r,c].invert_yaxis()

https://zenn.dev/hash_yuki/articles/3b0f782ccffa54

入力値は、腰(ROOT) を原点とした各関節の座標とする?

やること

進路関係

余談

歓迎されてきました

下校中

05648D2E-A88F-429E-8785-6FAD8D1124E3_1_105_c.jpeg (268.5 kB)

渋谷

IMG_6531.JPG (7.1 MB)

下北沢コメダ

IMG_6533.JPG (3.4 MB)

弊社オフィス

IMG_6536.JPG (4.8 MB)

ボザロの聖地

IMG_6539.JPG (3.0 MB)

セカオワの聖地

IMG_6541.JPG (3.4 MB)

帰宅

1516A0DE-2D2D-4077-9A77-575F06B7E5B4_1_105_c.jpeg (272.7 kB)

歓迎しました

いちねんせいたくさん

87197624-57D9-42A6-9C5B-055D61904401_1_105_c.jpeg (314.5 kB)