La red neuronal Python implementa un experimento de reconocimiento de dígitos escritos a mano

     El experimento de reconocimiento de dígitos escritos a mano es el ejemplo más común en el aprendizaje automático. Se puede implementar de muchas maneras. La más básica es utilizar el algoritmo knn para calcular la distancia en función de la matriz correspondiente de imágenes digitales y los números entrenados. Al final, la distancia es la más corta, entonces simplemente asuma qué número es.

     Aquí, el experimento de reconocimiento de dígitos escritos a mano se lleva a cabo directamente mediante el método de red neuronal. Escriba su red y luego pruébela sin recurrir a otro marco. En realidad, hay muchos códigos de este tipo en Internet y no son originales.

     Es necesario explicar aquí el conjunto de datos de dígitos escritos a mano. Aquí se utiliza el conjunto de datos mnist_dataset/mnist_train.csv. La dirección de datos es: https://www.kaggle.com/datasets/oddrationale/mnist-in-csv. Después de la descarga, es un paquete comprimido que contiene mnist_train.csv, mnist_test.csv.

    Podemos echar un vistazo a algunos datos de mnist_train.csv:

 

    En la figura anterior, ① indica que la primera línea de contenido es en realidad el título. Necesitamos filtrar esta línea durante el procesamiento de datos. ② representa el contenido de la etiqueta, que es un número real y consta del 0 al 9, que son 10 categorías. ③ La matriz 28 * 28 representada en ③, este número consta de 784 números. 

    En el proceso experimental, primero usamos datos mnist_train.csv para entrenar la red y luego usamos nuestros propios números escritos a mano para realizar pruebas. mnist_test.csv no se usa para pruebas aquí, principalmente porque son datos que otros usan para pruebas, por lo que lo probamos nosotros mismos aquí.

    Las fotografías digitales que preparé yo mismo son las siguientes:

    Estas imágenes son todas imágenes de 28 * 28 píxeles dibujadas de acuerdo con los requisitos del formato de datos de prueba mnist_train.csv aquí. Esta imagen es muy pequeña, pero puede usar la herramienta de dibujo de pintura del sistema Windows para seleccionar un lienzo de 28 * 28 píxeles y luego ampliarlo Finalmente, puede dibujar estos números en el área de edición.

     

     El código se proporciona a continuación:

import os
import numpy as np
import scipy.special
import imageio

image_path = 'number_images'


# 加载图片
def load_img_number(root_dir):
    files = os.listdir(root_dir)
    file_list = []
    for file in files:
        file_path = os.path.join(root_dir, file)
        file_list.append(file_path)
    return file_list


class neuralnetwork:
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # 输入层
        self.inodes = inputnodes
        # 隐藏层
        self.hnodes = hiddennodes
        # 输出层
        self.onodes = outputnodes
        # 学习率
        self.lr = learningrate
        # 输入层-隐藏层权重
        self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes)))
        # 隐藏层-输出层权重
        self.who = (np.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes)))
        # 激活函数
        self.activation_function = lambda x: scipy.special.expit(x)

    def train(self, inputs_list, targets_list):
        inputs = np.array(inputs_list, ndmin=2).T
        targets = np.array(targets_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        output_errors = targets - final_outputs
        hidden_errors = np.dot(self.who.T, output_errors)
        self.who += self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs)),
                                     np.transpose(hidden_outputs))
        self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs))

    def query(self, inputs_list):
        inputs = np.array(inputs_list, ndmin=2).T
        hidden_inputs = np.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = np.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs


input_nodes = 784
hidden_nodes = 200
output_nodes = 10
learning_rate = 0.2
# 构建模型
model = neuralnetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)
# 准备训练数据
training_data_file = open('mnist/mnist_train.csv', 'r')
training_data_list = training_data_file.readlines()
# 去掉第一行标题
training_data_list = training_data_list[1:]
training_data_file.close()

# 训练
for record in training_data_list:
    all_values = record.split(',')
    inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
    targets = np.zeros(output_nodes) + 0.01
    targets[int(all_values[0])] = 0.99
    model.train(inputs, targets)
    pass

img_list = load_img_number(image_path)

for i in range(len(img_list)):
    img_name = img_list[i]
    img_arr = imageio.v2.imread(img_name, mode='L')
    img_data = 255.0 - img_arr.reshape(784)
    inputs = (img_data / 255.0 * 0.99) + 0.01
    outputs = model.query(inputs)
    label = np.argmax(outputs)
    print(f'{img_name} 识别结果是 {label}')

    Ejecute el código e imprima los resultados:

 

    1. La tasa de reconocimiento es muy impresionante, pero de hecho muchos de ellos se reconocen incorrectamente. 

    2. Ejecútelo varias veces y los resultados serán diferentes.

    3. Si el reconocimiento es incorrecto, básicamente se considerará 6 u 8. No sé por qué hay un resultado tan extraño.

   Finalmente, se proporciona el código y los recursos de este ejemplo: https://gitee.com/buejee/aitutorial

Supongo que te gusta

Origin blog.csdn.net/feinifi/article/details/130854741
Recomendado
Clasificación