+7

[Paper Explain] Thủ thuật cho các mạng CNN trong Classification

Lời mở đầu

CNN (Convolutional Neural Network) lần đầu được ra mắt và áp dụng vào bài toán Classification (phân loại) là LeNet-5 vào năm 1989 của nhóm nghiên cứu của thầy Yann LeCun. Và với sự ra mắt tiếp đó của AlexNet vào năm 2012, chiến thắng cuộc thi phân loại ảnh ImageNet, CNN đã dần có được sự thống trị của mình trong các bài toán phân loại ảnh. Rất nhiều các kiến trúc CNN mới ra đời như VGG, Inception, ResNet, DenseNet,... và gần đây nhất là ConvNext.
Tuy nhiên, những sự phát triển vượt bậc này không chỉ nằm ở trong mỗi kiến trúc của chúng. Những thay đổi trong quá trình training, bao gồm những sự thay đổi trong hàm loss, cách xử lý dữ liệu, các phương pháp optimization khác nhau cũng đóng một vai trò vô cùng quan trọng. Những thay đổi này giống như những sát thủ thầm lặng, chỉ được nhắc tới rất ngắn trong các paper hoặc thậm chí là không nhắc tới, mà phải đọc source code mới có thể tìm ra, và cũng nhận được rất ít những sự quan tâm.
Hôm nay, chúng ta sẽ khám phá những thay đổi này, giúp cải thiện độ chính xác của model mà hầu như không làm tăng độ nặng tính toán. Có khá nhiều những thay đổi vô cùng nhỏ nhặt, được gọi là "tricks" (thủ thuật), như thay đổi stride trong lớp Convolution, thay đổi learning rate. Tuy nhiên, kết hợp nhiều thay đổi nhỏ sẽ tạo ra được sự thay đổi lớn. Chúng ta sẽ đánh giá những thay đổi này trên một số CNN và tìm hiểu tác động của chúng.

Quy trình training

image.png
Một mạng nơ-ron train với Stochastic Gradient Descent (SGD) sẽ tuân theo quy trình training như thuật toán 1.

Baseline cho quy trình training

Chúng ta cần một quy trình training baseline dùng để làm so sánh với sự thay đổi trong các quy trình về sau. Tiền xử lý dữ liệu trong lúc train và validation sẽ khác nhau. Trong lúc train, ta thực hiện tuần tự các bước sau:

  1. Lấy ngẫu nhiên ảnh, xử lý ảnh thành dạng float cho từng pixel với giá trị trong khoảng [0, 255].
  2. Ngẫu nhiên crop một vùng chữ nhật có tỉ lệ được lấy ngẫu nhiên trong khoảng [3/43/4, 4/34/3], diện tích của vùng được lấy ngẫu nhiên trong khoảng [88%, 100100%], sau đó được resize thành ảnh vuông với kích thước 224×224224 \times 224.
  3. Sử dụng Horizontal Flip với tỉ lệ 0.50.5
  4. Thay đổi hue, staturation và brightness với hệ số được lấy ngẫu nhiên trong khoảng [0.60.6, 1.41.4].
  5. Thêm nhiễu PCA với hệ số được lấy từ phân phối chuẩn N(0,0.1)\mathcal { N } ( 0,0.1 )
  6. Normalize kênh màu RGB bằng việc trừ đi 123.68,116.779,103.939123.68, 116.779, 103.939 và chia cho 58.393,57.12,57.37558.393, 57.12, 57.375

Trong lúc validation, ta resize cạnh ngắn hơn của ảnh xuống 256256, cạnh còn lại được resize theo tỉ lệ của ảnh. Sau đó, ta crop ra một vùng 224×224224 \times 224 ở trung tâm của ảnh và normalize RGB y như lúc training.
Weight của các lớp Convolution và Fully-Connected (FC) được khởi tạo ngẫu nhiên theo thuật toán Xavier. Với các lớp BatchNorm (BN), γ\gamma được khởi tạo là 11β\beta được khởi tạo là 00.
Nesterov Accelerated Gradient (NAG) Descent được sử dụng trong training. Model được train với 120 epochs, sử dụng 8 GPU V100 với tổng batch size là 256. Learning rate được khởi tạo là 0.1 và giảm đi mỗi 10 lần ở epoch thứ 30, 60 và 90.

Kết quả baseline

Áp dụng training đối với 3 model: ResNet-50, Inception-v3 và MobileNet. Kết quả được thể hiện ở Bảng 1. image.png

Training một cách hiệu quả

Training với batch size khác nhau

Vì mỗi máy tính sẽ có các cấu hình phần cứng khác nhau, nên chúng ta phải điều chỉnh batch size để phù hợp với phần cứng đó. Tuy nhiên, việc điều chỉnh batch size khác nhau sẽ đem lại những ảnh hưởng đến độ chính xác của mô hình chúng ta. Để có thể thay đổi batch size mà vẫn có độ chính xác tốt, các kĩ thuật dưới đây sẽ giúp chúng ta đạt được điều đó.

Linear scaling learning rate

