TensorFlow での CNN 画像分類と手順と例

⚡ スマートサマリー

畳み込みニューラルネットワークは、すべてのピクセルに均等な重み付けをするのではなく、小さなフィルタを使って画像をスキャンするため、コンピュータビジョン分野で主流となっています。このチュートリアルでは、各レイヤーについて説明した後、TensorFlowを使用してMNISTの数字を分類します。

  • 🔘 4 つのコンポーネント: 畳み込み、ReLU非線形性、プーリング、および全結合分類層が、すべての畳み込みニューラルネットワークに組み込まれています。
  • ☑️ 畳み込みの仕組み: 3×3または5×5のフィルタが画像上をスライドし、要素ごとの乗算によって特徴マップが構築される。
  • 3つのコントロール: Depthはフィルタ数を設定し、strideはウィンドウ間のジャンプを設定し、zero-paddingは出力次元を維持します。
  • 🧪 Pooling効果: 2×2のウィンドウとストライド2の最大プーリングにより、各軸を半分ずつ分割し、重みを削減して過学習を抑制します。
  • 🛠️ 構築手順7つ: データセットをアップロードし、入力層、畳み込み層、プーリング層、第2畳み込み層、全結合層、およびロジット層を定義します。
  • 📈 測定結果: 評価された推定器はMNISTデータセットで0.9689286の精度を示し、単純なニューラルネットワークが達成した96%を上回った。

TensorFlowにおけるCNN画像分類

畳み込みニューラルネットワークとは何ですか?

畳み込みニューラルネットワーク畳み込みニューラルネットワーク(CNN)は、コンピュータビジョン分野でよく知られた手法です。これは、視覚イメージの分析に使用される深層ニューラルネットワークの一種です。このタイプのアーキテクチャは、画像や動画から物体を認識する際に主流となっています。画像認識、動画認識、自然言語処理、レコメンデーションシステムなどのアプリケーションで使用されています。

Archi畳み込みニューラル ネットワークの構造

数年前の Facebook を思い出してください。プロフィールに写真をアップロードした後、写真上の顔に名前を手動で追加するように求められました。 現在、Facebook は convnet を使用して、写真内の友達を自動的にタグ付けします。

画像分類用の畳み込みニューラル ネットワークを理解するのはそれほど難しくありません。入力画像は畳み込みフェーズで処理され、その後ラベルが付けられます。

典型的な畳み込みニューラルネットワーク(ConvNet)のアーキテクチャは、以下の図にまとめられます。まず、画像がネットワークに入力されます。これを入力画像と呼びます。次に、入力画像は一連の処理ステップを経て、畳み込み層と呼ばれる部分を通過します。最後に、ニューラルネットワークは画像上の数字を予測します。

入力画像から畳み込み層を経て予測された数字に至るまでのエンドツーエンドの畳み込みニューラルネットワークアーキテクチャ
Archi畳み込みニューラル ネットワーク (CNN) の構造

画像は、高さと幅を持つピクセルの配列で構成されます。グレースケール画像にはチャンネルが1つしかありませんが、カラー画像には3つのチャンネル(赤、緑、青それぞれに1つずつ)があります。チャンネルは互いに重ね合わされています。このチュートリアルでは、チャンネルが1つだけのグレースケール画像を使用します。各ピクセルには、色の濃淡を表す0から255までの値があります。たとえば、値が0のピクセルは白色を表示し、値が255に近いピクセルはより暗くなります。

に保存されている画像を見てみましょう。 MNISTデータセット下の図は、左側の図をマトリックス形式で表現する方法を示しています。元のマトリックスは、0から1の範囲に標準化されていることに注意してください。濃い色のマトリックスの値は約0.9で、白いピクセルの値は0です。

手書きのMNIST数字が、0から1の間に標準化された値を持つ28×28ピクセルのマトリックスの横に表示されている。

畳み込み演算

このモデルにおいて最も重要な構成要素は畳み込み層です。この部分は、画像のサイズを縮小することで重みの計算速度を向上させ、汎化性能を高めることを目的としています。

畳み込み部分の間、ネットワークは画像の重要な特徴を維持し、無関係なノイズを除外します。 たとえば、モデルは、山を背景にした写真から象を認識する方法を学習しています。 従来のニューラル ネットワークを使用する場合、モデルはすべてのピクセルに重みを割り当てます。これには、必須ではなくネットワークを誤解させる可能性がある山のピクセルも含まれます。

