tek4

Xử Lý Hàng Loạt (Batch Processing) Neural Network Với PyTorch

by - September. 21, 2021
Kiến thức
Machine Learning
Python
<p style="text-align: justify;"><em>Ch&agrave;o mừng c&aacute;c bạn đến với b&agrave;i viết thứ 23 trong loạt b&agrave;i về&nbsp;<a href="https://tek4.vn/lap-trinh-neural-network-voi-pytorch-deep-learning-voi-pytorch/" target="_blank" rel="noopener"><strong>Lập Tr&igrave;nh Neural Network Với Pytorch.</strong></a>&nbsp;Mục ti&ecirc;u của ch&uacute;ng ta trong b&agrave;i viết n&agrave;y l&agrave; chuyển h&agrave;ng loạt h&igrave;nh ảnh v&agrave;o mạng để xử l&yacute; v&agrave; giải th&iacute;ch kết quả. Bắt đầu th&ocirc;i!</em></p> <p style="text-align: justify;">&nbsp;</p> <p style="text-align: justify;"><img style="width: 100%;" src="http://tek4vn.2soft.top/public_files/xu-ly-hang-loat-batch-processing-neural-network-voi-pytorch-png-1" alt="Xử L&yacute; H&agrave;ng Loạt (Batch Processing) Neural Network Với PyTorch" /></p> <p style="text-align: justify;">&nbsp;</p> <p style="text-align: justify;">Trong <a href="https://tek4.vn/du-doan-dau-ra-lap-trinh-neural-network-voi-pytorch-bai-22/" target="_blank" rel="noopener">b&agrave;i trước</a>, ch&uacute;ng ta đ&atilde; t&igrave;m hiểu về lan truyền xu&ocirc;i v&agrave; c&aacute;ch truyền một h&igrave;nh ảnh duy nhất từ ​​tập dữ đ&agrave;o tạo của ch&uacute;ng ta v&agrave;o mạng.&nbsp;B&acirc;y giờ, h&atilde;y xem c&aacute;ch thực hiện điều n&agrave;y bằng c&aacute;ch sử dụng một loạt h&igrave;nh ảnh.&nbsp;Ch&uacute;ng ta sẽ sử dụng data loader để lấy batch v&agrave; sau đ&oacute; chuyển batch v&agrave;o mạng, ch&uacute;ng ta sẽ giải th&iacute;ch đầu ra.</p> <h4 class="sub-section-heading" style="text-align: justify;">Truyền một loạt h&igrave;nh ảnh v&agrave;o mạng</h4> <p style="text-align: justify;">H&atilde;y bắt đầu bằng c&aacute;ch xem lại thiết lập code từ c&aacute;c b&agrave;i trước.&nbsp;Ch&uacute;ng ta cần những thứ sau:</p> <ol style="text-align: justify;"> <li>Imports của ch&uacute;ng ta</li> <li>Training set của ch&uacute;ng ta</li> <li>Định nghĩa lớp <em>Network</em> của ch&uacute;ng ta</li> <li>C&aacute;ch tắt gradient (kh&ocirc;ng bắt buộc)</li> <li>Một&nbsp;instance của lớp <em>Network.</em></li> </ol> <p style="text-align: justify;">B&acirc;y giờ, ch&uacute;ng ta sẽ sử dụng tập training set của m&igrave;nh để tạo một instance DataLoader mới v&agrave; ch&uacute;ng ta sẽ đặt batch_size = 10, v&igrave; vậy, kết quả đầu ra sẽ dễ quản l&yacute; hơn.</p> <pre class="language-python"><code>&gt; data_loader = torch.utils.data.DataLoader( train_set, batch_size=10 )</code></pre> <p style="text-align: justify;">Ch&uacute;ng ta sẽ lấy một batch từ data loader, giải n&eacute;n (unpack) h&igrave;nh ảnh v&agrave; nh&atilde;n c&aacute;c tensors từ batch.</p> <pre class="language-python"><code>&gt; batch = next(iter(data_loader)) &gt; images, labels = batch</code></pre> <p style="text-align: justify;">Điều n&agrave;y cho ch&uacute;ng ta hai tensors, một tensor h&igrave;nh ảnh v&agrave; một tensor nh&atilde;n tương ứng.</p> <p style="text-align: justify;">Data loader&nbsp;trả về một loạt ảnh được đ&oacute;ng g&oacute;i th&agrave;nh một tensor duy nhất c&oacute; shape phản &aacute;nh c&aacute;c axes sau.</p> <pre>(batch size, input channels, height, width)</pre> <pre class="language-python"><code>&gt; images.shape torch.Size([10, 1, 28, 28]) &gt; labels.shape torch.Size([10])</code></pre> <p style="text-align: justify;">H&atilde;y giải th&iacute;ch cả hai shape n&agrave;y. Axis đầu ti&ecirc;n của tensor images cho ch&uacute;ng ta biết rằng ch&uacute;ng ta c&oacute; một batch gồm mười h&igrave;nh ảnh.&nbsp;&nbsp;Mười h&igrave;nh ảnh n&agrave;y c&oacute; một k&ecirc;nh m&agrave;u duy nhất với chiều cao v&agrave; chiều rộng l&agrave; 28.</p> <p style="text-align: justify;">C&aacute;c tensor labels c&oacute; một axis duy nhất với shape l&agrave; 10, tương ứng với mười h&igrave;nh ảnh b&ecirc;n trong batch của ch&uacute;ng ta.&nbsp;Mỗi nh&atilde;n cho một h&igrave;nh ảnh.</p> <p style="text-align: justify;">H&atilde;y nhận dự đo&aacute;n bằng c&aacute;ch chuyển tensor images v&agrave;o network:</p> <pre class="language-python"><code>&gt; preds = network(images) &gt; preds.shape torch.Size([10, 10]) &gt; preds tensor( [ [ 0.1072, -0.1255, -0.0782, -0.1073, 0.1048, 0.1142, -0.0804, -0.0087, 0.0082, 0.0180], [ 0.1070, -0.1233, -0.0798, -0.1060, 0.1065, 0.1163, -0.0689, -0.0142, 0.0085, 0.0134], [ 0.0985, -0.1287, -0.0979, -0.1001, 0.1092, 0.1129, -0.0605, -0.0248, 0.0290, 0.0066], [ 0.0989, -0.1295, -0.0944, -0.1054, 0.1071, 0.1146, -0.0596, -0.0249, 0.0273, 0.0059], [ 0.1004, -0.1273, -0.0843, -0.1127, 0.1072, 0.1183, -0.0670, -0.0162, 0.0129, 0.0101], [ 0.1036, -0.1245, -0.0842, -0.1047, 0.1097, 0.1176, -0.0682, -0.0126, 0.0128, 0.0147], [ 0.1093, -0.1292, -0.0961, -0.1006, 0.1106, 0.1096, -0.0633, -0.0163, 0.0215, 0.0046], [ 0.1026, -0.1204, -0.0799, -0.1060, 0.1077, 0.1207, -0.0741, -0.0124, 0.0098, 0.0202], [ 0.0991, -0.1275, -0.0911, -0.0980, 0.1109, 0.1134, -0.0625, -0.0391, 0.0318, 0.0104], [ 0.1007, -0.1212, -0.0918, -0.0962, 0.1168, 0.1105, -0.0719, -0.0265, 0.0207, 0.0157] ] )</code></pre> <p style="text-align: justify;">Dự đo&aacute;n tensor c&oacute; shape l&agrave; 10 x 10, cho ch&uacute;ng ta hai axes m&agrave; mỗi axis c&oacute; chiều d&agrave;i l&agrave; 10.&nbsp;Điều n&agrave;y phản &aacute;nh thực tế l&agrave; ch&uacute;ng ta c&oacute; 10 h&igrave;nh ảnh v&agrave; với mỗi h&igrave;nh ảnh trong số mười h&igrave;nh ảnh n&agrave;y, ch&uacute;ng ta c&oacute; mười lớp dự đo&aacute;n.</p> <pre><code>(batch size, number of prediction classes)</code></pre> <p style="text-align: justify;">C&aacute;c phần tử của&nbsp;dimension đầu ti&ecirc;n l&agrave; c&aacute;c mảng c&oacute; độ d&agrave;i 10.&nbsp;Mỗi phần tử mảng n&agrave;y chứa mười dự đo&aacute;n cho mỗi danh mục h&igrave;nh ảnh tương ứng.</p> <p style="text-align: justify;">C&aacute;c phần tử của dimension l&agrave; số.&nbsp;Mỗi số l&agrave; gi&aacute; trị được ấn định của lớp đầu ra cụ thể.&nbsp;C&aacute;c lớp đầu ra được m&atilde; h&oacute;a bởi c&aacute;c indexes, v&igrave; vậy mỗi index đại diện cho một lớp đầu ra cụ thể.&nbsp;&Aacute;nh xạ n&agrave;y được đưa ra bởi bảng n&agrave;y:</p> <h4 class="sub-section-heading" style="text-align: justify;">Fashion MNIST Classes</h4> <p style="text-align: justify;"><img style="width: 375px; display: block; margin-left: auto; margin-right: auto;" src="http://tek4vn.2soft.top/public_files/1-1-png-1" alt="1-1" height="382" /></p> <p><img style="width: 657px; display: block; margin-left: auto; margin-right: auto;" src="http://tek4vn.2soft.top/public_files/fashion-mnist-grid-sample-png-2" alt="fashion-mnist-grid-sample" height="92" /></p> <h3 class="section-heading" style="text-align: justify;">Sử dụng argmax: Prediction vs label</h3> <p style="text-align: justify;">Để kiểm tra c&aacute;c dự đo&aacute;n so với c&aacute;c nh&atilde;n, ch&uacute;ng ta sử dụng h&agrave;m <em>argmax()</em> để t&igrave;m ra index n&agrave;o chứa gi&aacute; trị dự đo&aacute;n cao nhất.&nbsp;Khi ch&uacute;ng ta biết index n&agrave;o c&oacute; gi&aacute; trị dự đo&aacute;n cao nhất, ch&uacute;ng ta c&oacute; thể so s&aacute;nh index với nh&atilde;n để xem c&oacute; khớp hay kh&ocirc;ng.</p> <p style="text-align: justify;">Để l&agrave;m điều n&agrave;y, ch&uacute;ng ta gọi h&agrave;m <em>argmax()</em> tr&ecirc;n tensor dự đo&aacute;n v&agrave; ch&uacute;ng ta chỉ định dimension thứ hai.</p> <p style="text-align: justify;">Dimension thứ 2 l&agrave; dimension cuối c&ugrave;ng của tensor dự đo&aacute;n.&nbsp;H&atilde;y nhớ từ tất cả c&aacute;c nghi&ecirc;n cứu của ch&uacute;ng ta về tensor, dimension cuối c&ugrave;ng của tensor lu&ocirc;n chứa c&aacute;c số trong khi mọi&nbsp;dimension kh&aacute;c chứa tensor kh&aacute;c nhỏ hơn.</p> <p style="text-align: justify;">Trong trường hợp của tensor dự đo&aacute;n, ch&uacute;ng ta c&oacute; mười nh&oacute;m số.&nbsp;Những g&igrave; h&agrave;m <em>argmax()</em> đang l&agrave;m l&agrave; xem x&eacute;t b&ecirc;n trong mỗi nh&oacute;m trong số mười nh&oacute;m n&agrave;y, t&igrave;m gi&aacute; trị tối đa v&agrave; xuất ra index của n&oacute;.</p> <p style="text-align: justify;">Đối với mỗi nh&oacute;m mười số:</p> <ol style="text-align: justify;"> <li>T&igrave;m gi&aacute; trị lớn nhất.</li> <li>Index đầu ra</li> </ol> <p style="text-align: justify;">Điều n&agrave;y được giải th&iacute;ch l&agrave; với mỗi h&igrave;nh ảnh trong batch, ch&uacute;ng ta đang t&igrave;m ra lớp dự đo&aacute;n c&oacute; gi&aacute; trị cao nhất.&nbsp;Đ&acirc;y l&agrave; category m&agrave; mạng dự đo&aacute;n mạnh mẽ nhất.</p> <pre class="language-python"><code>&gt; preds.argmax(dim=1) tensor([5, 5, 5, 5, 5, 5, 4, 5, 5, 4]) &gt; labels tensor([9, 0, 0, 3, 0, 2, 7, 2, 5, 5])</code></pre> <p style="text-align: justify;">Kết quả từ h&agrave;m <em>argmax()</em> l&agrave; một tensor của mười danh mục dự đo&aacute;n.&nbsp;Mỗi số l&agrave; index nơi xuất c&oacute; trị cao nhất.&nbsp;Ch&uacute;ng ta c&oacute; mười số v&igrave; c&oacute; mười h&igrave;nh ảnh.</p> <p style="text-align: justify;">Khi ch&uacute;ng ta c&oacute; tensor index với gi&aacute; trị cao nhất,&nbsp;ch&uacute;ng ta c&oacute; thể so s&aacute;nh n&oacute; với tensor nh&atilde;n.</p> <pre class="language-python"><code>&gt; preds.argmax(dim=1).eq(labels) tensor( [False, False, False, False, False, False, False, False, True, False] ) &gt; preds.argmax(dim=1).eq(labels).sum() tensor(1)</code></pre> <p style="text-align: justify;">Để so s&aacute;nh, ch&uacute;ng ta đang sử dụng h&agrave;m <em>eq().&nbsp;</em>H&agrave;m <em>eq()</em> t&iacute;nh to&aacute;n một phần tử element-wise bằng hoạt động giữa đầu ra argmax v&agrave; tensor labels.</p> <p style="text-align: justify;">Điều n&agrave;y trả về True nếu index dự đo&aacute;n trong đầu ra argmax khớp với nh&atilde;n v&agrave; False nếu ngược lại.</p> <p style="text-align: justify;">Cuối c&ugrave;ng, nếu ch&uacute;ng ta gọi h&agrave;m <em>sum()</em> tr&ecirc;n kết quả n&agrave;y, ch&uacute;ng ta c&oacute; thể giảm đầu ra th&agrave;nh một số dự đo&aacute;n đ&uacute;ng b&ecirc;n trong tensor.</p> <p style="text-align: justify;">Ch&uacute;ng ta c&oacute; thể g&oacute;i lời gọi cuối c&ugrave;ng n&agrave;y th&agrave;nh một h&agrave;m c&oacute; t&ecirc;n <em>get_num_correct()</em>&nbsp;nhận v&agrave;o c&aacute;c dự đo&aacute;n v&agrave; nh&atilde;n, đồng thời sử dụng phương thức <em>item()</em> để trả về số lượng dự đo&aacute;n đ&uacute;ng trong Python.</p> <pre class="language-python"><code>def get_num_correct(preds, labels): return preds.argmax(dim=1).eq(labels).sum().item()</code></pre> <p style="text-align: justify;">Gọi h&agrave;m n&agrave;y, ch&uacute;ng ta c&oacute; thể thấy ch&uacute;ng ta nhận được gi&aacute; trị 1.</p> <pre class="language-python"><code>&gt; get_num_correct(preds, labels) 1</code></pre> <h3 class="section-heading" style="text-align: justify;">Kết Luận</h3> <p style="text-align: justify;">B&acirc;y giờ ch&uacute;ng ta đ&atilde; hiểu r&otilde; về c&aacute;ch xử l&yacute; h&agrave;ng loạt đầu v&agrave;o cho một mạng v&agrave; shape mong đợi l&agrave; g&igrave; khi xử l&yacute; một mạng neural t&iacute;ch chập.</p> <p><img style="width: 532px; display: block; margin-left: auto; margin-right: auto;" src="http://tek4vn.2soft.top/public_files/deep-neural-network-with-4-layers-png" alt="deep-neural-network-with-4-layers" height="376" /></p> <p style="text-align: justify;">Hẹn gặp lại bạn trong b&agrave;i tiếp theo!</p> <p style="text-align: justify;">&nbsp;</p> <hr /> <p style="text-align: center;"><em><strong>Fanpage Facebook:</strong>&nbsp;<a href="https://www.facebook.com/tek4.vn/">TEK4.VN</a></em>&nbsp;</p> <p style="text-align: center;"><em><strong>Tham gia cộng đồng để chia sẻ, trao đổi v&agrave; thảo luận:</strong>&nbsp;<a href="https://www.facebook.com/groups/tek4.vn/">TEK4.VN - Học Lập Tr&igrave;nh Miễn Ph&iacute;</a></em></p>