iPX社員によるブログ

iPX社員が"社の動向"から"自身の知見や趣味"、"セミナーなどのおすすめ情報"に至るまで幅広い話題を投下していくブログ。社の雰囲気を感じ取っていただけたら幸いです。

情報共有と情報伝達の重要性

EPLUの加藤です。

今回は、当社が抱えている課題について取り上げてみたいと思います。

情報共有と情報伝達の重要性

社内だけでなく社外も含めて、適切に情報を共有する、という事はビジネスを行う上で重要な活動のひとつです。

  • お客様に分かりやすく情報を提供する
  • お客様から必要な情報を入手する
  • プロジェクトメンバーにプロジェクトの内容を説明する

情報を共有するためには、いかに正しく情報を伝達するか、が鍵になります。

続きを読む

ルールの重要性

はじめに

久しぶりのブログになります。Suzukiです。
今回はルールの良いところ、気を付けなければいけないところを自分の解釈で述べていきます。

ルールの設定例

モデルの実装も同様で車両モデルを例に挙げて変数のルール化をしてみます。
車両システムの一部であるシステムAは以下のような値をもつことになります。
1. CANやセンサーから出力される値(入力変数)
2. システムA内のみ使用される入力変数
3. システムAで定義された定数
4. システムA内のみで使用される出力変数
5. CAN等に出力される変数

変数をグループ分けすると
① 1, 2は入力変数
② 4, 5は出力変数
③ 3は定数
④ 1, 5は他システムとのコミュニケーションする変数
⑤ 2, 3, 4は自システムのみで活用される変数

④は先頭を大文字, ⑤は先頭を小文字にルール化します。
結果として変数は外とコミュニケーションを行うものかシステム内部のものかを判定することができます。

当たり前のようなことですが、このようなルール化はヒューマンエラーの回避、チームや他部門のコミュニケーションが円滑に進むと考えています。

どんなルールを付ければいいのか分からない時は?

そんな時には参考に先駆者の知恵を借りて対応することがベターを考えます。
例えば、モデルのお作法はJAAMBが掲げるルールを模するなど。
JAAMBHP:http://jmaab.mathworks.jp/

ルール設定で気を付けないといけないところ

ルールというものは決まり事であり、破ることは許されないのが前提です。
つまりルールを縛りすぎるということは窮屈になることであると考えています。
今まで通りの業務ができなくなり、また“無駄な”工数増加になってしまう可能性もあります。
ルールを設定はそれ相応のメリットを掲げ、設定前によく議論する必要もあると考えます。

終わりに

ルールと聞くと不自由になると思われがちですが、自由すぎることはかえって不自由になり手間がかかることもあり、必要最低限のルールは時に効率をアップさせる魔法であることを読者の方へ伝えることができたら幸いです。

自社アピール

弊社ではより一層の高い品質を提供実現の一環としてQMS取得を目指しております。

ゲームマーケットで買ったゲーム

何回目かの投稿になります、高橋です。
GW中に開催されたゲームマーケットという非電源系のゲームメインの即売会に行ってきました。今回はそこで買った「おしまい畑と世界の種」というゲームについて紹介していこうと思います。
f:id:ipx-writer:20180531185555j:plain

続きを読む

5Gのデモを見に行きました

皆さまこんにちは、Chibaです。

前回の投稿からかなり経過しました。
今現在は業務内容として、自動車のEMC解析のお手伝いをしています。

EMCとはもちろん略語で、
Electro Magnetic Conpatibility 電磁両立性 というのが正式な表現となります。
電子機器同士が、お互いの発する電磁波によって、機器の動作に影響を与えていないかを調べるお仕事、
というのがざっくりした説明となります。

続きを読む

深層学習

初めに

ご無沙汰しております、iPX界の深層学習部(非公式)部長の小川です。
今回はDeep Learning(以下DL)につきまして記そうと思います。
既にありふれている情報で、インターネットを汚す事は大変恐縮してしまいますが、取り組み内容をアピールする場として発信させていただけたらと思います。

