BPニューラルネットワークに基づくMNISTデータセットの検出と認識(numpyバージョン)

1. 著者について

Wang Kai、男性、西安理工大学電子情報学部、2022 年度大学院生
研究方向: マシン ビジョンと人工知能
電子メール: [email protected]

Zhang Siyi、女性、西安理工大学電子情報学部、2022 年度大学院生、Zhang Honwei 人工知能研究グループ
研究方向: マシン ビジョンと人工知能
電子メール: [email protected]

2. BP ニューラル ネットワークの概要

2.1 BP ニューラル ネットワーク

2 つの層 (2 つの重み行列と 1 つの隠れ層) を持つニューラル ネットワークを構築します。このニューラル ネットワークでは、入力ノードと出力ノードの数がそれぞれ 784 と 10 に決定されます。隠れ層のノード数はまだ決定されておらず、隠れ層のノード数に対する明確な要件がないため、ここでは 50 とします。ニューラル ネットワークの構造が決定したので、内部がどのように見えるかを見てみましょう。データの計算プロセスは次のとおりです。
ここに画像の説明を挿入
数式:
ここに画像の説明を挿入

3. MNIST データセットでの BP ニューラル ネットワーク検出実験

3.1 データセットを読み取る

numpy をインストールします: pip install numpy
install matplotlib pip install matplotlib
mnist は、さまざまな手書きのデジタル画像を含むデータ セットです。60000 個のトレーニング データと 10000 個のテスト機会があります。つまり、60000 個の train_img と対応する train_label、10000 個の test_img とそれに対応する test_label です。
ここに画像の説明を挿入
このうち、train_img と test_img はこのような形になっており、train_img はニューラル ネットワーク アルゴリズムを学習するための学習データ、test_img はニューラル ネットワーク アルゴリズムをテストするためのテスト データです。 28 28= 784 ピクセル、各ピクセルの値は 0 ~ 255 で、ピクセル値のサイズはグレー レベルを表すため、ニューラル ネットワークの入力として 1 784 の行列を形成し、ニューラル ネットワークの出力形式となります。ネットワークは 110 個の行列で、それぞれ: [0.01, 0.01, 0.01, 0.04, 0.8, 0.01, 0.1, 0.01, 0.01, 0.01]、行列内の数字はニューラル ネットワークの予測値の確率を表します。たとえば、0.8 は 5 番目の数値の予測値の確率を表します。
このうち、train_labelとtest_labelは、学習データとテストデータに対応するラベルであり、one-hot-vector(正しい解だけが1で表現される)で表される1*10の行列として理解でき、one_hot_labelがTrueの場合、 、ラベルは one-hot 配列です。戻り値、one-hot 配列の例: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0]、つまり、行列内の数値 1 は、 5 番目の数字は True、つまりこれです。ラベルは数字の 5 を表します。
データセット読み取り:
load_mnist(normalize=True, flatten=True, one_hot_label=False): in,
Normalize : 画像のピクセル値を 0.0 ~ 1.0 に正規化するかどうか (ピクセル値を正規化すると精度が向上します)。flatten : 画像を 1 次元配列に平坦化するかどうか。one_hot_label: ワンホット表現を使用するかどうか。
ここに画像の説明を挿入
完全なコードとデータセットのダウンロード: https://gitee.com/wang-kai-ya/bp.git

3.2 順伝播

前方に伝播する場合、データを取り込んで予測を出力する関数を構築できます。

def predict(self, x):
    w1, w2 = self.dict['w1'], self.dict['w2']
    b1, b2 = self.dict['b1'], self.dict['b2']

    a1 = np.dot(x, w1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, w2) + b2
    y = softmax(a2)

3.3 損失関数

1*10 行列であるデータ セットに対するニューラル ネットワークの予測値を見つけます。
ここに画像の説明を挿入

このうち、Yk はラベル内の k 番目のノードの予測値、Tk はラベル内の k 番目のノードのワンホット値を表します。 5) のラベル Yk=[
0.01 , 0.01, 0.01, 0.04, 0.8, 0.01, 0.1, 0.01, 0.01, 0.01]
Tk=[0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ]
エントロピー誤差関数では、Tk の値には 1 が 1 つだけあり、残りは 0 であるため、このデータのクロスエントロピー誤差は E = -1 (log0.8) であることに注意してください。
ここでは、クロスエントロピー誤差が損失関数として選択され、コードは次のように実装されます。

def loss(self, y, t):
    t = t.argmax(axis=1)
    num = y.shape[0]
    s = y[np.arange(num), t]

    return -np.sum(np.log(s)) / num

3.4 ニューラルネットワークの構築

先ほど、予測値predict、損失関数loss、認識精度accuracy、および勾配gradを定義しました。次に、ニューラル ネットワーク クラスを構築し、これらのメソッドをニューラル ネットワーク クラスに追加します。

