次の方法で共有



February 2018

Volume 33 Number 2

機械学習 - CNTK を使用したディープ ニューラル ネットワーク分類器

James McCaffrey

Microsoft Cognitive Toolkit (CNTK) ライブラリは、機械学習 (ML) 予測システムの作成を可能にする関数の強力なセットです。2017 年 7 月号 (msdn.com/magazine/mt784662) では、バージョン 2 について紹介しました。今回は、CNTK を使用してディープ ニューラル ネットワーク分類器を作成する方法を解説します。今回の主旨を理解するには、図 1 のスクリーンショットを見るのが一番です。

小麦種子の種類を予測するデモ
図 1 小麦種子の種類を予測するデモ

CNTK ライブラリはパフォーマンス上の理由から C++ で記述されています。しかし、ライブラリ関数の呼び出しには CNTK Python 言語の API を用いるのが最も一般的です。ここでは、通常の Windows 10 コマンド シェルで以下のコマンドを発行して、デモ プログラムを呼び出しました。

> python seeds_dnn.py

デモ プログラムの目標は、小麦種子の種類を予測できるディープ ニューラル ネットワークの作成です。デモ プログラムでは、背後で以下のようなトレーニング データ セットを使用しています。

|properties 15.26 14.84 ... 5.22 |variety 1 0 0
|properties 14.88 14.57 ... 4.95 |variety 1 0 0
...
|properties 17.63 15.98 ... 6.06 |variety 0 1 0
...
|properties 10.59 12.41 ... 4.79 |variety 0 0 1

このトレーニング データには 150 個の項目があります。各行は 3 種類の小麦種子「Kama」、「Rosa」、「Canadian」のうちの 1 つを表します。 各行の最初の 7 個の数値は予測値です。機械学習用語では多くの場合、属性またはフィーチャーと呼ばれます。予測値は、種子の面積、周の長さ、密集度、丈、幅、アシンメトリー係数、溝の長さです。予測結果項目 (多くの場合、クラスまたはラベルと呼ばれます) は、最後の 3 つの列に設定され、1 0 0 が Kama、0 1 0 が Rosa、 0 0 1 が Canadian としてエンコードされます。

また、デモ プログラムでは 60 項目のテスト データ セットを使用します。各種子の種類に 20 項目が対応します。テスト データの形式は、トレーニング データの形式と同じです。

デモ プログラムでは、7-(4-4-4)-3 のディープ ニューラル ネットワーク を作成します。図 2 にこのネットワークを示します。ネットワークには 7 個の入力ノード (各予測値につき 1 個)、それぞれが 4 個の処理ノードを持つ 3 個の隠し層、および 3 つにエンコードされる小麦種子の種類に対応する 3 個の出力ノードがあります。

ディープ ニューラル ネットワークの構造
図 2 ディープ ニューラル ネットワークの構造

デモ プログラムでは、それぞれが10 個の項目を含む 5000 個のバッチを使用するネットワークを、確率的勾配降下 (SDG) アルゴリズムを使用してトレーニングします。予測モデルのトレーニングが完了したら、60 項目のテスト データ セットに当てはめます。このモデルは 78.33% の正確性を達成しました。つまり、60 個のテスト項目のうち 47 項目が正確に予測されたことになります。

デモ プログラムは種類が不明の小麦種子の種類を予測して終了します。7 個の入力値は (17.6, 15.9, 0.8, 6.2, 3.5, 4.1, 6.1) です。計算された出力ノード値そのものは (1.0530, 2.5276, -3.6578) で、関連付けられた出力ノードの確率値は (0.1859, 0.8124, 0.0017) です。真ん中の値が最も大きいため、出力は (0, 1, 0)、つまり Rosa にマッピングされます。

 今回は、読者が C ファミリ言語の中級レベルまたはそれ以上のプログラミング スキル、およびニューラル ネットワークの基礎知識を持っていることを前提とします。しかし、背景知識に関わらず、それほど苦労することなく理解できるでしょう。ここには、seeds_dnn.py プログラムのソース コードをすべて掲載しています。コード、および関連するトレーニング データ ファイルとテスト データ ファイルは、本稿付随のコード ダウンロードから入手することもできます。

CNTK v2 のインストール