代わりに、 ケラス 畳み込みニューラルネットワークは数学的手法を用いてtrac最も関連性の高いピクセルのみを抽出します。この数学的演算は畳み込みと呼ばれます。この手法により、ネットワークは各層でますます複雑な特徴を学習できます。畳み込みは行列を小さな断片に分割し、各断片内の最も重要な要素を学習します。

畳み込みニューラル ネットワーク (ConvNet または CNN) のコンポーネント

畳み込みニューラルネットワークは4つの構成要素から成り立っています。

  1. コンボリューション
  2. 非線形性 (ReLU)
  3. Poolingまたはサブサンプリング
  4. 分類 (完全接続層)

コンボリューション

畳み込みの目的は、tracこれは、画像内のオブジェクトの特徴を局所的に学習することを意味します。つまり、ネットワークは画像内の特定のパターンを学習し、画像内のどこでもそれらを認識できるようになります。

畳み込みは要素ごとの乗算です。その概念は理解しやすいものです。コンピュータは通常3×3の寸法で画像の一部をスキャンし、それをフィルタで乗算します。要素ごとの乗算の出力は特徴マップと呼ばれます。この手順は画像全体がスキャンされるまで繰り返されます。畳み込みの後、画像のサイズが縮小されることに注意してください。

下の図は、画像の一部分(パッチ)をフィルタで乗算して、特徴マップの単一セルを生成する様子を示しています。

3×3の画像パッチとフィルタを要素ごとに乗算し、特徴マップの1つの値を生成する。

以下のアニメーションは、同じ畳み込み演算が画像全体に適用される様子を示しています。

入力画像上をスライドしながらアニメーションフィルターが動き、セルごとに特徴マップを構築していく。

利用可能なフィルターは多数あります。以下にその一部を示します。各フィルターにはそれぞれ特定の目的があることがお分かりいただけるでしょう。なお、下の図ではカーネルはフィルターの同義語です。

エッジ検出、シャープ化、ぼかしなどの一般的な畳み込みカーネルと、それらによって得られる出力画像の表。

畳み込みの背後にある演算

畳み込みフェーズでは、画像内の小さなピクセル配列にフィルタが適用されます。フィルタは、入力画像に沿って3×3または5×5の形状で移動します。つまり、ネットワークはこれらのウィンドウを入力画像全体にスライドさせ、畳み込みを計算します。下の動画は、畳み込みの動作を示しています。パッチのサイズは3×3で、出力行列は画像行列とフィルタ間の要素ごとの演算の結果です。

3×3フィルタが画像値を乗算し、それらを合計して出力行列を作成する様子を段階的にアニメーションで示す。

出力の幅と高さが、入力の幅と高さと異なる場合があることがわかります。 それは境界効果によって起こります。

ボーダー効果

画像には5×5の特徴マップと3×3のフィルタが含まれています。フィルタが3×3のグリッドをフィルタリングできるウィンドウは中央に1つだけあります。出力される特徴マップは各軸で2タイルずつ縮小され、3×3のサイズになります。

5×5の特徴マップが3×3の出力に縮小されたのは、3×3のフィルタが境界まで届かないためである。

入力と同じ出力次元を得るには、パディングを追加する必要があります。パディングとは、行列の両側に適切な数の行と列を追加することです。これにより、畳み込み演算がすべての入力タイルを中央に収めることができます。下の図では、入力行列と出力行列は同じ次元の5×5です。

5×5の入力をゼロパディングのリングで囲むことで、畳み込み演算の結果、5×5の出力が得られます。

ネットワークを定義するとき、畳み込み特徴は XNUMX つのパラメーターによって制御されます。

深さ: これは、畳み込み処理中に適用するフィルターの数を定義します。前の例では、深さが1と表示されていましたが、これはフィルターが1つだけ使用されることを意味します。ほとんどの場合、フィルターは複数使用されます。以下の動画は、3つのフィルターを使用した場合の処理​​を示しています。

同じ入力を畳み込み、3つのスタックされた特徴マップを生成する3つの独立したフィルター

ストライド: これは、2つのスライス間の「ピクセル単位の移動量」を定義します。ストライドが1の場合、ウィンドウは1ピクセル分移動します。ストライドが2の場合、ウィンドウは2ピクセル分移動します。ストライドを大きくすると、特徴マップは小さくなります。以下の2つの図は、ストライド1とストライド2を比較したものです。

歩幅例1

フィルタウィンドウが入力行を1ピクセルずつ移動し、ストライドは1に設定されている。

