Chuyển đến nội dung chính

Convolutional Neural Network CNN

Convolutional Neural Network (CNN), hay mạng nơ-ron tích chập, là một họ mạng nơ-ron được thiết kế để khai thác cấu trúc cục bộ của dữ liệu dạng lưới, đặc biệt là hình ảnh. Thay vì nối mỗi pixel với tất cả neuron như MLP, CNN sử dụng những kernel nhỏ di chuyển trên ảnh để phát hiện các đặc trưng như cạnh, góc, texture và sau đó kết hợp chúng thành representation phức tạp hơn.

CNN trở thành nền tảng của nhiều hệ thống Computer Vision nhờ ba ý tưởng quan trọng: kết nối cục bộ, chia sẻ tham số và xây dựng đặc trưng phân cấp. Những nguyên lý này giúp CNN xử lý ảnh hiệu quả hơn nhiều so với việc flatten toàn bộ ảnh rồi đưa trực tiếp vào một mạng fully connected lớn.

Tóm tắt nội dung
  • Convolution layer dùng các kernel học được để tìm đặc trưng cục bộ trên ảnh.
  • Parameter sharing cho phép cùng một kernel được sử dụng tại nhiều vị trí, giúp giảm mạnh số tham số.
  • Stride, padding, pooling và receptive field quyết định kích thước và phạm vi thông tin của feature map.
  • Các layer đầu thường học cạnh và texture; layer sâu hơn có thể học bộ phận và cấu trúc đối tượng phức tạp.
Kiến trúc tổng quát của CNN Convolutional Neural Network Input H × W × C Convolution Feature maps Pooling Downsampling Deep Features Nhiều channels Global Pooling Classifier cat dog car ... Không gian thường giảm dần → đặc trưng ngữ nghĩa thường tăng dần Các kiến trúc CNN hiện đại có thể khác sơ đồ này, nhưng convolution và feature hierarchy vẫn là ý tưởng cốt lõi.
Luồng tổng quát của CNN cho phân loại ảnh: trích xuất feature map bằng convolution, giảm kích thước không gian và ánh xạ representation cuối sang lớp dự đoán.

Vì sao CNN phù hợp với hình ảnh hơn MLP?

Một ảnh không chỉ là tập hợp độc lập của các pixel. Các pixel gần nhau thường có quan hệ mạnh: một cạnh được tạo bởi sự thay đổi cường độ giữa các pixel lân cận, một texture xuất hiện từ nhiều mẫu cục bộ và một đối tượng được hình thành từ những cấu trúc nhỏ hơn.

Nếu flatten một ảnh RGB 224 × 224, số input feature sẽ là:

224 × 224 × 3 = 150528

Nếu nối trực tiếp vector này với một hidden layer 1024 neuron, riêng ma trận weight đã có hơn 154 triệu phần tử trước khi tính bias. Quan trọng hơn, MLP không được cung cấp thông tin rằng hai pixel cạnh nhau có quan hệ không gian đặc biệt.

CNN thay fully connected interaction trên toàn ảnh bằng sparse local interaction. Một neuron chỉ nhìn một vùng nhỏ của feature map trước đó. Cùng một bộ weight còn được dùng lại tại nhiều vị trí, tạo ra parameter sharing. Hai đặc điểm này là lý do CNN có thể xử lý ảnh lớn với số tham số hợp lý hơn.

Local connectivity và parameter sharing trong CNN MLP và CNN nhìn dữ liệu khác nhau Fully Connected Kết nối dày đặc với toàn bộ input Convolution Feature Một kernel nhỏ được dùng lại ở nhiều vị trí
CNN tận dụng sparse interaction và parameter sharing thay vì kết nối mọi input với mọi neuron.

Convolution hoạt động như thế nào?

Giả sử ta có một ảnh hoặc feature map X và một kernel K kích thước nhỏ, chẳng hạn 3 × 3. Kernel được trượt qua các vị trí trên input. Tại mỗi vị trí, các phần tử tương ứng được nhân rồi cộng lại để sinh một giá trị trong feature map mới.

Trong các thư viện Deep Learning như PyTorch, phép toán được gọi là Conv2d thực tế thường sử dụng cross-correlation, tức kernel không bị lật như định nghĩa convolution toán học cổ điển. Điều này không gây vấn đề trong mạng nơ-ron vì các hệ số kernel được học trực tiếp trong quá trình huấn luyện. PyTorch cũng mô tả Conv2d theo cross-correlation trong tài liệu chính thức.

