<jupyter_start><jupyter_text>Basic IntroductionLeNet-5, from the paper Gradient-Based Learning Applied to Document Recognition, is a very efficient convolutional neural network for handwritten character recognition.Paper: Gradient-Based Learning Applied to Document Recognition**Authors**: <NAME>, <NAME>, <NAME>, and <NAME>**Published in**: Proceedings of the IEEE (1998) Structure of the LeNet networkLeNet5 is a small network, it contains the basic modules of deep learning: convolutional layer, pooling layer, and full link layer. It is the basis of other deep learning models. Here we analyze LeNet5 in depth. At the same time, through example analysis, deepen the understanding of the convolutional layer and pooling layer.![lenet](img/lenet-5.png)LeNet-5 Total seven layer , does not comprise an input, each containing a trainable parameters; each layer has a plurality of the Map the Feature , a characteristic of each of the input FeatureMap extracted by means of a convolution filter, and then each FeatureMap There are multiple neurons.![lenet1](img/arch.jpg)Detailed explanation of each layer parameter: **INPUT Layer**The first is the data INPUT layer. The size of the input image is uniformly normalized to 32 * 32.> Note: This layer does not count as the network structure of LeNet-5. Traditionally, the input layer is not considered as one of the network hierarchy. **C1 layer-convolutional layer**>**Input picture**: 32 * 32>**Convolution kernel size**: 5 * 5>**Convolution kernel types**: 6>**Output featuremap size**: 28 * 28 (32-5 + 1) = 28>**Number of neurons**: 28 * 28 * 6>**Trainable parameters**: (5 * 5 + 1) * 6 (5 * 5 = 25 unit parameters and one bias parameter per filter, a total of 6 filters)>**Number of connections**: (5 * 5 + 1) * 6 * 28 * 28 = 122304**Detailed description:** 1. The first convolution operation is performed on the input image (using 6 convolution kernels of size 5 * 5) to obtain 6 C1 feature maps (6 feature maps of size 28 * 28, 32-5 + 1 = 28). 2. Let's take a look at how many parameters are needed. The size of the convolution kernel is 5 * 5, and there are 6 * (5 * 5 + 1) = 156 parameters in total, where +1 indicates that a kernel has a bias. 3. For the convolutional layer C1, each pixel in C1 is connected to 5 * 5 pixels and 1 bias in the input image, so there are 156 * 28 * 28 = 122304 connections in total. There are 122,304 connections, but we only need to learn 156 parameters, mainly through weight sharing. **S2 layer-pooling layer (downsampling layer)**>**Input**: 28 * 28>**Sampling area**: 2 * 2>**Sampling method**: 4 inputs are added, multiplied by a trainable parameter, plus a trainable offset. Results via sigmoid>**Sampling type**: 6>**Output featureMap size**: 14 * 14 (28/2)>**Number of neurons**: 14 * 14 * 6>**Trainable parameters**: 2 * 6 (the weight of the sum + the offset)>**Number of connections**: (2 * 2 + 1) * 6 * 14 * 14>The size of each feature map in S2 is 1/4 of the size of the feature map in C1.**Detailed description:** The pooling operation is followed immediately after the first convolution. Pooling is performed using 2 * 2 kernels, and S2, 6 feature maps of 14 * 14 (28/2 = 14) are obtained. The pooling layer of S2 is the sum of the pixels in the 2 * 2 area in C1 multiplied by a weight coefficient plus an offset, and then the result is mapped again. So each pooling core has two training parameters, so there are 2x6 = 12 training parameters, but there are 5x14x14x6 = 5880 connections. **C3 layer-convolutional layer**>**Input**: all 6 or several feature map combinations in S2>**Convolution kernel size**: 5 * 5>**Convolution kernel type**: 16>**Output featureMap size**: 10 * 10 (14-5 + 1) = 10>Each feature map in C3 is connected to all 6 or several feature maps in S2, indicating that the feature map of this layer is a different combination of the feature maps extracted from the previous layer.>One way is that the first 6 feature maps of C3 take 3 adjacent feature map subsets in S2 as input. The next 6 feature maps take 4 subsets of neighboring feature maps in S2 as input. The next three take the non-adjacent 4 feature map subsets as input. The last one takes all the feature maps in S2 as input.>**The trainable parameters are**: 6 * (3 * 5 * 5 + 1) + 6 * (4 * 5 * 5 + 1) + 3 * (4 * 5 * 5 + 1) + 1 * (6 * 5 * 5 +1) = 1516>**Number of connections**: 10 * 10 * 1516 = 151600**Detailed description:** After the first pooling, the second convolution, the output of the second convolution is C3, 16 10x10 feature maps, and the size of the convolution kernel is 5 * 5. We know that S2 has 6 14 * 14 feature maps, how to get 16 feature maps from 6 feature maps? Here are the 16 feature maps calculated by the special combination of the feature maps of S2. details as follows:The first 6 feature maps of C3 (corresponding to the 6th column of the first red box in the figure above) are connected to the 3 feature maps connected to the S2 layer (the first red box in the above figure), and the next 6 feature maps are connected to the S2 layer The 4 feature maps are connected (the second red box in the figure above), the next 3 feature maps are connected with the 4 feature maps that are not connected at the S2 layer, and the last is connected with all the feature maps at the S2 layer. The convolution kernel size is still 5 * 5, so there are 6 * (3 * 5 * 5 + 1) + 6 * (4 * 5 * 5 + 1) + 3 * (4 * 5 * 5 + 1) +1 * (6 * 5 * 5 + 1) = 1516 parameters. The image size is 10 * 10, so there are 151600 connections.![lenet1](img/c31.png)The convolution structure of C3 and the first 3 graphs in S2 is shown below:![lenet1](img/c32.png) **S4 layer-pooling layer (downsampling layer)**>**Input**: 10 * 10>**Sampling area**: 2 * 2>**Sampling method**: 4 inputs are added, multiplied by a trainable parameter, plus a trainable offset. Results via sigmoid>**Sampling type**: 16>**Output featureMap size**: 5 * 5 (10/2)>**Number of neurons**: 5 * 5 * 16 = 400>**Trainable parameters**: 2 * 16 = 32 (the weight of the sum + the offset)>**Number of connections**: 16 * (2 * 2 + 1) * 5 * 5 = 2000>The size of each feature map in S4 is 1/4 of the size of the feature map in C3**Detailed description:**S4 is the pooling layer, the window size is still 2 * 2, a total of 16 feature maps, and the 16 10x10 maps of the C3 layer are pooled in units of 2x2 to obtain 16 5x5 feature maps. This layer has a total of 32 training parameters of 2x16, 5x5x5x16 = 2000 connections. *The connection is similar to the S2 layer.* **C5 layer-convolution layer**>**Input**: All 16 unit feature maps of the S4 layer (all connected to s4)>**Convolution kernel size**: 5 * 5>**Convolution kernel type**: 120>**Output featureMap size**: 1 * 1 (5-5 + 1)>**Trainable parameters / connection**: 120 * (16 * 5 * 5 + 1) = 48120**Detailed description:**The C5 layer is a convolutional layer. Since the size of the 16 images of the S4 layer is 5x5, which is the same as the size of the convolution kernel, the size of the image formed after convolution is 1x1. This results in 120 convolution results. Each is connected to the 16 maps on the previous level. So there are (5x5x16 + 1) x120 = 48120 parameters, and there are also 48120 connections. The network structure of the C5 layer is as follows:![lenet1](img/c5.png) **F6 layer-fully connected layer**>**Input**: c5 120-dimensional vector>**Calculation method**: calculate the dot product between the input vector and the weight vector, plus an offset, and the result is output through the sigmoid function.>**Trainable parameters**: 84 * (120 + 1) = 10164**Detailed description:**Layer 6 is a fully connected layer. The F6 layer has 84 nodes, corresponding to a 7x12 bitmap, -1 means white, 1 means black, so the black and white of the bitmap of each symbol corresponds to a code. The training parameters and number of connections for this layer are (120 + 1) x84 = 10164. The ASCII encoding diagram is as follows:![lenet1](img/f61.png)The connection method of the F6 layer is as follows:![lenet1](img/f62.png) **Output layer-fully connected layer**The output layer is also a fully connected layer, with a total of 10 nodes, which respectively represent the numbers 0 to 9, and if the value of node i is 0, the result of network recognition is the number i. A radial basis function (RBF) network connection is used. Assuming x is the input of the previous layer and y is the output of the RBF, the calculation of the RBF output is:![lenet1](img/81.png)The value of the above formula w_ij is determined by the bitmap encoding of i, where i ranges from 0 to 9, and j ranges from 0 to 7 * 12-1. The closer the value of the RBF output is to 0, the closer it is to i, that is, the closer to the ASCII encoding figure of i, it means that the recognition result input by the current network is the character i. This layer has 84x10 = 840 parameters and connections.![lenet1](img/82.png)**Summary*** LeNet-5 is a very efficient convolutional neural network for handwritten character recognition.* Convolutional neural networks can make good use of the structural information of images.* The convolutional layer has fewer parameters, which is also determined by the main characteristics of the convolutional layer, that is, local connection and shared weights.  Code Implementation<jupyter_code>import keras
from keras.datasets import mnist

