機械学習 - ディープ ニューラル ネットワークの実践 (FCN、CNN、BP)

目次

シリーズ記事ディレクトリ

1. CNN (畳み込みニューラル ネットワーク) と FCN (完全接続ネットワーク) の類似点と相違点

1. 類似点

2. 違い

2. ニューラルネットワークの順方向および逆方向伝播アルゴリズムの最適な反復公式

3. ディープニューラルネットワークアルゴリズムの応用

1. 顔認識

1.1 データのインポート

1.2 モデルの構築と使用

1.3 結果と分析

2. 手書き認識

2.1 BPニューラルネットワークに基づく手書き数字認識コード

2.2 結果と分析

3. 画像の分類

3.1 モデル構築のプロセスと結果

3.2 初期の事前トレーニング分類

3.3 トレーニングの微調整

4. 革新的なニューラルネットワークアルゴリズムの設計

5. その他

1. データセットとリソース

2. 参考文献

要約する


シリーズ記事ディレクトリ

このブログ シリーズは、機械学習の概念、原則、コードの実践に焦点を当てており、面倒な数学的導出は含まれません (質問がある場合は、コメント エリアで議論して指摘するか、プライベート メッセージで私に直接ご連絡ください)。 。

コードをコピー    して再現できる原理とプロセスを誰もが理解することは理にかなっています(私は深層学習を理解していませんが)!

第 1 章 機械学習 - PCA (主成分分析) と顔認識

第 2 章 機械学習 - LDA (線形判別分析) と顔認識_@李忆如的博客-CSDN 博客

第 3 章 機械学習 - LR (線形回帰)、LRC (線形回帰分類)、および顔認識_@李梦如的博客

第 4 章 機械学習 - SVM (サポート ベクター マシン) と顔認識_@李梦如的博客

第 5 章 機械学習 - K 平均法 (クラスタリング) と顔認識 

第 6 章 機械学習 - ディープ ニューラル ネットワークの実践


概要

このブログでは、主にディープ ニューラル ネットワーク (FNC、CNN、BP など) アルゴリズムの概念と原理、関連する分析と導出を紹介し、FCN と CNN の類似点と相違点を比較し、ニューラル ネットワークの前方および逆伝播アルゴリズム。そして、ディープ ニューラル ネットワーク アルゴリズムを適用して実際的な問題を解決します (顔認識、手書き認識、画像分類を例に挙げます)。さらに、古典的なニューラル ネットワークの欠点を考慮して、さまざまな側面と角度から最適化された新しいディープ ニューラル ネットワーク アルゴリズムが設計されました (データセットとPython コードが添付されています)。


1. CNN (畳み込みニューラル ネットワーク)と FCN (完全接続ネットワーク)の類似点と相違点

1. 類似点

① 類似した構造: どちらのニューラル ネットワークもノードの層を通じて組織され、各ノードはニューロンであり、ノード間にはいくつかまたは 2 つのエッジがあります。

②プロセスは類似しています: 畳み込みニューラル ネットワークの入出力とトレーニング プロセスは基本的に全結合ニューラル ネットワークと同じです. 画像分類を列として考えると、畳み込みニューラル ネットワークの入力層は、画像、および各出力レイヤー ノードは、信頼性のさまざまなカテゴリを表します。これは、完全に接続されたニューラル ネットワークの入力と出力と一致します。同様に、全結合ニューラルネットワークの損失関数とパラメータの最適化処理は、畳み込みニューラルネットワークにも適用できます。

2. 違い

2 つの主な違いは、ニューラル ネットワークの 2 つの隣接する層が接続される方法です。全結合ニューラル ネットワークでは、隣接する 2 つの層ごとにノードがエッジで接続されますが、畳み込みニューラル ネットワークでは、隣接する 2 つの層の間には一部のノードのみが接続されます。上記の 2 つの違いにより、完全に接続されたニューラル ネットワークは画像データを適切に処理できません (データ層とネットワーク層の数が増加すると、パラメーターの数が爆発的に増加し、計算速度が遅くなり、過剰適合の問題が発生しやすくなります)。が発生します)、畳み込みニューラル ネットワークはこの欠点を克服します。2 つのアルゴリズムの違いと流れは大まかに次のとおりです。

2.ニューラルネットワークの順方向および逆方向伝播アルゴリズムの最適な反復公式