Với một channel, một phần tử output có thể viết:

Y i,j = ∑ u=0 Kh−1 ∑ v=0 Kw−1 K u,v X i+u , j+v + b

Với ảnh nhiều channel, mỗi output channel có một tập kernel trải qua tất cả input channels. Các kết quả theo channel được cộng lại trước khi thêm bias.

Kernel 3x3 trong convolution Kernel trượt trên input và tạo feature map Input 5 × 5 Kernel 3 × 3 k₁ k₂ k₃ Các giá trị kernel được học Output 3 × 3 nhân + cộng Kernel tiếp tục dịch chuyển để tính các vị trí còn lại của feature map.
Ví dụ stride = 1, padding = 0: kernel 3 × 3 trên input 5 × 5 tạo output 3 × 3.

Một kernel tạo một output channel

Nếu Conv2d có 64 output channels, layer học 64 bộ filter khác nhau. Mỗi filter có thể phản ứng với một loại pattern khác nhau. Sau quá trình huấn luyện, một số filter có thể trở nên nhạy với đường biên, hướng, texture hoặc những pattern phức tạp hơn.

Với convolution thông thường, số tham số của layer là:

Parameters = Cout × Cin G × Kh × Kw + Cout

Phần cuối là bias nếu layer bật bias. G là số groups; với convolution thông thường G = 1.

Stride, padding, pooling và receptive field

Stride

Stride là số bước kernel dịch chuyển sau mỗi lần tính toán. Stride = 1 giữ độ phân giải cao hơn; stride = 2 thường làm chiều cao và chiều rộng giảm xấp xỉ một nửa.

Padding

Padding bổ sung giá trị ở biên input trước khi convolution. Với kernel 3 × 3, stride 1 và dilation 1, padding 1 thường giữ nguyên chiều cao và chiều rộng.

Công thức tổng quát cho kích thước output theo một chiều là:

Hout = ⌊ Hin + 2P − D (K−1) − 1 S + 1 ⌋

Trong đó K là kernel size, S là stride, P là padding và D là dilation. Chiều rộng được tính tương tự.

Pooling

Pooling giảm kích thước không gian của feature map. Max Pooling lấy giá trị lớn nhất trong mỗi cửa sổ, trong khi Average Pooling lấy trung bình.

Ví dụ MaxPool 2 × 2 với stride 2 có thể biến feature map 32 × 32 thành 16 × 16. Việc giảm resolution giúp giảm computation cho các layer sau và tăng phạm vi input mà mỗi unit sâu có thể phụ thuộc vào.

Max Pooling 2x2 Max Pooling 2 × 2, stride 2 1 5 2 0 3 8 4 6 7 2 9 1 0 4 5 3 lấy max 8 6 7 9 Output 2 × 2
Max pooling giữ lại phản hồi lớn nhất trong mỗi vùng. Các CNN hiện đại cũng có thể giảm resolution bằng convolution stride 2 thay vì pooling riêng.

Tài liệu về CNN thường nhấn mạnh việc kết hợp local connectivity, parameter sharing và pooling/downsampling để xử lý input lớn hiệu quả.

Receptive field

Receptive field của một unit là vùng trên input có khả năng ảnh hưởng tới unit đó. Một convolution 3 × 3 ở layer đầu chỉ nhìn vùng nhỏ, nhưng khi xếp nhiều layer, các neuron ở tầng sâu phụ thuộc gián tiếp vào vùng input ngày càng rộng.

Ví dụ với các convolution 3 × 3, stride 1 và không xét ảnh hưởng của biên, receptive field tăng như sau:

Số convolution 3 × 3 Receptive field
1 3 × 3
2 5 × 5
3 7 × 7

Khi stride lớn hơn 1 hoặc có pooling, receptive field có thể tăng nhanh hơn. Đây là cơ chế cho phép layer sâu kết hợp thông tin trên vùng ảnh rộng mà mỗi convolution vẫn chỉ sử dụng kernel nhỏ.

CNN học đặc trưng phân cấp như thế nào?

Một đặc điểm quan trọng của Deep Learning là feature không cần được thiết kế hoàn toàn thủ công. Các kernel được cập nhật qua Backpropagation để phục vụ trực tiếp cho mục tiêu cuối cùng của model.

