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

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

機械学習のお勉強(活性化関数と損失関数と過学習対策)

活性化関数

活性化関数は、入力信号の総和がどのように活性化するかを決定する役割を持つ

単位ステップ関数 👈パーセプトロン

def step_function(x):     
    if x > 0:
        return 1
    else:
        return 0

or

def step_function(x):     
    if x > 0:
        return 1
    elif x == 0:
        return 0.5
    else:
        return 0

符号関数 👈パーセプトロン

def step_function(x):     
    if x > 0:
        return 1
    elif x == 0:
        return 0
    else:
        return -1

線形関数 👈ADALINE,線形回帰

def linear_function(x):     
    return x

区間線形関数 👈サポートベクトルマシン

def piecewise_linear_function(x):     
    if x >= 1/2:
        return 1
    elif -1/2 < x < 1/2:
        return x + 1/2
    else:
        return 0

シグモイド関数  👈ロジスティック回帰、ニューラルネットワーク

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

双曲線正接 👈ニューラルネットワーク

def sigmoid(x):
    return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))

ReLU関数 👈ニューラルネットワーク

出力値の飽和を防ぐことで勾配消失問題を克服した手法

def relu(x):
    return np.maximum(0,x)

ReLU関数 👈ニューラルネットワーク

出力値の飽和を防ぐことで勾配消失問題を克服した手法

def relu(x):
    return np.maximum(0,x)

Leaky ReLU関数 👈ニューラルネットワーク

負の入力で微分が0になる問題を対処する

alpha = 0.01

def relu(x):
    if x > 0:
        return x
    else:
        return alpha * x

aplhaは微小量にすることが一般的

Parametric ReLU関数 👈ニューラルネットワーク

上記のalphaが学習によって更新されるしくみを採用。

また、入力の次元によってalphaが異なる値をとれるようにしている。

Expotential Linear Unit 👈ニューラルネットワーク

正規化のように働き学習が早く進む他、ノイズに対して頑強だと言われている

alpha = 1

def ELU(x):
    if x > 0:
        return x
    else:
        return alpha * (np.exp(x) - 1)

ソフトマックス関数 👈分類問題に使用

def softmax(x):
    exp_a = np.exp(x)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y
  • ソフトマックスの出力の総和は1になるという性質があり、この性質により出力を確率と解釈することができる。
  • 学習と推論のうち、学習の際にこの関数が関係してくる。

まとめ

重要なことは非線形の関数であるということ。 線形関数では層を深くしても隠れ層のないネットワークになり、多層にする意味がなくなってしまう。

損失関数

二乗和誤差  👈回帰問題に使用

def mean_squared_error(y,t):
    return 0.5 * np.sum((y-t)**2)

交差エントロピー誤差 👈カテゴリ識別問題に使用

def cross_entropy_error(y, t):
    delta = 1e-7←発散防止
    return -np.sum(t * np.log(y+delta))

y:softmax t:one-hot-encoding と考えると、正解ラベルである確率が1であるときに最小値になる

過学習対策

DropOut

イテレーションごとにネットワークからランダムに選ばれたユニットを隠し、学習を行う

バッチ正規化

バッチごとに平均beta、分散gammaに変換になるよう入力を調整する

多層ニューラルネットでBatch Normalizationの検証 - Qiita

Weight decay

L2正規化

損失関数に重みをいれることで、パラメータが極端な値になることを防ぐ

L_w = L + rambda * 1 / 2 * sum(x[k] ** 2 for k in range(i)) 

L1正規化

L_w = L + rambda * sum(abs(x[k]) for k in range(i)) 

Gradient Clipping

勾配爆発を防ぐことで学習を安定化

考え方は損失関数の勾配をある範囲を超えないようclippingすること

nmarkou.blogspot.jp

機械学習のお勉強(性能評価)

全体の考え方

機械学習における学習方法と性能評価の基礎知識 - Build Insider

交差検定(クロスバリデーション)など機械学習の評価方法まとめ : 新規事業のつくり方

検証

ホールドアウト法

学習データとテストデータを単純に分割

参考:

機械学習の性能を正しく評価するための検証手法 - Qiita

k分割交差検証

ランダムにk個に分割し、k-1個をテストに使用し、これをk回繰り返す

参考:

機械学習における交差検証法の実装(備忘録) - Qiita 

「そのモデルの精度、高過ぎませんか?」過学習・汎化性能・交差検証のはなし - 六本木で働くデータサイエンティストのブログ

http://musashi.osdn.jp/tutorial/mining/xtclassify/accuracy.html

入れ子式の交差検証

さまざまな機械学習アルゴリズムからどれかを選択したい時に使用

クロスバリデーションでは予測性能を評価できない!ダブルクロスバリデーション(クロスモデルバリデーション)のススメ : 大学教授のブログ (データ分析相談所)