# Loading the dataset and perform splitting
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Peforming reshaping operation
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)

# Normalization
x_train = x_train / 255
x_test = x_test / 255

# One Hot Encoding
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)
# Building the Model Architecture

model = Sequential()
# Select 6 feature convolution kernels with a size of 5 * 5 (without offset), and get 66 feature maps. The size of each feature map is 32−5 + 1 = 2832−5 + 1 = 28.
# That is, the number of neurons has been reduced from 10241024 to 28 ∗ 28 = 784 28 ∗ 28 = 784.
# Parameters between input layer and C1 layer: 6 ∗ (5 ∗ 5 + 1)
model.add(Conv2D(6, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 1)))
# The input of this layer is the output of the first layer, which is a 28 * 28 * 6 node matrix.
# The size of the filter used in this layer is 2 * 2, and the step length and width are both 2, so the output matrix size of this layer is 14 * 14 * 6.
model.add(MaxPooling2D(pool_size=(2, 2)))
# The input matrix size of this layer is 14 * 14 * 6, the filter size used is 5 * 5, and the depth is 16. This layer does not use all 0 padding, and the step size is 1.
# The output matrix size of this layer is 10 * 10 * 16. This layer has 5 * 5 * 6 * 16 + 16 = 2416 parameters
model.add(Conv2D(16, kernel_size=(5, 5), activation='relu'))
# The input matrix size of this layer is 10 * 10 * 16. The size of the filter used in this layer is 2 * 2, and the length and width steps are both 2, so the output matrix size of this layer is 5 * 5 * 16.
model.add(MaxPooling2D(pool_size=(2, 2)))
# The input matrix size of this layer is 5 * 5 * 16. This layer is called a convolution layer in the LeNet-5 paper, but because the size of the filter is 5 * 5, #
# So it is not different from the fully connected layer. If the nodes in the 5 * 5 * 16 matrix are pulled into a vector, then this layer is the same as the fully connected layer.
# The number of output nodes in this layer is 120, with a total of 5 * 5 * 16 * 120 + 120 = 48120 parameters.
model.add(Flatten())
model.add(Dense(120, activation='relu'))
# The number of input nodes in this layer is 120 and the number of output nodes is 84. The total parameter is 120 * 84 + 84 = 10164 (w + b)
model.add(Dense(84, activation='relu'))
# The number of input nodes in this layer is 84 and the number of output nodes is 10. The total parameter is 84 * 10 + 10 = 850
model.add(Dense(10, activation='softmax'))

