可能な限り減少させる移動方向を見つけようとしているのです。より決まるということから証明できます。減少させる方向へと小刻みに動く方法と見なすことができます。最後の段落の主張を証明してください。コーシーシュワルツの不等式について詳しくなければ、習熟することが理解に役立つでしょう。二つの変数である場合と二つ以上の変数の関数の場合について説明しました。一つの関数の場合は何が起こるでしょう?あなたは一次元の場合の勾配降下法の動きについて幾何学的な説明が出来ますか?より現実のボールに近い形で物理法則を摸倣する種類を含め、これまで様々な勾配降下法が研究されてきました。いったボールを模倣する種類はいくつか長所を持っているものの、大きな欠点も持っています:二階偏微分の計算が必要であり、その計算が非常に大変なのです。計算したいと仮定してみましょう。!の計算が必要で計算量的に重くなります。言っても、こういった問題を回避する手段はいくつか存在していますし、また勾配降下法の代替手段の調査は研究が盛んな分野になっています。私たちはこの本では勾配降下法(とその派生形)をニューラルネットワークの学習への主要なアプローチに使いましょう。\nonumber\end{eqnarray}のコストを最小化する重みとバイアスの探索に勾配降下法を用いるというものです。重みとバイアスに置き換えて勾配降下法の更新規則を再定義しましょう。持っていることに一致します。この更新規則を繰り返し適用することで"坂を転がり降りる"ことができ、上手くいけばコスト関数の最小値を見つけられます。言い換えれば、この規則をニューラルネットワークの学習に使うことが出来ます。勾配降下法の規則の適用にはいくつか課題があります。この詳細は後の章で見ることにしましょう。それより今は一つの問題にだけ言及したいと思います。\nonumber\end{eqnarray}の二次コスト関数を振り返りましょう。総和になっていることが分かると思います。不運にも、訓練入力の数が非常に大きい場合はとても時間が掛かり、その結果学習は非常に遅くなってしまいます。学習の高速化に使えるアイディアの一つに確率的勾配降下法と呼ばれるものがあります。推定するというものです。推定でき、勾配降下法が高速化され、ひいては学習を高速化できます。無作為抽出し、訓練入力をその数だけ無作為に選ぶことで動くということです。ラベル付けし、これらをミニバッチと呼ぶことにしましょう。ここで二つ目の総和は全ての訓練データです。ランダムに選んだミニバッチを計算して全体の勾配を推定できることが確認できます。無作為に選んだ訓練入力のミニバッチによって動き、それらで訓練を行います。次に、私たちは別の無作為に選んだミニバッチで訓練を行います。同じように、訓練入力がなくなるまで続ければ、1回の訓練のエポック(訳注:訓練データ全体を1巡する事)が完了します。この時点で私たちは新しい訓練エポックをやり直します。ちなみに、コスト関数とミニバッチで重みとバイアスを更新する縮尺の取り方によって、更新規則が異なってくることは注目に値します。省略し、個々の訓練例のコストの平均を取る代わりに総和を取ります。これはとりわけ訓練例の総数が事前に分かっていない場合に有効です。これは、例えば、リアルタイムに訓練データが生成されている場合に生じ得ます。縮尺の大きさを変更することに相当するので概念的には大差がありません。世論調査のように考えることができます:国民総選挙よりも世論調査を実施する方が簡単であるように、全部一括処理で実施するより小さな標本のミニバッチの方が勾配降下法の適用は簡単です。ニューラルネットワークの学習によく用いられている強力な手法であり、また、私たちがこの本で開発する学習テクニックにおける大部分の基礎になります。極端な勾配降下法は大きさ1のミニバッチを使います。その次に、別の訓練入力を選び、そして再びバイアスを更新します。この手続きはオンライン学習または逐次学習として知られるものです。オンライン学習は、ニューラルネットワークの一回の学習を一つの訓練入力で行います(ちょうど人間がそうするように)。場合と比較して挙げてください。本節の結びに勾配降下法に慣れていない人をしばしば悩ませる点を議論させてください。それゆえに非常に高次元な空間上の曲面であるともいえます。一部の人はこのとき、"私はこれらの超次元の可視化ができるようになる必要がある"と考え、困ってしまいます。彼らは心配しはじめます:"私は四次元で考えることができないし、五次元(あるいは五百万次元)なんてもっと無理だ"。彼らには"真の"数学者が持っている何か特別な能力が欠けているのでしょうか?勿論、答えはノーです。本職の数学者でも四次元の可視化はできませんし、それ以上についてはなおさらです。彼らは別の表現方法を開発するというトリックを使っているのです。代数表現です(視覚化ではなく)。高次元について考えるのが得意な人は頭の中にこの種の多種多様なテクニックをライブラリとして持っています;私たちの代数的トリックもその一つです。これらのテクニックには私たちの慣れている三次元を視覚化する時の簡素性は持ってませんが、ひとたびそういったテクニックのライブラリを確立すれば、あなたは高次元について考えることがとても得意になるでしょう。読んで楽しめるでしょう。いくつかのテクニックに関する議論は非常に難解ですが、たくさんの素晴らしいコンテンツが直観的でとっつきやすく、そして、全ての人が習得できるものです。数字を分類するニューラルネットワークの実装それでは、手書き数字を認識する方法を学ぶプログラムを作成していきましょう。MNISTの訓練データを使用します。最初に私たちはMNISTデータを手に入れる必要があります。あなたがgitのユーザーならば、下記のリポジトリからクローンすることでデータを取得できます。ユーザーではない場合は、あなたはここからデータとコードをダウンロードすることができます。10,000枚の試験用画像に分かれているって言いましたよね。じつは、データの分け方を少々変えようと思います。検証データセットとしてとっておきます。ハイパーパラメータを設定するのに重宝します。学習アルゴリズムで直接選択できないもののことです。多くの人はMNISTをこのやり方で使っていますし、検証データはニューラルネットワークではよく使われます。50,000枚の画像からなるデータセットのことを指すこととします。(NIST)によって定義されているものです。Burgesによって整理・より便利なフォーマットを追加されました。詳しいことには、こちらのリンクを見てください。私のレポジトリの中のこのデータセットは、Pythonによって読み込みしやすく、操作しやすいフォーマットになっています。(link)から取得しました。MNISTデータとは別に、高速に線形代数を解くことができるNumpyと呼ばれるPythonライブラリーが必要です。あなたがNumpyをインストールしていないならば、ここから手に入れてください。それでは、完全なプログラムリストを示す前に、ニューラルネットワークのコードのコア機能の説明を以下でしましょう。コードの中心部はNetworkクラスであり、ニューラルネットワークを表現するために使います。以下が、Networkを初期化するためのコードです。sizes[1:])]sizesは、それぞれの層におけるニューロンの数を表しています。1層目に2つのニューロン、2層目に3つのニューロン、最終層に1つのニューロンを持つNetworkを作りたいならば、以下のようにコードを定義します。1])Networkの中のバイアスと重みは、Numpyのnp.random.randnによって生成された平均値0・標準偏差1のガウス分布の乱数に初期化されます。開始点として使用します。今回は乱数によって初期値を決めることにしますが、後半の章では、重みとバイアスの初期化のより良い方法を解説します。Networkの初期化のコードでは、ニューロンの1層目は入力層であり、バイアスは後半の層から出力を計算するときにだけ使われるので、入力層のニューロンのバイアスは省略する仮定をしていることについて注意してください。Numpy内の行列のリストとしてバイアスと重みは保存されることについても注意してください。net.weights[1]は、2層目と3層目をつなぐ重みを保存するNumpyの行列です。0から開始されるので、1層目と2層目を繋ぐ重みではありません。net.weights[1]という記述は冗長なので、ここでは$w$という行列として示しましょう。2層目の$k$番目のニューロンと3層目の$j$番目のニューロンを繋ぐ重みです。この$j$と$k$の順序は奇妙に見えるかもしれません。確かに$j$と$k$を交換するほうが理に適っていそうです。この順序の大きな利点は、ニューロン3層目の活性化のベクトルは以下を意味することです。この式では、かなり多くの振る舞いがあるので一つ一つ紐解いてみましょう。$a$は2層目の活性化のベクトルです。$a'$を得るために、私たちは$a$と重み行列$w$を掛け算し、バイアスのベクトル$b$を足し算します。+b$に関数$\sigma$を作用させます。(これは関数$\sigma$のvectorizingと呼ばれます。同じ結果になることを確認するのは簡単です。同じ結果を与えることを確認しましょう。出力を計算するコードを記述するのは簡単なことがわかります。シグモイド関数を定義することからはじめます。このとき、シグモイド関数はベクトル形式でNumpyを使って定義します。与えられたら、対応した出力を返すfeedforwardをNetworkクラスに追加します。aもちろん、Networkにしてほしいことは学習することです。そのために確率的勾配降下法(SGD)を使用します。コードはここに記します。不可解な場所がありますが、それについては下記で解説していきます。変数epochsとmini_batch_sizeは訓練のための世代数と、サンプリングするときに使用するミニバッチの大きさです。変数etaは学習率$\eta$です。オプションの引数test_dataがある場合、プログラムは各訓練のエポックのあとにネットワークを評価して、現在の進行状況を出力します。この機能は性能改善の進行状況を確認するときに役に立ちますが、計算に少し時間がかかるようになります。コードは以下のように機能します。各エポックでは、訓練データをランダムにシャッフルすることによって開始し、適切なサイズのミニバッチに分割します。このコードは、訓練データからランダムにサンプルする簡単な方法になります。各ミニバッチに、勾配降下法を1ステップ実行します。ミニバッチの訓練データだけを使用して勾配降下法を実行し、ネットワークの重みとバイアスを更新します。ここに、update_mini_batchのコードを示します。y)このコードは、コスト関数の勾配を計算する高速な方法である誤差逆伝播法(backpropagation)アルゴリズムを起動する部分です。update_mini_batchは単純にミニバッチ内の訓練データごとに勾配を計算し、self.weightsとself.biasesを適切に更新します。self.backpropのコードは今すぐには説明しません。次の章で誤差逆伝播法について勉強し、その際にself.backpropのコードを紹介します。今は、訓練データのxに関連するコストに対して適切な勾配を返す働きをするということを前提にします。それでは、下記の完全なプログラムを見てください。この際、説明を省略した部分や説明文を含んでいます。self.backpropを除いて、プログラムは明快であり、すでにお話しした通り、全ての処理の重い部分はself.SGDとself.update_mini_batchで行われています。$\sigma$関数の導関数を計算するsigmoid_prime、ベクトル形式のsigmoid_prime_vecとself.cost_derivativeです。次の章で詳細を確認しますが、コードと説明を見る事によって要点を理解する事ができます。プログラムが長いように見えますが、多くはプログラム内の理解を促すための解説文であり、コード自体は理解が簡単に書いているつもりです。実際、プログラムはたった空行と解説を除いて74行です。コードのすべてはGitHubで見つけることができます。np.vectorize(sigmoid_prime)それでは、このコードがどれだけ良く手書き数字を認識できるかを確認していきましょう。MNISTデータをダウンロードするところからはじめてみよう。ここではmnist_loader.pyを使用します。以下のコマンドをpythonシェルで実行してください。ここまで従ってきたならば、pythonシェルで簡単に処理できるでしょう。MNISTデータをダウンロードした後、私たちは$30$個の隠れニューロンをもつNetworkを設定します。私たちはnetworkと名前を付けた上記のpythonプログラムをインポートした後に、この処理を行います。3.0$の条件で、MNISTのtraining_dataから確率的勾配降下法を使用して学習します。test_data=test_data)もしこの文章を読みながらコードを実行しているならば、この計算は少々時間がかかるので注意してください。2014年における一般的なスペックのパソコンならば、訓練の1世代ごとに数分程度かかります。計算を実行しつつ、読み続けて、たまに計算結果を確認することをおすすめします。あなたが急いでいる場合は、あなたは世代数を減らすか、隠れニューロンの数を減らすか、訓練データの一部のみ使用することによって計算を速くすることができます。このpythonコードはニューラルネットワークを理解することを助けることが目的であるため、計算が早いわけではありません。一度ニューラルネットワークを訓練すれば、私たちは多くのコンピュータープラットホーム上で非常に高速に実行することができます。ニューラルネットワークの重みとバイアスの良いセットがあれば、webブラウザのJavascriptや、携帯デバイスのアプリに移植し、実行するのは簡単です。それでは以下に、ニューラルネットワークのある訓練プロセスの一部の結果を示しましょう。この出力は訓練のエポックごとにニューラルネットワークを使用して適切に訓練データを認識できた数を表しています。最初の世代が終わったあとに10000個中の9129個が正しく認識できており、その後は増加し続けていることがわかります。10000訓練されたネットワークは95%の分類率を有しており、ピーク性能は28世代での95.42%でした。この結果は、最初の試みとしては大変有望です。このコードを実行したとしても、上記で示した値と全く一緒になるとは限らないことに注意してください。この章では、3回の計算のうちのベストの解を示しています。それでは、隠れニューロンの数を100個にして上記の実験を再計算してみましょう。この計算も同様に時間がかかりますので、計算を実行しつつ読み進めることが賢明です。(今回の場合、隠れニューロンの数が多いので各世代での計算時間がよりかかるので。test_data=test_data)予想通り、この計算では性能が96.59%に向上しました。少なくともこのケースでは、より多くの隠れ層を使用することでより良い結果を得ることが出来ます。*読者のフィードバックによると、この実験では性能の違いが報告されており、いくつかの計算結果ではかなり性能が悪くなるようです。3章で紹介するテクニックを使用することで、計算ごとの予測性能の違いを劇的に減らすことができます。これらの精度を獲得するために、訓練のエポック数、ミニバッチのサイズ、学習率$\eta$を具体的に選択しなくてはなりませんでした。上記のように、学習アルゴリズムによって学習するパラメータ(重みとバイアス)と区別するために、これらはニューラルネットワークのハイパーパラメータとして呼ばれています。ハイパーパラメータを不適切に選択したならば、悪い結果を得ることになります。test_data=test_data)結果の改善の進捗は遅くなってしまいます。10000しかしながら、ネットワークの予測性能はゆっくりと良くなっていくことがわかります。0.01$にしてみましょう。この設定で計算した場合、より良い結果を得ることができます。この結果は、さらに学習率を増加させたほうが良いことを意味します。(もし変更を与えて性能が改善したならば、さらに変更を大きくさせてみてください。1.0$程度になるでしょう。最初にハイパーパラメータの不適切な選択をしたにもかかわらず、少なくともハイパーパラメータを選び方について性能を改善する情報を得ることができました。場合、ニューラルネットワークをデバッグすることは困難なことであると言えます。ハイパーパラメータの初期の選択が悪く、ランダムノイズとほぼ同然の結果しか得られないときは、特に困難です。100.0$に変更した場合を仮定してみましょう。test_data=test_data)この設定は実際に度を超しているとは思っていましたが、やはり学習率が高すぎるようです。10000初めてこの問題に直面したことを、今想像してみてください。私たちは前の実験を知っていて、学習率を下げることが正しいことだということを今は知っています。この問題に初めて直面する場合、出力結果は、何をすべきかを教えてはくれません。学習率だけでなく、ニューラルネットワークの他の全ての側面について心配するかもしれません。ネットワークが学習することを難しくさせるような方法で重みとバイアスを初期化したのかもしれないと疑うかもしれません。それとも、意味のある学習をするための十分な訓練データを持っていないと思うかもしれません。十分なエポック数を計算していないのかもしれない?手書き数字を認識するために学習することはニューラルネットワークでは不可能と思うかもしれません。この問題に直面する際は、常に何もわからない状態にあるのです。これらの疑問を取り除くためのニューラルネットワークのデバッグとしてのレッスンは些細な問題ではありません、そして通常のプログラミングに関して言えば、関係した技術があります。ニューラルネットワークから良い結果を得るためのデバッグ技術を学ぶ必要があります。一般的に言えば、私たちは良いハイパーパラメータと良いアーキテクチャを選択するためのヒューリスティック技術を開発する必要があります。この本を通して、上記のハイパーパラメータの設定方法を含むこれらの技術について解説します。Exercise隠れ層がない入力層と出力層のみの2層のネットワークを作ってみてください。それぞれニューロンは、784個と10個です。確率的勾配法で学習させてみてください。どんな分類精度を達成できるでしょうか。以前、MNISTデータのロード方法の詳細について説明を省略していました。簡単ではありますが、念のためにコードを以下に載せました。MNISTデータを格納するために使われるデータ構造は、資料内の解説にある通りで、Numpyのndarrayオブジェクトです。(もしndarrayに馴染みがない方は、ベクトルとして考えてください。eこのプログラムはかなり良い結果を得られたと言いました。これはどういう意味でしょうか。何と比較して良いと言っているのでしょうか。お互いに比較したり、何がよい実行結果なのかを理解したりするために、いくつかのニューラルネットワークではない単純な性能基準を持つことは有益です。全ての中で最もシンプルな基準は数字をランダムに推測するものです。それは、性能は10%程度になるでしょう。私たちは、それよりも遥かに良い性能を持っています。取るに足らなくない基準とはなんでしょうか。それでは、とてもシンプルなアイデアに挑戦してみましょう。画像がどれくらいか暗いかについて見ています。「2」の画像は「1」の画像に比べて、より暗い画像となります。下記の例を見ればわかる通り、多くのピクセルが黒く塗りつぶされているからです。9$)の黒色を持つピクセルの平均を計算するために訓練データを使用することを提案しています。新しい画像が示されたとき、画像がどれだけ黒いかを計算し、最も近い黒色を持つピクセルの平均の数字として区別します。これは簡単な手順であり、コーディングも簡単です。repositoryに公開しておきます。この方法では、10000枚の訓練データのうち2225枚を適切に区別することができ、つまり22.25%の精度、ランダム推測に比べて大きな改善をもたらします。予測精度20から50%程度の他のアイデアを見つけることは難しくありません。あなたが少し頑張れば、予測精度50%に到達できるでしょう。高精度を取得するためには、機械学習アルゴリズムを使用することが手助けになるでしょう。知られている手法の一つであるサポートベクターマシン(SVM)について挑戦してみましょう。SVMに馴染みがなかったとしても、心配しないでください。SVMの働きについて詳細に理解する必要はありません。代わりに、私たちはLIBSVMとして知られているSVMの高速なCベースのライブラリのpythonインターフェースであるscikit-learnというライブラリを使用します。scikit-learnのSVM分類器のデフォルト設定で計算したとすれば、10000個の画像中の9435個を適切に分類できます。(コードはここにあります。黒色の平均値に基づく分類から考えると、とても大きな改善です。確かに、SVMはだいたいニューラルネットワークと同じくらいか、ちょっと悪いくらいの性能を持っています。後の章では、私たちはSVMをはるかに超える良い性能を得るために、ニューラルネットワークを改良する新技術を紹介します。話はこれで終わりではありません。10000個中の9435個の適切な分類は、scikit-learnのデフォルト設定のSVMによるものでした。SVMは調整可能なパラメータをいくつか持っていて、さらに性能の良い判別が行うことができるパラメータを探すことができる可能性があります。Muellerのブログを確認してください。Muellerは、SVMのパラメータを最適化することで、98.5%の予測性能に到達していることを示しています。言い換えれば、適切にチューニングされたSVMでは間違いを70個しかしないことになります。これは、かなり良い性能です。ニューラルネットワークはこれより良い推定ができるでしょうか。現在、よく設計されたニューラルネットワークは、SVMを含めて他のMNISTの識字アルゴリズムの中で最も優れています。2014年現在の記録では、10000個中9979個の画像を適切に分類することが出来ています。Fergusによって行われたものです。この本の中の後半で、彼らが使用した技術の多くを見ることができます。その性能のレベルは人間とほぼ同等であり、おそらくより良いものです。人間が自信を持って認識することさえ難しいMNIST画像がいくつかあるからです。以下のようなものです。これらを分類するのは難しいと認めることを確信しています。MNISTデータセットの中でこのような画像があるのにもかかわらず、ニューラルネットワークは10000個の画像の中の21個以外は適切に分類できることは驚くべきことです。プログラミングをするとき、たいていはMNISTの識字を理解するような複雑な問題を解くことは、高度なアルゴリズムが必要だと考えています。Wanらのペーパーの中で言及したニューラルネットワークはかなりシンプルなアルゴリズムを意味しています。私たちがこの章で見てきたアルゴリズムのバリエーションも含んでいます。Learningに向けてニューラルネットワークは印象的な性能を提供していますが、その性能はやや神秘的です。ネットワークの重みとバイアスが自動的に発見されました。これはつまり、ネットワークがどのように機能しているかについて説明できないことを意味します。そのような原理を考え、さらによりよく出来るでしょうか?この質問により厳密に答えるために、向こう20~30年でニューラルネットワークは人工知能(AI)になるだろうと考えてください。私たちは、そんな賢いネットワークがどのように働くかを理解できるでしょうか。したら、私たちが把握していない重みとバイアスを使ったネットワークは、不透明なものになるかもしれない。いうのも、ネットワークは自動的に学習してきたからです。初期のAI研究者は、AIを構築するための努力によって知能の原理(人間の脳機能のような)を理解できるようになる、そんなことを望んでいました。私たちは脳だけでなく、人工知能の働きさえ理解せずに終わってしまうことになるかもしれません!これらの問題に答えるために、この章の最初に説明した人工ニューロンのパーセプトロンについて振り返ってみましょう。画像が人の顔を示しているか否かを判断したいとします。details.この問題に対しても、手書き文字認識と同じ方法で取り組むことができます。ニューラルネットワークの入力として画像のピクセルを使い、1つの出力ニューロンによって「顔である」か「顔でない」かを判定させるのです。学習アルゴリズムは使いません。その代わりに、ネットワークを手動で設計し、適切な重みとバイアスを設定していきます。どのように取り組めばよいでしょうか?ニューラルネットワークを一瞬全て忘れるとして、私たちが使うことのできるヒューリスティクスによって問題を小さな問題に分割します。「画像の左上に目はあるか」「画像の右上に目はあるか」「画像の中心に鼻はあるか」「画像の中央下に口はあるか」「髪の毛は上のほうにあるか」などなど。これらの質問の答えのいくつかが「YES」や「おそらくYES」だとすれば、その画像は顔であると言えるでしょう。逆に、質問の答えがほとんど「NO」だとすれば、それはおそらく顔ではないでしょう。これはかなり荒いヒューリスティクスであり、多くの欠点を持ちます。禿げた人を考えた場合は、彼らには髪の毛がありません。私たちは、顔の一部のみだったり、顔に角度がついていたり、顔の一部が隠されていたりしても、顔だと判断できます。それでも、このヒューリスティクスによって次のような示唆を得ることができます。小さい問題をニューラルネットワークを使って解くことができるなら、それらネットワークを組み合わせることで、顔判定のためのネットワークを構築することができる、ということです。以下に、ありうりそうなアーキテクチャを示しましょう。これは、サブネットワークを長方形で表しています。ここでは顔認識問題を解くための現実的なアプローチは意図していないことに注意してください。これは、どのようにネットワークが機能するかについて直感的な理解を促してくれます。サブネットワーク自体も小さく分解できる、というのはいかにもありそうなことです。それでは次のような質問について検討してみましょう。「画像の左上に目があるか?」これは次のような質問にさらに分けることができます。「眉毛はあるか?」「まつ毛はあるか?」「眼球の光彩はあるか?」などです。これらの質問は、実際は位置の情報を含んでいるべきです。「画像の右上に眉毛はあるか?それは光彩の上にあるか?」というように。このような感じですが、シンプルにはしておきましょう。このようにして、「左上に目はあるか?」は次のように分解できます。いった質問は、複数の層を介して、さらにさらに分解して行くことが可能です。究極的には、単一のピクセルレベルで簡単に答えられるようなシンプルな質問に答えるサブネットワークで作業することになります。その質問は、画像内のある特定の点での、シンプルな形状の有り・無しかもしれません。その手の質問は、画像のピクセルにそのまま直接接続された、単一のニューロンによって答えることができます。最終的な結果は、非常に込み入った問題(「画像は顔を表しているか否か」のような)を、単一のピクセルレベルで答えられる問題に分解したネットワークになります。以上の結果を得るためには、入力画像についてとても簡単で特定の質問に答える初期の層と、より複雑で抽象的な概念の階層を構築している後半の層を含む多くの層を通ることが必要です。多くの隠れ層(2つかそれ以上)を含む多層構造のネットワークは、ディープニューラルネットワークと呼ばれています。どのように再帰的にサブネットワークに分けていくのかについては、述べていません。ネットワーク内の重みとバイアスを手動で設計するのは、実用的ではありません。代わりに訓練データから、自動的に重みとバイアス(さらに言えば、概念の階層構造まで)を習得できるような学習アルゴリズムを使います。誤差逆伝播法をディープネットワークの訓練に使用してみようとしました。残念ながら、いくつかの特別なアーキテクチャを除いて、彼らは良い結果を得られませんでした。学習はするのですが、とても遅く、現実的に使用できませんでした。これらの学習技術は確率的勾配降下法と誤差逆伝播法に基づいてはいますが、新しいアイデアが追加されています。これらの技術は、より深く(そしてより大きな)ネットワークを訓練可能にし、現在では5~10層のネットワークが当然のように訓練されています。浅いニューラルネットワーク(特に隠れ層が1層のみの場合)よりも、多くの問題解決において非常に良くなっていることがわかりました。これは、ディープネットワークが、概念の複雑な階層構造を構築できるからです。従来のプログラム言語で複雑なプログラムを作るときによく使う、モジュール方式のデザインと考え方に少し似ています。ディープネットワークと浅いネットワークの関係は、関数作成と呼び出しが可能なプログラム言語と、そのような能力を持たない言語の関係に少し似ています。抽象化は、従来のプログラミングにおけるものとは異なる形式を取りますが、それは極めて重要なことなのです。