性能評価

正解率以外にも評価する指標が存在する

混同行列

真陽陰性(TP,TN)、偽陽陰性(FP,FN)を表現する行列

sklearn -> confusion_matrix(y_true=,y_pred=)

で作成できる

 適合率

PRE = TP / (TP + FP)

再現率

REC = TP / (FN + TP)

F1

よく使用される評価指標らしい

F1 = 2 * (PRE * REC) / (PRE + REC)

画像の読み込み方法

  1. chainer
    1. argparseで設定
      1. face_prediction/facePredictionTraining.py at master · tommyfms2/face_prediction · GitHub
      2. face_prediction/image2TrainAndTest.py at master · tommyfms2/face_prediction · GitHub
    2. path ベタ書き
      1. cnn-animeface-keras/animeface.py at master · satopirka/cnn-animeface-keras · GitHub
  2. OpenCV
    1. listdirで読み込み
      1. フォルダ内の全画像ファイルに対して一括処理を行う(python) - 技術メモ集
画像読み込みサンプル(OpenCV)

フォルダ分けされた大量の学習画像を一括で読みこむ方法(python) - 技術メモ集

# -*- coding: utf-8 -*-
import os
import cv2

class Prepro(object):
    def __init__(self):
        self.data_dir_path = u"./data/"
        self.dir = os.listdir(r'./data/')

    def get_image_and_label(self):
        dir_list = sorted([x for x in self.dir if os.path.isdir(self.data_dir_path+x)])
        label_f = open('list.txt', 'w')
        image_list = []
        label_list = []
        dir_label = 0

        for dir_name in dir_list:
            label_f.write(str(dir_name)+","+str(dir_label)+"\n")
            file_list = os.listdir(self.data_dir_path+dir_name)

            for file_name in file_list:
                root, ext = os.path.splitext(file_name)
                if ext == u'.png' or u'.jpeg' or u'.jpg':
                    abs_name = self.data_dir_path+dir_name+"/"+file_name
                    image = cv2.imread(abs_name)
                    image_list.append(image)
                    label_list.append(dir_label)
            dir_label +=1
        return image_list, label_list

if __name__ == '__main__':
    prepro = Prepro()
    images, lists =  prepro.get_image_and_label()

参考:

face_prediction/facePredictionTraining.py at master · tommyfms2/face_prediction · GitHub ここのwhoiswhoあたり

フォルダ内の全画像ファイルに対して一括処理を行う(python) - 技術メモ集

[Python]フォルダ内のファイルを取得する方法 - Qiita

python:画像処理tips その4 フォルダ内の画像の大きさを揃える - MATHGRAM

cnn-animeface-keras/animeface.py at master · satopirka/cnn-animeface-keras · GitHub

パラメータチューニング

sk-learn: ベイズ的最適化、グリッドサーチ、ランダムサーチも可能

Pythonでベイズ最適化を使ってハイパーパラメータを探索するライブラリ実装のメモ - Qiita

ハイパーパラメータの最適化と結果の見方【Pythonとscikit-learnで機械学習:第8回】

ベイズ的最適化・実験計画法のお勉強

目的

少ない実験回数で最適なパラメータを導出したい

ベイズ的最適化

まずはこの2つを見てお勉強

  1. 1020:ベイズ的最適化の入門と応用 機械学習による機械学習の実験計画 - YouTube

  2. » 機械学習のハイパーパラメータ探索 : ベイズ最適化の活用 TECHSCORE BLOG

要点を箇条書きでまとめる

  1. どういう実験を行えばblack box関数を最適化できるか

  2. 一回の実験コストが高い場合に有用

  3. black box関数をgausiann processでモデル化

  4. ベイズではblack box関数の最適化を行う代わりに獲得関数を最適化(活用・探索)

  5. 活用とは:近しい分野の本を読む

  6. 探索:本屋に行って面白い本を探す

  7. 活用と探索のトレードオフが重要

[TODO] 強化学習 活用 探索 でググッてこのあたりの知識を強化

参考: 1020:ベイズ的最適化の入門と応用 機械学習による機械学習の実験計画 - YouTube

» 機械学習のハイパーパラメータ探索 : ベイズ最適化の活用 TECHSCORE BLOG ←最高にわかりやすい!コード付き!!

第3回 機械学習のためのベイズ最適化入門|Tech Book Zone Manatee ←わかりやすい!

PRML第6章 ガウス過程による回帰 Python実装 - Qiita ←わかりやすい!

http://www.r.dl.itc.u-tokyo.ac.jp/study_ml/pukiwiki/index.php?plugin=attach&refer=schedule%2F2009-09-10&openfile=GP.pdf

ベイズ最適化についての入門記事を書きました - ほくそ笑む

統計学の考え方を抑えて機械学習との関連と相違を整理 - HELLO CYBERNETICS

ライブラリ

sk-learn: ベイズ的最適化、グリッドサーチ、ランダムサーチも可能

Pythonでベイズ最適化を使ってハイパーパラメータを探索するライブラリ実装のメモ - Qiita

ハイパーパラメータの最適化と結果の見方【Pythonとscikit-learnで機械学習:第8回】

GpyOpt:

Pythonでベイズ最適化を行うパッケージ GPyOpt - Qiita

カーネル

カーネルとはふたつのベクトル xx と yy の内積を(たいていはとても高次元の)特徴空間で計算する方法

参考: カーネルとは直感的に説明するとなんなのか? - Qiita

交差検定

例:正解付きのデータをK分割して,そのうち1つをテストデータに,残りのK-1個を訓練データとして学習と精度の評価を行う

参考:

第21回(最終回) 機械学習 はじめよう:機械学習 はじめよう|gihyo.jp … 技術評論社

交差検証 - Wikipedia

実験計画法

(TBD)

参考:

試験回数を減らそう(実験計画法)

Excelで学ぶ実験計画法の基礎(3):試作品の数を劇的に減らす直交配列実験の実務 (1/5) - MONOist(モノイスト)

実験計画法

実験計画法の概要~データを上手く使って実験のコスパを上げましょう!~

1020:ベイズ的最適化の入門と応用 機械学習による機械学習の実験計画 - YouTube

kinect v2をROS(KINETIC)で動かしてみる

環境設定

手順:Ubuntu16.04: Kinect V2の設定 | demura.net

  1. GitHub - OpenKinect/libfreenect2: Open source drivers for the Kinect for Windows v2 device

  2. GitHub - code-iai/iai_kinect2: Tools for using the Kinect One (Kinect v2) in ROS

修正点

  1. –from-paths ros -> - -from-paths

  2. Unable to compile anymore · Issue #377 · code-iai/iai_kinect2 · GitHub

iai_kinect2 -> kinect_registrationパッケージのCMakeLists.txtに

add_definitions( -fexceptions )

を追加

実行結果

f:id:robonchu:20170920234628p:plain

depth

f:id:robonchu:20170920234934p:plain

PCL

PCL(Point Cloud Library)+ROSで3次元画像処理入門 - karaage. [からあげ]

mzrandom : kinect から 距離画像を取ってくるROSパッケージ

www.slideshare.net

Python x PointCloud

kinect - how to effeciently convert ROS PointCloud2 to pcl point cloud and visualize it in python - Stack Overflow

http://olinivlab.weebly.com/uploads/2/2/1/5/22158624/ros_by_example_hydro_volume_1.pdf

Zの取得

#!/usr/bin/env python

import roslib
import rospy
from sensor_msgs.msg import PointCloud2
import numpy
import pylab
import time
import sensor_msgs.point_cloud2 as pc2

def callback(data):
    resolution = (data.height, data.width)

    # 3D position for each pixel
    img = numpy.fromstring(data.data, numpy.float32)

    cloud_points = []
    for p in pc2.read_points(data, field_names = ("x", "y", "z"), skip_nans=False):
        cloud_points.append(p[2])

    z_points = numpy.array(cloud_points, dtype=numpy.float32)
    z = z_points.reshape(resolution)
  print z[data.height/2 , data.width/2]

def listener():
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('/kinect2/sd/points',
                     PointCloud2, callback)
    rospy.spin()

if __name__ == "__main__":
    listener()

rvizでの表示、TFの出し方

  1. roslaunch kinect2_bridge kinect2_bridge.launch publish_tf:=true

  2. FixedFrame -> kinect2_link へ変更

roslaunch kinect2_bridge kinect2_bridge.launch publish_tf:=true fps_limit:=10

Does the kinect2_bridge publish the actual RGBXYZ point cloud? · Issue #153 · code-iai/iai_kinect2 · GitHub

TFについて

ROStfのお勉強 - 空飛ぶロボットのつくりかた

SD, HD, QHD

画質の違い【SD/HD/フルHD/4K】 - 動画配信サービスナビ

QHDとは - IT用語辞典

参考

How to install libopenni2-dev on Ubuntu 16.04 (Xenial Xerus)

Errors occured when doing cmake in ubuntu - Ask Ubuntu

KINECT WITH ROS

ubuntu16.04でkinect_v2を使うための環境構築 - potblog

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) = 1/2 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 : シグモイド関数

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

尤度関数

0,1の2クラス分類より以下のように表せる

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 … 技術評論社

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

教師あり学習

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

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

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

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

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

強化学習

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

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

教師なし学習

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

クラスタリング

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

次元削減

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

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