血圧グラフモデル:

ネットワーク内の単一のアクティベーション ユニット:

ヒント: 上の図は、バイアス項目bを含む隠れ層のアクティベーション ユニットを定義しています関連する操作を図に示します。シンボルの右上隅は、ネットワーク内のユニットの層としてマークされています。コード実装と組み合わせると、ネットワーク起動ユニット間の重みは通常、前の層のユニットに保存されます。

損失関数の定義:

特定の順方向伝播アルゴリズムと逆方向伝播アルゴリズムの最適化された反復公式の導出は次のようになります。

ニューラル ネットワークの順方向伝播と逆方向伝播の導出と実装 - liangxinGao のブログ - CSDN ブログ

ニューラルネットワークの順伝播と逆伝播を詳しく解説(ゼロから導出) - Maples,'s Blog - CSDN Blog

3.ディープニューラルネットワークアルゴリズムの応用

1. 顔認識

Pycharm では、CNN ベースのディープ ニューラル ネットワーク モデルが ORL データセット上に構築され、顔認識に使用されます。コードは次のとおりです。

1.1 データのインポート

import numpy
import pandas
from PIL import Image
from keras import backend as K
from keras.utils import np_utils


"""
加载图像数据的函数,dataset_path即图像olivettifaces的路径
加载olivettifaces后,划分为train_data,valid_data,test_data三个数据集
函数返回train_data,valid_data,test_data以及对应的label
"""

# 400个样本,40个人,每人10张样本图。每张样本图高57*宽47,需要2679个像素点。每个像素点做了归一化处理
def load_data(dataset_path):
    img = Image.open(dataset_path)
    img_ndarray = numpy.asarray(img, dtype='float64') / 256
    print(img_ndarray.shape)
    faces = numpy.empty((400,57,47))
    for row in range(20):
        for column in range(20):
            faces[row * 20 + column] = img_ndarray[row * 57:(row + 1) * 57, column * 47:(column + 1) * 47]
    # 设置400个样本图的标签
    label = numpy.empty(400)
    for i in range(40):
        label[i * 10:i * 10 + 10] = i
    label = label.astype(numpy.int)
    label = np_utils.to_categorical(label, 40)  # 将40分类类标号转化为one-hot编码

    # 分成训练集、验证集、测试集,大小如下
    train_data = numpy.empty((320, 57,47))   # 320个训练样本
    train_label = numpy.empty((320,40))   # 320个训练样本,每个样本40个输出概率
    valid_data = numpy.empty((40, 57,47))   # 40个验证样本
    valid_label = numpy.empty((40,40))   # 40个验证样本,每个样本40个输出概率
    test_data = numpy.empty((40, 57,47))   # 40个测试样本
    test_label = numpy.empty((40,40))  # 40个测试样本,每个样本40个输出概率

    for i in range(40):
        train_data[i * 8:i * 8 + 8] = faces[i * 10:i * 10 + 8]
        train_label[i * 8:i * 8 + 8] = label[i * 10:i * 10 + 8]
        valid_data[i] = faces[i * 10 + 8]
        valid_label[i] = label[i * 10 + 8]
        test_data[i] = faces[i * 10 + 9]
        test_label[i] = label[i * 10 + 9]

    return [(train_data, train_label), (valid_data, valid_label),(test_data, test_label)]


if __name__ == '__main__':
    [(train_data, train_label), (valid_data, valid_label), (test_data, test_label)] = load_data('olivettifaces.gif')
    oneimg = train_data[0]*256
    print(oneimg)
    im = Image.fromarray(oneimg)
    im.show()

1.2 モデルの構築と使用

import numpy as np

np.random.seed(1337)  # for reproducibility
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, AveragePooling2D
from PIL import Image
import FaceData

# 全局变量
batch_size = 128  # 批处理样本数量
nb_classes = 40  # 分类数目
epochs = 23000  # 迭代次数
img_rows, img_cols = 57, 47  # 输入图片样本的宽高
nb_filters = 32  # 卷积核的个数
pool_size = (2, 2)  # 池化层的大小
kernel_size = (5, 5)  # 卷积核的大小
input_shape = (img_rows, img_cols, 1)  # 输入图片的维度

[(X_train, Y_train), (X_valid, Y_valid), (X_test, Y_test)] = FaceData.load_data('olivettifaces.gif')

X_train = X_train[:, :, :, np.newaxis]  # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数
X_valid = X_valid[:, :, :, np.newaxis]  # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数
X_test = X_test[:, :, :, np.newaxis]  # 添加一个维度,代表图片通道。这样数据集共4个维度,样本个数、宽度、高度、通道数

print('样本数据集的维度:', X_train.shape, Y_train.shape)
print('测试数据集的维度:', X_test.shape, Y_test.shape)

# 构建模型
model = Sequential()
model.add(Conv2D(6, kernel_size, input_shape=input_shape, strides=1))  # 卷积层1
model.add(AveragePooling2D(pool_size=pool_size, strides=2))  # 池化层
model.add(Conv2D(12, kernel_size, strides=1))  # 卷积层2
model.add(AveragePooling2D(pool_size=pool_size, strides=2))  # 池化层
model.add(Flatten())  # 拉成一维数据
model.add(Dense(nb_classes))  # 全连接层2
model.add(Activation('sigmoid'))  # sigmoid评分

# 编译模型
model.compile(loss='categorical_crossentropy', optimizer='adadelta', metrics=['accuracy'])
# 训练模型
model.fit(X_train, Y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X_valid, Y_valid))
# 评估模型
score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])

y_pred = model.predict(X_test)
y_pred = y_pred.argmax(axis=1)  # 获取概率最大的分类,获取每行最大值所在的列
for i in range(len(y_pred)):
    oneimg = X_test[i, :, :, 0] * 256
    im = Image.fromarray(oneimg)
    # im.show()
    print('第%d个人识别为第%d个人' % (i, y_pred[i]))

1.3 結果と分析

Pycharm では、CNN ベースのディープ ニューラル ネットワーク モデルが ORL データセットに基づいて構築され、顔認識に使用され、反復回数エポックによる損失と顔認識率の関係がそれぞれ記録されました。結果は次のグラフに示されています。 :

 分析: ORL データセットでは、反復回数が増加するにつれて、CNN ディープ ニューラル ネットワーク モデルの効果が徐々に向上し、損失率が減少し続け、顔認識率が増加し続けていることがわかります (実行後は最大 99.37%)。 20,000 回の反復)、ほとんどのアルゴリズムよりも優れています。

2. 手書き認識

Pycharm では、手書き数字認識用の BP ディープ ニューラル ネットワーク モデルに基づいて Mnist データ セットが構築されます。コードは次のとおりです。

2.1 BPニューラルネットワークに基づく手書き数字認識コード

import numpy as np
from sklearn.datasets import load_digits
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt

# 载入数据
digits = load_digits()
# 显示图片
for i in range(min(digits.images.shape[0], 2)):
    plt.imshow(digits.images[i], cmap='gray')
    plt.show()

# 数据
X = digits.data
# 标签
y = digits.target

# 定义一个神经网络,结构,64-100-
# 定义输入层到隐藏层之间的权值矩阵
V = np.random.random((64, 100)) * 2 - 1
# 定义隐藏层到输出层之间的权值矩阵
W = np.random.random((100, 10)) * 2 - 1

# 数据切分
# 1/4为测试集,3/4为训练集
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 标签二值化
# 0 -> 1000000000
# 3 -> 0003000000
# 9 -> 0000000001
labels_train = LabelBinarizer().fit_transform(y_train)


# 激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))


# 激活函数的导数
def dsigmoid(x):
    return x * (1 - x)


#  训练模型
def train(X, y, steps=10000, lr=0.011):
    global V, W
    for n in range(steps + 1):
        # 随机选取一个数据
        i = np.random.randint(X.shape[0])
        # 获取一个数据
        x = X[i]
        x = np.atleast_2d(x)
        # BP算法公式
        # 计算隐藏层的输出
        L1 = sigmoid(np.dot(x, V))
        # 计算输出层的输出
        L2 = sigmoid(np.dot(L1, W))
        # 计算L2_delta,L1_delta
        L2_delta = (y[i] - L2) * dsigmoid(L2)
        L1_delta = L2_delta.dot(W.T) * dsigmoid(L1)
        # 更新权值
        W += lr * L1.T.dot(L2_delta)
        V += lr * x.T.dot(L1_delta)

        # 每训练1000次预测一次准确率
        if n % 1000 == 0:
            output = predict(X_test)
            predictions = np.argmax(output, axis=1)
            acc = np.mean(np.equal(predictions, y_test))
            dW = L1.T.dot(L2_delta)
            dV = x.T.dot(L1_delta)
            gradient = np.sum([np.sqrt(np.sum(np.square(j))) for j in [dW, dV]])
            print('steps', n, 'accuracy', acc, 'gradient', gradient)
            # print(classification_report(predictions,y_test))


