畳み込みニューラルネットワーク(CNN)とTensorFlow2コードの実装の詳細な説明

畳み込みニューラルネットワークの名前は怖いように聞こえますが、この記事ではそれをわかりやすく説明しています。誰もが理解できます。


畳み込みとは

畳み込みニューラルネットワークは、従来のニューラルネットワークが行列畳み込みを使用するテクノロジーです。
2次元線形畳み込み:
行列の例:
ここに画像の説明を挿入します

内容の一部はこの記事から抜粋されています
これで、画像(下の図の左側)とカーネルコア(下の図の中央)があります。下の図の右側の結果は、畳み込みによって取得できます。
画像は実際には巨大な数値行列であり、これは私たちがしばしばピクセルと呼ぶものです。灰色の画像は巨大な2次元マトリックスです。マトリックス内の各要素は白黒の度合いを表しており、数学的なマトリックスとして理解できます。
ここに画像の説明を挿入します

2次元たたみ込み:2次元行列から最初の値、つまり、図のマークされた赤いボックス1の位置と、図の赤いボックスである上部のたたみ込みカーネルの中心位置を取得します(畳み込みカーネルは行列です)、対応する位置の値に行列要素を掛けて最終的に合計し、得られた値は新しい値-8になります(計算方法については、上記の行列畳み込み操作を参照してください)。 、すべての位置を取得します。新しい値については、最終画像の最外層に0を入力します。二次元畳み込みによって得られるサイズは畳み込みカーネルに依存し、畳み込みカーネルのサイズは一般に奇数サイズ(たとえば、3×3、5×5)です。これは、ピクセル値がピクセル値に依存することを意味します。製品コアは、領域の特定の特徴を抽出することを決定します。


1.畳み込みニューラルネットワークの概要

畳み込みニューラルネットワーク(CNN)を使用して、マシンに物事を視覚化し、画像分類、画像認識、オブジェクト検出、インスタンスセグメンテーションなどのタスクを実行させることができます。これは、手書き認識など、CNNの最も一般的な領域です。

畳み込み層-ローカル画像の特徴を抽出します

ここに画像の説明を挿入します
画像にはRGBの3つのカラーチャネルがあるため、入力は3レイヤーです。3つの入力チャネル(赤のR、緑のG、青のB)があるため、表示される画像はすべて3チャネルの画像です。これは3層として理解できるため、畳み込みカーネルも3層になります。これは、2つの3 * 3ルービックキューブに対応する9つの要素を乗算し、最後の9つの積を加算することに相当します。したがって、畳み込みカーネルは、3層の2次元(長さと幅)フィルターを使用することと同等であり、画像のチャネル(層)の数はフィルター層の数と同じです。
2D畳み込み操作と同様に、フィルターを水平方向にスライドさせます。フィルタを移動するたびに、画像全体の3つのチャネル(3層)の加重平均、つまりRGB値の加重近傍が取得されます。カーネルを左から右、上から下の2次元でスライドするだけなので、この操作の出力は2D出力になります。
サイズが7x7の2D入力があり、画像の左上隅から開始して3x3フィルターを画像に適用するとします。画像上のカーネルを左から右、上から下にスライドすると、出力が入力(5x5)よりも小さいことは明らかです。
ここに画像の説明を挿入します
出力を入力と同じサイズにしたい場合はどうなりますか?
元の入力のサイズが7x7の場合、出力サイズも7x7にする必要があります。したがって、その場合、入力の周囲に人工的なパディングを均等に追加することで(値はゼロ)、画像ピクセルにフィルターK(3x3)を配置して、隣接する平均の重みを計算できます。値。
畳み込みカーネルは特徴を抽出するため、画像の特徴を完全に抽出するには、画像の特徴を抽出するために複数の畳み込みカーネルが必要です。これは畳み込みカーネルの深さと呼ばれ、結果は複数の2Dになります。 Togetherにスタックされた出力には、複数の出力レイヤーがあります。図に示すように、
ここに画像の説明を挿入します
この図を理解すると、最後の畳み込みニューラルネットワークのアーキテクチャ図を理解できます。多層畳み込みにより、この色の層の数が増加します。

拡張パディング、畳み込み後の画像の長さと幅を変更しないでください