ストライド2

フィルタウィンドウをスキップping ストライドを2に設定して位置間に2ピクセルを配置することで、出力が短くなります。

ゼロパディング: パディングとは、入力特徴マップの両側に、対応する行数と列数を追加する操作です。この場合、出力は入力と同じ次元になります。

非線形性 (ReLU)

畳み込み演算の最後に、出力は非線形性を可能にするために活性化関数によって処理されます。畳み込みニューラルネットワークで一般的に使用される活性化関数はReLUです。負の値を持つすべてのピクセルはゼロに置き換えられます。

Pooling Opera生産

この手順は理解しやすいものです。プーリングの目的は、入力画像の次元を削減することです。これらの手順は、演算の計算量を減らすために行われます。次元を削減することで、ネットワークが計算する重みが少なくなり、過学習を防ぐことができます。

この段階では、サイズとストライドを定義する必要があります。入力画像をプーリングする標準的な方法は、特徴マップの最大値を使用することです。下の図を見てください。プーリングは、4×4 特徴マップの 4 つのサブマトリックスをスクリーニングし、最大値を返します。プーリングは 2×2 配列の最大値を取得し、このウィンドウを 2 ピクセル移動します。たとえば、最初のサブマトリックスは [3,1,3,2] なので、プーリングは最大値である 3 を返します。

4×4の特徴マップを、2×2のウィンドウとストライド2の最大プーリングによって2×2の出力に縮小します。

平均などの別のプーリング操作もあります。

この操作は、特徴マップのサイズを大幅に縮小します。

完全に接続されたレイヤー

最後のステップでは、従来の 人工ニューラルネットワーク 前のチュートリアルで行ったように。 前の層のすべてのニューロンを次の層に接続します。 ソフトマックス アクティベーション関数を使用して、入力画像上の数値を分類します。

要約:

TensorFlowの畳み込みニューラルネットワークは、予測を行う前にさまざまな層をコンパイルします。ニューラルネットワークには次の要素があります。

  • 畳み込み層
  • ReLU活性化機能
  • Pooling層
  • 密に接続された層

畳み込み層は、画像のサブ領域に異なるフィルターを適用します。ReLU活性化関数は非線形性を加え、プーリング層は特徴マップの次元を削減します。

これらのレイヤーはすべてtrac画像から重要な情報を抽出します。最後に、特徴マップをソフトマックス関数を持つ全結合層に入力して予測を行います。

TensorFlow を使用して CNN をトレーニングする

これで畳み込みニューラルネットワークの構成要素がわかったので、 TensorFlow。 CNN 画像分類には MNIST データセットを使用します。

データの準備は前回のチュートリアルと同じです。コードを実行して、CNN のアーキテクチャに直接ジャンプできます。

CNN を使用して画像を分類するには、次の手順に従います。

  1. ステップ 1: データセットをアップロードする
  2. ステップ 2: 入力レイヤー
  3. ステップ 3: 畳み込み層
  4. ステップ4: Pooling層
  5. ステップ 5: XNUMX 番目の畳み込み層と Pooling レイヤー
  6. ステップ6: 緻密な層
  7. ステップ 7: ロジット層

バージョンノート: 以下のリストは TensorFlow 1.x を対象としています。TensorFlow 2 では、tf.layers 名前空間と tf.estimator.inputs.numpy_input_fn は存在しなくなりました。同等のものは tf.keras.layers.Conv2D、Max です。Pooling2D、Dense、Dropoutをtf.keras.Modelに組み込み、model.fit()で学習させます。各レイヤーの仕組みについては手順を読み、Keras APIにマッピングしてください。

ステップ 1: データセットをアップロードする

MNISTデータセットはscikit-learnから入手できます。ダウンロードして「ダウンロード」フォルダに保存してください。fetch_mldata('MNIST original')でアップロードできます。

バージョンノート: mldata.org は閉鎖され、scikit-learn 0.22 で fetch_mldata() が削除されました。現在のインストールでは、同じ数字を読み込むには、 fetch_openml 代わりに、fetch_openml('mnist_784', version=1)を使用します。パイプラインの残りの部分は変更されていません。

トレーニング/テスト セットを作成する

train_test_split を使用してデータセットを分割する必要があります。

機能を拡張する

最後に、以下のTensorFlow CNNを使用した画像分類の例に示すように、MinMaxScalerを使用して特徴量をスケーリングできます。

import numpy as np
import tensorflow as tf
from sklearn.datasets import fetch_mldata