Có thể hình dung representation của một CNN phân loại ảnh theo các mức:

Pixels
RGB
→
Low-level
Edges / gradients
→
Mid-level
Texture / shapes
→
High-level
Object parts
→
Prediction
Class / mask

Đây là cách giải thích trực quan chứ không phải mọi filter đều có thể gắn một nhãn ngữ nghĩa rõ ràng. Representation thực tế được phân bố trên nhiều channels và có thể khó diễn giải trực tiếp.

Translation equivariance

Do cùng một kernel được áp dụng tại nhiều vị trí, nếu pattern trong input dịch chuyển thì response của convolution cũng có xu hướng dịch chuyển tương ứng. Tính chất này thường được gọi là translation equivariance.

Equivariance không đồng nghĩa với invariance. Một feature map vẫn giữ thông tin vị trí. Downsampling, pooling và các thao tác tổng hợp toàn cục có thể làm representation cuối ít nhạy hơn với những dịch chuyển nhỏ, nhưng CNN không tự động bất biến hoàn toàn với mọi phép dịch.

Điểm dễ nhầm: convolution có tính translation equivariance mạnh hơn là translation invariance. Hai thuật ngữ này không nên dùng thay thế cho nhau.

Các kiến trúc CNN không chỉ là Conv → Pool → FC

Sơ đồ Conv → activation → pooling → fully connected rất hữu ích để học nguyên lý, nhưng CNN hiện đại có thể sử dụng residual connection, normalization, bottleneck, depthwise convolution, global average pooling và nhiều cơ chế khác.

Điểm chung vẫn là các phép convolution khai thác locality và weight sharing. Những sơ đồ công khai về CNN trên Wikimedia Commons cũng thể hiện việc feature map thay đổi số channel và kích thước không gian qua nhiều layer.

Xây dựng CNN hoàn chỉnh bằng PyTorch

Ví dụ sau xây dựng một CNN nhỏ cho ảnh RGB 32 × 32 với 10 lớp. Kiến trúc sử dụng hai convolution block và AdaptiveAvgPool2d để tránh phụ thuộc vào việc tính thủ công kích thước flatten của feature map.

import torch
import torch.nn as nn


class SimpleCNN(nn.Module):

    def __init__(self, num_classes=10):
        super().__init__()

        self.features = nn.Sequential(

            # Input: B × 3 × 32 × 32
            nn.Conv2d(
                in_channels=3,
                out_channels=32,
                kernel_size=3,
                padding=1
            ),
            nn.ReLU(),

            # B × 32 × 16 × 16
            nn.MaxPool2d(
                kernel_size=2,
                stride=2
            ),

            nn.Conv2d(
                in_channels=32,
                out_channels=64,
                kernel_size=3,
                padding=1
            ),
            nn.ReLU(),

            # B × 64 × 8 × 8
            nn.MaxPool2d(
                kernel_size=2,
                stride=2
            ),

            nn.Conv2d(
                in_channels=64,
                out_channels=128,
                kernel_size=3,
                padding=1
            ),
            nn.ReLU(),

            # B × 128 × 1 × 1
            nn.AdaptiveAvgPool2d((1, 1))
        )

        self.classifier = nn.Linear(
            128,
            num_classes
        )

    def forward(self, x):

        x = self.features(x)

        # B × 128 × 1 × 1 → B × 128
        x = torch.flatten(x, start_dim=1)

        # Raw logits
        logits = self.classifier(x)

        return logits


model = SimpleCNN(num_classes=10)

x = torch.randn(
    8,
    3,
    32,
    32
)

logits = model(x)

print(logits.shape)
# torch.Size([8, 10])

Trong PyTorch, Conv2d nhận tensor ảnh theo thứ tự B × C × H × W. Tham số in_channels là số channel đầu vào, còn out_channels là số filter và cũng chính là số channel của output feature map.

Huấn luyện CNN cho multi-class classification

import torch
import torch.nn as nn

model = SimpleCNN(num_classes=10)

criterion = nn.CrossEntropyLoss()

optimizer = torch.optim.Adam(
    model.parameters(),
    lr=1e-3
)

