Python neural network realizes handwritten digit recognition experiment

Handwritten digit recognition experiment is the most common example in machine learning. There are many ways to realize it. The most basic is actually to use the knn algorithm to calculate the distance between the corresponding matrix of the digital picture and the trained number. The last distance is the shortest, then Just think which number it is.

Here, the handwritten digit recognition experiment is carried out directly through the method of neural network. Write your network, then test it, without resorting to another framework. There are actually a lot of this code on the Internet, and it is not original.

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

We can look at some data of mnist_train.csv:

In the figure above, ① indicates that the content of the first line is actually the title, and we need to filter this line during data processing. ② Indicates the label content, that is, the real number, which is composed of 0-9, that is, 10 categories. The 28 * 28 matrix represented by ③, this number is composed of 784 numbers.

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

The digital picture prepared by myself is 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 small, but you can use the Windows system paint drawing tool to select a 28*28 pixel canvas and then zoom in. Finally these figures can be drawn in the editing area.

IMG ALT = \ “” SRC = \ “// I2.WP.COM/img-blog.csdnimg.cn/dd726B59DCD33345edd2D2D BC0.png \ “>  \

The code is given below:

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

image_path = 'number_images'


# load image
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 neural network:
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        # input layer
        self.inodes = inputnodes
        # hidden layer
        self.hnodes = hiddennodes
        # output layer
        self.onodes = outputnodes
        # learning rate
        self.lr = learningrate
        # input layer-hidden layer weights
        self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes)))
        # Hidden layer - output layer weights
        self.who = (np.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes)))
        # activation function
        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
# Build the model
model = neuralnetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)
# prepare training data
training_data_file = open('mnist/mnist_train.csv', 'r')
training_data_list = training_data_file. readlines()
# Remove the first row header
training_data_list = training_data_list[1:]
training_data_file. close()

# train
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} recognition result is {label}')

Run the code and print the result:

1. The recognition rate is very impressive. In fact, many of them are misrecognized.

2. Running multiple times, the results are also different.

3. If the identification is incorrect, it will basically be regarded as 6 or 8. Not sure how this strange result came about.

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

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge