Detección y reconocimiento del conjunto de datos MNIST basado en la red neuronal BP (versión numpy)

1. Sobre el Autor

Wang Kai, hombre, Escuela de Información Electrónica, Universidad Politécnica de Xi'an, estudiante graduado de 2022
Dirección de investigación: visión artificial e inteligencia artificial
Correo electrónico: [email protected]

Zhang Siyi, mujer, Escuela de Información Electrónica, Universidad Politécnica de Xi'an, estudiante de posgrado de 2022, Grupo de Investigación de Inteligencia Artificial de Zhang Hongwei
Dirección de investigación: visión artificial e inteligencia artificial
Correo electrónico: [email protected]

2. Introducción a la red neuronal de BP

Red neuronal 2.1 BP

Construya una red neuronal con dos capas (dos matrices de peso y una capa oculta), en la que se determina el número de nodos de entrada y de salida, que son 784 y 10 respectivamente. La cantidad de nodos en la capa oculta aún no se ha determinado, y no hay un requisito claro para la cantidad de nodos en la capa oculta, por lo que aquí se toman 50. Ahora que se ha determinado la estructura de la red neuronal, echemos un vistazo a cómo se ve por dentro. Aquí está el proceso de cálculo para un dato:
inserte la descripción de la imagen aquí
Fórmula matemática:
inserte la descripción de la imagen aquí

3. Experimento de detección de red neuronal BP en conjunto de datos MNIST

3.1 Leer el conjunto de datos

Install numpy: pip install numpy
install matplotlib pip install matplotlib
mnist es un conjunto de datos que contiene varias imágenes digitales escritas a mano: hay 60000 datos de entrenamiento y 10000 ocasiones de prueba, es decir, 60000 train_img y el correspondiente train_label, 10000 test_img y su correspondiente test_label.
inserte la descripción de la imagen aquí
Entre ellos, train_img y test_img tienen la forma de esta imagen. train_img son los datos de entrenamiento para entrenar el algoritmo de red neuronal, y test_img son los datos de prueba para probar el algoritmo de red neuronal. Cada imagen es 2828, y la imagen se convierte en 28 28= 784 píxeles, el valor de cada píxel es de 0 a 255, el tamaño del valor del píxel representa el nivel de gris, formando así una matriz de 1 784 como la entrada de la red neuronal y la forma de salida de la red neuronal es una matriz de 110, cada uno: por ejemplo: [0.01, 0.01, 0.01, 0.04, 0.8, 0.01, 0.1, 0.01, 0.01, 0.01], los números en la matriz representan la probabilidad del valor predicho de la red neuronal, por ejemplo, 0.8 representa la probabilidad del valor predicho del quinto número.
Entre ellos, train_label y test_label son etiquetas correspondientes a datos de entrenamiento y datos de prueba, que pueden entenderse como una matriz 1*10, representada por one-hot-vectors (solo la solución correcta se representa como 1), y cuando one_hot_label es True , la etiqueta es one-hot array devuelve, one-hot array ejemplo: [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], es decir, el número 1 en la matriz significa que el quinto número es Verdadero, que es este La etiqueta representa el número 5.
Lectura del conjunto de datos:
load_mnist(normalize=True, flatten=True, one_hot_label=False): in,
normalize : Si normalizar el valor de píxel de la imagen a 0,0~1,0 (la normalización del valor de píxel es beneficiosa para mejorar la precisión). flatten : si se aplana la imagen en una matriz unidimensional. one_hot_label: Si se debe usar una representación one-hot.
inserte la descripción de la imagen aquí
Código completo y descarga del conjunto de datos: https://gitee.com/wang-kai-ya/bp.git

3.2 Propagación hacia adelante

Cuando se propaga hacia adelante, podemos construir una función que tome datos y genere predicciones.

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 Función de pérdida

Encuentre el valor predicho de la red neuronal para un conjunto de datos, que es una matriz de 1*10.
inserte la descripción de la imagen aquí

Entre ellos, Yk representa el valor pronosticado del nodo k-ésimo, y Tk representa el valor uno caliente del nodo k-ésimo en la etiqueta. Por ejemplo, el anterior, por ejemplo: (el valor pronosticado del número escrito a mano 5 y la etiqueta de 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 ]
Cabe mencionar que en la función de error de entropía, el valor de Tk tiene solo un 1, y los demás son 0, por lo que el error de entropía cruzada para este dato es E = -1 (log0.8).
Aquí, el error de entropía cruzada se selecciona como la función de pérdida y el código se implementa de la siguiente manera:

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 Construcción de una red neuronal

Anteriormente, definimos la predicción del valor de predicción, la pérdida de la función de pérdida, la precisión de la precisión del reconocimiento y la graduación del gradiente. A continuación, construimos una clase de red neuronal y agregamos estos métodos a la clase de red neuronal:

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 Formación

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 = []

Guardar pesos:

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'])

Visualización de resultados:
inserte la descripción de la imagen aquí inserte la descripción de la imagen aquí

3.6 Inferencia del modelo

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)

Ejecute python reasoning.py
para ver que el modelo tiene una alta tasa de precisión.

4. código completo

tren

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()

prueba

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)

Supongo que te gusta

Origin blog.csdn.net/m0_37758063/article/details/131087214
Recomendado
Clasificación