def predict(x):
    # 计算隐藏层的输出
    L1 = sigmoid(np.dot(x, V))
    # 计算输出层的输出
    L2 = sigmoid(np.dot(L1, W))
    return L2


# 开始训练
train(X_train, labels_train, 20000, lr=0.11)
train(X_train, labels_train, 20000, lr=0.011)
# 训练后结果对比
output = predict(X_test)
predictions = np.argmax(output, axis=1)
acc = np.mean(np.equal(predictions, y_test))
print('accuracy', acc)
print(classification_report(predictions, y_test, digits=4))

2.2 結果と分析

Pycharm では、BP ディープ ニューラル ネットワーク モデルに基づいて Mnist データ セットが構築され、手書き数字認識に使用され、認識率と反復エポック数の関係が記録されます。結果は次のグラフに示されています。

分析: Mnist データセットでは、反復回数が増加するにつれて、BP ディープ ニューラル ネットワーク モデルの効果が徐々に向上し、認識率が増加し続けていることがわかります (10,000 回の反復後でも基本的に約 96% で安定しています)。

3. 画像の分類

このパートでは主に MindSpore (CPU) バージョンを使用して、ファインチューニングを通じて犬猫分類モデル (Huawei Cloud 実験) をトレーニングします。全体的な実験プロセスは次のとおりです。

3.1 モデル構築のプロセスと結果

モデル構築のプロセスと結果を図に示します。

3.2 初期の事前トレーニング分類

最初のトレーニング前の分類結果は次のとおりです。

分析: context_device_init 関数はトレーニング環境を初期化し、ネットワーク構造を定義し、CKPT パラメーターを読み取り、ネットワーク ハイパーパラメーターを構成します。しかし、事前学習でバックボーンのパラメータを読み取った後、直接予測を行って結果を表示すると、予測精度が不十分であることがわかります。

3.3トレーニングの微調整

微調整トレーニング後の結果は次のようになります。

分析: 事前トレーニング後、オプティマイザー、学習率、損失関数が定義されます。公式の微調整トレーニングの後、元のデータセット ファイルにいくつかの npy ファイルが生成されます。アンケートは主にトレーニング プロセスで関連する変数とラベルを保存します。その後、ネットワークはローカル トレーニングを完了し、MindIR モデルを正常に取得しました。上の図からわかるように、微調整トレーニング後は正解率が向上し、分類が正確になり、モデルが正常に構築されています。

4.革新的なニューラルネットワークアルゴリズムの設計

① 古典的な CNN の欠陥: 結果の過学習、教師付き問題のパフォーマンスの低下、特徴の理解の低下、解釈のしやすさの低下

② 最適化の方向性:データ処理、畳み込み手法の設計、アーキテクチャ設計、活性化関数の選択原理、オプティマイザの選択など。

③最適化指標:モデルの精度、学習速度、メモリ消費量

④ 革新的なニューラル ネットワーク アルゴリズム プロセスの簡単な説明:

一。データのクリーニングと強化: データの選択とクリーニングが適切に行われていない場合、得られる結果は過学習のように見えることがよくあります。アプリケーションのシナリオに応じて、さまざまなデータ拡張方法を使用してデータ品質を向上させると同時に、データのスキュー/不均衡に対して、オーバーサンプリング、ダウンサンプリング、SMOTE、統合学習、カテゴリの重み付け、学習方法の変更などを追加したり、データを使用したりできます。バッチトレーニングを直接ロードします。

二。絶妙な畳み込み設計: MobileNets (深度分離畳み込み)、XNOR-Net (バイナリ畳み込み)、ShuffleNet (点群畳み込みとチャネルのランダム化)、ネットワーク プルーニング (CNN の一部の重みを削除)