for images, labels in train_loader:

    model.train()

    optimizer.zero_grad()

    logits = model(images)

    loss = criterion(
        logits,
        labels
    )

    loss.backward()

    optimizer.step()

Không thêm Softmax vào cuối model khi sử dụng CrossEntropyLoss. Model trả trực tiếp logits. Khi inference, nếu chỉ cần class ID có thể lấy argmax trực tiếp trên logits:

model.eval()

with torch.no_grad():

    logits = model(images)

    predictions = logits.argmax(dim=1)

    probabilities = torch.softmax(
        logits,
        dim=1
    )

Theo dõi shape để tránh lỗi CNN

Một trong những lỗi phổ biến nhất khi viết CNN là không kiểm soát shape. Có thể thêm đoạn kiểm tra đơn giản:

x = torch.randn(
    1,
    3,
    32,
    32
)

for layer in model.features:

    x = layer(x)

    print(
        layer.__class__.__name__,
        x.shape
    )

Cách này đặc biệt hữu ích khi thay đổi stride, pooling hoặc kernel size và muốn kiểm tra chính xác kích thước feature map tại từng bước.

CNN được sử dụng ở đâu và thường mắc lỗi gì?

CNN không chỉ được sử dụng cho image classification. Convolution tạo feature map không gian nên phù hợp với nhiều tác vụ Computer Vision.

Bài toán Vai trò của CNN
Image Classification Trích xuất representation và dự đoán lớp của ảnh
Object Detection Backbone tạo feature maps dùng để tìm và phân loại đối tượng
Semantic Segmentation Encoder trích xuất đặc trưng không gian cho dự đoán từng pixel
Medical Imaging Phân loại ảnh, phát hiện bất thường và segmentation
Remote Sensing Phân tích ảnh vệ tinh, đất đai và công trình
1D Signals Conv1d có thể xử lý tín hiệu thời gian hoặc chuỗi đặc trưng cục bộ

Nhầm Conv2d với convolution toán học có lật kernel

Trong nhiều framework, Conv2d triển khai cross-correlation. Khi học Deep Learning, thuật ngữ convolution vẫn được sử dụng theo quy ước của lĩnh vực. Điều cần quan tâm là kernel được học bằng gradient chứ không phải việc tự lật kernel trong code.

Sai thứ tự channel

PyTorch Conv2d thường nhận input B × C × H × W. Nếu ảnh đang ở dạng B × H × W × C như một số pipeline khác, cần chuyển dimension trước khi đưa vào model.

Flatten feature map quá sớm

Flatten sớm làm mất cấu trúc không gian và có thể tạo fully connected layer rất lớn. Các kiến trúc hiện đại thường giữ feature map qua nhiều convolution block rồi mới dùng global pooling hoặc prediction head.

Không chuẩn hóa ảnh

Scale của input ảnh ảnh hưởng tới tối ưu. Với pretrained model, preprocessing phải tương thích với cách model được huấn luyện ban đầu, bao gồm resize và normalization.

Tăng số filter mà không kiểm tra chi phí

Tăng channels làm tăng khả năng biểu diễn nhưng cũng tăng số tham số, activation memory và số phép tính. Khi thiết kế CNN cần theo dõi đồng thời accuracy, FLOPs, memory và latency.

Baseline CNN thực tế:

Dùng kernel 3 × 3 làm điểm bắt đầu.
Giữ padding phù hợp nếu cần bảo toàn resolution.
Tăng dần số channels khi resolution giảm.
Dùng normalization và augmentation khi phù hợp.
Dùng Global Average Pooling thay vì fully connected rất lớn khi có thể.
Theo dõi validation metric thay vì chỉ training accuracy.

Kết luận

CNN khai thác hai tính chất rất quan trọng của hình ảnh: các pattern cục bộ có ý nghĩa và cùng một loại pattern có thể xuất hiện ở nhiều vị trí. Kernel convolution tạo sparse local interaction, còn parameter sharing cho phép cùng một filter được sử dụng trên toàn feature map.

Khi nhiều convolution layer được xếp chồng, receptive field tăng dần và model có thể xây dựng representation từ cạnh, texture đến cấu trúc phức tạp hơn. Hiểu rõ kernel, channel, stride, padding, pooling và receptive field là nền tảng để tiếp tục nghiên cứu ResNet, U-Net, EfficientNet, object detection, semantic segmentation và các kiến trúc kết hợp CNN với Transformer.