CNTK v2 は比較的新しいので、インストール プロセスに馴染みがないかもしれません。簡単に説明すると、まず Python 言語ディストリビューションをインストールします (Anaconda ディストリビューションを強くお勧めします)。ディストリビューションには、中核となる Python 言語、必要な Python パッケージが含まれます。次に、追加の Python パッケージとして CNTK をインストールします。つまり、CNTK 単独ではインストールされません。

本稿執筆時点の CNTK の最新バージョンは v2.3 です。CNTK は活発に開発されているため、本稿が公開されるころには新しいバージョンがリリースされているかもしれません。今回は、Anaconda ディストリビューションのバージョン 4.1.1 (Python のバージョン 3.5.2、NumPy のバージョン 1.11.1、SciPy のバージョン 0.17.1 が含まれます) を使用しました。Anaconda をインストールしたら、pip ユーティリティ プログラムを使用して CPU 版 の CNTK をインストールします。CNTK のインストールは、バージョンの互換性について注意しないと少しやっかいになる可能性があります。ただし、CNTK のドキュメントにはインストール プロセスについて詳しく説明されています。

データについて

機械学習システムの作成はほとんどの場合、トレーニング データとテスト データのファイルを設定することから始めます。これは時間のかかる面倒なプロセスです。手を加えていない小麦種子のデータ セットについては bit.ly/2idhoRK を参照してください。210 個の項目のタブ区切りの手を加えていないデータは、次のようになっています。

14.11  14.1   0.8911  5.42  3.302  2.7  5      1
16.63  15.46  0.8747  6.053 3.465  2.04 5.877  1

今回はユーティリティ プログラムを作成して、CNTK で簡単に処理できる形式のファイルを生成しました。その結果、210 個の項目のファイルは次のようになります。

|properties 14.1100 14.1000 ... 5.0000 |variety 1 0 0
|properties 16.6300 15.4600 ... 5.8770 |variety 1 0 0

このユーティリティ プログラムは、フィーチャーの位置を特定する "|properties" タグを先頭に追加し、予測するクラスの位置を特定する "|variety" を追加します。手を加えていないクラス値は 1-of-N エンコーディング (one-hot エンコーディングとも呼ばれます) し、タブは空白文字に置き換え、すべての予測値は正確に小数点以下 4 桁 の形式にします。

多くの場合、数値予測値を、どれもほぼ同じ範囲に収まるように正規化するのがお勧めです。今回は、説明を簡単にするためにデータを正規化しません。正規化の一般的な形式は、z スコア正規化と最小最大正規化の 2 つです。一般的に、デモ以外のシナリオでは予測値を正規化します。

次に、CNTK 形式の 210 項目のデータ ファイルを受け取り、そのファイルを使用して seeds_train_data.txt という名前の 150 項目のトレーニング データ ファイル (各種類の先頭 50 項目) と seeds_test_data.txt という名前の 60 項目のテスト ファイル (各種類の末尾 20 項目) を生成しす。

予測変数は 7 個あるため、データの完全なグラフを作成するのは現実的ではありません。しかし、図 3 に示すように、一部のデータをグラフにすることで、データの構造を大まかに把握できます。今回は 60 項目のテスト データセットの種子の周の長さと種子の密集度の予測値のみを使用しています。

テスト データの部分的なグラフ
図 3 テスト データの部分的なグラフ

ディープ ニューラル ネットワークのデモ プログラム

今回は、メモ帳を使ってデモ プログラムを作成しました。筆者はメモ帳がお気に入りですが、同僚のほとんどは利用可能な多くの優れた Python エディターを好んでいます。Python 言語アドインが含まれる無料の Visual Studio Code エディターは特にすばらしいと感じます。スペースを節約するために少し編集したデモ プログラムの完全なソース コードを 図 4 に示します。行が継続していることを示すために Python によってバックスラッシュ文字が使用されています。

図 4 完全な種子分類器デモ プログラム

# seeds_dnn.py
# classify wheat seed variety
import numpy as np
import cntk as C
def create_reader(path, is_training, input_dim, output_dim):
  strm_x = C.io.StreamDef(field='properties',
    shape=input_dim, is_sparse=False)
  strm_y = C.io.StreamDef(field='variety',
    shape=output_dim, is_sparse=False)
  streams = C.io.StreamDefs(x_src=strm_x,
    y_src=strm_y)
  deserial = C.io.CTFDeserializer(path, streams)
  sweeps = C.io.INFINITELY_REPEAT if is_training else 1
  mb_source = C.io.MinibatchSource(deserial,
    randomize=is_training, max_sweeps=sweeps)
  return mb_source
def main():
  print("\nBegin wheat seed classification demo  \n")
  print("Using CNTK verson = " + str(C.__version__) + "\n")
  input_dim = 7
  hidden_dim = 4
  output_dim = 3
  train_file = ".\\Data\\seeds_train_data.txt"
  test_file = ".\\Data\\seeds_test_data.txt"
  # 1. create network and model
  X = C.ops.input_variable(input_dim, np.float32)
  Y = C.ops.input_variable(output_dim, np.float32)
  print("Creating a 7-(4-4-4)-3 tanh softmax NN for seed data ")
  with C.layers.default_options(init= \
    C.initializer.normal(scale=0.1, seed=2)):
    h1 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
      name='hidLayer1')(X)
    h2 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
      name='hidLayer2')(h1)
    h3 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
      name='hidLayer3')(h2)
    oLayer = C.layers.Dense(output_dim, activation=None,
      name='outLayer')(h3)
  nnet = oLayer
  model = C.softmax(nnet)
  # 2. create learner and trainer
  print("Creating a cross entropy, SGD with LR=0.01, \
    batch=10 Trainer \n")
  tr_loss = C.cross_entropy_with_softmax(nnet, Y)
  tr_clas = C.classification_error(nnet, Y)
  learn_rate = 0.01
  learner = C.sgd(nnet.parameters, learn_rate)
  trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])
  max_iter = 5000  # maximum training iterations
  batch_size = 10   # mini-batch size
  # 3. create data reader
  rdr = create_reader(train_file, True, input_dim,
    output_dim)
  my_input_map = {
    X : rdr.streams.x_src,
    Y : rdr.streams.y_src
  }
  # 4. train
  print("Starting training \n")
  for i in range(0, max_iter):
    curr_batch = rdr.next_minibatch(batch_size,
      input_map=my_input_map)
    trainer.train_minibatch(curr_batch)
    if i % 1000 == 0:
      mcee = trainer.previous_minibatch_loss_average
      pmea = trainer.previous_minibatch_evaluation_average
      macc = (1.0 - pmea) * 100
      print("batch %6d: mean loss = %0.4f, \
        mean accuracy = %0.2f%% " % (i,mcee, macc))
  print("\nTraining complete")
  # 5. evaluate model on the test data
  print("\nEvaluating test data \n")
  rdr = create_reader(test_file, False, input_dim, output_dim)
  my_input_map = {
    X : rdr.streams.x_src,
    Y : rdr.streams.y_src
  }
  numTest = 60
  allTest = rdr.next_minibatch(numTest, input_map=my_input_map)
  acc = (1.0 - trainer.test_minibatch(allTest)) * 100
  print("Classification accuracy on the \
    60 test items = %0.2f%%" % acc)
  # (could save model here)
  # 6. use trained model to make prediction
  np.set_printoptions(precision = 4)
  unknown = np.array([[17.6, 15.9, 0.8, 6.2, 3.5, 4.1, 6.1]],
    dtype=np.float32)
  print("\nPredicting variety for (non-normalized) seed features: ")
  print(unknown[0])
  raw_out = nnet.eval({X: unknown})
  print("\nRaw output values are: ")
  for i in range(len(raw_out[0])):
    print("%0.4f " % raw_out[0][i])
  pred_prob = model.eval({X: unknown})
  print("\nPrediction probabilities are: ")
  for i in range(len(pred_prob[0])):
    print("%0.4f " % pred_prob[0][i])
  print("\nEnd demo \n ")
# main()
if __name__ == "__main__":
  main()

デモではまず必要な NumPy および CNTK パッケージをインポートし、np および C というショートカット エイリアスを各パッケージに割り当てます。create_reader 関数は、トレーニング データの読み取り (is_training パラメーターが True に設定されている場合) と、テスト データの読み取り (is_training が False に設定されている場合) に使用できるプログラム定義のヘルパーです。

create_reader 関数は、ニューラル ネットワーク分類問題の定型コードと考えることができます。ほとんどの状況で唯一変更する必要があるのが、StreamDef 関数の呼び出しにおける field 引数の 2 つの文字列です。このデモでは "properties" と "varieties" です。