入力の周りに円(ゼロ)を追加することにより、出力の形状を入力と同じに保つことができます。より大きなフィルターK(5x5)がある場合、同じ出力サイズを維持できるように、適用する必要のあるゼロパディングの数も増加します。このプロセスでは、出力サイズは出力サイズと同じであるため、パディングと呼ばれます。元のテキストについては、このリンクを参照してください
ここに画像の説明を挿入します

プーリングレイヤー-次元を削減し、モデルの複雑さと計算の複雑さを軽減します

フィーチャマップを取得したら、通常、プーリング操作と呼ばれる操作を実行します。画像に存在する複雑な関係を学習するために必要な隠れ層の数は非常に多くなります。プーリング操作を適用して入力特徴の表現を減らし、それによってネットワークに必要な計算能力を減らします。
入力フィーチャマップが取得されたら、フィーチャマップに特定の形状のフィルタを適用して、フィーチャマップのその部分から最大値を取得します。これは最大プーリングと呼ばれます。これは、カーネルがカバーするフィーチャマップの全体から最大値をサンプリングするため、サブサンプリングとも呼ばれます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

平坦化-多次元データを巨大な1次元ベクトルにします

畳み込みレイヤーセクションの最後の図に示すように、複数のピンクの畳み込み結果が得られました。これらは多次元です。
しかし、私たちの予測の結果は、0または1の2つのカテゴリなどの1次元です。多次元データはどのようにして1次元の出力を取得できますか?
多くのルービックキューブを1つずつ分割して一列に並べるのと同じように、単純で、すべての多次元データを1次元配列に平坦化します。ルービックキューブは多次元です。複数の多次元配列を一次元配列に変えてみませんか?
ここに画像の説明を挿入します
ここに画像の説明を挿入します

完全に接続されたレイヤー出力結果

画像の特徴表現に対して一連の畳み込みおよびプーリング操作を実行したら(最大マージまたは平均マージ、ダウンサンプリングとも呼ばれます)。最終的なプーリング層の出力をベクトルに平坦化し、それを、異なる数の隠れ層を持つ完全に接続された層(フィードフォワードニューラルネットワーク)を通過させ、最後にフィッティングのための多層ディープニューラルネットワークを通過させます。
最後に、完全に接続された層の出力は、必要なサイズのSoftmax層を通過します。Softmax層は、確率分布のベクトルを出力します。これは、画像分類タスクの実行に役立ちます。ディジットレコグナイザーの問題(上に表示)では、出力ソフトマックス層に10個のニューロンがあり、入力を10個のカテゴリ(0〜9個の数値)のいずれかに分類できます。2クラスの分類問題の場合、Softmax層は2ニューロンであり、それぞれ0と1を出力するため、最終的なSoftmax層は、最終結果を分割する必要のあるクラスの数に応じて決定されます。
ここに画像の説明を挿入します
2カテゴリの場合、最後のsoftmaxアチーブメントには2つのニューロンしかなく、2カテゴリの出力を示します。ここに画像の説明を挿入します

2、TensorFlow2コードの実装

1.データをインポートします

TensorFlow2に付属のmnistを使用して、手書きの0〜9の数字をテストし、彼が書いた数字を判別します。
データをインポートするには、新しいMNISTLoaderクラスを作成します。
コードは次のとおりです(testData.pyという名前):

import numpy as np
import tensorflow as tf

class MNISTLoader():
    def __init__(self):
        mnist = tf.keras.datasets.mnist
        (self.train_data,self.train_label),(self.test_data,self.test_label) = mnist.load_data()
        # MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道RGB,如果没有这个维度就是灰度的图片,没有彩色。
        self.train_data = np.expand_dims(self.train_data.astype(np.float)/255.0,axis=-1)  # [60000, 28, 28, 1]
        self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1)        # [10000, 28, 28, 1]
        self.train_label = self.train_label.astype(np.int32)    # [60000]
        self.test_label = self.test_label.astype(np.int32)      # [10000]
        self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]   #60000,10000

    def get_batch(self, batch_size):
        # 从数据集中随机取出batch_size个元素并返回
        index = np.random.randint(0, self.num_train_data, batch_size)  #可以重复取某条数据
        return self.train_data[index, :], self.train_label[index]

# mnist = MNISTLoader()
# batch_size = 1
# train_data,train_label = mnist.get_batch(batch_size)
# print(train_data*255)
# print(train_label)
# print(train_data[0,:,1])