#Change USERNAME by the username of your machine
## Windows USER
mnist = fetch_mldata('C:\\Users\\USERNAME\\Downloads\\MNIST original')
## Mac User
mnist = fetch_mldata('/Users/USERNAME/Downloads/MNIST original')

print(mnist.data.shape)
print(mnist.target.shape)
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train  = y_train.astype(int)
y_test  = y_test.astype(int)
batch_size =len(X_train)

print(X_train.shape, y_train.shape,y_test.shape )
## resclae
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# Train
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# test
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
feature_columns = [tf.feature_column.numeric_column('x', shape=X_train_scaled.shape[1:])]
X_train_scaled.shape[1:]

CNN を定義する

CNNは、従来のニューラルネットワークが学習するグローバルパターンとは異なり、画像の生ピクセルにフィルタを適用して詳細なパターンを学習します。CNNを構築するには、以下を定義する必要があります。

  1. 畳み込み層:特徴マップにn個のフィルタを適用します。畳み込みの後、ReLU活性化関数を使用してネットワークに非線形性を追加する必要があります。
  2. Pooling層:畳み込みの次のステップは、特徴マップをダウンサンプリングすることです。目的は、特徴マップの次元を削減して過学習を防ぎ、計算速度を向上させることです。最大プーリングは従来の手法で、特徴マップをサブ領域(通常は2×2サイズ)に分割し、最大値のみを保持します。
  3. 完全に接続された層: 前の層のすべてのニューロンが次の層に接続されます。CNN は、畳み込み層からの特徴とプーリング層で削減された特徴に従ってラベルを分類します。

CNNアーキテクチャ

  • 畳み込み層: 14個の5×5フィルタを適用します(例)tracReLU活性化関数を用いた5×5ピクセルのサブ領域(5×5ピクセルのサブ領域)
  • Pooling レイヤー: 2×2 フィルターとストライド 2 で最大プーリングを実行します (プールされた領域が重複しないように指定します)
  • 畳み込み層: 36 個の 5×5 フィルターを適用、ReLU 活性化関数付き
  • Pooling レイヤー2: 再び、2×2フィルターとストライド2で最大プーリングを実行します。
  • 1,764 個のニューロン、ドロップアウト正則化率は 0.4 (トレーニング中に特定の要素がドロップされる確率は 0.4)
  • 密層 (ロジッツ層): 10 個のニューロン (数字のターゲット クラス (0 ~ 9) ごとに XNUMX つずつ)。

CNN の作成に使用する重要なモジュールが XNUMX つあります。

  • conv2d()。 フィルター数、フィルターカーネルサイズ、パディング、活性化関数を引数として二次元畳み込み層を構築します。
  • max_pooling2d()。最大プーリング アルゴリズムを使用して XNUMX 次元プーリング層を構築します。
  • 密集()。 非表示のレイヤーとユニットを使用して高密度のレイヤーを構築します

CNNを構築するための関数を定義します。ラップする前に、各構成要素をどのように構築するかを詳しく見ていきましょう。ping すべてを一つの機能にまとめる。

ステップ 2: 入力レイヤー

def cnn_model_fn(features, labels, mode):
    input_layer = tf.reshape(tensor = features["x"],shape =[-1, 28, 28, 1])

データの形状を使用してテンソルを定義する必要があります。 そのためには、モジュール tf.reshape を使用できます。 このモジュールでは、再形成するテンソルとテンソルの形状を宣言する必要があります。 最初の引数はデータの特徴であり、関数の引数で定義されます。

画像には高さ、幅、チャンネルがあります。MNISTデータセットは28×28サイズのモノクロ画像です。shape引数でバッチサイズを-1に設定することで、features[“x”]の形状になります。利点は、バッチサイズを調整可能なハイパーパラメータにできることです。バッチサイズを7に設定すると、テンソルには5,488個の値(28×28×7)が供給されます。

ステップ 3: 畳み込み層

# first Convolutional Layer
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=14,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

最初の畳み込み層は、カーネルサイズが5×5でパディングが同じ14個のフィルタで構成されています。パディングが同じとは、出力テンソルと入力テンソルの高さと幅が同じであることを意味します。TensorFlowは、行と列にゼロを追加してサイズを均一にします。

ReLU活性化関数を使用します。出力サイズは[28, 28, 14]になります。

ステップ4: Pooling層

