徒然なるままにMake:

Fusion360 3Dプリンタ 電子工作 面白そうなモノづくりをやっていくブログ

ディープラーニングを始めてみる 6

前回

something-make.hatenablog.com

参考書はこれ

 

前回は活性化関数までやったので、今日は行列の内積をやります。

行列というのはアレです。線形代数でやったやつ

数字がズラズラと行と列で並んでる、ものすごく計算に手間のかかるアレです。

私は一つ計算ミスをすると全部滅茶苦茶になるアレが学生時代大嫌いでした。

まあ、コンピューターが使えるなら話は別なんですけどね。

あれは人間が手計算でやるもんじゃありません。

行列の内積が具体的にどういう計算なのかといえば、

f:id:something-make:20180918201924p:plain

こういう計算です。数字を行と列で並べた行列を2つ用意して、掛け算っぽいことをしています。

このままだと分からないので、詳しくやっていきます。

行列の内積を計算するときは、右の行列を上に動かすと計算を理解しやすくなります。

f:id:something-make:20180918202038p:plain

左の行列は行が2つ、列が3つ

右の行列は行が3つ、列が2つ

 

これをどうするのかというと、左の行列の行と、右の行列の列で、それぞれ1番目と1番目、2番目と2番目、3番目と3番目を掛けて足し合わせて並べます

f:id:something-make:20180918201927p:plain

f:id:something-make:20180918201937p:plain

f:id:something-make:20180918201945p:plain

f:id:something-make:20180918201948p:plain

一体この計算に何の役に立つのかという話なんですが、

滅茶苦茶役に立ちます。

この行列の内積を使えば、ニューラルネットワークの計算を簡単にすることができます。

something-make.hatenablog.com

パーセプトロンの頃からずっと続いている、こういった入力xにそれぞれ違う重みを掛けて、合計するというのがニューロンの計算です。

f:id:something-make:20180918211626p:plain

この計算をそのまま書くとかなり面倒なのですが、これを行列の内積で書くと

XW = Y

というものすごく簡単な式になってしまいます。

f:id:something-make:20180918212118p:plain

実際に計算するとこんな感じです。

ちなみにこの式はフリーソフトwxMaximaで作りました。

こういう行列を取り扱うのに便利なフリーソフトです。

 

 

バイアスの取り扱いもすごく簡単になります。

f:id:something-make:20180918213256p:plain

f:id:something-make:20180918213324p:plain

XW + b = Y

そう、たったこれだけであの面倒だった計算が終わってしまいます。

この計算結果を前回やった活性化関数にそのまま放り込めばニューラルネットワークの一段の計算が完了します。

f:id:something-make:20180916125150p:plain

この計算を繰り返せば何段ものニューラルネットワークも簡単に構築することができます。

 

行列の活用方法と便利さが分かったところで、今日はここまでにします。

ディープラーニングを始めてみる 5

前回

something-make.hatenablog.com

参考書はこれ

 

今回は活性化関数について

ニューラルネットワークに使われる主な活性化関数はシグモイド関数

h x = 1 1 + exp - x

 を使うことが多い。

このグラフは

f:id:something-make:20180917135023p:plain

こんな形状のグラフになる。

 

一方、これまでパーセプトロンで使っていた活性化関数はステップ関数と呼ばれ入力が0を超えたら1を出力し、それ以外では0を出力する。パーセプトロンニューラルネットワークの大きな違いはここにある。

 

f:id:something-make:20180917135208p:plain

二つを重ねて比べてみるとこんな感じ

・滑らかさが違う。シグモイド関数はステップ関数に比べて滑らか

シグモイド関数はステップ関数と違い、1と0の中間の値、0.8等も出す

f:id:something-make:20180917145406p:plain

ちなみに、二つに共通する特徴として

・どれだけ大きい値を入力してもかならず0から1の間の値を返す

というものがあります。

 

