Experts」を初心者のために翻訳したものである。純粋な翻訳ではなく、初心者のためのチュートリアルの解説を目的としている。故に、基本的に意訳を用いている点と、原文にはない部分や噛み砕いている部分があることをご了承いただきたい。優秀な翻訳があればこの記事を書く必要はなかったが、事前に他の翻訳に目を通したところ、機械翻訳を整形した程度の誤った翻訳ばかりが存在していたため、改めて翻訳を行うこととした。2016年末から2017年始にかけて企画しているクラウドMLに関するハンズオンの資料として利用する予定である。この企画については詳細が決まり次第追記する。MNISTTensorFlowは大規模な数値演算を行うための強力なライブラリです。Networks)の実装と訓練があります。MNIST分類器を構築しながら、TensorFlowモデルの基本的な構成要素を学んでいきます。このチュートリアルでは、ニューラルネットワークとMNISTデータセットに精通している方を前提としています。あなたがそれらについてよくわかっていない場合は、初心者のためのチュートリアルをチェックアウトしてください。事前にTensorFlowのインストールを済ませておいてください。前半は、TensorFlowモデルの基本的な実装であるmnist_softmax.pyのコードについて、何が起きているのか説明していきます。後半では、精度を改善するための幾つかの方法を示します。あなたはこのチュートリアルのコードスニペットをPython環境にコピー&ペーストすることもできますし、コードを読むだけでも構いません。このチュートリアルで達成することは以下のとおりです。Network)を構築、訓練、テストするセットアップモデルを作る前に、最初にMNISTデータセットをロードするためにTensorFlowセッションを開始します。MNISTデータのロードもしこのチュートリアルのコードをコピー&ペーストする場合は、次の2行のコードでデータを自動的にダウンロードして読み込むことができます。one_hot=True)mnistは訓練、検証、テストのセットをNumPy配列として格納している軽量クラスです。以下で使用するデータミニバッチを反復処理する関数も提供します。開始TensorFlowは非常に効率的なC++バックエンドを使用することで計算を実行します。このバックエンドへの接続をセッションと呼びます。TensorFlowプログラムの一般的な使い方として、まずグラフを作成してからセッションを起動します。ここでは代わりに便利なInteractiveSessionクラスを使用します。これにより、TensorFlowはコードの構造をより柔軟にします。これは、グラフを実行する演算グラフを作成する動作をインターリーブすることができます。これはIPythonのような対話的コンテキストの中で作業する時に特に便利です。InteractiveSessionを使用していない場合は、セッションを開始してグラフを起動する前に、計算グラフ全体を構築する必要があります。tf.InteractiveSession()演算グラフPythonで効率的な数値計算を行うために、別の言語で実装された効率的なコードを使用して、行列の乗算のような高コストな演算をするNumPyのようなライブラリを使用しています。残念ながら、まだすべての操作をPythonからスイッチバックするには多くのオーバーヘッドがある場合があります。データの転送に高いコストがかかるGPUや分散環境で計算を実行したい場合、このオーバーヘッドは致命的です。TensorFlowもまたPythonの外に重い処理を持ち出しますが、このオーバーヘッドを少し回避する方法を取ります。単一の高コストな操作をPythonから独立して実行するのではなく、Pythonの外で実行する操作を相互作用のグラフとして記述することができます。(これは、いくつかの機械学習ライブラリーに見られるようなアプローチです)Pythonコードの役割は、この外部演算グラフを作成し、計算グラフのどの部分を実行するか指示することとなります。詳細については「基本的な使用法」の「計算グラフ」セクションを参照してください。ソフトマックス回帰モデルを構築するこのセクションでは、単一の線形層を持つソフトマックス回帰モデルを構築します。次のセクションでは、これを多層畳み込みニューラルネットワークを使用するソフトマックス回帰に拡張します。プレースホルダ入力画像と目標となる出力のためのノードを作成するところから計算グラフを構築していきましょう。10])xとy_は特定の値ではありません。それらはそれぞれただのプレースホルダ(場所を保持するもの=値そのものではない)です。これは、TensorFlowに計算を実行をさせようとする時に入力する値を保持する場所です。入力画像xは浮動小数点数の2次元Tensorで構成されます。ここでは、[None、784]の形状を割り当てます。ここで、784は単一の平坦化された28×28ピクセルのMNIST画像の次元数であり、Noneはバッチサイズに対応する最初の次元が任意のサイズであることを示します。プレースホルダのshape引数の指定は任意ですが、TensorFlowはTensorの形状の不一致から生じるバグを自動的に補足することができるようになります。変数モデルの重みWとバイアスbを定義します。これらを追加の入力のように扱うと想像されるかもしれませんが、TensorFlowではこれを処理するためのより良い方法として、Variable(変数)を使います。変数は、TensorFlowの計算グラフ上に存在する値です。それは計算に使用したり、修正したりすることができます。機械学習アプリケーションでは、一般的に、モデルパラメータを変数で保持します。tf.Variable(tf.zeros([10]))tf.Variableの呼び出しで各パラメータの初期値を渡します。この場合、Wとbをどちらも全てのパラメータを0で初期化します。Wは784×10の行列です(784個の入力と、10個の出力を想定しているため)。bは10次元のベクトルです(クラスが10個であるため)。セッション内で変数を使用するには、そのセッションを使用して変数を初期化する必要があります。このステップでは、既に指定されている初期値(この場合はzero-fill)を割り当てます。これは全ての変数に同時に実行できます。回帰モデルを実装します。それはたったの一行です。ベクトル化された入力画像xに重み行列Wを乗算し、バイアスbを加算します。b損失関数は簡単に指定できます。損失は、モデルの予測が1つのサンプルについてどれほど悪いかを示します。この損失が最小になるように、すべてのサンプルを訓練していきます。損失関数は、目標と、ソフトマックス活性化関数が適用されたモデルの予測との間の交差エントロピーを使います。初心者向けのチュートリアルと同様に、安定した演算を使用します。y_))tf.nn.softmax_cross_entropy_with_logitsは内部的にモデルの非正規化モデル予測としてsoftmaxを適用し、それをすべてのクラスにわたって合計し、更にtf.reduce_meanがそれらの合計に対して平均をとることに注意してください。モデルの訓練モデルと訓練のための損失関数を定義したので、TenosrFlowを使って訓練を行うのは簡単です。TensorFlowは計算グラフ全体を把握しているため、自動微分を使用して各変数に対する損失の勾配を見つけることができます。TensorFlowにはさまざまな組み込みの最適化アルゴリズムがあります。Descent)をステップ長0.5で使用します。tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)この一行でTensorFlowが実際に行うのは、新たな演算を演算グラフに追加することです。これらの操作には、勾配を計算し、パラメータ更新ステップを計算し、パラメータに更新ステップを適用する操作が含まれています。返されたtrain_stepが実行されると、勾配降下の更新がパラメータに適用されます。したがって、train_stepを反復実行することで、モデルの訓練を行うことができます。batch[1]})各反復において、100個の訓練サンプルを読み込みます。次にfeed_dictを使用してプレースホルダxとy_を訓練用に置き換えるtrain_stepオペレーションを実行します。このようにfeed_dictを使用して計算グラフのテンソルを置き換えることができます。これはプレースホルダだけに限定されません。モデルの評価モデルの出来はどうでしょう?最初に、予測した正しいラベルはどれなのかを特定しましょう。tf.argmaxはある軸に沿ったTensorの最高エントリのインデクスを取得する非常に便利な関数です。tf.argmax(y,1)はモデルが最も可能性が高いと予測したラベルであり、tf.argmax(y_,1)は本当のラベルです。tf.equalを使って、モデルの予測が真実と一致するかどうかを調べることができます。tf.argmax(y_,1))これは真偽値のリストを返します。どの程度正しかったかを判断するために、浮動小数点数にキャストして平均を取ります。[True、False、True、True]は[1,0,1,1]になり、結果は0.75になります。tf.float32))最後に、テストデータの精度を評価することができます。これは約92%ほどの正答率になるはずです。多層畳み込みネットワークの構築MNISTでの92%の精度は悪い結果です。それはもう恥ずかしいくらい悪いです。このセクションでは、非常に単純なモデルから、やや洗練されたもの、つまりは小さな畳み込みニューラルネットワークに修正します。これにより、約99.2%の精度を得ることができます。これは最先端の結果ではありませんが、立派といえるレベルでしょう。重みの初期化このモデルを作成するには、たくさんの重みとバイアスを作る必要があります。一般に、対象性を壊すために僅かなノイズで重みを初期化し、勾配が0になるのを防止する必要があります。Unit)ニューロンを使用しているため、「死んだニューロン」を避けるために、僅かな正のバイアスで初期化するのも良いことでしょう。モデルを構築する時にこれを繰り返し行うのではなく、自分たちのために便利な関数を2つ用意しましょう。Pooling)TensorFlowは、畳み込みと集約の操作に多くの柔軟性をもたらします。境界をどう扱うか?ストライド長はどうするか?この例では、常にバニラを使用します。畳み込みは1のストライドを使用し、出力と入力が同じサイズになるようにゼロパディングされます。Pooling)を用います。コードを見通しよく保つために、これらの操作を関数として抽象化しておきましょう。padding='SAME')第一畳み込み層これで、最初の層を実装できます。畳み込みとそれに続く最大値集約から構成されます。畳み込みは5×5パッチごとに32個の特徴を計算します。最初の2つの次元はパッチサイズ、次が入力チャネル数、最後が出力チャネル数を示しています。出力チャネルごとにコンポーネントを持つバイアスのベクトルも用意します。bias_variable([32])層を適用するには、最初にxを、第2次元と第3次元が画像の幅と高さ、最後の次元がカラーチャネルに対応した4次元Tensorに再構築します。[-1,28,28,1])次に、x_imageを重みで畳み込み、バイアスを加え、ReLU関数を適用し、最後に最大値集約を適用します。深層ニューラルネットワークを構築するために、同型の複数の層をスタックします。第二層では、5×5パッチごとに64個の特徴を出します。layer)を追加します。Tensorを集約層からベクトルのバッチに再構築し、重みを乗算し、バイアスを加算し、ReLUを適用します。b_fc1)ドロップアウト過学習(Overfitting)を減らすために、読み出し層の前にドロップアウトを適用します。ドロップアウト中にニューロンの出力が保持される確率を示すプレースホルダを作成します。これにより、訓練中はドロップアウトをオンに、テスト中にはオフにすることができるようになります。TensorFlowのtf.nn.dropoutオペレーションは、マスキングに加えてスケジューリングニューロンの出力を自動的に処理するので、ドロップアウトは追加のスケーリングなしに動作します1。最後に、前半のソフトマックス回帰と同様に、層を追加します。b_fc2モデルの訓練と評価このモデルの精度はどうなったでしょうか?それを訓練して評価するために、前半の一層型ソフトマックスネットワークとほぼ同じコードを使用します。違いは次のとおりです。最急勾配降下オプティマイザを、より洗練されたADAMオプティマイザに置き換えるfeed_dictに追加のパラメータkeep_probを追加して、ドロップアウト率を制御する訓練プロセスで100回ごとにログを出力するこのコードは自由に実行してもらって構いませんが、2万回の訓練の反復に結構時間がかかると思います(おそらく最大30分)。プロセッサに依ります。1.0}))このコードを実行した場合、最終的なテストの結果の精度は99.2%になるはずです。私たちは、TensorFlowを使ってかなり洗練された深層学習モデルを素早く簡単に構築、訓練、評価する方法を学びました。この小さな畳み込みネットワークでは、パフォーマンスはドロップアウトの有無にかかわらず事実上ほぼ同じです。ドロップアウトは多くの場合で過学習を減らすのに非常に効果的ですが、特に非常に大きなニューラルネットワークを訓練する時に最も便利です。LLCでAIエンジニアをしてます。このブログでは、ITに関する記事や、セミナーの開催、執筆、登壇の告知などをまとめています。LLCでAIエンジニアをしてます。このブログでは、ITに関する記事や、セミナーの開催、執筆、登壇の告知などをまとめています。