空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

Gazebo+ROSのお勉強

Gazebo Tutorial

Gazebo : Tutorials

gazebo_ros_pkgs - ROS Wiki

わかりやすいブログ

Controller と HardwareInterface との間の処理の仕組み(1. ロボットモデルの定義と登録) - Qiita

Controller と HardwareInterface との間の処理の仕組み(2. RobotHWSimのプラグインについて) - Qiita

Controller と HardwareInterface との間の処理の仕組み(3. Controllerについて) - Qiita

Gazebo から ROS のプラグインを呼ぶ処理の仕組み(1. Gazebo起動時のSystemPluginの読込み) - Qiita

ros_controls/ros_controllers の制御の仕組み (position/effort/velocity_controllers の基礎) - Qiita

レポジトリ:Learning_ROS_for_Robotics_Programming_2nd_edition/chapter10_tutorials at hydro-devel · AaronMR/Learning_ROS_for_Robotics_Programming_2nd_edition · GitHub

参考

Gazeboによるマニピュレータのシミュレーション - 研究紹介ページ

Gazebo + ROS で自分だけのロボットをつくる 5. GazeboとROSの連携 - Qiita

gazebo、ros_controlについて - akak1のブログ

No.6-1:GazeboをROSに繋ぐ (ROSの概要 編) - 九州工業大学 CIR-KIT Blog

No.6-2:GazeboをROSに繋ぐ (どのGazebo/ROSのバージョンの組み合わせを使うか 編) - 九州工業大学 CIR-KIT Blog

No.6-3:GazeboをROSに繋ぐ (Gazebo_ros_pkgsをインストールする 編) - 九州工業大学 CIR-KIT Blog

No.6-4:GazeboをROSに繋ぐ (Roslaunchを使う 編) - 九州工業大学 CIR-KIT Blog

No.6-5:GazeboをROSに繋ぐ (GazeboにおけるURDF 編) - 九州工業大学 CIR-KIT Blog

No.6-6:GazeboをROSに繋ぐ (ROSにおけるGazeboのプラグイン 編) - 九州工業大学 CIR-KIT Blog

No.6-7:GazeboをROSに繋ぐ (ROS Control 編) - 九州工業大学 CIR-KIT Blog

No.6-8:GazeboをROSに繋ぐ (ROS Communication 編) - 九州工業大学 CIR-KIT Blog

No.6-9:GazeboをROSに繋ぐ (ROS Plugin 編) - 九州工業大学 CIR-KIT Blog

No.6-10:GazeboをROSに繋ぐ (発展的なROSの統合 編) - 九州工業大学 CIR-KIT Blog

No.7-1:プラグインを書く (Gazebo Plugin 101 編) - 九州工業大学 CIR-KIT Blog

機械学習のお勉強(単層ニューラルネットワーク)

人工ニューロン

神経細胞を2値処理を行う単純なゲートとして表現。