畳み込みの次のステップはプーリング処理です。プーリング処理によってデータの次元が削減されます。max_pooling2dモジュールをサイズ2×2、ストライド2で使用できます。入力には前のレイヤーを使用します。出力サイズは[batch_size, 14, 14, 14]になります。

# first Pooling Layer 
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

ステップ 5: XNUMX 番目の畳み込み層と Pooling レイヤー

2番目の畳み込み層では36個のフィルタが適用され、出力サイズは[batch_size, 14, 14, 36]となります。プーリング層では、以前と同じ2×2のウィンドウとストライド2を使用するため、各空間軸が半分になり、出力形状は[batch_size, 7, 7, 36]となります。

conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=36,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

ステップ6: 緻密な層

次に、全結合層を定義する必要があります。特徴マップは、全結合層に接続する前に平坦化する必要があります。モジュールreshapeを7×7×36のサイズで使用できます。

密結合層は 1,764 個のニューロンを接続します。ReLU 活性化関数を追加します。さらに、ドロップアウト正則化項を 0.3 の割合で追加します。これは、活性化の 30 パーセントが 0 に設定されることを意味します。ドロップアウトはトレーニング フェーズでのみ発生することに注意してください。関数 cnn_model_fn には、以下の CNN 画像分類 TensorFlow の例に示すように、モデルをトレーニングするか評価するかを宣言する引数 mode があります。

pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])

dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
dropout = tf.layers.dropout(
      inputs=dense, rate=0.3, training=mode == tf.estimator.ModeKeys.TRAIN)

ステップ 7: ロジット層

最後に、TensorFlowの画像分類の例では、モデルの予測結果を含む最終層を定義できます。出力形状はバッチサイズと、対象クラスの総数である10に等しくなります。

# Logits Layer
logits = tf.layers.dense(inputs=dropout, units=10)

クラスとその各クラスの確率を含む辞書を作成できます。関数 tf.argmax() は、ロジット層で最も高い値のインデックスを返します。softmax 関数は、各クラスの確率を返します。

predictions = {				
	# Generate predictions				
    "classes": tf.argmax(input=logits, axis=1),				
    "probabilities": tf.nn.softmax(logits, name="softmax_tensor")  }			

モードが「予測」に設定されている場合にのみ、予測辞書を返すようにします。予測結果を表示するには、このコードを追加します。

if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

次のステップは、モデルの損失を計算することです。前回のチュートリアルでは、多クラスモデルの損失関数は交差エントロピーであることを学びました。損失は、以下のコードで簡単に計算できます。

# Calculate Loss (for both TRAIN and EVAL modes)
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

TensorFlow CNNの例の最後のステップは、モデルを最適化すること、つまり重みの最適な値を見つけることです。そのためには、学習率0.001の勾配降下法オプティマイザを使用します。目的は損失を最小化することです。

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())

CNNの処理は完了しました。しかし、評価モード中にパフォーマンス指標を表示したいとします。マルチクラスモデルのパフォーマンス指標は精度です。TensorFlowには、ラベルと予測値の2つの引数を取る精度モジュールが用意されています。

eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

それでおしまい。 最初の CNN を作成しました。モデルのトレーニングと評価に使用するために、すべてを関数にラップする準備が整いました。

def cnn_model_fn(features, labels, mode):
  """Model function for CNN."""
  # Input Layer
  input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])

  # Convolutional Layer
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=32,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

  # Pooling Layer
  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

  # Convolutional Layer #2 and Pooling Layer
  conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=36,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

  # Dense Layer
  pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 36])
  dense = tf.layers.dense(inputs=pool2_flat, units=7 * 7 * 36, activation=tf.nn.relu)
  dropout = tf.layers.dropout(
      inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

  # Logits Layer
  logits = tf.layers.dense(inputs=dropout, units=10)

  predictions = {
      # Generate predictions (for PREDICT and EVAL mode)
      "classes": tf.argmax(input=logits, axis=1),
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  # Calculate Loss
  loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

  # Configure the Training Op (for TRAIN mode)
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  # Add evaluation metrics Evaluation mode
  eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(
          labels=labels, predictions=predictions["classes"])}
  return tf.estimator.EstimatorSpec(
      mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

組み立て後の機能に関する注記: 上記のラップ版では、最初の畳み込み層を32個のフィルターと0.4のドロップアウトに設定していますが、ステップバイステップのコードスニペットでは14個のフィルターと0.3を使用しています。どちらも実行できますが、いずれかの値のペアを選択して一貫性を保つことで、印刷される形状がレイヤーテーブルと一致するようにします。

以下の手順は前のチュートリアルと同じです。

まず、画像分類用の CNN モデルを使用して推定器を定義します。

# Create the Estimator
mnist_classifier = tf.estimator.Estimator(
    model_fn=cnn_model_fn, model_dir="train/mnist_convnet_model")

CNNの学習には時間がかかるため、50回の反復ごとにソフトマックス層の値を保存するログフックを作成します。

# Set up logging for predictions
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)

モデルの推定準備が整いました。バッチサイズを100に設定し、データをシャッフルします。トレーニングステップ数を16,000に設定しているため、トレーニングにはかなりの時間がかかる場合があります。しばらくお待ちください。

# Train the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": X_train_scaled},
    y=y_train,
    batch_size=100,
    num_epochs=None,
    shuffle=True)