Trong mini-batch SGD, gradient descent là một quá trình ngẫu nhiên vì data được lấy ngẫu nhiên ở mỗi batch. Việc tăng batch size sẽ không thay đổi kì vọng của SGD nhưng sẽ làm giảm phương sai. Nói cách dễ hiểu hơn là, việc có một batch size lớn hơn sẽ giảm đi nhiễu ở trong các lần đạo hàm, vì vậy, ta cần phải tăng learning rate để quá trình hội tụ của SGD hiệu quả hơn. Giả sử learning rate ban đầu là 0.10.1 với batch size là 256, khi chuyển sang batch size là bb learning rate mới sẽ được tính theo công thức 0.1×b/2560.1 \times b / 256.

Learning rate warmup

Khi bắt đầu training, các tham số thường được khởi tạo ngẫu nhiên và sẽ khác rất nhiều so với tham số cuối cùng của model. Vì vậy, việc sử dụng một learning rate lớn thường sẽ gây khó khăn cho việc hội tụ ở giai đoạn đầu. Từ đó sinh ra giai đoạn "warmup", ta sẽ sử dụng một learning rate nhỏ rồi chuyển lại về learning rate ta muốn khi mà model đã đạt được một sự ổn định. Giả sử ta sử dụng mm epoch đầu tiên để warmup, learning rate ta muốn là η\eta, thì tại batch thứ ii với 1im1 \leq i \leq m, learning rate sẽ tính theo công thức iη/mi \eta / m.

Zero γ\gamma

ResNet bao gồm các Residual Block, mỗi Residual Block bao gồm một vài lớp Convolution. Với đầu vào xx, gọi block(x)block(x) là đầu ra của lớp cuối cùng trong Residual Block, thì đầu ra của cả Residual Block sẽ là x+block(x)x + block(x). Lưu ý rằng lớp cuối cùng trong Residual Block có thể là BatchNorm (BN). BN trước tiên sẽ standardize xx, tạo ra x^\hat{x}, sau đó thực hiện biến đổi theo công thức γx^+β\gamma \hat{x} + \beta. Cả γ\gammaβ\beta đều là các tham số học được và thường được khởi tạo với giá trị 1100. Với việc khởi tạo γ\gamma00 cho toàn bộ các lớp BN ở cuối Residual Block, các Residual Block sẽ trả lại luôn giá trị đầu vào của chúng là xx, làm cho model như có ít lớp hơn, do đó sẽ dễ train hơn ở các giai đoạn đầu.

No bias decay

Chúng ta thường áp dụng weght decay cho các parameters, bao gồm cả weight và bias. Việc này giống như sử dụng L2 regularization lên các parameters. Tuy nhiên, có các nghiên cứu đã chỉ ra rằng chỉ nên áp dụng regularization lên weight để tránh overfitting. Vì vậy, chiến lược no bias decay chỉ áp dụng weight decay lên weight của các lớp convolution và FC. Các parameter khác như γ\gammaβ\beta trong lớp BN không được áp dụng.

Kết quả

image.png

Tinh chỉnh model

Tinh chỉnh model là những thay đổi vô cùng nhỏ đến cấu trúc của mạng nơ-ron, chẳng hạn như thay đổi stride trong một lớp Convolution. Những thay đổi vô cùng nhỏ đó sẽ không ảnh hưởng đáng kể đến tốc độ của model nhưng lại có thể đem lại một vài thay đổi không nhỏ đến độ chính xác của model. Trong mục này, ta sẽ cải tiến ResNet-50 (Hình 1) để cho thấy sự hiệu quả của việc tinh chỉnh model.
image.png

Tinh chỉnh B (Hình 2)

Cải tiến B thay đổi khối Down sampling của ResNet. Quan sát thấy rằng việc sử dụng 1×11 \times 1 Convolution với stride 2 trong Path A sẽ làm mất rất nhiều thông tin từ Feature map đầu vào, ResNet-B đổi stride trong 1×11 \times 1 Convolution thành 1, stride trong 3×33 \times 3 Convolution thành 2 và đảm bảo đầu ra từ Path A vẫn giữ nguyên kích thước.
image.png

Tinh chỉnh C (Hình 3)

Quan sát thấy khối lượng tính toán của lớp Convolution 7×77 \times 7 gấp 5.4 lần so với lớp Convolution 3×33 \times 3. Tinh chỉnh này thay đổi Input stem, thay thế lớp Convolution 7×77 \times 7 thành 3 lớp Convolution 3×33 \times 3. Điều này giúp trích xuất thông tin tốt hơn mà không làm tăng độ phức tạp tí image.png

Tinh chỉnh D (Hình 4)

Trong khối Down sampling của ResNet, ở Path B cũng sử dụng 1×11 \times 1 Convolution với stride 2 gây mất đi nhiều thông tin. Tinh chỉnh này thêm vào một lớp 2×22 \times 2 Average Pooling với stride 2 trước 1×11 \times 1 Convolution, và thay stride của lớp Convolution thành 1.
image.png

Kết quả

image.png

Cải tiến training

Learning rate decay (Hình 5)