z = w0 * x0 + w1 * x1 + …. + wm * xm and phi(z)={ 1 (z>=0) or -1 (z<0)

これは脳内の一つのニューロンの働き(発火するかしないか)を模倣している。

パーセプトロンの学習規則

  1. 重みを0 or 値の小さい乱数で初期化する
  2. トレーニングサンプルxjごとに以下の手順で実行
    1. 出力値を計算(上記で言う1 or -1)
    2. 重みの更新

重みの更新方法

  1. wj = wj * delta wj <- delta wj = myu * (y - y^) * xj
    1. delta w0 = myu (y - y^)
    2. delta w1 = myu (y - y^) * x1
    3. delta w2 = myu (y - y^) * x2

このように重みすべてが更新されるまでy^は再計算されない。

パーセプトロンの収束性

  1. 2つのクラスが線形分離可能な場合
  2. 学習率が小さい場合

に限られる

ADALINEと学習の収束(Adaptive Linear Neuron)

重みの更新方法がパーセプトロンと異なる

単位ステップ関数ではなく、線形活性化関数に基づいて重みが更新される

目的関数

クラスラベルと計算結果の誤差平方和

J(w) = ½ sum(y - phi(z))2

z = w * x

特徴

線形活性化関数により、微分可能

凸関数出るため勾配降下法を用いて目的関数を最小化する重みをみつけることができる

重みの更新(バッチ勾配降下法)

w = w + delta w

delta w = - myu * sum ( y - phi(z) ) * x

z = w * x

重みの更新はトレーニングデータセットすべてのサンプルに基づいて計算する(バッチ勾配降下法)

パフォーマンスを上げるポイント

特徴量のスケーリング!

X_std = (X - X.mean()) / X.std()

平均を引き、標準偏差で割る。平均0 , 標準偏差を1にする。

 確率的勾配降下法

w = w + delta w

delta w = - myu * ( y - phi(z) ) * x

z = w * x

sumがない分高速に収束させることができる。その分1サンプルの影響を受けるためノイズが多い

また、データが追加されれば随時学習するオンライン学習が可能

ポイント

エポックごとにトレーニングデータをシャッフルして循環を避ける

適応的学習率を使う(ex: myu = a / (iter回数 + b))

ミニバッチ学習

確率的・バッチ勾配降下法の折衷案

すべてをバッチとするわけでなくいくつかを抽出し、ミニバッチとして学習する

ロジスティック回帰(クラス確率のモデリング)

名前とは裏腹に回帰ではなく分類のためのモデル

線形分離可能なクラスに関してのみ有効

logit(p) = log p / (1 - p)
logit(p(y = 1 | x)) = w * x = z
p = phi(z) = 1 / (1 + e^-z) 

p : シグモイド関数

サンプルがクラスに属している確率が予測できる(天気予報や医療診断などに用いられる)

尤度関数

L(w) = PI (phi(z))^y (1- phi(z))^(1-y)

コスト関数

J(w) = sum (-y * log(phi(z)) - (1 - y)* log(1 - phi(z)))

実装

ADALINEのコスト関数を上記に置き換えるだけ

 過学習・学習不足

データに対してモデルが複雑・簡単すぎるときに発生する

過学習をするモデル(偶発誤差):「バリアンス(分散?)が高い」という

学習不足をするモデル(系統誤差):「バイアス(平均?)が高い」という

モデルの汎化誤差 = バイアス2 + バリアンス + ノイズ

バイアスとバリアンスの調整手法(L2正規化)
lambda * || w || ^2 / 2 = lambda * sum(w^2) / 2

TODO:バリアンスとバイアスのトレードオフについて調査

参考: バイアスとバリアンス | Nana-Korobi

参考

第18回 ロジスティック回帰:機械学習 はじめよう|gihyo.jp … 技術評論社

機械学習のお勉強(全体像)

教師あり学習

クラスラベルを予測するための分類

カテゴリデータをインスタンスに割り当てる

連続値を予測するための回帰

予測したい変数:結果変数

予測に使用される変数:説明変数

強化学習

エージェント:環境とのやりとりに基づいて性能を改善するシステム

環境の現在の状況に関する情報には報酬信号が含まれる。

教師なし学習

データ構造を調べることで意味のある情報を取り出すことができる

クラスタリング

大量の情報を意味のあるグループとして構造化する手法

次元削減

教師なし学習のサブフィールド

データからノイズを取り除き、関連する大半の情報を維持したままデータをより低い次元に圧縮する

機械学習のお勉強(DeepPose, OpenPose)

やること

  1. pythonでのcaffe環境構築
  2. OpenPoseを動かしてみる

Caffe Install

設定(GPU)

【Caffe】はじめてCaffeをmakeするまでOn Ubuntu16.04 - 緑茶思考ブログ

Ubuntu 14.04にCaffeをインストール(GPU編) - Qiita

Installing Caffe on Ubuntu (CPU-ONLY) - Chun’s Machine Learning Page

nvcc fatal : Unsupported gpu architecture 'compute_61' · Issue #5141 · BVLC/caffe · GitHub

PYTHON_INCLUDE := /usr/include/python2.7 \
/usr/lib/python2.7/dist-packages/numpy/core/include

to this:

PYTHON_INCLUDE := /usr/include/python2.7 \
/usr/local/lib/python2.7/dist-packages/numpy/core/include

設定(CPU only)

configをcpu onlyに変更

Caffeでニューラルネットワークを試してみる - Sample Space of BB-Club

Ubuntu14.04にCaffeをインストール(CPUモード) - Qiita

OpenPose(Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields)

論文:https://arxiv.org/abs/1611.08050

プレゼン資料:http://image-net.org/challenges/talks/2016/Multi-person%20pose%20estimation-CMU.pdf

Git : GitHub - ZheC/Realtime_Multi-Person_Pose_Estimation: Code repo for realtime multi-person pose estimation in CVPR'17 (Oral)

Git : GitHub - CMU-Perceptual-Computing-Lab/openpose: OpenPose: A Real-Time Multi-Person Keypoint Detection And Multi-Threading C++ Library

実行結果

外骨君だとある程度ちゃんとでた↓

f:id:robonchu:20170911141520p:plain

イラスト等ではうまくでないこともあった…

コード理解

part_str = [nose, neck, Rsho, Relb, Rwri, Lsho, Lelb, Lwri, Rhip, Rkne, Rank, Lhip, Lkne, Lank, Leye, Reye, Lear, Rear, pt19]

この体の19点の位置を出力する

f:id:robonchu:20170911162745p:plain

実装部

all_peaks[i][j][0:2]に位置情報が入っている

# visualize
colors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0], \
          [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], \
          [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85]]