for i in range(epoch):
    batch_mask = np.random.choice(train_size, batch_size)  # 从0到60000 随机选100个数
    x_batch = x_train[batch_mask]
    y_batch = net.predict(x_batch)
    t_batch = t_train[batch_mask]
    grad = net.gradient(x_batch, t_batch)

    for key in ('w1', 'b1', 'w2', 'b2'):
        net.dict[key] -= lr * grad[key]
    loss = net.loss(y_batch, t_batch)
    train_loss_list.append(loss)

    # 每批数据记录一次精度和当前的损失值
    if i % iter_per_epoch == 0:
        train_acc = net.accuracy(x_train, t_train)
        test_acc = net.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        print(
            '第' + str(i/600) + '次迭代''train_acc, test_acc, loss :| ' + str(train_acc) + ", " + str(test_acc) + ',' + str(
                loss))

3.5 トレーニング

import numpy as np
import matplotlib.pyplot as plt
from TwoLayerNet import TwoLayerNet
from mnist import load_mnist

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
net = TwoLayerNet(input_size=784, hidden_size=50, output_size=10, weight_init_std=0.01)

epoch = 20400
batch_size = 100
lr = 0.1

train_size = x_train.shape[0]  # 60000
iter_per_epoch = max(train_size / batch_size, 1)  # 600

train_loss_list = []
train_acc_list = []
test_acc_list = []

重みを保存します。

np.save('w1.npy', net.dict['w1'])
np.save('b1.npy', net.dict['b1'])
np.save('w2.npy', net.dict['w2'])
np.save('b2.npy', net.dict['b2'])

結果の視覚化:
ここに画像の説明を挿入 ここに画像の説明を挿入

3.6 モデル推論

import numpy as np
from mnist import load_mnist
from functions import sigmoid, softmax
import cv2
######################################数据的预处理
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
batch_mask = np.random.choice(100,1)  # 从0到60000 随机选100个数
#print(batch_mask)
x_batch = x_train[batch_mask]

#####################################转成图片
arr = x_batch.reshape(28,28)
cv2.imshow('wk',arr)
key = cv2.waitKey(10000)
#np.savetxt('batch_mask.txt',arr)
#print(x_batch)
#train_size = x_batch.shape[0]
#print(train_size)
########################################进入模型预测
w1 = np.load('w1.npy')
b1 = np.load('b1.npy')
w2 = np.load('w2.npy')
b2 = np.load('b2.npy')

a1 = np.dot(x_batch,w1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1,w2) + b2
y = softmax(a2)
p = np.argmax(y, axis=1)

print(p)

pythonreasoning.py を実行して、
モデルの精度が高いことを確認します。

4. 完全なコード

訓練

import numpy as np
import matplotlib.pyplot as plt
from TwoLayerNet import TwoLayerNet
from mnist import load_mnist

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
net = TwoLayerNet(input_size=784, hidden_size=50, output_size=10, weight_init_std=0.01)

epoch = 20400
batch_size = 100
lr = 0.1

train_size = x_train.shape[0]  # 60000
iter_per_epoch = max(train_size / batch_size, 1)  # 600

train_loss_list = []
train_acc_list = []
test_acc_list = []

for i in range(epoch):
    batch_mask = np.random.choice(train_size, batch_size)  # 从0到60000 随机选100个数
    x_batch = x_train[batch_mask]
    y_batch = net.predict(x_batch)
    t_batch = t_train[batch_mask]
    grad = net.gradient(x_batch, t_batch)

    for key in ('w1', 'b1', 'w2', 'b2'):
        net.dict[key] -= lr * grad[key]
    loss = net.loss(y_batch, t_batch)
    train_loss_list.append(loss)

    # 每批数据记录一次精度和当前的损失值
    if i % iter_per_epoch == 0:
        train_acc = net.accuracy(x_train, t_train)
        test_acc = net.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        print(
            '第' + str(i/600) + '次迭代''train_acc, test_acc, loss :| ' + str(train_acc) + ", " + str(test_acc) + ',' + str(
                loss))

np.save('w1.npy', net.dict['w1'])
np.save('b1.npy', net.dict['b1'])
np.save('w2.npy', net.dict['w2'])
np.save('b2.npy', net.dict['b2'])

markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()

テスト

import numpy as np
from mnist import load_mnist
from functions import sigmoid, softmax
import cv2
######################################数据的预处理
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)
batch_mask = np.random.choice(100,1)  # 从0到60000 随机选100个数
#print(batch_mask)
x_batch = x_train[batch_mask]

#####################################转成图片
arr = x_batch.reshape(28,28)
cv2.imshow('wk',arr)
key = cv2.waitKey(10000)
#np.savetxt('batch_mask.txt',arr)
#print(x_batch)
#train_size = x_batch.shape[0]
#print(train_size)
########################################进入模型预测
w1 = np.load('w1.npy')
b1 = np.load('b1.npy')
w2 = np.load('w2.npy')
b2 = np.load('b2.npy')

a1 = np.dot(x_batch,w1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1,w2) + b2
y = softmax(a2)
p = np.argmax(y, axis=1)

print(p)

おすすめ

転載: blog.csdn.net/m0_37758063/article/details/131087214