Việc lựa chọn learning rate đúng là cực kì quan trọng. Sau learning rate warmup đã nhắc tới ở trên, ta sẽ giảm từ từ learning rate. Chiến thuật giảm learning rate đơn giản hay được lựa chọn là:

  • Giảm 0.1 learning rate mỗi 30 epochs, gọi là step decay
  • Giảm 0.94 learning rate mỗi epoch

Một chiến thuật nữa là giảm learning rate theo hàm cos\cos. Giả dụ tổng số batch là TT (bỏ qua warmup), thì ở tại batch thứ tt, learning rate ηt\eta_{t} được tính theo công thức:
image.png
với η\eta là learning rate lựa chọn. Chiến thuật này được gọi là Cosine Annealing.
image.png

Label smoothing

Lớp cuối cùng của một mạng nơ-ron phân loại thường là một lớp FC với số unit bằng số class, kí hiệu là KK, để sinh ra giá trị dự đoán. Với một ảnh đầu vào, mạng nơ-ron sẽ sinh ra giá trị dự đoán cho class ii kí hiệu là ziz_i. Giá trị dự đoán này có thể được normalized sử dụng softmax để thu được xác suất dự đoán của từng class. Gọi qq là output của softmax với q=softmax(z)q = softmax(z), xác suất của class ii, qiq_i có thể được tính theo công thức:
image.png
Có thể dễ dàng thấy là qi>0q_i > 0j=1Kqi=1\sum_{j=1}^{K}q_i=1 nên có thể coi qq là một phân phối.
Mặt khác, giả dụ ground truth label cho ảnh là yy, ta có thể dựng một phân phối xác suất ground truth cho pi=1p_i = 1 nếu i=yi=y00 nếu ngược lại. Trong training, mục tiêu của ta là minimize Cross Entropy (CE) loss.
image.png
để làm cho 2 phân phối là phân phối dự đoán từ model và phân phối ground truth trở nên giống nhau. Cụ thể hơn, qua cách xây dựng pp, ta thấy (p,q)=logpy=zy+log(i=1Kexp(zi))\ell (p, q)=-log{p_y}=-z_y+log(\sum_{i=1}^{K}exp(z_i)). Kết quả tối ưu nhất sẽ là zy=infz^*_{y}=inf. Nói cách khác, việc này khuyến khích các class khác nhau trở nên cực kì phân biệt với nhau, do đó có thể dẫn tới overfitting.
Ý tưởng về label smoothing được giới thiệu ở trong Inception-v2. Nó thay đổi cách biểu diễn ground truth label yy thành dạng:
image.png
với ε\varepsilon là một hằng số nhỏ. Lúc này, kết quả tối ưu sẽ trở thành:
image.png
với α\alpha là một số thực bất kì. Điều này khiến kết quả từ lớp FC sẽ generalized tốt hơn.

Knowledge distillation

Trong knowledge distillation, ta sử dụng một teacher model để giúp đỡ train model hiện tại, gọi là student model. Teacher model thường là một model được pre-trained với accuracy cao, để giúp student model cải thiện accuracy mà độ phức tạp của student model vẫn giữ nguyên.
Trong training, ta thêm vào distillation loss để phạt sự khác nhau giữa output từ teacher và student. Cho trước một input, giả sử pp là phân phối ground truth, zzrr là output của student model và teacher model. Ta sẽ dùng CE loss làm distillation loss theo công thức như sau:
image.png
với TT là hyper-parameter để làm mượt output của softmax để chắt lọc kiến thức từ kết quả dự đoán của teacher.

Mixup training

Trong phần baseline cho training, đầu vào đã được đi qua một số augmentations. Ở đây, ta sử dụng thêm một phương pháp augmentation nữa gọi là MixUp. Trong MixUp, ta sẽ lấy ngẫu nhiên 2 mẫu dữ liệu (xi,yi)(x_i, y_i)(xj,yj)(x_j, y_j), sau đó tạo nên một mẫu dự liệu mới theo công thức kết hợp:
image.png
với λ[0,1]\lambda \in [0, 1] được lấy ngẫu nhiên theo phân phối Beta(α,α)Beta(\alpha, \alpha).

Kết quả

image.png

TL;DR

Phía trên là những phân tích rất dài, trình bày sơ qua những phương pháp đó là gì, áp dụng ra sao và có ảnh hưởng tới kết quả của một model Classification như nào. Tuy nhiên, có một số những phương pháp khá dễ áp dụng và đạt hiệu quả ổn định mà mình đã có dịp sử dụng qua dưới đây:

  • Learning rate warmup: Cho learning rate tăng từ từ ở những epoch đầu
  • Learning rate decay: Learning rate sẽ giảm theo thời gian
  • Label smoothing: thay vì sử dụng one-hot encode thì label sẽ được smooth hơn, tránh overfitting
  • Áp dụng các phương pháp augmentation phù hợp với bộ dữ liệu sử dụng: đây là một phương pháp mình thấy cực kì đơn giản mà độ hiệu quả mang lại khá cao

Hy vọng các bạn có thể áp dụng được những phương pháp nói trên vào các bài toán Image Classification của mình và đem lại hiệu quả tốt.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.