2.TensorFlow2を使用してCNNネットワークを構築します

コード構造は次のとおりです
。1。ハイパーパラメータを定義します
。2。モデル構造を設定します。3
モデルを
トレーニングします。4。テストセットを予測し、精度をテストします。

import numpy as np
import tensorflow as tf
from testData import *
import time

class CNN(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1= tf.keras.layers.Conv2D(
            filters=32, #卷积核的数目32,提取32维特征
            kernel_size=[5,5], #感觉野,卷积核的长和宽
            padding='same', #padding 策略 (vaild、same)
            activation= tf.nn.relu #激活函数

        )
        self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2,2],strides=2) #池化层一般用2X2矩阵
        self.conv2 = tf.keras.layers.Conv2D(
            filters=64,
            kernel_size=[5,5],
            padding='same',
            activation=tf.nn.relu
        )
        self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2,2],strides=2) #池化层一般用2X2矩阵
        self.flatten = tf.keras.layers.Reshape(target_shape=(7*7*64,))  #把二维的矩阵展平为1维
        self.dense1 = tf.keras.layers.Dense(units=1024,activation=tf.nn.relu) #第一层全连接层,1024个神经元
        self.dense2 = tf.keras.layers.Dense(units=10) #最后一层全连接层,激活函数要用softmax,神经元数量为分类数量

    def call(self,inputs):
        x = self.conv1(inputs) #经过第一个卷积层
        x = self.pool1(x)  #经过第一个池化层,下采样
        x = self.conv2(x)  #经过第二个卷积层
        x = self.pool2(x)  #经过第二个池化层,下采样
        x = self.flatten(x)  #把中间结果拉平成一个大的一维向量
        x = self.dense1(x)   #经过第一个全连接层
        x = self.dense2(x)   #结果第二个全连接层,也是最后一层,叫softmax层
        output = tf.nn.softmax(x)
        return output

#主控程序,调用数据并训练模型
#定义超参数
num_epochs = 5  #每个元素重复训练的次数
batch_size = 50
learning_rate = 0.001

print('now begin the train, time is ')
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))
model = CNN()
data_loader = MNISTLoader()
optimier = tf.keras.optimizers.Adam(learning_rate=learning_rate)

num_batches = int(data_loader.num_train_data//batch_size*num_epochs)
for batch_index in range(num_batches):
    X,y = data_loader.get_batch(batch_size)
    with tf.GradientTape() as tape:
        y_pred = model(X)
        loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y,y_pred=y_pred)
        loss = tf.reduce_sum(loss)
        print("batch %d: loss %f"%(batch_index,loss.numpy()))
    grads = tape.gradient(loss,model.variables)
    optimier.apply_gradients(grads_and_vars=zip(grads,model.variables))

print('now end the train, time is ')
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
#模型的评估
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
num_batches_test = int(data_loader.num_test_data//batch_size)  #把测试数据拆分成多批次,每个批次50张图片
for batch_index in range(num_batches_test):
    start_index,end_index = batch_index*batch_size,(batch_index+1)*batch_size
    y_pred = model.predict(data_loader.test_data[start_index:end_index])
    sparse_categorical_accuracy.update_state(
        y_true = data_loader.test_label[start_index:end_index],
        y_pred=y_pred
    )
print('test accuracy: %f'%sparse_categorical_accuracy.result())
print('now end the test, time is ')
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))

操作の予測精度は99.15%に達する可能性があります。それは信じられないです。
出力結果:

batch 5999: loss 0.094517
now end the train, time is 
2021-03-18 17:15:46
test accuracy: 0.991500
now end the test, time is 
2021-03-18 17:16:05

総括する

畳み込みニューラルネットワークを構築するには、満たす必要があるだけです。層の数を決定し、畳み込み、アクティブ化、プーリングなどのプロセスに従って各層間の入力と出力のマッチングを定義し、結果を出力するには、次のことを行う必要があります。 2次元または多次元を配置する行列は大きな1次元行列にフラット化され、出力で多層ニューラルネットワークを完全な接続で構築できます。最終的な出力層はsoftmax関数を使用して分類し、出力確率が最も高い結果が予測結果です。
したがって、畳み込みニューラルネットワークの構築が実現されます。正解率はすでにかなり良いです。

おすすめ

転載: blog.csdn.net/weixin_43290383/article/details/114964920