cmap = matplotlib.cm.get_cmap('hsv')

canvas = cv.imread(test_image) # B,G,R order

for i in range(18):
    rgba = np.array(cmap(1 - i/18. - 1./36))
    rgba[0:3] *= 255
    for j in range(len(all_peaks[i])):
        cv.circle(canvas, all_peaks[i][j][0:2], 4, colors[i], thickness=-1)

to_plot = cv.addWeighted(oriImg, 0.3, canvas, 0.7, 0)
plt.imshow(to_plot[:,:,[2,1,0]])
fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 12)

この点をつなぐと↓こんな感じ

f:id:robonchu:20170911162935p:plain

わかりやすい参考

www.slideshare.net

http://www-hi.comlab.soft.iwate-pu.ac.jp/wp-content/uploads/2017/04/Realtime_Multi-Persion_2D_Pose_Estimation_using_PAFs.pdf

CVPR2017勉強会 Realtime Multi-Person 2D Pose Estimation using Part Affin…

【やじうまPC Watch】Webカメラからリアルタイムにボーン検出できるソフト「OpenPose」が無償公開 - PC Watch

HACKist on Tumblr | 日々、博報堂アイ・スタジオで挑戦している、ちょっと変わった新しい実験をお知らせしていきます。 | 動画や写真からボーンが検出できる OpenPose を試してみた どうも貴田です。今回は...

OpenPoseチュートリアルのソースコードを読む。 - Qiita

OpenPose de ROS - Qiita

Caffe: Tutorial: Blob, 層, そしてネット : Caffe モデルの解剖 – PyTorch

DeepPose

論文: https://arxiv.org/pdf/1312.4659.pdf

わかりやすい参考:

PyTorchでDeepPoseを実装してみた - Qiita

PyTorchでDeepPoseを実装してみた PartⅡ - Qiita

GitHub - ynaka81/DeepPoseComparison: DeepPose with chainer and pytorch

sumoをros(kinetic)で動かしてみる

動かし方

基本的には以下のREADMEの通り

GitHub - arnaud-ramey/rossumo: Wrapper of the ARDroneSDK3 sample "JumpingSumoPiloting.c" as a C++ lightweight class for ROS.

はじめに、WIFIでsumo(名前:Jett~)と接続しておく

変更点

catkin_make --only-pkg-with-deps rossumo -DARDRONESDK3_PATH=~/out/Unix-base/staging/usr

catkin_make --only-pkg-with-deps rossumo -DARDRONESDK3_PATH=~/out/arsdk-native/staging/usr

に修正

packageの追加

$sudo apt-get install ros-kinetic-teleop-twist-keyboard

動かした結果

rqtで

  1. /rossumo1/cmd_vel_normで移動できることを確認(/rossumo1/cmd_velでは動かず)

  2. /rossumo1/camera/image_rawで画像が見れることを確認

chainerで動かしたいものリスト

動かしながら理解を深めたい