プログラムの制御ロジックはすべて単一の main 関数に含めています。デモのサイズを小さく抑え、中心となる考え方を明確にするために、通常のエラー チェックはすべて省略しています。一般的にはスペース 4 文字でインデントしますが、コラムの領域を節約するために、デモでは 2 文字にしています。

ネットワークとモデルを作成する

main 関数ではまず、ニューラル ネットワーク アーキテクチャの次元数を設定します。

def main():
  print("Begin wheat seed classification demo")
  print("Using CNTK verson = " + str(C.__version__) )
  input_dim = 7
  hidden_dim = 4
  output_dim = 3
...

CNTK は急速に開発が進んでいるため、使用しているバージョンを出力するかコメントを追加すると良いでしょう。デモでは 3 つの隠し層があり、すべての隠し層に 4 個のノードがあります。隠し層の数と各層のノードの数は試行錯誤によって決めなければなりません。必要に応じて各層に異なる数のノードを含めることも可能です。たとえば、hidden_dim = [10, 8, 10, 12] は、それぞれ 10、8、10、12 個のノードを持つ 4 つの隠し層を持つディープ ネットワークを意味します。

次に、トレーニング データ セットとテスト データ セットの位置を指定し、ネットワークの入力ベクトルと出力ベクトルを作成します。

train_file = ".\\Data\\seeds_train_data.txt"
test_file = ".\\Data\\seeds_test_data.txt"
# 1. create network and model
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)

トレーニング ファイルとテスト ファイルを別の Data サブディレクトリに配置しているのがわかります。モデルの作成中には多くの異なるデータ ファイルが生じることが多いため、これは一般的な手法です。np.float64 データ型よりも np.float32 データ型を使用するのがより一般的な方法です。64 ビットを使用することで得られる正確性は通常、64 ビットを使用することで生じるパフォーマンスの低下に見合わないためです。

次に、ネットワークを作成します。

print("Creating a 7-(4-4-4)-3 NN for seed data ")
with C.layers.default_options(init= \
  C.initializer.normal(scale=0.1, seed=2)):
  h1 = C.layers.Dense(hidden_dim,
    activation=C.ops.tanh, name='hidLayer1')(X)
  h2 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
    name='hidLayer2')(h1)
  h3 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
    name='hidLayer3')(h2)
  oLayer = C.layers.Dense(output_dim, activation=None,
    name='outLayer')(h3)
nnet = oLayer
model = C.softmax(nnet)

ネットワークの作成に関しては多くのことが行われます。Python の with ステートメントは、一連の一般的な値をネットワークの複数の層に適用するショートカット構文です。ここでは、すべての重みに、標準偏差が 0.1 で平均値が 0 のガウス (釣鐘曲線) 乱数値を指定します。シード値を設定することで再現性が確保されます。CNTK は、"uniform"、"glorot"、"he"、"xavier" など、多数の初期化アルゴリズムをサポートします。 ディープ ニューラル ネットワークは初期化アルゴリズムの選択に驚くほど左右されるため、トレーニングが失敗した場合に最初に試すことの 1 つが、代わりの初期化アルゴリズムの選択です。

3 個の隠し層は Dense 関数を使用して定義しています。この関数の名前は、各層が前後の層のノードに完全に接続されていることに由来しています。使用する構文が混乱を招く可能性があります。ここでは、X は隠し層 h1 への入力として機能します。h1 層は隠し層 h2 への入力として機能します。

出力層では活性化関数が使用されないため、出力ノード値の合計が必ずしも 1 になるとは限らないことに注意してください。他のニューラル ネットワーク ライブラリを使用した経験がある読者の皆さんには、少し解説が必要になります。他の多くのニューラル ライブラリでは、出力値の合計が常に 1 となり、確率として解釈できるように出力層でソフトマックス活性化関数が使用されます。続いて、トレーニングの間は、クロス エントロピ誤差 (対数損失とも呼ばれる) を使用して、一連の値の合計を 1 にする必要があります。

しかし、意外にも CNTK v2.3 ではトレーニング用の基本的なクロス エントロピ誤差関数がサポートされていません。代わりに、CNTK にはソフトマックス関数を使用するクロス エントロピがあります。つまり、トレーニングの間、誤差値を計算するために、その場でソフトマックス関数を使用して、出力ノード値が確率に変換されます。

