Hướng dẫn dùng matrix convolution trong PHP
Hiệu đính lại bài viết. Sau khi đăng lên, một số chuyên gia góp ý thực ra thuật toán áp dụng trong CNN là cross correlation chứ không phải là convolution. Nhiều lập trình viên viết thư viện Deep Learning có chút nhầm lẫn hoặc quen miệng giữa 2 thuật toán này bởi chúng rất giống nhau. Nếu Kernel matrix đối xứng trên với dưới, trái và phải thì kết quả Convolution và Correlation giống hệt nhau. Nội dung chính Tham khảo thêm ở đây nhé Convolution là một kỹ thuật quan trọng xử lý ảnh (digital image processing). Nó có mặt trong hầu hết các thuật toán làm mờ (Gausian Blur), hay làm rõ các đường (edge detector). Trong nhận dạng ảnh (deep learning image processing), convolution layer là một tầng biến đổi ma trận đầu vào để làm rõ và tách ra các đặc tính của hình ảnh mà vẫn bảo toàn tính tương quan không gian giữa đầu ra và đầu vào. Convolution hay còn gọi là tích chập cũng được sử dụng trong phép biến đổi Fourrier nhưng sẽ biến đổi từ miền thời gian sang tần số hoặc ngược lại. Khi tôi xem các paper về Convolution tôi thấy các hàm toán học rất trừu tượng, ngược lại xem các ví dụ mẫu Keras, TensorFlow, thì convolution layer chỉ được đóng gói sẵn nên cũng khó hình dung nó sẽ làm gì. Bài viết này sẽ trình bày nhiều bước khác nhau tôi lập trình hàm convolution bằng Python
trong ngày nghỉ lễ 2/9/2019 Bước 1: Thí nghiệm xử lý ảnh trực quan trên setosa.ioHãy vào web site này http://setosa.io/ev/image-kernels/ để trải nghiệm với kernel khác nhau kết quả đầu ra sẽ khác nhau như thế nào. Nếu hiểu được thí nghiệm này, các bước tiếp theo bạn sẽ thấy rất dễ dàng. Bước 2: Thí nghiệm với ma trận đủ nhỏTrước tiên hãy thử nghiệm với ma trận image đầu vào đủ nhỏ để tính toán thủ công và kiểm tra kết quả đã! Bên trái là ma trận đầu vào, có thể là ảnh. Bên phải là kernel là một ma trận dùng để biến đổi ma trận đầu vào trong 2 vòng lặp lồng nhau convolution. Có vài điểm cần lưu ý:
Bước 3: Code thử nghiệmĐây là code ban đầu chưa tối ưu, dùng nhiều vòng lặp lồng nhau, quan trọng là dễ hiểu. Định nghĩa convolve_nest_loop trong file convolute_lib.py
Tại sao vòng lặp i, j không bằng đầu từ 0 mà lại bắt đầu từ H, W? Hãy thử nhìn vào hình minh hoạ và tự trả lời nhé.
Kết quả ra được là ma trận cùng kích thước bằng ma trận đầu vào nhưng xung quanh viền toàn là số 0, thực chất các phần tử này không được ghi giá trị vào trong phép tích chập.
Bước 4: thay 2 vòng lặp bằng np.tensordotlogic code này có thể thay bằng numpy tensordot . Code ngọn và chạy nhanh hơn
Tốc độ nhanh hơn 3-5 lần với tensordot. Xem hàm def convolve_np(img, kernel) nhé
Bước 5: bỏ padding zero ở ma trận đầu ra hoặc thêm padding zero ở ma trận đầu vàoTrong file convolute_lib.py có một số hàm :
File thực hành là https://github.com/TechMaster/CythonOpenCV/blob/master/Convolution/Convolute_Basic.py Chúng ta chỉ tập trung vào def convolve_np4(img, kernel): vì nó giữ nguyên kích thước ma trận sau biến đổi. Trong các bài tiếp theo tôi sẽ giải thích cơ chế của pool layer trong Convolution Network, pool layer mới thực sự thu nhỏ lại kích thước của ma trận.
Bước 6: kiểm thử hàm convoluteĐể kiểm tra hàm convolute có lập trình đúng hay không hãy sử dụng kernel là ma trận identity, phần tử chính giữa bằng 1, còn lại bằng 0 tất .
Kết luận
|