Nguồn tham khảo

  1. Goodfellow, Bengio & Courville — Deep Learning, Chapter 9: Convolutional Networks. Nguồn nền tảng cho convolution, sparse interaction, parameter sharing, pooling và các tính chất của CNN.
  2. PyTorch Documentation — torch.nn.Conv2d. Đối chiếu API Conv2d, input/output channels, stride, padding, dilation, groups và việc Conv2d sử dụng phép cross-correlation.
  3. LeCun và cộng sự — Gradient-Based Learning Applied to Document Recognition. Một công trình kinh điển về mạng tích chập và nhận dạng ký tự.

Nguồn hình ảnh công khai để đối chiếu kiến thức

  1. Convolutional Network (vector).svg — Will Whitney, Wikimedia Commons. Minh họa convolution và pooling trên ảnh. Giấy phép CC BY-SA 4.0.
  2. Convolutional Layers of a Convolutional Neural Network.svg — Renanar2, Wikimedia Commons. Minh họa sự thay đổi spatial resolution và channels qua các convolution layer. Giấy phép CC BY-SA 4.0.
  3. ConvolutionAndPooling.svg — Andreas Maier và cộng sự, Wikimedia Commons. Minh họa local receptive field, shared weights và pooling. Giấy phép CC BY 4.0.
Các SVG chính trong bài này được dựng lại độc lập để đảm bảo giao diện sáng, responsive và không phụ thuộc vào máy chủ hình ảnh bên ngoài. Các hình công khai kể trên được sử dụng làm nguồn đối chiếu kiến thức và ghi đầy đủ tác giả, nguồn cùng giấy phép.
© The CS Note · THE CS NOTE

Nội dung gốc thuộc tác giả. Vui lòng không đăng lại toàn văn khi chưa được phép, trừ trường hợp pháp luật hoặc giấy phép áp dụng cho phép. Nội dung của bên thứ ba tuân theo quyền và giấy phép tương ứng.

Nguồn gốc: Convolutional Neural Network CNN

Về trang chủ Về đầu bài

Bài Đăng Phổ Biến

Bài toán tháp Hà nội

Trải nghiệm Tháp Hà Nội Kéo thả đĩa hoặc chạm vào các nút bên dưới để di chuyển. Bạn phải chuyển toàn bộ đĩa sang cột ngoài cùng bên phải (Cột 3) mà không đặt đĩa to lên đĩa nhỏ. Cột 1 Cột 2 Cột 3 Điều khiển & Chế độ Số lượng đĩa 4 Tốc độ máy giải ↪ Undo ↻ Chơi lại 🤖 Máy tự giải Thống kê ván chơi Nước đã đi 0 Thời gian 00:00 Tối thiểu cần 15 Kỷ lục của bạn - Lịch sử và Nguồn gốc Truyền thuyết Bài toán Tháp Hà Nội (hay Tháp Brahma) là một trò chơi xếp hình toán học kinh điển được giới thiệu lần đầu vào năm 1883 bởi nhà toán học người Pháp Édouard L...

Bài toán phân tích cảm xúc trong văn bản

Bài toán phân tích cảm xúc (sentiment analysis) là một bài toán NLP nhằm xác định thái độ hoặc cảm xúc được thể hiện trong văn bản. Ví dụ, từ một đánh giá như “Điện thoại đẹp, chạy nhanh nhưng pin hơi yếu”, hệ thống có thể nhận biết rằng người dùng có cả nhận xét tích cực và tiêu cực. Điểm thú vị của bài toán nằm ở khoảng cách giữa cách con người hiểu ngôn ngữ và cách máy tính xử lý dữ liệu. Một hệ thống phân tích cảm xúc cần biến văn bản tự nhiên thành dữ liệu có cấu trúc, học được các mẫu ngôn ngữ từ dữ liệu huấn luyện và đưa ra dự đoán hợp lý trên những câu chưa từng gặp. 1. Bài toán phân tích cảm xúc bắt đầu từ đâu? Hãy tưởng tượng một cửa hàng trực tuyến có hàng nghìn đánh giá mỗi ngày. Con người có thể đọc từng đánh giá để biết khách hàng hài lòng hay không, nhưng việc này nhanh chóng trở nên tốn thời gian khi dữ liệu tăng lên. NLP có thể biến bài toán đó thành một bài toán phân loại. Với mỗi văn bản, hệ thống nhận vào một chuỗi ký...