そのため、CNTK では出力ノード値そのものでディープ ネットワークをトレーニングしますが、予測を行う際に通常と同じように予測の確率を求めたい場合は、明示的にソフトマックス関数を適用しなければなりません。デモでは、(出力層で活性化関数を使用せずに) "nnet" オブジェクトでトレーニングし、ソフトマックス関数を適用して追加の "model" オブジェクトを作成して予測時に使用する方法を用いています。

実際には、出力層でソフトマックス活性化関数を使用し、トレーニング中にソフトマックス関数を使用するクロス エントロピを使用することが可能になりました。この方法では、ソフトマックス関数が 2 回適用されることになります。最初は出力値そのものに、そして再度、正規化した出力ノード値に適用されます。結果的に、この方法は機能しますが、もっと複雑な技術上の理由から、トレーニングはそれほど効率的ではありません。

隠し層の連鎖はある程度までは実行可能です。非常にディープなネットワーク向けに、CNTK は Sequential というメタ関数をサポートします。Sequential は多層ネットワークを作成できるようにショートカット構文を提供します。また、CNTK ライブラリにはモデルのオーバーフィットを防ぐために使用できる Dropout 関数もあります。たとえば、最初の隠し層にドロップアウトを追加するために、デモ コードを次のように修正できます。

h1 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
  name='hidLayer1')(X)
d1 = C.layers.Dropout(0.50, name='drop1')(h1)
h2 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
  name='hidLayer2')(d1)
h3 = C.layers.Dense(hidden_dim, activation=C.ops.tanh,
  name='hidLayer3')(h2)
oLayer = C.layers.Dense(output_dim, activation=None,
  name='outLayer')(h3)

同僚の多くは隠し層が数個しかないディープ ニューラル ネットワークにも、常に Sequential を使用することを好んでいます。筆者は手動での連鎖法を好みますが、これは単純にスタイルの問題です。

ネットワークをトレーニングする

ニューラル ネットワークとモデルの作成が完了したら、デモ プログラムは Learner オブジェクトと Trainer オブジェクトを作成します。

print("Creating a Trainer \n")
tr_loss = C.cross_entropy_with_softmax(nnet, Y)
tr_clas = C.classification_error(nnet, Y)
learn_rate = 0.01
learner = C.sgd(nnet.parameters, learn_rate)
trainer = C.Trainer(nnet, (tr_loss, tr_clas), [learner])

Learner はアルゴリズム、Trainer は Learner アルゴリズムを使用するオブジェクトと考えることができます。tr_loss (「トレーニング損失」) オブジェクトはネットワークで計算された出力値とトレーニング データの既知の正しい出力値の誤差を測定する方法を定義します。分類にはほとんどの場合クロス エントロピが使用されますが、CNTK は他にもいくつかの方法をサポートしています。この関数の名前の "with_softmax" 部分はこの関数がソフトマックス関数で正規化された値ではなく出力ノード値そのものを想定していることを示しています。これが、出力層で活性化関数を用いない理由です。

tr_clas (「トレーニング分類誤差」) オブジェクトは、トレーニング中に正しい予測と正しくない予測の数を計算する方法を定義します。CNTK は、一部の他のライブラリで使用される分類正確性関数ではなく、分類誤差 (正しくない予測の割合) ライブラリ関数を定義します。つまり、トレーニングの間に計算される誤差の形式は 2 つあります。tr_loss 誤差は重みとバイアスを調整するために使用します。tr_clas は予測の正確性を監視するために使用します。

Learner オブジェクトは学習率が常に 0.01 に設定された SGD アルゴリズムを使用します。SGD は最も単純なトレーニング アルゴリズムですが、最もパフォーマンスが優れたアルゴリズムになることはほとんどありません。CNTK は多数の学習アルゴリズムをサポートします。そのうちの一部は非常に複雑です。経験則から、まず SGD を使用し、トレーニングが失敗した場合にのみ、より特殊なアルゴリズムを試すことをお勧めします。Adam (Adam は略語ではありません) アルゴリズムは、筆者が SGD の次に使用することが多いアルゴリズムです。

