前回、パーセプトロンにバイアスという考え方を導入しました。今回はそれを復習しながら、ディープラーニングの実体に迫りたいと思います。

パーセプトロンで微調整はできる?

パーセプトロンは「複数の入力(に重みを掛け算した)値とバイアスの値を受け取り、1つの出力を返す」という構造です。入力は数値で、出力は0か1のいずれかになります。

パーセプトロンの構造

パーセプトロンのメリットは、幾重にも繋げられる(層を形成できる)ことです。例えば、2層にすると次のようになります。

2層のネットワーク。文献によってはこの図の0層目を1層目と数え、3層としているものもある

このように、パーセプトロンを繋いで層が形成されたものを「ネットワーク」と呼びます。前回説明したのはここまでです。

ここで、機械学習の説明を思い出してみてください。機械学習(教師あり学習)では、教師データが持つ正解と、その時点のモデルが出力する値を見て、パラメータを微調整するのだと説明してきました。機械学習の一種であるディープラーニングにおいて、パラメータに相当するのが重みやバイアスです。

ネットワークは教師データを用いて重みとバイアスの値を調整することで、教師データに潜むパターンやルールを学習していきます。では、上図のようなパーセプトロンを用いたネットワークで、微調整は可能でしょうか。

CやDは、1か0しか出力できませんから、重みやバイアスをちょっと変えただけで1が0になったり、0が1になったりします。つまり、出力が2択しかないために「ちょっとだけここの重みを増やそう」とか、「ここの重みはあちらに比べて、ほんの少しだけ減らしたほうがいいな」という細かな調整が生かせません。どうしたらよいのでしょうか?

「活性化関数」を使おう

機械学習でとても重要な微調整ができないのは、非常に大きな問題です。

そこで、出力として0から1の間のあらゆる値が出るようにします。AとBとバイアスの値が合算されてCに入るところまでは変わりませんが、Cで「入力された値が0以上ならば1、0未満ならば0を出力する」とされていたところを変えましょう。Cに送られてきた値を変化させるフィルターを設定するようなイメージです。

このCの値を変化させるフィルターは「活性化関数」と呼ばれます。名前は難しいですが、要するに入力された数を別の数に変化させるものです。最初、Cに設定されていた「0以上ならば1、0未満ならば0を出力する」という条件も、Cの値を変化させるという意味ではフィルターの一種だと言えます。つまり、「0以上ならば1、0未満ならば0を出力する」活性化関数が設定されていた、ということです。

ここで「0以上ならば1、0未満ならば0を出力する」活性化関数を、「入力に応じて0から1の間のあらゆる値を出力する」活性化関数へと変えてみます。これまでは、何が入力されても0か1のいずれかしか出力されませんでしたが、今度は「0.001、0.002、0.003……」といった値も出力される可能性があるわけです。出力のバリエーションが無数に広がることがおわかりいただけるでしょう。なお、活性化関数にはさまざまな種類があるので、課題に応じて適切なものをあらかじめ設定しておくことになります。

ネットワークの構造や動きは同じですが、出力される値は0か1ではなく、0~1の間の全ての値が出力されるようになりました。このようなネットワークは「ニューラルネットワーク」と呼ばれます。ニューラルネットワークでは0層目を「入力層」、最終層を「出力層」、それ以外の入力層と出力層の間にある層を「隠れ層」と呼びます。

0層目を「入力層」、最終層を「出力層」、それ以外の入力層と出力層の間にある層を「隠れ層」と呼ぶ

ディープラーニングとは、このニューラルネットワークがディープに(深く)なったもののことです。ただし、何層くらいになればディープラーニングと呼ばれるのかはきちんと定義されていません。一般的には隠れ層を2層以上持つニューラルネットワークによる学習をディープラーニングと呼ぶことが多いです。

原理は1950年代という非常に早い時期に出来ていたにも関わらず、ディープラーニングがすぐに流行らなかったことには大きく2つの理由があります。1つは、層を深くした場合に重みをうまく計算(調整)することができなかったためです。もう1つは、層が深くなればなるほど計算量が増え、当時のコンピュータでは計算できなかったことが挙げられます。

また少し異なる観点で言えば、ディープラーニングを用いて精度の高い学習をするためには膨大なデータが必要ですが、当時はそのような大規模なデータはなかった、ということもあるのではないかと思います。技術の進歩でこれらの課題がクリアされた結果、現在のディープラーニング旋風が起こったのです。

より深く学んで行く方向けの「+α」

ここで、これから本格的にディープラーニングを学習する方に向けて、2つ補足をしておきたいと思います。

まず、本連載では出力層にはいつも1個だけ値があるかのように記載していましたが(例えば上図のE)、実際には出力層にいくつ値が出ていても構いません。ディープラーニングでは解きたい課題に応じてネットワークの構造を設定しますが、その際に出力層に出力する値の数も決めておく必要があります。

例えば、手書き文字の認識をしたい場合、入力される手書き文字が「1」かどうかだけを判定したいのであれば、出力層の値は1個で良いでしょう。その際、最終的に出力層から出力される値は「入力された手書き文字が1である確率」となります。

一方、入力される手書き文字が0~9のいずれであるかを判定したいのであれば、出力層に出力される値は10個になるように設定しておくべきでしょう。出力層から出力される値は「入力された手書き文字が0である確率」「入力された手書き文字が1である確率」「入力された手書き文字が2である確率」……と続き、「入力された手書き文字が9である確率」まで出力されます。

解きたい課題に応じて、出力層に出力する値の数を決めておく。入力される手書き文字が0~9のいずれであるかを判定したいならば、出力層に出力する値は10個必要

また、ニューラルネットワークでは重みやバイアスは各々異なる値を持っていますが、隠れ層の活性化関数は同じものを使うのが一般的です。出力層に設定する活性化関数だけは他の層とは異なるものを用いることが多いのですが、詳細はここでは割愛します。

著者紹介


国立研究開発法人 情報通信研究機構
ユニバーサルコミュニケーション研究所
データ駆動知能システム研究センター 専門研究員
大西可奈子

2012年お茶の水女子大学大学院博士後期課程修了。 博士(理学)。同年、大手通信会社に入社。2016年より現職。
一貫して自然言語処理、特に対話に関する研究開発に従事。
人工知能(主に対話技術)に関する講演や記事執筆も行う。
twitter:@WHotChocolate