ひとつずつ動かしていく〜(TBD

サンプル集

Chainerのサンプルコードを集めてみた(メモ) - あおのたすのブログ

2D-CNN

Chainerによる畳み込みニューラルネットワークの実装 - 人工知能に関する断創録

3D-CNN

VoxcelChain 3次元畳み込みニューラルネットワークを使ったディープラーニング (深層学習)|Chainerによる3次元形状の認識 ~ BRILLIANTSERVICE TECHNICAL BLOG

YOLO

GitHub - leetenki/YOLOv2: YOLOv2のchainerの再現実装です(darknetのchainerローダと、完全なchainer上での訓練コードを含みます)

ペンパイナッポーとアッポーペンを識別する(ChainerでYOLO ver2) - Qiita

SSD(keras)

SSD: Single Shot MultiBox Detector 高速リアルタイム物体検出デモをKerasで試す - Qiita

Segmentation(Servey)

[Survey]Learning to Segment Object Candidates - Qiita

FCN

memo: Fully Convolutional Networks 〜 Chainerによる実装 再考1 〜

ペンパイナッポーとアッポーペンを識別する(ChainerでYOLO ver2) - Qiita

強化学習(ChainerRL)

https://research.preferred.jp/2017/02/chainerrl/

これさえ読めばすぐに理解できる強化学習の導入と実践 - DeepAge Good!

【強化学習】DQNを秒速で扱える『ChainerRL』使い方メモ - プロクラシスト Good!

強化学習で〇×ゲームに強いコンピュータを育てる(深層学習 Deep Learning) | 株式会社フォワードネットワーク

ChainerRL を用いた NoisyNet-DQN の実装~深層強化学習における探索手法 - もっちさんの明日はどっちだ

ChainerRLで三目並べを深層強化学習(Double DQN)してみた - Qiita

ChainerRLの紹介

ChainerRL Quickstart Guideを和訳してDQNしてみた - ゲーム制作のためのメモ Good!

DeepPose, OpenPose

PyTorchでDeepPoseを実装してみた - Qiita

DeepPose: Human Pose Estimation via Deep Neural Networks

chainerコード理解

Chainerのソースを解析。MNISTサンプルを追ってみる | コード7区 Good!

Chainer: ビギナー向けチュートリアル Vol.1 - Qiita Good!

ディープラーニングの様々なモデルを使ってCIFAR-10画像データセットの分類を行う - Qiita Good!

勤労感謝の日なのでChainerの勤労(Training)に感謝してextensionsを全部試した話 - EnsekiTT Blog

Chainerチュートリアル の和訳【Chainerの紹介と多層パーセプトロン】 - 俺とプログラミング

chainer初心者が畳み込みニューラルネット試してみた - 技術系メモ

クラスタリング(k-means)のお勉強

k-meansでクラスタリング(教師なし)

import numpy as np
from sklearn.cluster import KMeans

# size 量的データ
features = np.array([
        [20, 95, 190],
        [52, 103, 103],
        [50, 70, 280],
        [65, 65, 210],
        [84, 84, 96],
        [20, 50, 140],
        [28, 49, 176],
        [40, 75, 80],
        [2, 25, 25],
        [2, 30, 50],
        [14, 68, 132],
        ])

# size, weight, stiffness 質的データ
features = np.array([
        [1, 1, 1],
        [1, 0, 1],
        [1, 1, 1],
        [1, 0, 1],
        [1, 1, 1],
        [1, 1, 1],
        [1, 1, 1],
        [1, 0, 1],
        [0, 0, 0],
        [0, 0, 0],
        [1, 1, 1],
        ])

kmeans_model = KMeans(n_clusters=2, random_state=10).fit(features)

labels = kmeans_model.labels_

for label, feature in zip(labels, features):
    print(label, feature, feature.sum())

可視化

import numpy as np
from sklearn.cluster import KMeans

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# width height depth
features = np.array([
        [20, 95, 190],
        [52, 103, 103],
        [50, 70, 280],
        [65, 65, 210],
        [84, 84, 96],
        [20, 50, 140],
        [28, 49, 176],
        [40, 75, 80],
        [2, 25, 25],
        [2, 30, 50],
        [14, 68, 132],
        ])

km = KMeans(n_clusters=3, random_state=10)
kmeans_model = km.fit(features)
labels = kmeans_model.labels_

X = features
y_km = labels
names = ["class1" , "class2", "class3" ]

for label, feature in zip(labels, features):
    print(label, feature, feature.sum())

#Predicted data plot
fig = plt.figure()
ax = Axes3D(fig)
ax_km1=ax.scatter3D(np.ravel(X[y_km==0,0]),np.ravel(X[y_km==0,1]),np.ravel(X[y_km==0,2]),c='y', marker='x')
ax_km2=ax.scatter3D(np.ravel(X[y_km==1,0]),np.ravel(X[y_km==1,1]),np.ravel(X[y_km==1,2]),c='r', marker='x')
ax_km3=ax.scatter3D(np.ravel(X[y_km==2,0]),np.ravel(X[y_km==2,1]),np.ravel(X[y_km==2,2]),c='b', marker='x')

ax_km4=ax.scatter3D(km.cluster_centers_[:, 0],km.cluster_centers_[:, 1],km.cluster_centers_[:, 2],c='lightgreen', marker='s')

plt.legend((ax_km1, ax_km2, ax_km3,ax_km4),
           (names[0], names[1], names[2],"Centroid"),
           scatterpoints=1,
           loc='upper left',
           ncol=3,
           fontsize=8)
plt.show()

f:id:robonchu:20170904225705p:plain

参考:

データの種類 (質的データ、量的データ) - ナンバーズ予想で学ぶ統計学

scikit-learn による最も基本的なクラスタリング分析 - Qiita

Python 機械学習 Scikit-learnによるクラスタリング分析(k-means法)の実践 – colab 学習ログ