Trainer オブジェクトを作成する珍しい構文に注目してください。2 つの損失関数オブジェクトはかっこで表記される Python のタプルとして渡されます。しかし、Learner オブジェクトは角かっこで表記される Python リストとして渡されます。複数の Leaner オブジェクトを Trainer に渡すことが可能ですが、デモ プログラムでは 1 つしか渡していません。

実際にトレーニングを実行するコードを以下に示します。

for i in range(0, max_iter):
  curr_batch = rdr.next_minibatch(batch_size,
    input_map=my_input_map)
  trainer.train_minibatch(curr_batch)
  if i % 1000 == 0:
    mcee = trainer.previous_minibatch_loss_average
    pmea = trainer.previous_minibatch_evaluation_average
    macc = (1.0 - pmea) * 100
    print("batch %6d: mean loss = %0.4f, \
      mean accuracy = %0.2f%% " % (i, mcee, macc))

トレーニングは失敗することが多いので、トレーニングの進捗を監視することが重要です。使用されたばかりの 10 個のトレーニング項目のクロス エントロピ誤差の平均は、1000 回の繰り返しごとに表示します。デモは、分類の正確性の平均 (現在の 10 項目の正しい予測の割合) を表示します。これは、分類誤差 (正しくない予測の割合) と比較してより自然なメトリックだと思います。

トレーニング後のモデルを保存する

トレーニング項目は 150 個しかないため、デモのニューラル ネットワークのトレーニングはたった数秒で完了します。しかし、デモ以外のシナリオで非常にディープなニューラル ネットワークをトレーニングする場合、数時間から数日、またはそれ以上かかる可能性があります。トレーニングの実行後、再度ゼロからトレーニングしなくて済むようにモデルを保存します。トレーニング後の CNTK モデルの保存および読み込み方法はとても簡単です。保存するには、以下のようなコードをデモ プログラムに追加します。

mdl = ".\\Models\\seed_dnn.model"
model.save(mdl, format=C.ModelFormat.CNTKv2)

最初に save 関数に渡す引数は単なるファイル名で、パスを含めることもできます。必須のファイル拡張子はありませんが、"model" を使用するのが理にかなっています。format パラメーターには既定値 ModelFormat.CNTKv2 があるため、省略することはできません。また、代わりに新しい Open Neural Network Exchange (ONNX) 形式を使用することもできます。

デモ プログラムで (出力層でソフトマックスを使用せずに) nnet オブジェクトと (ソフトマックスを使用して) model オブジェクトの両方を作成したことを思い出してください。通常はソフトマックス バージョンのトレーニング後のモデルを保存することをお勧めしますが、必要に応じてソフトマックス以外のオブジェクトを保存することもできます。

モデルの保存が完了したら、次のようにメモリに読み込むことができます。

model = C.ops.functions.Function.Load(".\\Models\\seed_dnn.model")

そして、ちょうどトレーニングが完了したばかりのようにモデルを使用できます。save と load の呼び出しにはやや異なる点があります。save は Function オブジェクトのメソッドで、load は Function クラスの静的メソッドです。

まとめ

分類の問題の多くは、1 つの隠し層を含む単純な順伝播型ニューラルネットワーク (FNN) で対処することができます。理論的には、いくつかの仮定に基づくと、FNN はディープ ニューラル ネットワークが処理できる問題のすべてに対処できます。しかし実際には、ディープ ニューラル ネットワークのほうが FNN よりもトレーニングしやすい場合があります。このような考え方の数学的根拠は普遍近似定理と呼ばれます (Cybenko の定理と呼ばれることもあります)。

ニューラル ネットワーク分類を使用したことがなければ、決めなければならないことの数に圧倒されるかもしれません。隠し層の数、各層のノードの数、各隠し層の初期化スキームと活性化関数、トレーニング アルゴリズム、学習率や慣性項などのトレーニング アルゴリズム パラメーターを決める必要があります。しかし、実践を積むことで対処する問題の種類に対する経験則をすばやく作り上げることができるでしょう。


Dr.James McCaffrey は、ワシントン州レドモンドの Microsoft Research に勤務しています。これまでに、Internet Explorer、Bing などの複数のマイクロソフト製品にも携わってきました。Dr.McCaffrey の連絡先は jammc@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Chris Lee、Ricky Loynd、Kenneth Tran に心より感謝いたします。


この記事について MSDN マガジン フォーラムで議論する