mnist_classifier.train(
    input_fn=train_input_fn,
    steps=16000,
    hooks=[logging_hook])

モデルの学習が完了したので、モデルを評価して結果を出力できます。

# Evaluate the model and print results
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": X_test_scaled},
    y=y_test,
    num_epochs=1,
    shuffle=False)
eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
print(eval_results)

評価結果は、復元されたチェックポイント、停止したステップ、および最終的なメトリクス辞書を出力します。

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-08-05-12:52:41
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from train/mnist_convnet_model/model.ckpt-15652
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Finished evaluation at 2018-08-05-12:52:56
INFO:tensorflow:Saving dict for global step 15652: accuracy = 0.9589286, global_step = 15652, loss = 0.13894269
{'accuracy': 0.9689286, 'loss': 0.13894269, 'global_step': 15652}

現在のアーキテクチャでは、評価辞書は精度0.9689286、つまり約97%を報告しています。アーキテクチャ、バッチサイズ、反復回数を変更することで精度を向上させることができます。CNNは、 人工ニューラルネットワーク またはロジスティック回帰:人工ニューラルネットワークのチュートリアルでは、精度は96%でしたが、これはCNNよりも低い値です。CNNは、より大きな画像セットを使用した場合、計算速度と精度の両面で優れた性能を発揮します。

よくあるご質問

有効なパディングは何も追加しないため、出力は縮小し、境界ピクセルから供給されるニューロンの数が減少します。同じパディングは入力をゼロで囲むため、出力は入力の高さと幅を維持します。これは、このチュートリアルリクエストでconv2dが呼び出すものです。

変更なし。tf.layers と tf.estimator.inputs.numpy_input_fn が削除されました。tf.keras.layers.Conv2D、Max を使用して同じスタックを再構築します。Pooling2D、Dense、Dropout を内部で TensorFlow Keras モデルを作成し、Estimator の代わりに model.fit() を使用してトレーニングします。

自動検索ライブラリは、フィルタ数、カーネルサイズ、ドロップアウト率、学習率を並列に探索し、検証精度に基づいて実行結果をランク付けします。これにより、推測に頼るのではなく、測定に基づいた比較が可能になりますが、計算予算と重要な評価指標を決定するのは依然として人間です。

Yes. GitHubコパイロット 短いコメントから、繰り返し畳み込みとプーリングのスタックと入力パイプラインのドラフトが作成されます。提案には削除された TensorFlow 1 の API と現在の Keras の API が混在していることが多いため、出力形状はご自身で確認してください。

ランダムな反転、回転、シフト、ズームによって各トレーニング画像の新たなバリエーションが生成されるため、ネットワークはより幅広い例を学習し、個々の画像を記憶することをやめます。ドロップアウトとの相性が良く、通常はトレーニング精度と検証精度の差を縮めます。

この実行では、バッチサイズ100で16,000ステップを実行します。精度はほとんどの場合、もっと早い段階で向上するため、低速なマシンで全ステップを待つのではなく、評価指標を監視し、数値が横ばいになった時点で停止してください。

mldata.org が閉鎖され、scikit-learn 0.22 でヘルパーが削除されました。代わりに fetch_openml('mnist_784', version=1) を使用してください。これは同じ 70,000 個の平坦化された 784 ピクセルの数字を返すため、このチュートリアルのスケーリングと分割の手順は引き続き機能します。

これらはバッチ、高さ、幅、チャネルの順で読み取られます。つまり、14×14は28×28の数字に対して1回のプーリング処理を行った後の空間サイズであり、36はその畳み込み層のフィルタ数、つまりフィルタごとに1つの特徴マップです。