1 minute read

LeNet-5는 손글씨, 우편 인식 등 이미지 분류에 쓰이던 DNN(Deep Neural Network)이다.
LeNet-5에 대한 자세한 정보는 [1]에서 찾아 볼 수 있지만, 간단하게 설명한 후에 TensorFlow로 어떻게 구현해야 하는지 코드리뷰를 하겠다.

LeNet-5는 입력층과 출력층을 제외하고 3개의 Convolutional Layer(C), 2개의 Sub-Sampling Layer(S), 그리고 1개의 Fully-Connected Layer(F)로 총 6개의 층으로 구성되어 있다.
그래서 위 그림에서 C1-S2-C3-S4-C5-F6와 같이 층이 쌓이는 걸 확인할 수 있다.

Sub-Sampling Layer는 Pooling Layer라고도 하는데 이미지 크기를 줄여 파라미터 수를 감소시키기 위해 사용되며, 논문에서는 Max와 Avg 중 Average Pooling을 사용했다.
여기서 C5 Layer를 그림만 보고 FC Layer(Fully-Connected Layer)로 잘못 이해하는 사람이 많은 것 같은데 논문에서도 직접 C5는 Convolution Layer라고 언급했으며, C5는 S4의 Output인 5$\times$5 이미지를 입력으로 받아 5$\times$ 필터로 합성곱 연산을 수행해 (1, 1, filter size)의 크기를 갖는다. (*tensorflow 기준)
Yann Lecun은 학습할 때 손실 함수(Loss function)로 MSE(Mean Squared Error)를 채택했지만, Cross Entropy 기법이 훨씬 좋기 때문에 코드에서는 후자를 채택했다.

Import

1
2
3
4
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import models
from tensorflow.keras.layers import Conv2D, Flatten, AvgPool2D, Dense

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def lenet5():
    model = models.Sequential([
        Conv2D(filters=6, kernel_size=5, strides=1, activation='tanh', input_shape=(32, 32, 1)),
        AvgPool2D(pool_size=(2, 2), strides=2),
        Conv2D(filters=16, kernel_size=5, strides=1, activation='tanh'),
        AvgPool2D(pool_size=(2, 2), strides=2),
        Conv2D(filters=120, kernel_size=5, strides=1, activation='tanh'),
        Flatten(),
        Dense(84, activation='tanh'),
        Dense(10, activation='softmax')
    ])

    model.compile(loss='sparse_categorical_crossentropy',
                  optimizer=keras.optimizers.Adam(),
                  metrics=['accuracy'])

    return model

Reference

[1] Y. LeCun, L. Bottou, Y. Bengio, and P. Haffner. “Gradient-based learning applied to document recognition”. Proceedings of the IEEE, November 1998.