KAN cho phân đoạn khối u não với bộ BraTS 2020

Kolmogorov-Arnold Network (KAN) mở ra một hướng khác với MLP truyền thống: thay vì chỉ học các trọng số vô hướng trên mỗi kết nối, KAN có thể học những hàm phi tuyến một biến trên các cạnh . Khi đưa ý tưởng này vào kiến trúc encoder-decoder như U-Net, ta có thể sử dụng convolution để giữ cấu trúc không gian của ảnh MRI và dùng KAN để thực hiện các phép biến đổi phi tuyến mạnh hơn trên representation trung gian. Một bài toán phù hợp để nghiên cứu hướng này là phân đoạn u thần kinh đệm trên BraTS 2020 . Dataset cung cấp MRI đa mô thức và yêu cầu xác định các vùng Whole Tumor (WT), Tumor Core (TC) và Enhancing Tumor (ET). Đây là bài toán 3D có sự mất cân bằng voxel lớn, hình dạng khối u rất đa dạng và ranh giới giữa các mô bệnh lý không đơn giản. Lưu ý học thuật quan trọng: U-KAN gốc được công bố cho nhiều benchmark phân đoạn ảnh y tế nhưng không báo cáo kết quả BraTS 2020. Một công trình sau đó đã mở rộng U-KAN sang 3D MRI brain tumor segmentation , nhưng đánh giá trên BraTS 2...

Tách từ trong tiếng Việt Word Segmentation

Tách từ tiếng Việt là bài toán xác định ranh giới giữa các từ trong một chuỗi văn bản. Khó khăn nằm ở chỗ khoảng trắng trong tiếng Việt thường phân cách các âm tiết , nhưng một từ hoàn chỉnh có thể gồm nhiều âm tiết như “sinh viên” , “đại học” , “công nghệ” hay “tự nhiên” . Tách từ đúng giúp các hệ thống NLP dựa trên từ biểu diễn văn bản hợp lý hơn, đặc biệt trong tìm kiếm, TF-IDF, phân loại văn bản, gán nhãn từ loại và một số mô hình ngôn ngữ tiếng Việt. Tuy nhiên, với các Transformer sử dụng tokenizer dưới mức từ như subword hoặc SentencePiece, tách từ thủ công không phải lúc nào cũng là bước bắt buộc . Việc có cần tách từ trước hay không phụ thuộc vào mô hình và pipeline cụ thể. Tóm tắt nội dung Khoảng trắng trong tiếng Việt không phải lúc nào cũng là ranh giới từ ; nhiều từ gồm hai hoặc nhiều âm tiết. Word segmentation và tokenization có liên quan nhưng không hoàn toàn đồng nghĩa. Ba hướng chính gồm dựa trên từ điển, mô hình thống kê và mô hình học sâu . Tron...

KAN là gì? Mạng Kolmogorov-Arnold khác MLP thế nào?

Kolmogorov-Arnold Network (KAN) là một kiến trúc mạng nơ-ron trong đó mỗi cạnh không chỉ chứa một trọng số vô hướng mà mang một hàm một biến có thể học được . Đây là khác biệt cốt lõi so với Multi-Layer Perceptron (MLP), nơi các cạnh chủ yếu thực hiện phép nhân với trọng số còn hàm kích hoạt thường được áp dụng tại các node. KAN được lấy cảm hứng từ định lý biểu diễn Kolmogorov-Arnold và đặc biệt đáng chú ý trong các bài toán xấp xỉ hàm, mô hình hóa khoa học và symbolic regression. Tuy nhiên, KAN không nên được hiểu là kiến trúc đã thay thế MLP trong mọi bài toán Deep Learning; khả năng biểu diễn, chi phí tính toán và mức độ phù hợp của hai kiến trúc khác nhau theo từng nhiệm vụ. Tóm tắt nội dung MLP học chủ yếu trọng số trên các cạnh , còn KAN đặt hàm một biến học được trên từng cạnh . Một KAN layer cộng kết quả của nhiều hàm cạnh để tạo activation của node tiếp theo. KAN gốc sử dụng B-spline để tham số hóa các hàm phi tuyến trên cạnh. KAN có lợi thế đáng chú ý về trực...