TỔNG HỢP HOMEWORK MÔN THỊ GIÁC MÁY TÍNH, Giảng viên hướng dẫn: Phạm Việt Cường, MỤC LỤC I. TỔNG HỢP HOMEWORK NHÓM 5 2 1. Homework 0: Image Processing 2 2. Homework 1 :Viola Jones: training 16 3. Homework 2 : Partial derivative with chain rule. Check your results with numerical derivative. 20 4. Homework 3 21 5. Homework 4:Write a program implementing gradient descent method. Consider at least two nonconvex twovariable functions f(x,y), multiple initial points and various learning rates. 24 6. Homework 5:Why local connectivity shared weights? 29 7. Homework 6:How many parameters (weights and biases) are there in AlexNet? 31 8. Homework 7:Compute top1 top5 error rates for AlexNet and two other models. Use at least 5 classes with minimum 20 images per class. 33 Thực hiện training mô hình, ta được kết quả như bên dưới (xem file code đính kèm) 33 9. Homework 8:Evaluate the performance of AlexNet using images with various aspect ratios. 34 10. Homework 9:AlexNet transfer learning, at least 5 classes with minimum 20 images per class. 36 11. Homework 10:For classification problems, why we use onehot encoding instead of one output (e.g. encoding 4 classes as 1, 2, 3, 4) or binary encoding (e.g encoding 4 classes as 00, 01, 10, 11)? 43 12. Homework 11:Write a program implementing feature nomalization. 43 13. Homework 12:Cascade object detection: use pretrained model and evaluate error. 46 14. Homework 13:How to obtain Precision Recal curve? 48 15. Homework 14:Evaluate object detector YOLORCNNSSD. 51 16. Homework 15:Train object detection YOLORCNNSSD. 56 17. Homework 16:How to handle multiple detections. 59 18. Homework 17:What are PF, FN for object detection problem? 60 II. TÀI LIỆU THAM KHẢO 64
TỔNG HỢP HOMEWORK NHÓM 5
Homework 0: Image Processing
1 Image Enhancement Histogram Equalization p(rk): có thể hiểu đây là phân trăm số pixels có giá trị màu là rkf nk: số pixels có giá trị màu là rk n : tổng số pixels trong bức ảnh
Các hàm sử dụng : a HÀM IMHIST: imhist(I) % tạo histogram
Hiển thị một biểu đồ của hình ảnh thang độ xám, theo mặc định, biểu đồ sẽ có 256 mức sáng (trắng đen).
I=imread('pout.tif');% đọc anh về' figure Name 1 subplot(2,2,1) imshow(I) % show anh subplot(2,2,2) imhist(I) % tạo histogram load mristack; subplot(2,2,3) imhist(mristack) b HÀM histeq: J=histeq(K); % tạo ảnh đã cân bằng tăng độ tương phảnTăng cường độ tương phản của hình ảnh cường độ bằng cách sử dụng cân bằng biểu đồ Có nghĩa ta hàm này sẽ dải đều histogram của tấm ảnh ra đều trên dải màu
K=imread('tire.tif'); figure Name 2 subplot(2,2,1) imshow(K) subplot(2,2,2)
J=histeq(K);% tạo anh đã cân bằng tăng độ tương phan
%J = histeq(I,hgram)% dựng theo histogram chuân imshowpair(K,J,'montage') axis off % bo trục
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% enhanced = histeq(mristack); figure name 3 subplot(1,2,1) imshow(mristack(:,:,1)) title('Slice of Original Image') subplot(1,2,2) imshow(enhanced(:,:,1)) title('Slice of Enhanced Image') c HÀM imhistmatch: imhistmatch(A,Ref);
Hàm imhistmatch sẽ điều chỉnh phân bố dải histogram theo một hệ quy chiếu, theo câu lệnh này thì hình A sẽ được phân bố mức ảnh theo hình Ref
B = imhistmatch(A,Ref); figure name 4 subplot(2,3,1) imshow(A) title('RGB Image with Color Cast') subplot(2,3,2) imshow(Ref) title('Reference Grayscale Image') subplot(2,3,3) imshow(B) title('Histogram Matched RGB Image')
L = imread('office_4.jpg'); ref = imread('office_2.jpg'); subplot(2,3,4) montage({L,ref}) title('Input Image (Left) vs Reference Image (Right)');
K = imhistmatch(L,ref,'method','uniform'); subplot(2,3,6) montage({J,K}) title('Histogram-Matched Image Using Polynomial Method (Left) vs Uniform Method (Right)');
2 Sử dụng hàm cơ bản để điều chỉnh gray level
Ta sử dụng các hàm cơ bản để thay đổi gray level
Có 3 loại thường được sử dụng là :
Power law o n th power/nth root các hàm sử dụng:
Khi sử dụng hàm log để điều chỉnh dải histogram của ảnh thì phần tối của ảnh sẽ tăng mức sáng lớn hơn so với phân sáng của ảnh
%% SỬ DỤNG HÀM cơ ban log
M=imread('tire.tif'); r=imhist(M); s=log(r);
N=histeq(M,s); figure name 5 montage({M,N}) title('Input Image (Left) vs Reference Image (Right)'); b Hàm mũ: hàm mũ sẽ ngược lại với hàm log
%% SỬ DỤNG HÀM cơ ban mũ
P=histeq(O,s); figure name 6 montage({O,P}) title('Input Image (Left) vs Reference Image (Right)');
Có nhiều dạng filter và nó có những chức năng khác nhau Chức năng chính của filter giúp làm mờ hoặc làm sắc nét ảnh, lọc nhiễu
Các hàm sử dụng a Filter trung bình (ô trung tâm trong Kenel sẽ được tính trung bình bởi tất cả các ô xung quanh)
C=imboxfilt(A,11); figure name filter_trung_binh subplot(2,1,1) imshowpair(A,B,'montage') title('mặc định') subplot(2,1,2) imshowpair(A,C,'montage') title('matrix mask 11x11') b (TRUNG BÌNH CÓ TRỌNG SỐ) gaussian filte (trọng số nhân thêm vào giá trị các ô được chỉ định)
%% (TRUNG BÌNH CÓ TRỌNG SỐ\ ) gaussian filter
E=imgaussfilt(D); % mặc định sigma bằng 0.5
F=imgaussfilt(D,2); figure name gaussian_filter subplot(2,1,1) imshowpair(D,E,'montage') title('mặc định') subplot(2,1,2) imshowpair(D,F,'montage') title('sigma = 2') c medium filter (trung vị)
Hình này filter trung vị đang giúp loại bỏ đi nhiễu Ta thấy tra trận lớn hơn sẽ làm mờ ảnh đi nhiều hơn
H = imnoise(G,'salt & pepper',0.02);% làm nhiềa u muố\ i tiều
K = medfilt2(H,[4 4]); figure name medium_filter subplot(2,1,1) imshowpair(H,I,'montage') title('mặc định') subplot(2,1,2) imshowpair(H,K,'montage') title('matrix medium 4x4') d Order filter (là tổng quan của medium filter)
%% order filter (là tống quan cua medium filter)
C = ordfilt2(A,1,[0 1 0; 1 0 1; 0 1 0]);% matrix mask tự chọn figure name order_filter subplot(2,1,1) imshowpair(A,B,'montage') title('matrix 5x5 kiều max') subplot(2,1,2) imshowpair(A,C,'montage') title('mask tự chọn')
Làm đầy các nét đứt, tách ảnh (phục chế ảnh)
Các hàm sử dụng: a J = imerode(I,SE) ; % SE =[0,1,1] erosion Ảnh gốc sau khi được viền thì sẽ có một viền đen xung quanh hình, điều này nhằm mục đích cho Kenel có thể nhận ra được mép của hình bên trong Và ta thấy được kết quả khi có viền và không viền Ảnh có viền cho ra kết quả trính xác còn ảnh không viền thì ra kết quả sai
Ip=padarray(I,[1 1]);% tạo viề' n cho anh
Iep=imerode(Ip,SE); figure; subplot(2,2,1) imshow(I,'InitialMagnification','fit') title('anh gố\ c') subplot(2,2,2) imshow(Ip,'InitialMagnification','fit') title('anh viề' n') subplot(2,2,3) imshow(Ie,'InitialMagnification','fit') title('anh gố\ c erosion với SE') subplot(2,2,4) imshow(Iep,'InitialMagnification','fit') title('anh đã viề' n erosion với SE') b J = imdilate(I,SE) dilation
BW=imbinarize(I); % chuyền thành anh nhị phân
SE= strel('disk',5); % định nghĩa phâ' n tư câ\ u trúc kernel
SE= strel('disk',15); BW2=imerode(BW1,SE);
SE= strel('disk',9); BW3=imdilate(BW2,SE); imfill(BW3,'holes'); % làm đâ' y khoang trố\ ng bền trong hình figure subplot(2,2,1) imshow(I,'InitialMagnification','fit'); title('anh gố\ c') subplot(2,2,2) imshow(BW1,'InitialMagnification','fit') title('anh chỉnh SE 5') subplot(2,2,3) imshow(BW2,'InitialMagnification','fit') title('anh chỉnh SE 15') subplot(2,2,4) imshow(BW3,'InitialMagnification','fit') title('anh chỉnh SE 9')
% BW2 = bwareaopen(BW, 50); xóa phâ' n tư có ít hơn 50 pixel coins = bwconncomp(BW3); disp('số\ coins'); disp(coins);
Khác nhau chủ yếu của 2 cách lấy ngưỡng này là Otsu method lấy ngưỡng trên toàn cục còn Adaptive threshold thì lấy ngưỡng trên từng vùng nhỏ hơn.
%Otsu method level = graythresh(I); % chuân hoá ngưỡng xám cua anh I
BW1 = imbinarize(I,level); % chuyền thành nhị phân theo level(giá trị pixel> level->tră\ ng, đen)
T= adaptthresh(I,0.4,'ForegroundPolarity','dark'); % Sư dụng Adaptthresh đề xác định ngưỡng sư dụng
BW2 = imbinarize(I,T);% Chuyền đối hình anh thành hình anh nhị phân, chỉ định giá trị ngưỡng theo T. subplot(2,2,1) imshow(I,'InitialMagnification','fit') title('anh gố\ c') subplot(2,2,2) imshow(BW1) title('anh sư dụng pp Otsu method') subplot(2,2,3) imshow(BW2) title('anh sư dụng pp adaptthresh (anh nhị phân)') subplot(2,2,4) imshow(T) title('ngưỡng lâ\ y threshold cho từng vị trí pixel')
6 Point, Line and Edge Detection
edge(I,'canny') : dùng để xác định các đường line
[H,,] = hough(BW): ý tưởng của hough là chuyển đổi các điểm trên ảnh sang không gian tọa độ khác, để có thể biểu diễn đường thẳng một cách đơn giản hơn Trong không gian tọa độ mới, mỗi điểm được biểu diễn dưới dạng một đường thẳng, và mỗi đường thẳng được biểu diễn bởi hai tham số (rho và theta).
Biến là khoảng cách từ gốc tọa độ đến đường thẳng dọc theo một vectơ vuông góc với đường thẳng là góc của hình chiếu vuông góc từ gốc tọa độ đến đường thẳng được đo bằng độ theo chiều kim đồng hồ từ trục x dương Phạm vi của theta là –90° ≤ θ < 90° Góc của đường thẳng là θ + 90°, cũng được đo theo chiều kim đồng hồ đối với trục x dương. ρ = x*cos(θ) + y*sin(θ)) + y*sin(θ) + y*sin(θ))
BW = edge(I,'canny');% pp canny
[H,T,R] = hough(BW,'RhoResolution',0.5,'Theta',-90:0.5:89); figure subplot(2,2,1); imshow(RGB); title('anh gố\ c'); subplot(2,2,2) imshow(BW); title('các cạnh tìm đươc sau khi sư dụng edge') subplot(2,2,3:4); imshow(imadjust(rescale(H)),'XData',T,'YData',R,'InitialMagnification','fit '); title('Hough transform cua anh gố\ c'); xlabel('\theta'), ylabel('\rho'); axis on, axis normal, hold on; colormap(gca,cool);
Homework 1 :Viola Jones: training
Tóm tắt thuật toán Viola Jones:
Thuật toán Viola Jones được sử dụng trong phát hiện khuôn mặt (face detection) Thuật toán này sử dụng các đặc trưng Haar (Haar-like features) với các kích thước, vị trí, loại khác nhau Có tổng cộng 4 loại đặc trưng sau:
Theo lý thuyết sẽ có tồn tại 160K features có thể có Tuy nhiên, một số loại features sẽ không có nhiều ý nghĩa trong bài toán phát hiện khuôn mặt do đó chúng ta sẽ áp dụng điều kiện cho nó, tạo thành các bộ lọc yếu (Weak Classifiers):
Trong đó hj(x) là giá trị ngõ ra của bộ lọc, pj là trọng số của biểu thức và dấu của biểu thức, fj(x) là đặc trưng (sự khác biệt giữa giá trị pixel trong ảnh gốc giữa vùng trắng và đen), theta j là ngưỡng xét đến.
Sau đó dựa vào sự khác biệt giữa tổng giá trị của vùng pixel của màu trắng và vùng pixel màu đen thông qua thuật toán AdaBoost để huấn luyện mô hình.
Chúng ta sử dụng nhiều bộ lọc yếu (weak classifiters) để tạo thành một bộ lọc mạnh để tăng độ chính xác của thuật toán.
Tuy nhiên, việc sử dụng tất cả các dữ liệu đang có như vậy sẽ có tốc độ tính toán lâu
Do đó người ta sử dụng cấu trúc dạng tầng (Haar Cascade) để có thể loại bớt các chi tiết không cần thiệt ở các tầng trước, tăng tốc độ tính toán của mô hình Các tầng đầu tiên sẽ làm tỉ số False Negative giảm (Nghĩa là tiêu chí Positive dễ dàng nên dễ lọt qua, làm tăng False Positive ) để đảm bảo rằng không bỏ sót hình ảnh có chưa object thật Các tầng sau tỉ số False Postive được giảm dần
Ngoài ra, người ta còn sử dụng khái niệm ảnh tích phân để có thể tái sử dụng lại các thông số tính toán, giảm số lượng phép tính.
Huấn luyện mô hình sử dụng Viola Jones:
- Dữ liệu positive: Sử dụng công cụ Image Labeler
Dữ liệu được huấn luyện là hình ảnh biển số xe được thu thập từ bãi giữ xe Số lượng được lấy và label là 270 ảnh
Chứa những ảnh không có chứa bảng số xe Số lượng 70 ảnh.
Code: positiveInstances = LicensePlate(:,1:2); negativeFolder=fullfile(matlabroot,'toolbox','vision','vis iondata','nonStopSigns'); negativeImages = imageDatastore(negativeFolder); trainCascadeObjectDetector('LicensePlate.xml',positiveInst ances,negativeFolder,'FalseAlarmRate',0.5,'NumCascadeStage s',20);
Used 246 positive and 148 negative samples
Time to train stage 12: 50 seconds
Used 246 positive and 59 negative samples
Time to train stage 13: 51 seconds
Detector=vision.CascadeObjectDetector('LicensePlate.xml
; img = imread('0519_04671_b.jpg'); bbox = step(detector,img); detectedImg=insertObjectAnnotation(img,'rectangle',bbox ,'LicensePlate'); figure; imshow(detectedImg);
Homework 2 : Partial derivative with chain rule Check your results with numerical derivative
Partial derivative with chain rule là một kỹ thuật tính đạo hàm của hàm nhiều biến với quy tắc chuỗi Nó được sử dụng để tính toán đạo hàm của một hàm số nhiều biến,trong đó mỗi biến tham gia cùng một hàm khác.
Quy tắc chuỗi cho phép chúng ta tính toán đạo hàm của một hàm theo cách nối các đạo hàm của các hàm ngược lại với nhau Đây là phương pháp quan trọng trong nhiều lĩnh vực của toán học, trong đó bao gồm các hàm tuyến tính và phi tuyến. Để tính đạo hàm bằng quy tắc chuỗi, đầu tiên ta sử dụng quy tắc đạo hàm của một hàm số một biến để tính toán đạo hàm của hàm số theo biến trung gian Sau đó, chúng ta áp dụng quy tắc chuỗi để tính toán đạo hàm của hàm số ban đầu theo biến đầu vào.
Ví dụ, giả sử chúng ta có một hàm số f (x, y) = g (u, v) và các phương trình x h1(u, v), y = h2 (u, v) Để tính đạo hàm của f theo u, ta có thể sử dụng quy tắc chuỗi như sau:
Trong công thức trên, các đạo hàm ∂f/∂g, ∂g/∂u, ∂f/∂x, ∂x/∂u, ∂f/∂y, ∂y/∂u có thể được tính toán bằng các phương trình tương ứng, sau đó thay vào công thức để tính toán đạo hàm của f theo biến u.
Homework 3
a) -dL/dW (the mean vector for batch and mini batch) is the direction of the steepest descent for batch gradient descent but that's not true for stochastic/mini batch gradient descent Why not?
Hướng giảm dốc nhất đối với giảm dần độ dốc hàng loạt là độ dốc âm của hàm chi phí đối với các tham số mô hình, tức là dL/dW, trong đó L là hàm chi phí và W là ma trận trọng số Trong giảm dần độ dốc hàng loạt, độ dốc được tính toán bằng cách sử dụng tất cả các ví dụ trong tập huấn luyện, do đó, hướng giảm dần dốc nhất tương ứng với độ dốc tổng thể của hàm chi phí.
Tuy nhiên, trong giảm độ dốc ngẫu nhiên (SGD) và giảm độ dốc lô nhỏ, độ dốc được tính toán bằng cách sử dụng một tập hợp con các ví dụ đào tạo (một ví dụ duy nhất cho SGD và một loạt ví dụ nhỏ cho GD lô nhỏ) thay vì toàn bộ tập huấn luyện.Điều này có nghĩa là độ dốc cho mỗi bước là một ước tính ồn ào về độ dốc thực của hàm chi phí và nó có thể đi chệch khỏi hướng thực sự của độ dốc dốc nhất.
Do đó, hướng dốc nhất của SGD và GD lô nhỏ không nhất thiết giống với độ dốc âm của hàm chi phí đối với các tham số mô hình Tuy nhiên, hướng của gradient vẫn là một hướng dẫn hữu ích để cập nhật các tham số mô hình nhằm giảm thiểu hàm chi phí Trên thực tế, ước tính ồn ào của độ dốc trong SGD và GD lô nhỏ có thể giúp thuật toán tránh bị mắc kẹt trong cực tiểu cục bộ và đạt được tiến bộ hướng tới cực tiểu toàn cầu.
Tóm lại, mặc dù hướng giảm dốc nhất không nhất thiết phải giống với SGD và GD lô nhỏ giống như đối với giảm dần độ dốc hàng loạt, nhưng độ dốc vẫn cung cấp một hướng dẫn hữu ích để cập nhật các tham số mô hình theo đúng hướng nhằm giảm thiểu hàm chi phí. b) Why is stochastic gradient descent better than batch gradient descent at avoiding local minimum?
Stochastic Gradient Descent (SGD) thường tốt hơn so với giảm độ dốc hàng loạt trong việc tránh cực tiểu cục bộ do tính chất ngẫu nhiên của nó, đưa nhiễu ngẫu nhiên vào quá trình tối ưu hóa.
Trong batch gradient descent, độ dốc được tính toán bằng cách sử dụng tất cả các ví dụ trong tập huấn luyện và điều này có thể dẫn đến việc giảm dần nhưng chậm về mức tối thiểu Tuy nhiên, nó cũng có thể khiến thuật toán hội tụ đến cực tiểu cục bộ nếu hàm chi phí có nhiều cực tiểu cục bộ.
Mặt khác, trong SGD, độ dốc được tính toán bằng cách sử dụng một ví dụ được chọn ngẫu nhiên từ tập huấn luyện ở mỗi lần lặp Điều này đưa tính ngẫu nhiên vào quy trình tối ưu hóa, có thể giúp thuật toán thoát khỏi điểm cực tiểu cục bộ và tìm điểm cực tiểu toàn cầu Tính ngẫu nhiên cũng giúp SGD khám phá không gian tìm kiếm kỹ lưỡng hơn, điều này có thể dẫn đến sự hội tụ nhanh hơn và hiệu suất tốt hơn.
Ngoài ra, mini-batch gradient descent, là sự thỏa hiệp giữa giảm dần độ dốc theo lô và ngẫu nhiên, cũng có thể có hiệu quả trong việc tránh cực tiểu cục bộ Bằng cách sử dụng các lô ví dụ nhỏ để tính toán độ dốc, mini batch gradient descent cung cấp sự cân bằng giữa tính trơn tru của batch GD và tính ngẫu nhiên của SGD, điều này có thể dẫn đến sự hội tụ nhanh hơn và hiệu suất tốt hơn so với chỉ một trong hai phương pháp.
Tóm lại, Stochastic Gradient Descent (SGD) và các biến thể của nó, chẳng hạn như mini-batch GD, tốt hơn so với batch gradient descent trong việc tránh cực tiểu cục bộ do khả năng đưa tính ngẫu nhiên vào quy trình tối ưu hóa và khám phá không gian tìm kiếm kỹ lưỡng hơn.
c) Why is mini batch gradient descent the best among the three?
Mini-batch gradient descent (GD) thường được coi là phương pháp tốt nhất trong số ba phương pháp: batch gradient descent, stochastic gradient descent và mini-batch gradient descent Dưới đây là một số lý do vì sao:
Hội tụ tốt hơn: Mini-batch GD có thể hội tụ nhanh hơn so với batch GD vì nó cập nhật các tham số mô hình nhiều hơn Nó cũng có thể hội tụ nhanh hơn so với stochastic GD vì nó sử dụng nhiều hơn một ví dụ để tính gradient tại mỗi lần lặp, dẫn đến một hành trình giảm tốc độ ổn định hơn.
Tổng quát hóa tốt hơn: Mini-batch GD có thể tổng quát hóa tốt hơn so với stochastic GD vì nó sử dụng nhiều hơn một ví dụ để tính gradient tại mỗi lần lặp Điều này có thể dẫn đến một ước tính gradient chính xác hơn, dẫn đến tổng quát hóa tốt hơn.
Hiệu quả hơn: Mini-batch GD có thể hiệu quả hơn so với batch GD vì nó xử lý chỉ một tập con nhỏ của dữ liệu đào tạo tại mỗi lần lặp, giảm bớt gánh nặng tính toán.
Nó cũng có thể hiệu quả hơn so với stochastic GD vì nó sử dụng các batch lớn hơn, có thể dẫn đến sử dụng phần cứng tốt hơn.
Tránh mức tối thiểu cục bộ tốt hơn: Mini-batch GD có thể tránh mức tối thiểu cục bộ tốt hơn so với batch GD vì nó giới thiệu sự ngẫu nhiên vào quá trình tối ưu hóa. Điều này có thể giúp thuật toán thoát khỏi các điểm tối thiểu cục bộ và tìm thấy điểm tối thiểu toàn cục.
Homework 4:Write a program implementing gradient descent method Consider at
Chương trình thực hiện phương pháp gradient descent trong Python: import numpy as np import matplotlib.pyplot as plt
# Định nghĩa hàm cần tối ưu def f(x, y): return (x ** 2 + y - 11) ** 2 + (x + y ** 2 - 7) ** 2
# Định nghĩa hàm gradient def gradient_f(x, y): grad_x = 2 * (2 * x * (x ** 2 + y - 11) + x + y ** 2 - 7) grad_y = 2 * (x ** 2 + 2 * y * (x + y ** 2 - 7) + y - 11) return np.array([grad_x, grad_y])
# Định nghĩa hàm gradient descent def gradient_descent(initial_point, learning_rate, num_iterations): x = np.zeros((num_iterations, 2)) x[0,:] = initial_point for i in range(1, num_iterations): x[i,:] = x[i-1,:] - learning_rate * gradient_f(x[i-1,0], x[i-1,1]) return x
# Khởi tạo tham số learning_rate = 0.01 num_iterations = 1000 initial_points = [(-3, -2), (3, -2), (0.5, 3.0), (-1, 1)]
# Vẽ đường contour của hàm x_range = np.linspace(-5, 5, 100) y_range = np.linspace(-5, 5, 100)
Z = f(X, Y) plt.contour(X, Y, Z, levels0) plt.colorbar()
# Gọi hàm gradient descent với các điểm khởi tạo khác nhau for point in initial_points: x = gradient_descent(point, learning_rate, num_iterations) plt.plot(x[:,0], x[:,1], 'o-', label='start point: '+str(point)) plt.legend() plt.title('Gradient Descent') plt.xlabel('x') plt.ylabel('y') plt.show()
Trong ví dụ này, chúng ta đã chọn hàm không lồi "Rosenbrock function" làm hàm cần tối ưu Đầu tiên, chúng ta định nghĩa hàm và đạo hàm của nó, sau đó thực hiện thuật toán gradient descent để lặp lại cập nhật điểm hiện tại theo hướng giảm mạnh nhất Sau đó, chúng ta vẽ kết quả cho các điểm khởi tạo và tỷ lệ học khác nhau.
Lưu ý rằng lựa chọn tỷ lệ học có thể ảnh hưởng đáng kể đến sự hội tụ của gradient descent và tìm tỷ lệ học phù hợp thường là quá trình thử và sai.
Chương trình thực hiện phương pháp gradient descent trong Matlab:
Chương trình Matlab thực hiện phương pháp gradient descent cho hai hàm hai biến không lồi khác nhau Chương trình này sẽ lặp lại việc cập nhật điểm hiện tại bằng cách sử dụng việc tính toán gradient tại điểm hiện tại, với mục tiêu tìm ra điểm tối ưu của hàm.
% Hàm cần tối ưu 2 f2 = @(x, y) 0.5 + (sin(x.^2 - y.^2).^2 - 0.5)./(1+0.001*(x.^2 + y.^2)).^2;
% Gradient của hàm 2 grad_f2 = @(x, y) [4*x.*y.*cos(x.^2-y.^2).*sin(x.^2-y.^2)./(1+0.001*(x.^2+y.^2)).^3+ 2*x.*cos(x.^2-y.^2).^2./(1+0.001*(x.^2+y.^2)).^2;
% Khởi tạo các tham số learning_rates = [0.01, 0.1, 0.5, 1.0]; num_iterations = 1000; initial_points = [1, 1; -1, -1; 0, 2; -3, 1; 2, -2];
% Vẽ đường đẳng cấp của hàm x_range = -5:0.1:5; y_range = -5:0.1:5;
Z2 = f2(X, Y); figure; subplot(1,2,1); contour(X, Y, Z1); title('Hàm 1') xlabel('x'); ylabel('y'); subplot(1,2,2); contour(X, Y, Z2); title('Hàm 2') xlabel('x'); ylabel('y');
% Vẽ đường từng bước cập nhật và điểm tối ưu for i = 1:length(initial_points) for j = 1:length(learning_rates) x = zeros(num_iterations, 2); x(1,:) = initial_points(i, :); for k = 2:num_iterations x(k,:) = x(k-1,:) - learning_rates(j) * grad_f1(x(k-1,1), x(k-1,2)); % Chọn hàm cần tối ưu tại đây end subplot(1,2,1); hold on; plot(x(:,1), x(:,2), 'LineWidth', 1.5); scatter(x(end,1), x(end,2), 'r'); subplot(1,2,2); hold on; plot(x(:,1), x(:,2), 'LineWidth', 1.5); scatter(x(end,1), x(end,2), 'r'); end end
Trong ví dụ này, chúng ta đã định nghĩa hai hàm hai biến không lồi và các gradient của chúng Chúng ta đã khởi tạo các tham số cho phương pháp gradient descent, bao gồm các điểm khởi đầu và các tỷ lệ học khác nhau Sau đó, chúng ta đã vẽ đường đẳng cấp của từng hàm Cuối cùng, chúng ta đã sử dụng vòng lặp để tính toán gradient và cập nhật các điểm hiện tại trong quá trình tối ưu hàm, và vẽ đường dẫn từng bước cập nhật và điểm tối ưu.
Homework 5:Why local connectivity & shared weights?
Local connectivity là một khái niệm thường được sử dụng trong các mạng thần kinh tích chập (CNN), được thiết kế để xử lý các đầu vào có cấu trúc liên kết dạng lưới, chẳng hạn như hình ảnh. Ý tưởng đằng sau local connectivity là các pixel lân cận trong một hình ảnh có khả năng tương quan với nhau và chia sẻ các tính năng tương tự Do đó, điều hợp lý là lớp tích chập chỉ kết nối với một vùng cục bộ của đầu vào thay vì toàn bộ đầu vào. Điều này làm giảm số lượng tham số cần học và làm cho mạng hiệu quả hơn và dễ huấn luyện hơn.
Ngoài ra, local connectivity cho phép mạng tìm hiểu các mẫu và tính năng cục bộ tại các vị trí khác nhau trong đầu vào Bằng cách sử dụng các trọng số và độ lệch được chia sẻ trên các vùng cục bộ này, mạng có thể nhận ra các mẫu tương tự ở các phần khác nhau của đầu vào và khái quát hóa tốt hơn cho các hình ảnh mới.
Nhìn chung, local connectivity là một kỹ thuật hiệu quả trong việc thiết kế CNN cho các tác vụ xử lý hình ảnh bằng cách giảm số lượng tham số, nâng cao hiệu quả và cho phép mạng tìm hiểu các mẫu và tính năng cục bộ. b) Why shared weights?
Shared weights là một kỹ thuật phổ biến được sử dụng trong học sâu, đặc biệt là trong mạng thần kinh tích chập (CNN), để giảm số lượng tham số cần học trong mạng thần kinh.
Trong CNN, mỗi nơ-ron trong một lớp nhất định được kết nối với một vùng nhỏ của hình ảnh đầu vào và cùng một bộ trọng số được sử dụng cho tất cả các nơ-ron trong lớp đó có chung kiểu kết nối Điều này cho phép mạng tìm hiểu một tập hợp các bộ lọc hoặc tính năng có thể được áp dụng cho các phần khác nhau của hình ảnh đầu vào, giảm số lượng tham số cần học so với mạng được kết nối đầy đủ.
Kỹ thuật shared weights đặc biệt hiệu quả trong CNN, nơi hình ảnh đầu vào thường lớn và có nhiều chiều Bằng cách chia sẻ trọng số trên các phần khác nhau của hình ảnh, mạng có thể học cách nhận ra các mẫu tương tự ở các phần khác nhau của hình ảnh và khái quát hóa tốt hơn cho các hình ảnh mới Ngoài ra, các trọng số được chia sẻ giúp giảm nguy cơ trang bị quá mức bằng cách hạn chế khả năng ghi nhớ dữ liệu huấn luyện của mạng.
Tóm lại, shared weights là một kỹ thuật hiệu quả để giảm số lượng tham số và cải thiện hiệu suất của mạng thần kinh, đặc biệt là trong bối cảnh các tác vụ xử lý hình ảnh có đầu vào lớn và nhiều chiều.
Homework 6:How many parameters (weights and biases) are there in AlexNet?
Như vậy có các trọng số W1 = 96 * 11 *11 *3 = 34848
Do strike bằng 4, nên ảnh đầu ra sẽ là (227-11)/4 +1 = 55
Lớp có đầu vào: 27*27*256 Có 256 kernel 5x5
B2 = 256 Ở sau có 1 lớp max pooling nên 13*13*256
Lớp 3: Đầu vào tensor 13*13*384 Nên có 384 kernel kích thước 3*3*256
Lớp 4 Đầu vào tensor 13*13*384 Nên có 384 kernel kích thước 3*3*384
Lớp 5: Đầu vào 13*13*256- có 256 kernel kích thước 3*3*384
Lớp 6: Đầu vào 6*6*256 chuyển thành vector 1*4096
Homework 7:Compute top-1 & top-5 error rates for AlexNet and two other models
Thực hiện training mô hình, ta được kết quả như bên dưới (xem file code đính kèm)
Top1_acc = top_k_accuracy_score(score,y_hat,k=1)
Top1_error = 1 - Top1_acc print("Top 1 error rate: ",Top1_error)
Top5_acc = top_k_accuracy_score(score,y_hat,k=5)
Top5_error = 1 - Top5_acc print("Top 5 error rate: ",Top5_error)
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_ranking.py:1802:
UndefinedMetricWarning: 'k' (5) greater than or equal to 'n_classes' (5) will result in a perfect score and is therefore meaningless. warnings.warn(
Nhận xét : Độ chính xác Top-1 là độ chính xác cao nhất: câu trả lời mô hình (câu trả lời có xác suất cao nhất) phải chính xác là câu trả lời mong đợi. Độ chính xác của top 5 có nghĩa là bất kỳ câu trả lời nào trong số 5 câu trả lời có xác suất cao nhất trong mô hình của bạn phải khớp với câu trả lời dự kiến.
Ví dụ, giả sử bạn đang áp dụng học máy để nhận dạng đối tượng bằng mạng Alexnet Hình ảnh của một con mèo được hiển thị và đây là kết quả đầu ra của mạng thần kinh của bạn:
Sử dụng độ chính xác top 1, dự đoán đầu ra là sai vì khi mô hình dự đoán đúng phải là quả táo với xác xuất là 0.4.
Sử dụng độ chính xác của top 5, dự đoán đầu ra là đúng, bởi vì con mèo nằm trong số
Homework 8:Evaluate the performance of AlexNet using images with various aspect ratios.34 10 Homework 9:AlexNet transfer learning, at least 5 classes with minimum 20 images per class 36 11 Homework 10:For classification problems, why we use one-hot encoding instead of one
Khi kích thước ảnh đầu vào càng lớn thì sau quá trình training sẽ cho ra kết quả càng sai lệch, nguyên nhân hiện trạng trên là các ảnh đầu vào càng lớn thì có nhiều đặc điểm không chính xác với đối tượng cần nhận diện dẫn đến hiện trạng trên.
Dưới đây là mô tả cách ảnh kích thước đầu vào 64x64
Dưới đây là mô tả cách ảnh kích thước đầu vào 80x80.
Dưới đây là mô tả cách ảnh kích thước đầu vào 100x100
Khi kích thước ảnh đầu vào càng lớn thì sau quá trình training sẽ cho ra kết quả càng sai lệch, nguyên nhân hiện trạng trên là các ảnh đầu vào càng lớn thì có nhiều đặc điểm không chính xác(không cần thiết) với đối tượng cần nhận diện dẫn đến nhận diện đối tượng không chính xác.Trong khoảng đầu vào 64x64 thì đối tượng training và validation giá trị xác lặp được tăng dần và giữ ổn định, ảnh đầu vào càng lớn thì sai số xác lặp càng nhiều.Tương tự với trường hợp kiểm tra bằng training loss và validation loss, validation loss sẽ giảm dần ý nghĩa là điểm chung của traning loss và validation loss càng nhiều điểm chung càng nhiều đối tượng cần nhận diện càng chính xác
10 Homework 9:AlexNet transfer learning, at least 5 classes with minimum
20 images per class. model = tf.keras.Sequential([ keras.layers.Conv2D(filters8, kernel_size=(11,11), strides=(4,4), activation='relu', input_shape=(64,64,3)), keras.layers.BatchNormalization(), keras.layers.MaxPool2D(pool_size=(2,2)), keras.layers.Conv2D(filters%6, kernel_size=(5,5), strides=(1,1), activation='relu', padding="same"), keras.layers.BatchNormalization(), keras.layers.MaxPool2D(pool_size=(3,3)), keras.layers.Conv2D(filters%6, kernel_size=(3,3), strides=(1,1), activation='relu', padding="same"), keras.layers.BatchNormalization(), keras.layers.Conv2D(filters%6, kernel_size=(1,1), strides=(1,1), activation='relu', padding="same"), keras.layers.BatchNormalization(), keras.layers.Conv2D(filters%6, kernel_size=(1,1), strides=(1,1), activation='relu', padding="same"), keras.layers.BatchNormalization(), keras.layers.MaxPool2D(pool_size=(2,2)), keras.layers.Flatten(), keras.layers.Dense(1024,activation='relu'), keras.layers.Dropout(0.5), keras.layers.Dense(1024,activation='relu'), keras.layers.Dropout(0.5), keras.layers.Dense(5,activation='softmax')]) model.summary()
_ Layer (type) Output Shape Param #
==== conv2d (Conv2D) (None, 14, 14, 128) 46592 batch_normalization (BatchN (None, 14, 14, 128) 512 ormalization) max_pooling2d (MaxPooling2D (None, 7, 7, 128) 0
) conv2d_1 (Conv2D) (None, 7, 7, 256) 819456 batch_normalization_1 (Batc (None, 7, 7, 256) 1024 hNormalization) max_pooling2d_1 (MaxPooling (None, 2, 2, 256) 0
2D) conv2d_2 (Conv2D) (None, 2, 2, 256) 590080 batch_normalization_2 (Batc (None, 2, 2, 256) 1024 hNormalization) conv2d_3 (Conv2D) (None, 2, 2, 256) 65792 batch_normalization_3 (Batc (None, 2, 2, 256) 1024 hNormalization) conv2d_4 (Conv2D) (None, 2, 2, 256) 65792 batch_normalization_4 (Batc (None, 2, 2, 256) 1024 hNormalization) max_pooling2d_2 (MaxPooling (None, 1, 1, 256) 0
2D) flatten (Flatten) (None, 256) 0 dense (Dense) (None, 1024) 263168 dropout (Dropout) (None, 1024) 0 dense_1 (Dense) (None, 1024) 1049600 dropout_1 (Dropout) (None, 1024) 0 dense_2 (Dense) (None, 5) 5125
Non-trainable params: 2,304 model.compile(loss = 'categorical_crossentropy', optimizer='Adam', metrics=['accuracy']) history = model.fit(train_generator, epochs0, validation_data = validation_generator) model.save("/content/drive/MyDrive/Alexnet.h5")
4/4 [==============================] - 1s 315ms/step - loss: 9.6463e-04 - accuracy: 1.0000 - val_loss: 0.0246 - val_accuracy: 0.9900
4/4 [==============================] - 1s 271ms/step - loss: 7.9934e-04 - accuracy: 1.0000 - val_loss: 0.0159 - val_accuracy: 0.9900
4/4 [==============================] - 1s 272ms/step - loss: 9.4120e-04 - accuracy: 1.0000 - val_loss: 0.0135 - val_accuracy: 0.9900
4/4 [==============================] - 1s 290ms/step - loss: 0.0011 - accuracy: 1.0000 - val_loss: 0.0143 - val_accuracy: 0.9900
4/4 [==============================] - 1s 284ms/step - loss: 8.9954e-04 - accuracy: 1.0000 - val_loss: 0.0156 - val_accuracy: 0.9900 acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] epochs = range(len(acc)) plt.plot(epochs, acc, 'r', label='Training accuracy') plt.plot(epochs, val_acc, 'b', label='Validation accuracy') plt.title('Training and validation accuracy') plt.legend(loc=0) plt.figure() plt.show()
loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(acc)) plt.plot(epochs, loss, 'r', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.legend(loc=0) plt.figure() plt.show()
x,y = test_generator.next() print(y.shape) score = np.zeros(50) for i in range(50): for j in range(5): if y[i,j] == np.max(y[i,:]): score[i] = j print(score)
11 Homework 10:For classification problems, why we use one-hot encoding instead of one output (e.g encoding 4 classes as 1, 2, 3, 4) or binary encoding (e.g encoding 4 classes as 00, 01, 10, 11)?
Việc sử dụng one-hot encoding hay binary encoding tùy thuộc vào ứng dụng cần sử dụng Thông thường, các bài toán phân loại (classification) thường sử dụng one-hot encoding bởi 2 lý do sau:
Khi chúng ta có một biến phân loại với nhiều lớp, việc sử dụng một đầu ra đơn (Decimal Encoding) (mã hóa các lớp là 1, 2, 3, 4) hoặc mã hóa nhị phân (mã hóa các lớp là 00, 01, 10, 11) có thể ý nghĩa thứ tự hoặc mức độ giữa các lớp Ví dụ, nếu chúng ta có bốn lớp A, B, C và D, và chúng ta mã hóa chúng thành 1, 2, 3 và 4, thì nó ngụ ý rằng B là "tốt hơn" hoặc "quan trọng hơn" so với A vì 2 lớn hơn 1 Tuy nhiên, điều này có thể không đúng với bài toán phân loại vì đây là bài toán không có thứ tự Do đó, việc sử dụng decimal encoding có thể dẫn đến sự sai lệch mô hình.
Các giá trị xác suất có giá trị trong khoảng [0,1] Việc sử dụng one-hot encoding phù hợp cho việc tính toán xác suất (ví dụ: tính toán hàm Softmax, tính toán hàm lỗi Cross Entropy).
Việc sử dụng one-hot encoding giúp biểu diễn kết quả dưới dạng vector thuận tiện cho các tính toán ma trận khác Đối với Binary Encoding trong bài toán phân loại
Classification có thể được sử dụng nó không được sử dụng phổ biến như one-hot encoding Ưu điểm so với one-hot encoding chính là giảm số lượng biến để biểu diễn các phân lớp Tuy nhiên, lại có hạn chế đối với việc thể hiện xác suất của từng lớp.
Homework 11:Write a program implementing feature nomalization
Normalization (chuẩn hóa) là một quá trình biến đổi các giá trị của một biến thành một dạng chuẩn hóa để giúp cho các biến có thể được so sánh và xử lý một cách hiệu quả hơn Các giá trị của biến có thể được chuẩn hóa về đơn vị, phân phối, hoặc phạm vi Lợi ích của kĩ thuật này bao gồm:
Việc chuẩn hóa giúp các giá trị của các biến được đưa về cùng một phạm vi, giúp cho các thuật toán hoạt động hiệu quả hơn.
Tăng tốc độ hội tụ của các thuật toán tối ưu
Giảm tác động của outliers (điểm ngoại lai)
Có một số phương pháp chuẩn hóa thông dụng như Min-Max Scaling, Z-Score Scaling, Log Transformation, Box-Cox Transformation, Quantile Transformation, Tùy thuộc vào tính chất của dữ liệu và mục đích sử dụng, ta có thể lựa chọn phương pháp phù hợp.
Xét một ảnh xám đầu vào, được biểu diễn dưới dạng ma trận như sau:
Ta sử dụng hai kĩ thuật: Min-max scaling và Standardization để minh họa choNormalization:
Trong đó: là phương sai của ảnh, là giá trị trung bình của ảnh
Source code (Python): import numpy as np import cv2
PATH = r'D:\BKU\Monhoc\222\CV\Homework\samples\1.jpg' img = cv2.imread(PATH,0) print("Kích thước ma trận:",img.shape) print(img)
# Max-min scaling max = np.max(img) min = np.min(img) normalized = (img - min) / (max-min) print(np.round(normalized,2))
# Standardization mean = np.mean(img) std = np.std(img) normalized = (img - mean) / std print(np.round(normalized,2))
Homework 12:Cascade object detection: use pretrained model and evaluate error
Cascade object detection: sử dụng mô hình được huấn luyện sẵn và đánh giá sai số Cascade object detection là một kỹ thuật máy học phổ biến được sử dụng để phát hiện đối tượng trong hình ảnh và video Nó hoạt động bằng cách sử dụng một loạt các bộ phân loại, trong đó mỗi bộ phân loại cố gắng lọc bỏ những dương tính giả được tạo ra bởi bộ phân loại trước đó. Để sử dụng một mô hình được huấn luyện trước đó và đánh giá sai số của nó, làm theo các bước sau:
1) Tải xuống một mô hình Cascade Object Detection được huấn luyện trước đó.
Có nhiều mô hình được huấn luyện sẵn có trên mạng, chẳng hạn như OpenCV Haar Cascade hoặc Tensorflow Object Detection API.
2) Tải mô hình được huấn luyện trước vào mã Python của bạn Thông thường điều này liên quan đến tải một số tệp XML mô tả bộ phân loại của hoạt động.
3) Lấy một tập hình ảnh thử nghiệm, trong đó bạn biết các nhãn địa chỉ chính xác của các đối tượng trong hình ảnh Thông thường điều này được thực hiện bằng cách nhãn cho một tập hình ảnh hoặc sử dụng tập dữ liệu đã được gán nhãn trước.
4) Áp dụng mô hình được huấn luyện trước vào mỗi hình ảnh thử nghiệm và lấy các hộp giới hạn được dự đoán cho mỗi đối tượng đã phát hiện.
5) So sánh các hộp giới hạn được dự đoán với các nhãn địa chỉ chính xác để tính toán các chỉ số lỗi Các chỉ số lỗi phổ biến được sử dụng trong phát hiện đối tượng là precision, recall và F1 score. Đây là một ví dụ về mã Python sử dụng OpenCV Haar Cascade để phát hiện mặt người trong hình ảnh: import cv2
# load the pre-trained face detection model cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
# load the image and convert it to grayscale image = cv2.imread("test_image.jpg") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# apply the face detection model to the grayscale image faces = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# loop over the detected faces and draw rectangles around them for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# show the annotated image cv2.imshow("Annotated Image", image) cv2.waitKey(0) cv2.destroyAllWindows()
Trong đó, file "haarcascade_frontalface_default.xml" chứa mô hình được huấn luyện trước để phát hiện khuôn mặt, và hàm `cv2.CascadeClassifier()` được sử dụng để tải mô hình vào trong chương trình Sau đó, hình ảnh đầu vào được chuyển đổi sang độ xám bằng hàm `cv2.cvtColor()`, và mô hình phát hiện khuôn mặt được áp dụng vào hình ảnh độ xám bằng hàm `cascade.detectMultiScale()` Kết quả trả về là các hình chữ nhật bao quanh các khuôn mặt được phát hiện, và chúng được vẽ lên hình ảnh gốc bằng hàm `cv2.rectangle()`.
Lưu ý rằng quá trình đánh giá sai số của một mô hình phát hiện đối tượng có thể phức tạp, và có nhiều yếu tố cần xem xét, chẳng hạn như kích thước tập dữ liệu huấn luyện, chất lượng các chú thích và độ phức tạp của các đối tượng được phát hiện Do đó, quan trọng là thiết kế cẩn thận quy trình đánh giá của bạn và lựa chọn các chỉ số lỗi thích hợp.
Homework 13:How to obtain Precision - Recal curve?
Đường cong Precison và Recall là một thông số đánh giá phổ biến trong các bài toán Object Detection Trước khi giải thích đường cong này, ta sẽ tìm hiểu các khái niệm Confusion matrix, Precision, Recall.
Confusion matrix (được trình bày chi tiết ở HW17):
Một mô hình thực hiện 10 dự đoán và tính toán giá trị Precision, Recall như công thức trên Ta được kết quả ở bảng sau: (Cho rằng đây là kết quả khi tính 1 class)
Ta thể hiện lần lượt giá trị Precision và Recall, ta thu được biểu đồ sau:
Khi đó, AP được tính như sau:
Nghĩa là AP chính là phần diện tích tạo bởi đồ thị p(r) và trục hoành (Trục Recall).
Trước khi tính AP, người ta sẽ xấp xỉ đường zigzag trở thành các đoạn thẳng nằm ngang để dễ tính toán.
Trong một số trường hợp, ta phải tính AP cho từng class và tính trung bình của chúng, đại lượng này gọi là mean Average Precision
Trong bài toán Object Detection, người ta thường sử dụng mAP để đánh giá mô hình thay vì chỉ sử dụng đơn lẻ các đại lượng khác như: Confusion matrix, Recall, Precision,…Lý do được giải thích như sau:
Việc chỉ sử dụng Confusion matrix để đánh giá không phù hợp do số lượng background thường sẽ chiếm phần lớn, dẫn đến chỉ số True Negative sẽ cao Hiện tượng này gọi là sự chênh lệch dữ liệu (imbalanced dataset)
Việc chỉ sử dụng Precision hay Recall không thể đánh giá toàn diện Do không phải cứ hai thông số này càng cao thì mô hình sẽ càng tốt Xét các trường hợp sau:+ Precision: Khi Precision cao, khi này tỉ lệ False Positive giảm Tương tự đối với tình huống ngược lại
+ Recall: Khi Recall cao, khi này tỉ lệ False Negative giảm Tương tự đối với tình huống ngược lại
Ta mong muốn cả hai chỉ số False Negative và False Positive giảm Tuy nhiên, chỉ số Precision và Recall thường nghịch biến nhau Do đó, ta cần cân bằng giữa hai thông số này Điều này lý giải cho việc vì sao đồ thị AP thường có dạng zigzag và lý do người ta sử dụng thông số mAP (do thể hiện được cả hai đặc trưng).
Homework 14:Evaluate object detector YOLO/R-CNN/SSD
YOLOv5 được công bố với những so sánh ban đầu cho thấy độ chính xác tương đương YOLOv4 và có tốc độ nhanh hơn khi thực hiện dự đoán.
So với YOLOv1, các thế hệ YOLO về sau sử dụng kĩ thuật Anchor Box thay cho kĩ thuật Anchor Free YOLOv5 kế thừa các đặc điểm của các YOLO thế hệ trước đó, ngoài ra còn phát triển một số thuộc tính như: thay đổi hàm Activation, hàm Loss, Data Augmentation,
YOLOv4 sử dụng Mish hoặc LeakyReLU cho phiên bản nhẹ (light weight), trong khi đó, YOLOv5, activation function được sử dụng là SiLU.
Hình 1: So sánh hàm LeakyReLU và SiLUHàm ReLU đang được sử dụng khá nhiều trong nhiều năm trước khi huấn luyện các mạng neuron ReLU đơn giản lọc các giá trị < 0
Tốc độ hội tụ nhanh hơn hẳn ReLU có tốc độ hội tụ nhanh gấp 6 lần Tanh
Tuy nhiên ReLU cũng có một nhược điểm: Với các node có giá trị nhỏ hơn 0, qua ReLU activation sẽ thành 0, hiện tượng đấy gọi là “Dying ReLU“ Nếu các node bị chuyển thành 0 thì sẽ không có ý nghĩa với bước linear activation ở lớp tiếp theo và các hệ số tương ứng từ node đấy cũng không được cập nhật với gradient descent.
Khi learning rate lớn, các trọng số (weights) có thể thay đổi theo cách làm tất cả neuron dừng việc cập nhật.
Leaky ReLU là một phát triển từ hàm ReLU mà mục đích:
Cố gắng trong việc loại bỏ "dying ReLU" Thay vì trả về giá trị 0 với các đầu vào < 0 thì Leaky ReLU tạo ra một đường xiên có độ dốc nhỏ.
Gọi 4 giá trị dịch chuyển mà YOLOv3 predict ra là tx,ty,t,th Giới hạn tx,ty ở trong khoảng [0,1] việc giới hạn này được áp dụng sử dụng hàm sigmoid σ. Xét một grid cell (cx,cy) trong feature map, Anchor Box được sinh ra có chiều dài, chiều rộng là (p,ph), với các giá trị dự đoán tx,ty,t,th công thức biến đổi có dạng: bx=tx+cx (1) by=ty+cy (2) b=p.et (3) bh=pheth (4) với (bx,by) là tâm của Bounding Box, (b,bh) là chiều dài, chiều rộng củaBounding Box
Hình 2: Bounding Box tính theo YOLOv3 Tuy nhiên công thức tính bounding box này có nhược điểm là khi bx=cx và bx=cx+1 (do tính chất của sigmoid) phải có giá trị âm hoặc giá trị dương cực kì lớn
Vì vậy ở YOLOv5 sẽ sử dụng một hàm cải tiến hơn để loại bỏ GridSensitivity bx=2tx-0.5+cx (5) by=2ty-0.5+cy (6) b=p.2σ.t2 (7) bh=ph2σth2 (8)
Các kĩ thuật Data Augmentation được áp dụng trong YOLOv5 bao gồm:
5 Anchor box Để tìm được bounding box cho vật thể, YOLO sẽ cần các anchor box làm cơ sở ước lượng Những anchor box này sẽ được xác định trước và sẽ bao quanh vật thể một cách tương đối chính xác Sau này thuật toán regression bounding box sẽ tinh chỉnh lại anchor box để tạo ra bounding box dự đoán cho vật thể Trong một mô hình YOLO:
Mỗi một vật thể trong hình ảnh huấn luyện được phân bố về một anchor box Trong trường hợp có từ 2 anchor boxes trở lên cùng bao quanh vật thể thì ta sẽ xác định anchor box mà có IoU với ground truth bounding box là cao nhất.
Hình 3: Xác định anchor box cho một vật thể
Xét ví dụ trêm, ta xác định được 3 anchor boxes viền xanh như trong hình Cả 3 anchor boxes này đều giao nhau với bounding box của vật thể Tuy nhiên chỉ anchor box có đường viền dày nhất màu xanh được lựa chọn làm anchor box cho vật thể bởi nó có IoU so với ground truth bounding box là cao nhất.
Anchor Box trong YOLOv5 nhận được 2 sự thay đổi lớn: Đầu tiên là sử dụng Auto Anchor, một kĩ thuật áp dụng giải thuật di truyền (GA) vào Anchor Box ở sau bước k-means để Anchor Box hoạt động tốt hơn với những custom dataset của người dùng, tránh việc overfitting với tập dữ liệu COCO
Thứ hai đó chính là offset tâm của object để lựa chọn nhiều Anchor Box cho một object Ý tưởng được thể hiện trong hình dưới:
Hình 4: Anchor box cải tiến
Homework 15:Train object detection YOLO/R-CNN/SSD
1 Tải thư viện cho model
Ta sử dụng lệnh pip install để tải các thư viện theo yêu cầu:
%cd /content/drive/MyDrive/yolov5_army/yolov5_army
3 Download ảnh từ trên internet và thực hiện label Ở bài này, dữ liệu được sử dụng khoảng 4000 tấm được chia thành 2 tập là train và val được chia số lượng khoảng 80% và 20% Định dạng file label sẽ có 5 số các nhau bởi dấu cách với số đầu tiên đại diện cho tên số thứ tự của class, số thứ 2 là x center, thứ 3 là y center, thứ tư là width của bounding box và cuối cùng là height của bounding box Tất cả các số đều được chuẩn hoá với với x center và width của bounding box sẽ được chia cho width của cả bức ảnh và tương tự với y center và height.
4 Chỉnh sửa file dẫn đường truyền train yaml path: /datasets/train_data train: images/train val: images/val
0: military truck 1: civilian car 2: military tank 3: civilian aircraft 4: military aircraft 5: military helicopter
Vì bài này ta train 6 class nên name sẽ có 6 class
Path là đường dẫn ngoài vào file data, còn train và val là đường dẫn từ file data vào trong file ảnh và label.
Vì ta có ít dữ liệu và ít class nên ta có thể sử dụng các file pretrain đã được tác giả train từ trước để train tiếp vì vậy ta sẽ tải về file train.pt với loại file mình muốn Ở bài này, sử dụng train theo model YOLOv5n
!python train.py data coco128.yaml epochs 100 weights '/content/drive/MyDrive/yolov5_army/yolov5_army/yolov5n.pt' cfg yolov5n.yaml batch-size 128
Weights sẽ chứa đường link dẫn vào file pretrain
Data sẽ chứa file dẫn vào file data train
Cfg sẽ chứa file dẫn vào model train yolov5n
Các thông số epochs và bactch sẽ tuỳ trỉnh
Sau quá trình training, thu được kết quả như sau:
Nhìn chung, hàm loss có xu hướng giảm ở cả tập train và val, tránh được hiện tượng overfitting Giá trị mAP có xu hướng tăng dần, chứng tỏ mô hình đang được cải thiện theo hướng tốt, cân bằng giữa giá trị recall và precision Tuy nhiên, các thông số ở mức thấp và cần training thêm do số lượng epoch training đang thực hiện chỉ ở mức
Sau đây, một số kết quả dự đoán:
Homework 16:How to handle multiple detections
Khi thực hiện phát hiện đối tượng bằng mô hình được huấn luyện, có thể xuất hiện nhiều phát hiện cho mỗi đối tượng do tính chất của thuật toán và ảnh đầu vào Việc xử lý nhiều phát hiện là một bước quan trọng trong xử lý kết quả phát hiện đối tượng.Dưới đây là một số phương pháp thông dụng để xử lý nhiều phát hiện:
1) Non-maximum suppression (NMS): Đây là một kỹ thuật chọn ra bounding box tốt nhất giữa nhiều bounding box có độ chồng chéo cao với nhau NMS loại bỏ bounding box với điểm số độ tin cậy thấp và chọn từ các bounding box có điểm số độ tin cậy cao, bounding box có điểm số độ tin cậy cao nhất sẽ được giữ lại. Phương pháp này có thể hiệu quả loại bỏ các bounding box trùng lặp và giảm phát hiện giả.
2) Intersection-over-union (IOU): Đây là một phương pháp đo lường sự chồng chéo giữa hai bounding box Bằng cách tính toán IOU giữa tất cả các cặp bounding box, chúng ta có thể xác định và loại bỏ các phát hiện trùng lặp.
3) Tracking: Nếu đối tượng được phát hiện đang di chuyển, chúng ta có thể sử dụng theo dõi đa đối tượng để theo dõi quỹ đạo của nó theo thời gian Kết quả phát hiện có thể được kết hợp trên nhiều khung hình bằng cách sử dụng các mô hình chuyển động, liên kết và các kỹ thuật khác.
4) Thresholding: Có thể thiết lập ngưỡng điểm số độ tin cậy cho kết quả phát hiện, dưới ngưỡng đó, tất cả các phát hiện đều bị bỏ qua Ngưỡng cao có thể giảm số lượng phát hiện giả, nhưng có thể ảnh hưởng xấu đến số lượng phát hiện đúng.
Bằng cách áp dụng một hoặc nhiều phương pháp này, chúng ta có thể cải thiện chất lượng kết quả phát hiện đối tượng và giảm số lượng phát hiện giả, từ đó cải thiện hiệu suất tổng thể của bộ phát hiện
Homework 17:What are PF, FN for object detection problem?
Ta có khái niệm IoU như sau:
Trong bài toán Object Detection không chỉ đơn thuần phụ thuộc vào việc có hay không có object mà còn đánh giá dựa trên thông số IoU Cụ thể, như sau:
True Positive (TP): Box phân loại là đúng phân lớp (class) của object và có chỉ số IoU> alpha Với alpha là một ngưỡng cho trước (thông thường alpha = 0.5)
False Positive (FP): Box phân loại không đúng phân lớp (class) của object hoặc có chỉ số IoU< alpha
False Negative (FN): Ảnh có object nhưng không tìm được object trong ảnh
True Negative (TN): Ảnh không có object và mô hình cũng không tìm được object trong ảnh True Negative cũng bao gồm trường hợp phân lớp sai nhưng không tìm được vị trí trên ảnh.
Thông thường trong ảnh vùng background chiếm nhiều vị trí trong hình hơn foreground Điều này gây ra sự mất cân bằng của các class Do đó, thông số True Negative không được sử dụng để đánh giá độ hiệu quả của mô hình.
Hình bên dưới minh họa cho các thông số trên (Ghi chú: màu xanh đại diện cho grouth truth (giá trị dán nhãn), màu đỏ đại diện cho bounding box (giá trị dự đoán.
Hình 2: Minh họa cho False Negative: Không tìm được Object trong ảnh
Hình 1: Minh họa cho True Positive: Phân lớp đúng (có object) và tìm được vị trí của đối tượng trong hình với IoU = 0.86 (xét alpha =0.5)
Hình 2: Minh họa cho False Positive: Phân lớp đúng (có object) nhưng IoU