Nhận dạng ảnh chó mèo bằng Neural Network

Phân loại hình ảnh (classification) là bài toán quen thuộc trong Machine Learning. Vô tình gặp 1 bài hướng dẫn về ANN (Artifical Neural Network) khá hay & dễ hiểu nên mình dịch lại. Kèm theo đó là sửa đổi đôi chút trong code để code ngắn gọn và dễ sử dụng hơn.

Trong bài viết gốc hướng dẫn cách implement code, giải thích code tuy nhiên ít hình minh họa. Mình sẽ thêm hình minh họa và mô tả giải thuật bằng cách đơn giản nhất. Hy vọng các bạn sẽ mở rộng ra nhiều thứ hơn là chỉ nhận dạng ảnh chó mèo bằng Neural Network.

Các bạn có thể xem paper: Is-It-a-Cat-or-a-Dog.pdf.

Bài viết chỉ giải thích tương đối, source code có sẵn cuối bài, xem code để hiểu sâu về cách thực hiện.

Chuẩn bị

1. Bộ dữ liệu hình ảnh chó mèo tại Kaggle (271 MB)
2. OpenCV 3.x (Mình đã integrate lib OpenCV vào source code cuối bài rồi)
3. Visual Studio 2015 Community


Giải thuật

1. Chia hình ảnh thành 2 bộ: trainset và testset
2. Đọc hình ảnh từ trainset để lấy thông tin ảnh & class của ảnh để training
3. Biến đổi ảnh vừa đọc xong thành data phù hợp với giải thuật Neural Network.
4. Đọc hình ảnh từ testset để tiến hành predict
5. So sánh và in kết quả ra màn hình


1. Chia hình ảnh thành 2 bộ: trainset và testset

Để đánh giá 1 thuật toán người ta lấy ngẫu nhiên ảnh để sắp thành 2 bộ. Tỉ lệ 2 bộ ảnh có thể là 3/4 + 1/4, 2/3 + 1/3, 9/10 + 1/10,… Lúc nào bộ trainset cũng lớn hơn bộ testset vài lần.

Chương trình này làm như sau:
– Chương trình sẽ đọc hết tất cả ảnh trong thư mục
– Sắp xếp lại danh sách ảnh theo thứ tự ngẫu nhiên (dùng hàm std::random_shuffle())
– Lấy file từ 0 -> số lượng mà user chỉ định làm trainset
– Số lượng file còn lại làm testset


2. Đọc hình ảnh từ trainset

Các file ảnh có tên theo dạng cat.xxx.jpg hoặc dog.xxx.jpg, cho nên chúng ta lấy 3 ký tự đầu tiên làm tên class.
Tiếp theo sử dụng KAZE để lấy decriptor của ảnh làm input.


3. Biến đổi ảnh thành data phù hợp với giải thuật Neural Network

Để training cần 2 mảng: 1 mảng 2 chiều (Mat) chứa data & 1 mảng 2 chiều chứa class tương ứng. Mảng chứa data có mỗi dòng tương ứng 1 ảnh, mảng chứa class cũng tương tự.

Mảng chứa class có đặc trưng như sau: số dòng là số lượng ảnh dùng để train, số cột của mảng là số class. Trong bài này có 2 class là cat & dog, giả sử với 8 ảnh ta sẽ có mảng chứa class như sau:
mat_class

Như hình trên ảnh 1 là dog, nên cột tương ứng với cat là 0, cột dog là 1,… tương tự cho tất cả các ảnh còn lại.


4. Đọc hình ảnh từ testset để tiến hành predict

Đọc hình ảnh từ testet tương tự như trainset, sau đó dùng hàm predict() để lấy kết quả. Kết quả vẫn là 1 mảng 2 chiều (Mat), mỗi dòng ở output tương ứng với 1 dòng ở input.

Và mảng output cũng có cấu tương tự mảng chứa class ở bước training. Điều đó có nghĩa là với mỗi dòng kết quả bạn cần phải sử dụng vòng lặp tìm class tương ứng. Bên dưới là ví dụ mẫu về mảng output:

mat_class_out

Với mỗi dòng, lặp qua tất cả các ô để tìm giá trị lớn nhất, sau đó trả về class tương ứng với giá trị lớn nhất đó. Với dòng 1, giá trị lớn nhất nằm ở cột Dog, vậy kết quả là predict của ảnh 1 là Dog. Tương tự dòng 2 có giá trị lớn nhất nằm ở cột Cat, vậy kết quả là Cat,…


5. So sánh và in kết quả ra màn hình

Tiến hành so sánh kết quả class sau khi predict với class trong tên file ảnh. Ta lập ma trận confusion như sau:

mat_confusion

Ảnh Cat dự đoán là Cat: 2 | Ảnh Dog dự đoán là Cat: 60
Ảnh Cat dự đoán là Dog: 3 | Ảnh Dog dự đoán là Dog: 110

Như vậy độ chính xác bằng số ảnh dự đoán đúng trên tổng số ảnh: (2 + 110) / (2 + 60 + 3 + 110) = 0.64

Mình đề nghị các từ chuyên môn như Neural Network, feature, descriptor giữ nguyên, không dịch lại tiếng Việt. Điều đó sẽ giúp dễ dàng tra cứu tài liệu và giữ nguyên ngữ nghĩa.

Download

Trong link đã bao gồm project viết bằng C++ sử dụng Visual Studio 2015 và bộ ảnh Cat & Dog. Tham số truyền vào gồm: thư mục chứa ảnh input, số layer và tỉ lệ trainset/tổng số ảnh = 0.75

AnnExample (Github)

6 thoughts on “Nhận dạng ảnh chó mèo bằng Neural Network

Leave a Reply