三つ。コンボリューション カーネル係数 (オプトイン) : 一般に、コンボリューション カーネルが大きいほど精度は高くなりますが、トレーニング速度が遅くなり、より多くのメモリを消費します。また、コンボリューション カーネルが大きいほどネットワークの汎化につながります。非常に貧弱で拡張されたコンボリューションの例は次のとおりです。

ヒント: コンボリューション カーネルの重みの間にスペースを使用します。これにより、ネットワークはパラメータの量を増やさずに受容野を拡張できるため、メモリ消費量が増加しません。このアプローチは、速度のトレードオフを小さくしながらネットワークの精度を向上させることが示されています。

四。ネットワーク サイズ (幅/深さ)の合理的な拡張: GPU は並列処理されるため、深さを増やすよりも幅を増やす方が GPU にとってより有利です。多くの研究では、ネットワークを深くするよりもネットワークを広げる方がトレーニングが容易であることも示しています。ただし、幅と深さによってもたらされる利点は限界効果によって制限され、各レイヤーの幅が大きくなるほど、レイヤー幅の増加によるモデルのパフォーマンスの向上は少なくなるため、合理的な選択を行う必要があります。

五。活性化関数選択の最適化: エンジニアリングの経験によれば、通常、ReLU を使用すると最初はすぐに良い結果が得られますが、ReLU で良い結果が得られない場合は、それでも機能しない場合は、シグモイド関数に置き換えることができます。モデルやその他の部分を調整して精度の向上を試みます。良好な結果が得られない場合は、ELU、PReLU、Sigmoid、LeakyReLU などの活性化関数を使用してみてください。

六。オプティマイザー選択の最適化: 画像分類問題に適用される単純な CNN の場合、さまざまなオプティマイザーを使用することによるトレーニングの高速化効果は次のとおりです。

分析: オプティマイザを合理的に選択し、良好な結果が得られた場合はモデルの他のハイパーパラメータを調整します。学習率をあまり高く設定しないように注意してください。組み合わせて使用​​することもできます。つまり、高速オプティマイザーを使用して前段で学習効率を低く設定し、トレーニングの後半で低速オプティマイザーを選択して複合オプティマイザーを実行することもできます。

5. その他

1. データセットとリソース

この実験で使用したデータ セット: ORL5646、Mnist、猫および犬のデータ セット。

一般的に使用される顔データセットは次のとおりです(売春しないでください、笑)

リンク: https://pan.baidu.com/s/12Le0mKEquGMgh5fhNagZGw 
抽出コード: yrnb

ディープ ニューラル ネットワーク アプリケーションの完全なコードと必要なデータセット: Li Yiru/Yiru の機械学習 - Gitee.com

2. 参考文献

1.完全畳み込みニューラルネットワーク(FCN)と畳み込みニューラルネットワーク(CNN)の主な違い_時々寝そべる塩辛のブログ-CSDN

2.ニューラルネットワークの前方伝播と後方伝播の導出と実装_liangxinGao のブログ - CSDN ブログ

3.マスターでのkeras/Face_Recognition · data-infra/keras · GitHub

4.ニューラルネットワークで手書きフォント認識を実現_myourdream2のブログ-CSDNブログ_ニューラルネットワークフォント認識 

5.「人工知能入門」ディープラーニング実験マニュアル 

6. CNN (畳み込みニューラル ネットワーク) - 最適化ガイド - Zhihu (zhihu.com)


要約する

ディープ ニューラル ネットワークは、ディープ ラーニングにおいて人気があり重要な研究分野であり、ほとんどのアルゴリズム (CNN、BP など) は、機械学習やパターン認識の分野での実際のタスクにおいて、さまざまな古典的なアルゴリズムを上回る優れたパフォーマンスを発揮します。さらに、ディープ ニューラル ネットワークはビッグ データ タスクの処理に優れたパフォーマンスを発揮し、大きな開発の可能性を秘めています。しかし同時に、まだ多くの欠陥があり、その最初の欠陥はモデルの選択と構築であり、深層学習手法の一般的な問題である解釈可能性の低さと堅牢性の課題です。これは実験結果に大きく影響するため、ディープニューラルネットワークをいかに使いこなすか、モデルをどう選ぶか、アルゴリズムを最適化するかはディープラーニングの分野において非常に重要な課題となります。

おすすめ

転載: blog.csdn.net/weixin_51426083/article/details/125255519