model.summary()
model.compile(loss=keras.metrics.categorical_crossentropy, optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=128, epochs=2, verbose=1, validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test)
print('Test Loss:', score[0])
print('Test accuracy:', score[1])
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D,Flatten,Dense
##Training your own images using LeNet Architecture
model = Sequential()
# Select 6 feature convolution kernels with a size of 5 * 5 (without offset), and get 66 feature maps. The size of each feature map is 32−5 + 1 = 2832−5 + 1 = 28.
# That is, the number of neurons has been reduced from 10241024 to 28 ∗ 28 = 784 28 ∗ 28 = 784.
# Parameters between input layer and C1 layer: 6 ∗ (5 ∗ 5 + 1)
model.add(Conv2D(6, kernel_size=(5, 5), activation='relu', input_shape=(28, 28, 3)))
# The input of this layer is the output of the first layer, which is a 28 * 28 * 6 node matrix.
# The size of the filter used in this layer is 2 * 2, and the step length and width are both 2, so the output matrix size of this layer is 14 * 14 * 6.
model.add(MaxPooling2D(pool_size=(2, 2)))
# The input matrix size of this layer is 14 * 14 * 6, the filter size used is 5 * 5, and the depth is 16. This layer does not use all 0 padding, and the step size is 1.
# The output matrix size of this layer is 10 * 10 * 16. This layer has 5 * 5 * 6 * 16 + 16 = 2416 parameters
model.add(Conv2D(16, kernel_size=(5, 5), activation='relu'))
# The input matrix size of this layer is 10 * 10 * 16. The size of the filter used in this layer is 2 * 2, and the length and width steps are both 2, so the output matrix size of this layer is 5 * 5 * 16.
model.add(MaxPooling2D(pool_size=(2, 2)))
# The input matrix size of this layer is 5 * 5 * 16. This layer is called a convolution layer in the LeNet-5 paper, but because the size of the filter is 5 * 5, #
# So it is not different from the fully connected layer. If the nodes in the 5 * 5 * 16 matrix are pulled into a vector, then this layer is the same as the fully connected layer.
# The number of output nodes in this layer is 120, with a total of 5 * 5 * 16 * 120 + 120 = 48120 parameters.
model.add(Flatten())
model.add(Dense(120, activation='relu'))
# The number of input nodes in this layer is 120 and the number of output nodes is 84. The total parameter is 120 * 84 + 84 = 10164 (w + b)
model.add(Dense(84, activation='relu'))
# The number of input nodes in this layer is 84 and the number of output nodes is 10. The total parameter is 84 * 10 + 10 = 850
model.add(Dense(5, activation='softmax'))