さらに最近使われる活性化関数にReLU(Rectifield Linear Unit)関数というものがあります。入力が0以下なら0を出力し、0を超えたならそのまま出力する関数で、数式で表すと

  h x = { x x > 0 O x 0

グラフで表すとこうなります。

f:id:something-make:20180917160453p:plain

 

 

さて、ここで疑問点があります。

 

なぜ活性化関数を使わないといけないのか?

 

どうしてこういった関数を使わないといけないのでしょうか?

それにはちゃんとした理由があります。

それはどちらの活性化関数も非線形関数だということ。

非線形な関数だからこそネットワークに意味ができます。

逆に線形関数とは言ってしまえば一直線の関数。

  y = a x + bの形式で表される関数です。

f:id:something-make:20180917152748p:plain

非線形関数は一直線ではない関数です。シグモイド関数もステップ関数も直線ではありません。

 

線形の関数でネットワークを作るとどうなるのか?

試しに活性化関数 h x = a xの線形関数にして3重のネットワークを作ってみます。

このネットワークは

y x = h h h x

という式で表されます。

f:id:something-make:20180917153728p:plain

この計算結果は

  y = a * a * a * x

y = a 3 x

になります。青枠で囲まれたところに着目すると、aの3乗をxに掛けているだけです。

f:id:something-make:20180917153731p:plain

aの3乗というのはただの定数ですから、結局これはただの線形の式ということになり

f:id:something-make:20180917153735p:plain

 こういう単純なニューロンに置き換えることができてしまいます。

これの何が問題かというと、以前パーセプトロンでやったように単純なニューロンでは動作に限界があるということです。XORゲートは1重のパーセプトロンではつくれませんでした。

something-make.hatenablog.com

線形の活性化関数でニューラルネットワークを作ってどんなに層を重ねても、結局は1重のニューラルネットワークと同じ動作しかしないわけです。

 

複雑な動作をさせるには非線形関数が絶対に必要になるわけです。

 ニューラルネットワークが複雑な動作をするためには活性化関数に非線形なものを使用しなければいけないのがよくわかりました。

 

今日はここまでです。

ディープラーニングを始めてみる 4

前回

something-make.hatenablog.com

参考書はこれ

 

 
1.パーセプトロンのすごいところとダメなところ

前回はパーセプトロンを何層にも重ねることで、コンピュータ等の複雑な論理回路を構成できることを書きました。

パーセプトロンはコンピュータを構成できるので、理論上はこれを複雑に組み合わせれば、どんなコンピュータでもプログラムでも

作ることができます。

しかしパーセプトロンには致命的な問題があります。手動なことです。

パーセプトロンのパラメータは人間が計算して設定してやらないといけないのです。複雑なパーセプトロンを作っても全部人間が決めてあげないといけません。

超めんどくさいです。

この辺りの問題を解決するためにニューラルネットワークが生まれました。このニューラルネットワークは自動でパラメータを決定してくれるすごいシステムです。

まずはニューラルがどのようなものかを学びます。

 

2.ニューラルネットワークってどんな感じ?

f:id:something-make:20180916125150p:plain

一番左の層が入力層、一番右が出力層、中間が中間層と呼ばれます。中間層はプログラム等では隠されるので隠れ層と呼ぶこともあります。パーセプトロンと違い、はじめから複数の層で構成されています。

ちなみの層の順番は左から0層,1層と数えて行きます。Pythonでは数を0から数えることが多いのでこの方が都合がいいからです。

 

しかし、これではただの多層パーセプトロンと変わりないように見えます。

そこでパーセプトロンニューラルネットワークの違いをはっきりさせるため、パーセプトロンをもう一度しっかりと扱い、捉えなおして見ます。

 

3.パーセプトロンってどういうのだっけ?

something-make.hatenablog.com

f:id:something-make:20180913113422p:plain

y = { 0 b + w 1 x 1 + w 2 x 2 0 1 b + w 1 x 1 + w 2 x 2 > 0  

パーセプトロンはこういう図と式で表されます。

bはバイアスでニューロンの発火(0から1への変化)をコントロールします。

w1,w2は信号の「重み(重要さ)」をコントロールします。

ただ、この図にはバイアスが入っていないので入れてやります。

f:id:something-make:20180916141912p:plain

この図では重みbの入力1が追加されます。これでバイアスがわかりやすくなりました。

さらに式のほうもさらにシンプルにします。

パーセプトロンの場合分けの動作(0を超えたら1を出力し、それ以外では0を出力する)をひとつの関数で表します。

新しい関数h(x)によって式を簡単にすることができます。

y = h b + w 1 x 1 + w 2 x 2  

h x = { 0 x 0 1 x > 0

パーセプトロンの動作を0以上と0以下の2つに分けず、一つの式で表せるようになりました。

この関数h(x)を活性化関数と呼びます。

さらにこの活性化関数を図に書き加えます。

f:id:something-make:20180916151337p:plain

活性化関数の部分をしっかりと式にすると

a = b + w 1 x 1 + w 2 x 2

  y = h a

という形になります。この表し方でニューロンがどうやって動作しているのかがしっかり分かるようになりました。

 

次回は活性化関数についてやっていきます。

ディープラーニングを始めてみる 3

前回

something-make.hatenablog.com

参考書はこれ

 

前回はパーセプトロンでいくつかの論理回路を作りました。そして、XORゲートはパーセプトロンでは作ることができないということがわかりました。

ではXORゲートはどうやって作られているか?

パーセプトロンは「値の和が一定値以上、以下で出力が変わる(0か1か)」という特性を持っています。これは半導体等に近い性質です。

基本的にコンピューターに使われる論理回路半導体の性質を利用して作られています。

しかしXORゲートも論理回路なわけですから、半導体と同じようにパーセプトロンで作ることができるはずなのです。

ならば参考にすべきは半導体論理回路です。XORゲートは半導体でどうやって作られているのか?

いくつか方法はありますが、その一つは論理回路を組み合わせて作ること。

AND,NAND,ORゲートを組み合わせることでXORゲートを作ることができます。

 

論理回路の記号は一般的に下の図のようになります。

f:id:something-make:20180915102523p:plain

記号はこちらからお借りしました。

要はこの論理回路を組み合わせることで、XORゲートを作ることができるわです。

f:id:something-make:20180915110951p:plain

 

このNANDとORとANDを組み合わせた論理回路の動作を見てみます。

まずNANDゲートの出力s1

f:id:something-make:20180915111536p:plain

次にORゲートの出力s2

f:id:something-make:20180915111546p:plain

この二つとXORゲートの出力yを並べてみると

f:id:something-make:20180915111733p:plain

s1,s2の片方が0,もう片方が1のとき0を出力,両方が1のとき1を出力するのがわかります。つまり最後にANDゲートを取り付けることで、XORゲートになります。

このとき、最後のANDゲートに両方が0の入力がされたときの反応が書いてありませんが、それを考える必要はありません。

この論理回路の入力はx1,x2だけで、入力される全組み合わせは(0,0),(0,1),(1,0),(1,1)の4通りだけです。そしてx1,x2に入力した場合の出力はs1,s2以外はありえません。

つまりどうやっても最後のANDゲートに(0,0)が入力されることは回路の構造を変えたりしない限りありえないので心配する必要はありません。

x1,x2からs1,s2を計算し、さらにs1,s2からyを計算することでXORゲートを実装することができました。

f:id:something-make:20180915122247p:plain

パーセプトロンの結果をさらにパーセプトロンに入れることで、単純なパーセプトロンでは作ることができなかった論理回路を製作することができます。このパーセプトロンの構造を図にすると下のような多層構造のネットワークになります。

f:id:something-make:20180915123028p:plain

このネットワークで一番左の段を第0層、その右が第1層、一番右の段を第2層と呼びます。

このパーセプトロンはこれまで見てきたANDやORような1層のパーセプトロンと違い、2層のパーセプトロンになっています。こういった何重の層になるように重ねたパーセプトロン多層パーセプトロンと呼びます。

 

パーセプトロンは層を重ねることで、XORのような直線でグラフを区切るだけの1層のパーセプトロンより柔軟な表現ができるようになりました。

このパーセプトロンをさらに組み合わせていくことで、コンピューター自体も作り上げることができます。

 

今日はここまで

 

ディープラーニングを始めてみる 2

前回

something-make.hatenablog.com

参考書はこれ

 

前回はパーセプトロンでAND NAND ORゲートを作りました。

ただ、このパーセプトロンには限界があるようで、XORゲートを実装できないらしいのです。

f:id:something-make:20180914201155p:plain

これがそのXOR

x1とx2が違うときに1を出力し、同じときは0を出力します

なぜこれを実装できないのかをORゲートで考えてみます。

パラメーターが(b,w1,w2)=(-0.5,1.0,1.0)のとき、真理値表は

f:id:something-make:20180913123348p:plain

 このときのパーセプトロンの式は次のようになります。

y = { 0 - 0.5 + x 1 + x 2 0 1 - 0.5 + x 1 + x 2 > 0  

このパーセプトロンの式を変形して境界を求めると

  - 0.5 + x 1 + x 2 = 0

x 2 = 0.5 - x 1  

この直線を引いて境界を考えると次のようになります。

f:id:something-make:20180914205212p:plain

直線の上(緑))側でパーセプトロンの式は1、下側(青)で0になります。

このグラフを見るとORゲートでは(x1,x2)=(0,0)で0を出力、(0,1),(1,0),(1,1)で1を出力することがわかります。

 

ANDゲートについても考えてみます。

f:id:something-make:20180913113658p:plain

f:id:something-make:20180914211302p:plain

直線の上(緑))側でパーセプトロンの式は1、下側(青)で0になります。

パラメーターが(b,w1,w2)=(-0.7,0.5,0.5)

式を同じように変形して境界線を引くと(x1,x2)=(0,0),(0,1),(1,0)で0を出力、(1,1)で1を出力することがわかります。

 

NANDゲートはパラメーターが(b,w1,w2)=(0.7,-0.5,-0.5)となりパラメータが逆転します。(x1,x2)=(1,1)で0を出力、(0,0),(0,1),(1,0)で1を出力します。

f:id:something-make:20180913123204p:plain

f:id:something-make:20180914212019p:plain

OR,AND,NANDゲートはパーセプトロンの式が、直線でグラフを0と1で区切ることでできていることがわかります。

区切り方を変えればOR,AND,NANDが全て実装できるわけです。

 

ならXORはどう区切ればいいのか?

f:id:something-make:20180914214917p:plain

要するにこれを直線一本で区分けすればいいわけです。

当然ながら無理です。どうやっても区切れません。つまりパーセプトロンでXORは作れないわけです。

 

f:id:something-make:20180914220557p:plain

こんな風に曲線で区切ることができればいいんですが、パーセプトロンは直線でしか区切れないのです。残念ながら。

そんなわけで今日はここまでです。

ディープラーニングを始めてみる 1

多脚ロボットがバッテリーの宅配待ちになったので、今回からは流行りのディープラーニングをはじめてみようと思います。

参考書はこれ

 

一章はまるまるPythonの説明なので2章から開始

パーセプトロンに関してやっていきます。

f:id:something-make:20180913113422p:plain

y = { 0 w 1 x 1 + w 2 x 2 θ 1 w 1 x 1 + w 2 x 2 > θ

このパーセプトロンの構造はW1×X1+W2×X2が一定の値θを超えたら1を出力して、それ以外なら0を出力するというもの。

これを使って論理回路を作ってみます。まずはANDゲートです

f:id:something-make:20180913113658p:plain

流石にソースコードの載せるのはアレなので実行結果だけに留めます。

f:id:something-make:20180913120605p:plain

きちんとANDゲートをつくることができました。

ここでパーセプトロンの構造を少し変更して、重みとバイアスを導入します。

y = { 0 b + w 1 x 1 + w 2 x 2 0 1 b + w 1 x 1 + w 2 x 2 > 0  

このbがバイアスで、一番目の式のθを左辺に移したものになっています。

また、これ以降はw1,w2を重みと呼び、ベクトルの掛け算をして和が0を超えたなら1を出力し、0以下なら0を出力します。

f:id:something-make:20180913122650p:plain

これでAND回路を問題なく実装できることがわかりました。

このままNANDゲートとORゲートを実装します。

NANDゲート

f:id:something-make:20180913123204p:plain

f:id:something-make:20180913123324p:plain

ORゲート

f:id:something-make:20180913123348p:plain

f:id:something-make:20180913123618p:plain

AND,NAND,ORのゲートを、重みとバイアスの値を変えるだけで同じ仕組みで実装できることがわかりました。

今日はここまで。

参考書の丸写しですが、備忘録的にこのまま進めて行きたいと思います。

3Dプリンターでロボット作ってみる 多脚ロボット編15

前回

something-make.hatenablog.com

このロボットの3Dデータは下のリンクのものを使用しています

www.thingiverse.com

昨日電源を搭載して動かしてみたところ、どうにも動きが悪くなってしまいました。

ひょっとしてバッテリーが重すぎるのではという可能性に思い至りました。

作者さんのサイトを見てみると550mAhのバッテリーを搭載しているようです。

regishsu.blogspot.com同じバッテリーを探しても見つからなかったので、容量が近いものを探して、スペックを見てみると、700mAhで41g、大体これを参考にしていいと思います。

ちなみに今回ロボットに搭載したエネループの容量は1900mAh重量は電池ボックス込みで118gとおよそ3倍

f:id:something-make:20180912172316j:plain

さらにArduinoの電源用の9V電池が45g、

f:id:something-make:20180912172318j:plain

 合計163gなのでなんと作者さんの使用したバッテリーの4倍近いものを搭載してしまっていたわけです。

流石にこれはまずいので、上の700mAhのバッテリーを購入することにしました。