これまで道具を使う為の自己研鑽は多く積んできました、そして物体認識や深層強化学習にトライし、一定の結果も残せたと思います。

今後はエッジデバイスから始まり、DLが量産品に導入されるケースも増えてくると思います。
近い未来に問われるであろうDLの品質保証をどう担保していくか。
今一度基礎に立ち返り理論への理解を深める事、それが私に求められる次なる自己研鑽なのであります。

記事方針

記事の内容は書籍を元に構成しております、正確な情報は是非書籍をお手にとっていただけたらと思います(参考書籍の項をご参照ください)。
ここでは新入社員向けに噛み砕けるだけ噛み砕き説明する事に徹します。
よって事実とは異なる点があることを予めご了承願います。
また、私自身も未熟至る為、数式や説明が間違っている可能性が有ります点も併せてご容赦いただけたら幸いです。

記事中のプログラムはpython3で実装しています。

DLの目的

ある関数を近似(まね)することです。
利点としては下記があると考えています。

  • 既知の計算量が膨大な関数を近似することで高速化する
  • 未知の関数を近似することで実装が困難な処理を実現する

これら恩恵を受ける為には道具と使い方を学ぶ必要が有ります。
具体的にはパーセプトロン、活性化関数、多層ネットワークといった枠組みや、順伝搬や誤差逆伝播法などの枠組みの使い方です。

ニューラルネットワーク

ここではニューラルネットワークの構築に必要となるいくつかの枠組みを一つづつ知っていきます。

パーセプトロン

いくつかの入力をまとめて一つの出力を返す枠組みです。
登場人物は下記3名です。

名称 役割
ユニットさん 入力とか出力のあの丸(○)の部分
重みさん 重みさんを良しなに変化させる事が学習
バイアスさん 微調整

数式

u_j = \sum_{i=1}^I w_{ji} x_i + b_j
行列版

u = Wx+b
魚のような記号はΣ(シグマ)で、直訳すると総和です。
プログラムではsum変数に計算結果をループで足す処理に当たります。

pythonプログラムにて行列演算ライブラリのnumpyを用いて表現してみます。

import numpy as np

I = 4
J = 1
x = np.random.rand(I)
W = np.random.rand(J,I)
b = np.random.rand(J)

# for文版
u = .0
for i in range(I):
    u += W[0,i] * x[i]
else:
    u += b[0]
print(u)

# 行列版
u_d = np.dot(W,x)+b
print(u_d) 

numpyの演算を使うととっても楽でした。

活性化関数

パーセプトロンはあくまで複数の入力に重みとバイアスを加えて1つの出力を行う枠組みでした。
出力にある変換を行う活性化関数が知られています。
DLでは非線形関数(1本の直線ではない)を適用することがお決まりです。

名称 特徴
ロジスティック関数さん 範囲が0~1  f(u)=\frac{1}{1+e^{-u}}
双曲線正接関数さん 範囲が-1~1  f(u) = \tanh(u)
正規化線形関数(ReLU)さん マイナスが無い  f(u) = \max(u,0)
恒等写像さん そのまま  f(u) = u

pythonにてグラフ描画ライブラリのmatplotlibを用いて関数の形を可視化してみます。

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5., 5., .1)

def logistic(u):
    return 1/(1+np.exp(-u))

def hyperbolic(u):
    return np.tanh(u)

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

plt.plot(x, logistic(x), label='logistic', linestyle='--')
plt.plot(x, hyperbolic(x), label='hyperbolic', linestyle='--')
plt.plot(x, relu(x), label='relu', linestyle='--')

plt.legend()
plt.xlim(-5.2, 5.2)
plt.ylim(-1.2, 1.2)
plt.title('activation functions')
plt.show()

f:id:ipx-writer:20180521015559p:plain

いずれも確かに直線ではない事と、データ範囲と形に特徴がある事が分かりました。

多層ネットワーク

パーセプトロンと、活性化関数を組み合わせて、ユニットを横にも積んで多層化します。
多層化することでニューラルネットワークの表現力が高まります。
層の上から計算していき、最終的な出力を求める事を順伝搬と呼びます。

ネットワークの作成と順伝搬をpythonで表現してみます。
書籍「ゼロから作るDeep Learning - Pythonで学ぶディープラーニングの理論と実装」の例を参考にしました。

from functools import reduce
import numpy as np
import matplotlib.pyplot as plt

class layer:
    def __init__(self, W, b, f):
        self.W = W
        self.b = b
        self.f = f

def logistic(u):
    return 1/(1+np.exp(-u))

def identity(u):
    return u

layer1 = layer(np.array([[.1, .3, .5], [.2, .4, .6]]), np.array([.1, .2, .3]), logistic)
layer2 = layer(np.array([[.1, .4], [.2, .5], [.3, .6]]), np.array([.1, .2]), logistic)
layer3 = layer(np.array([[.1,.3], [.2, .4]]), np.array([.1, .2]), identity)
network = [layer1, layer2, layer3]

x = np.array([1., .5])
y = reduce(lambda z, l: l.f(np.dot(z, l.W) + l.b), network, x)
print(y)    # output:[ 0.31682708  0.69627909]

1つ目の層は入力層、最後の層は出力層と呼ばれます。
また、各層の出力をzと置き、任意の総数Lと置くと多層ネットワークは下記に一般化出来ます。

 u^{(l+1)} = W^{(l+1)} z^{(l)}+b^{(l+1)}

 z^{(l+1)} = f(u^{(l+1)})

 y≡z^{(L)}


≡(合同)は左辺を右辺で定義する意味です。

以降は書籍「深層学習」に則り、ネットワークのパラメータ全てを成分に持つベクトルwを定義し、下記で表す事とします。

 y(x;w)

学習

ここまでで多層ネットワークを定義し、順伝搬することで出力yを得ることが出来るようになりました。
次に必要な事は多層ネットワークの枠組みを用いて、重みを調整する事、即ち学習です。
任意のデータから適切な重みを調整する為にはいくつか覚えることが必要です。

  • 教師(訓練)データ
  • 誤差
  • 回帰
  • 分類
  • (時間切れ... TBD)

教師(訓練)データ

DLではデータから任意の関数を近似することが目的でした、ここでデータとは入力と出力の組み合わせとなっており、教師データと呼ばれます。

誤差

全ての教師データの入力と出力(答え)と、ニューラルネットワークの出力が一致すれば、学習が完了したということになります。
そこで教師データと、現在のニューラルネットワークがどれだけかけ離れているかを表す指標が誤差と呼ばれます。
つまり学習とは誤差を返す誤差関数の結果が最小とする事です。

回帰

DLでは解きたい問題によって出力が変わります。
回帰問題では連続値の推定が問題設定となります。
例えば、ある入力から適切なモーターのトルク値を出力するような問題は、この回帰問題です。
回帰問題の場合は誤差関数として二乗誤差がよく用いられます。
目標出力(答え)をdと置くと、下記数式で表せます。

 ||d-y(x;w)||^2

全教師データに適用する場合は、1/2を掛ける事で、微分計算の際に二乗と相殺されるようにするのが一般的です。
回帰問題の場合はこの二乗誤差関数のwを最小化することが学習タスクとなります。

 E(w) = \frac{1}{2} \sum_{n=1}^{N}||d_n - y(x_n;w)||^{2}

分類

分類問題では離散値(不連続な数値)の推定となります。
例えば、手書きした0~9の文字画像から、手書きされた数値が何であるかを推定するような問題は、この分類問題です。

二値分類

先ずは分類の中でも2つに分ける二値分類から理解していきます。
簡単の為、出力ユニットは1つで、0-1の値が0.5から上下どちらにあるかで二値の内どちらかを表現することにします。
∈は右辺が左辺に含まれるという意味です。

 d ∈ \{0,1\}