model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])

from keras.preprocessing.image import ImageDataGenerator

train_gen=ImageDataGenerator(rescale=1./255)

test_gen=ImageDataGenerator(rescale=1./255)


training_set=train_gen.flow_from_directory('D:/parent/train',target_size=(28,28),batch_size=8,class_mode='categorical')

testing_set=test_gen.flow_from_directory('D:/parent/valid',target_size=(28,28),batch_size=8,class_mode='categorical')


history=model.fit_generator(training_set,steps_per_epoch=800,epochs=25,validation_data=testing_set,validation_steps=100)

model.save('lenetn.h5')<jupyter_output>Found 310 images belonging to 5 classes.
Found 76 images belonging to 5 classes.
Epoch 1/25
800/800 [==============================] - 86s 108ms/step - loss: 0.6859 - accuracy: 0.7240 - val_loss: 3.0733 - val_accuracy: 0.4079
Epoch 2/25
800/800 [==============================] - 88s 109ms/step - loss: 0.0203 - accuracy: 0.9958 - val_loss: 3.5313 - val_accuracy: 0.4474
Epoch 3/25
800/800 [==============================] - 90s 112ms/step - loss: 0.0118 - accuracy: 0.9958 - val_loss: 4.1319 - val_accuracy: 0.4474
Epoch 4/25
800/800 [==============================] - 83s 103ms/step - loss: 0.0074 - accuracy: 0.9956 - val_loss: 8.1018 - val_accuracy: 0.4342
Epoch 5/25
800/800 [==============================] - 80s 100ms/step - loss: 0.0065 - accuracy: 0.9950 - val_loss: 3.2343 - val_accuracy: 0.4474
Epoch 6/25
800/800 [==============================] - 85s 107ms/step - loss: 0.0056 - accuracy: 0.9950 - val_loss: 3.1960 - val_accuracy: 0.4211
Epoch 7/25
800/800 [=============================[...]
{'fraction_non_alphanumeric': 0.10288242886116404, 'fraction_numerical': 0.0725216643107369, 'mean_word_length': 4.3632168754119975, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '146670', 'license': 'MIT', 'n_tokens_mistral': 5630, 'n_tokens_neox': 4619, 'n_words': 2442, 'path': 'LeNet.ipynb', 'repo_name': 'asiftandel96/Computer-Vision-', 'size': '16296'}