Python neural network implements handwritten digit recognition experiment

     The handwritten digit recognition experiment is the most common example in machine learning. It can be implemented in many ways. The most basic one is to use the knn algorithm to calculate the distance based on the corresponding matrix of digital pictures and the trained numbers. In the end, the distance is the shortest, then Just assume which number it is.

     Here we directly use the neural network method to conduct handwritten digit recognition experiments. Without the help of other frameworks, write the network and then test it. There are actually many codes for this on the Internet, and they are not original.

     It is necessary to explain the handwritten digit data set here. The mnist_dataset/mnist_train.csv data set is used here. The data address is: https://www.kaggle.com/datasets/oddrationale/mnist-in-csv. After downloading, it is a compressed package containing mnist_train.csv, mnist_test.csv.

    We can take a look at some data from mnist_train.csv:

 

    In the above figure, ① indicates that the first line of content is actually the title. We need to filter this line during data processing. ② represents the label content, which is a real number. It consists of 0-9, which is 10 categories. ③ The 28 * 28 matrix represented at ③, this number consists of 784 numbers. 

    In the experimental process, we first use mnist_train.csv data to train the network, and then use our own handwritten numbers for testing. mnist_test.csv is not used for testing here, mainly because it is the data used by others for testing, so we test it ourselves here.

    The digital pictures I prepared myself are as follows:

    These pictures are all 28*28 pixel pictures drawn according to the requirements of the test data mnist_train.csv data format here. This picture is very small, but you can use the Windows system paint drawing tool to select a 28*28 pixel canvas and then enlarge it. Finally, you can draw these numbers in the editing area.

     

     The code is given below:

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

    Run the code and print the results:

 

    1. The recognition rate is very impressive, but in fact many of them are recognized incorrectly. 

    2. Run it multiple times, and the results will be different.

    3. If the recognition is incorrect, it will basically be regarded as 6 or 8. Don't know why there is such a strange result.

   Finally, the code and resources of this example are given: https://gitee.com/buejee/aitutorial

Guess you like

Origin blog.csdn.net/feinifi/article/details/130854741
Recommended