入力xが1であることを表すために、事後確率モデルを用いることが一般的です。
書籍「深層学習」に則り、下記で表すことにします。

 p(d=1|x)

DLでは事後確率をモデル化する為にニューラルネットワークを用います。
ここで2つの波線は近似を意味します。

 p(d=1|x) \approx y(x;w)

1の場合、0の場合も含めて事後確率をモデル化する場合は、べき乗を使うことで、1つの式で表すことが出来ます。
dが1の場合は右辺式中の左因子が、dが0の場合は右因子が計算されます、これはプログラムでいうところの条件演算に似ていますね。

 p(d|x) = p(d=1|x)^{d}p(d=0|x)^{1-d}

入力データxが上記の確率分布を最もよく整合する事を定める為に、最尤推定を行う事を考えます。

最尤推定

尤度(もっともらしさ)を求める考え方です。
尤度関数L(θ)を計算し、出力を最大とするθを推定します。
寄り道になりますが、よく見る例として確率分布が正規分布に従っているという仮定の元、下記の数式が出てきます。

 f(x) = \frac{1}{\sqrt{2\pi\sigma^{2}}} \exp(-\frac{1}{2}\frac{(x-\mu)^{2}}{\sigma^{2}})

複数データの確率分布を考える場合、各データに相関が無い場合は各データが独立同一分布であると言います。
独立である事で、全体の確率は確率密度の積に等しいと考える事が出来ます。
よって下記数式で表せます。
Πは総乗という意味です、Σの掛け算バージョンです。

 P(x_1, x_2, ..., x_n) = \prod_{i=1}^{n} \frac{1}{\sqrt{2\pi\sigma^{2}}} \exp(-\frac{1}{2}\frac{(x-\mu)^{2}}{\sigma^{2}})

正規分布の場合は平均μと、偏差σを求めたい確率変数として、尤度関数を定義します。

 L(\mu,\sigma) = \prod_{i=1}^{n} \frac{1}{\sqrt{2\pi\sigma^{2}}} \exp(-\frac{1}{2}\frac{(x-\mu)^{2}}{\sigma^{2}})

最尤推定ではL(μ,σ)が最大となるような確率変数μ、σを求める事がタスクとなります。

ここまで正規分布を例として、尤度関数の成り立ちを追ってきました。
今回はニューラルネットワークによって事後確率を表現することが目的となります。
よって尤度関数は下記と考えることが出来ます。

 L(w) = \prod_{n=1}^{N} p(d_n|x_n;w)

前項の二値分類より、下記の数式に置き換えて考えることが出来ます。

 L(w) = \prod_{n=1}^{N} \{y(x_n;w)\}^{d_n} \{1 - y(x_n;w)\}^{1-d_n}

ここまでで、二値分類における尤度関数を定義しました。
この尤度関数にもうひと手間加えて、誤差関数を定義していきます。
ここでいきなりlog(対数)が登場します。

単調性

logには単調性という性質があります。
単調性の中で、単調増加と呼ばれる性質は下記数式におけるxが増加した場合にyも増加するという性質です。

 y = f(x)

この性質から、定義した尤度関数にlogを適用しても、尤度関数として成り立つと考えることが出来ます。

 L(w) = \log [\prod_{n=1}^{N} \{y(x_n;w)\}^{d_n} \{1 - y(x_n;w)\}^{1-d_n} ]

次に下記のlogの公式から累乗と総乗を除外することが出来ます。

 \log_a MN = \log_a M + \log_a N

 \log_a M^{k} = k\log_a M

変形して累乗と総乗を除外した尤度関数は下記となります。

 L(w) = \sum_{n=1}^{N} [d_n \log y(x_n;w) + (1-d_n) \log \{1-y(x_n;w)\}^{1-d_n} ]

ここで尤度関数はL(w)を最大にすることが目的でした。
誤差関数では誤差を最小にすることが目的なので、符号を逆転する必要が有ります。

 E(w) = -\sum_{n=1}^{N} [d_n \log y(x_n;w) + (1-d_n) \log \{1-y(x_n;w)\}^{1-d_n} ]

これで二値分類における誤差関数が定義出来ました。

条件付き確率

早速誤差関数を使って学習の為の勉強に入って行きたいところですが、活性化関数には何を選択すれば良いでしょうか?
ロジスティック関数を用いると仮定して、事後確率モデルとマッチしているかを確認してみます。
条件付き確率の公式より、事後確率は下記事前確率で計算されると見なすことが出来ます。

 p(d=1|x) = \frac{p(x,d=1)}{p(x,d=0) + p(x,d=1)}

上記がuのロジスティック関数と同義であることを確認するために、下記の仮定を置きます。
ここで log x は底にネイピア数(e)が省略されているものとします。

 u ≡ \log \frac{p(x,d=1)}{p(x,d=0)}

logの公式より、上記式を変形します

 x = a^{y}

 y = \log_a x

 \frac{p(x,d=1)}{p(x,d=0)} = e^{u}

次に条件付き確率の公式より変形した式を、p(x,d=0)で割り、更に変形していきます。

 \frac{\frac{p(x,d=1)}{p(x,d=0)}} {\frac{p(x,d=0) + p(x,d=1)}{p(x,d=0)}}

約分します。

 \frac{\frac{p(x,d=1)}{p(x,d=0)}} {1+ \frac{p(x,d=1)}{p(x,d=0)}}

logの公式で変形した式を当てはめます。

 \frac{e^{u}} {1+ e^{u}}

さらにeuで割ります。

 \frac{\frac{e^{u}}{e^{u}}} {\frac{1+ e^{u}}{e^{u}}}

約分します。

 \frac{1} {\frac{1}{e^{u}} + 1}

逆数の公式により、式を変形します。

 \frac{1} {1 + e^{-u}}

上記はロジスティック関数さんと同じ式なので、事後確率はuのロジスティック関数だということが分かりました。

 p(d=1|x) = \frac{1} {1 + e^{-u}}

活性化関数にはロジスティック関数を用いれば良さそうです。

最後に

大変申し訳ございません、力尽きました。
実際に二値分類の学習を行うコードまで載せたかったですが、書籍「深層学習」の P17-18 への理解に時間が取られました。
学習を行うためには、微分法やチェーンルール、勾配や、勾配降下法、そして誤差逆伝播法を学ぶ必要が有ります。
次回は上記を載せた上で、学習を実施するpythonプログラムを載せた内容をゴールと定めて、執筆を頑張りたいと思います。

参考にさせていただきました書籍の著者様、わかりやすい記事を公開してくださった皆様に感謝を申し上げます。

参考書籍

参考サイト

ROSをCUDA対応してみる

こんにちは、和田です。
最近、プロジェクトでちょいちょいROSを利用することが増えてきました。

ROSってノードをちょいちょい組み合わせるだけでそれなりに動く物つくれるんで便利なんですよね。
そんな中、独自のノードを作ることも多々あるんですが、PointCloudの整形とかってCUDAを使った並列処理に向いているんだよなと。

nVidiaのJetsonTX2などを使う場合は特に、GPUを有効に使うことが大事ですし。
http://www.nvidia.co.jp/object/embedded-systems-dev-kits-modules-jp.html

そして、案外調べてみると日本語でROS+CUDAの環境構築を記事にしている人少ないんで、とりあえず書いてみようかなと言う流れです。
(英語で調べると結構出てきますが。。。)

続きを読む

うつのみやぐらし!

ご無沙汰しております。Inoです。
前回、入社してすぐに書いた記事からあっという間に半年が経過しました。時が経つのは早いものです。
今回こそは先輩たちに倣って技術的な記事を!と思いましたが、
まだまだ学習中の身で書けるまでのものも見つからないため、
入社してすぐに異動でやってきた栃木県宇都宮市の生活について書いてみたいと思います。

続きを読む