Bài 1: Cho biết ý nghĩa của Batch size và Epoch trong chương trình demo, thay đổi các giá trị này để thấy sự ảnh hướng đến quá trình huấn luyện.. Kết quả sau khi cài đặt thành công C cod
Trang 1DAI HOC QUOC GIA THÀNH PHỐ HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN KHOA ĐIỆN TỬ - VIỄN THONG
BO MON MAY TINH -HE THONG NHUNG
0e B04
@ 4
š d :
› là ? ce 2
* PDHQG-HCM
THU'C HANH XU’ LY ANH
Gvhd : Th.s Dang Tấn Phát
Sv Nguyễn Hữu Luân Mssv 20200253
Bài tập Lưu ý: Sinh viên cần thực hiện bài tập theo trình tự
Bài 1: Cho biết ý nghĩa của Batch size và Epoch trong chương trình demo, thay đổi
các giá trị
này để thấy sự ảnh hướng đến quá trình huấn luyện
Bài 2: Chạy chương trình lenet5.py từ link bên dưới, xuất các weight ra file txt như
sau:
1 convolution 1 (w_conv1.txt)
2 bias cua convolution 1 (b_conv1.txt)
3 convolution 2 (w_conv2.txt)
4, bias cua convolution 2 (b_conv2.txt)
5 fully connection 1 (w_fc1.txt)
6 bias cua fully connection 1 (b_fc1.txt)
Trang 27 fully connection 2 (w_fc2.txt)
8 bias cua fully connection 2 (b_fc2.txt)
9 fully connection 3 (w_fc3.txt)
10 bias cia fully connection 3 (b_fc3.txt)
Bài 3: Sử dụng các file từ link:
e Mô hình Lenet-5: main_lenet_ 5.c và tensor.h
® Data cho kiểm tra: mnist-test-image.txt và mnist-test-target.txt
e Weight: Các file được tạo ra từ Bài 1
Xây dựng mô hình Lenet-5 bang C code để hoàn tất hàm Prediction trong file
main_lenet_5.c
với các đối số đầu vào như sau:
void Prediction( float image[28][28], // Anh dau vao
float w_conv1[6][1][1], // weight cua convolution 1
float w_conv2[16][6][5][5], // weight cua convolution 2
float w_fc1[120][400], // weight cua fully connection 1
float w_fc2[84][120], // weight cua fully connection 2
float w_fc3[10][84], // weight cia fully connection 3
float b_conv1[6], // bias của convolution 1
float b_conv2[16], // bias cua convolution 2
float b_fc1[120], // bias cua fully connection 1
float b_fc2[84], // bias cua fully connection 2
float b_fc3[10], // bias cia fully connection 3
float probs[10]) //kết quả xác suất của 10 lớp của softmax
Trang 3Kết quả sau khi cài đặt thành công C code cho kiến trúc Lenet-5 và kiểm tra với 10
data đạt được
độ chính 100%
Bài 1 và bài 2 nhóm em làm chung
Trong chương trình demo của bạn, batch_ size và epochs là hai tham số quan trọng
liên quan đến quá trình huấn luyện mô hình Dưới đây là ý nghĩa của chúng:
Batch Size ( batch-size):
Là số lượng mẫu dữ liệu được sử dụng trong mỗi lần cập nhật trọng số của mô hình
Batch size ảnh hưởng đến việc tính toán đồng thời và quản lý bộ nhớ GPU Batch size
càng lớn, mô hình càng được huấn luyện nhanh chóng, nhưng đòi hỏi nhiều bộ nhớ
hơn
Một giá trị thông thường là chọn batch size la một lũy kế của 2 (ví dụ: ó4, 128, 25ó)
Epochs ( epochs):
Là số lượng lần mô hình sẽ được huấn luyện trên toàn bộ tập dữ liệu
Mỗi epoch sẽ thực hiện một lượt qua toàn bộ tập dữ liệu để cập nhật trọng số
Số epochs quyết định độ lâu dài của quá trình huấn luyện Một giá trị thông thường
có thể là một số lượng đủ lớn để mô hình học được càng nhiều thông tin càng tốt mà
không gây ra overfitting
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.optim.|r_scheduler import StepLti
import numpy as np
#import adamod
class LeNet5(nn.Module):
def init (self):
super(LeNet5, self) init ()
self.conv1 = nn.Conv2d(1, 6, 1, 1)
self.conv2 = nn.Conv2d(6, 16, 5, 1)
self.pooling = nn.AvgPool2d(2,2)
self.fc1 = nn.Linear(400, 120)
self.fc2 = nn.Linear(120, 84)
Trang 4
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = self.pooling(x)
x = self.conv2(x)
x = F.relu(x)
x = self.pooling(x)
x = torch.flatten(x, 1)
x = self.fc1(x)
x = F.relu(x)
x = self.fc2(x)
x = F.relu(x)
x = self.fc3(x)
output = torch.log_softmax(x, dim=1)
return output
def train(args, model, device, train_loader, optimizer, epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if batch_idx % args.log_interval == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100 * batch_ idx / len(train_ loader), loss.item()))
lf args.dry_ run:
break
def test(model, device, test_loader):
model.eval()
test_loss = O
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
Trang 5
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss
pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability
correct += pred.eq(target.view_ as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print(nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100 * correct / len(test_loader.dataset)))
def main():
# Training settings
parser = argparse.ArgumentParser(description='PyTorch MNIST Example’)
parser.add_argument(' batch-size’, type=int, default=64, metavar='N',
help='input batch size for training (default: 64)')
parser.add_argument(' test-batch-size', type=int, default=1000, metavar='N',
help='input batch size for testing (default: 1000)')
parser.add_argument(' epochs', type=int, default=1, metavar='N',
help='number of epochs to train (default: 1)')
parser.add_argument(' Ir', type=float, default=1.0, metavar='Lti',
help='learning rate (default: 1.0)')
parser.add_argument(' gamma', type=float, default=0.7, metavar='M',
help='Learning rate step gamma (default: 0.7)')
parser.add_argument(' no-cuda', action='store_true', default=False,
help='disables CUDA training')
parser.add_argument(' dry-run', action='store_true', default=False,
help='quickly check a single pass’)
parser.add_argument(' seed', type=int, default=1, metavar='S',
help='random seed (default: 1)')
parser.add_argument(' log-interval', type=int, default=10, metavar='N',
help='how many batches to wait before logging training status')
parser.add_argument(' save-model', action='store_ true', default=True,
help='For Saving the current Model’) args = parser.parse_args()
use_cuda = not args.no_cuda and torch.cuda.is_available()
torch.manual_seed(args.seed)
device = torch.device("cuda" if use_cuda else "cpu")
#device = torch.device("cpu")
Trang 6
train_kwargs = {'batch_size': args.batch_size}
test_kwargs = {'batch_size': args.test_batch_size}
if use_cuda:
cuda_kwargs = {'num_workers': 1,
‘pin_memory': True,
‘shuffle’: True}
train_kwargs.update(cuda_kwargs)
test_kwargs.update(cuda_kwargs)
new_batch_size = 32
new_epochs = 5
args.batch_size = new_batch_size
args.epochs = new_epochs
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
dataset1 = datasets MNIST(‘data’, train=True, download=True,
transform=transform) dataset? = datasets.MNIST(‘data’, train=False,
transform=transform)
train_loader = torch.utils.data DataLoader(dataset1, * *train_kwargs)
test_loader = torch.utils.data.DataLoader(dataset2, **test_kwargs)
model = LeNet5().to(device)
optimizer = optim.Adadelta(model.parameters(), lr=args.lr)
scheduler = StepLti(optimizer, step_size=1, gammma=args.gamma)
### Training Phase
for epoch in range(1, args.epochs + 1):
train(args, model, device, train_loader, optimizer, epoch)
test(model, device, test_loader)
scheduler.step()
### Save the model
if args.save_model:
torch.save(model.state_ dict(), '"data/lenet5_model.pt")
Trang 7
### Load the model from lenet5_model.pt file
print(model)
model.load_ state_ dict(torch.load("data/lenet5_ model.pt"))
#keys = model.state_dict().keys()
### Export all model's weights to *.txt file
for steps, weights in enumerate(keys):
w = model.state_dict()[weights].data
w_reshaped = w.reshape(w.shape[0],-1)
np.savetxt(r' /data/weights/' + str(weights) + '.txt', w_reshaped, fmt='%f')
bn_w = model.state_dict()['bn.weight'].data
bn_b = model.state_ dict()['bn.bias'].data
bn_running_mean = model.state_ dict()['bn.running_mean'].data
bn_running_var = model.state_dict()['bn.running_var'].data
bn_num_batches_tracked = model.state_dict()['bn.num_batches_tracked'].data
conv1_weight = model.conv1.weight.data.cpu().numpy()
conv1_bias = model.conv1.bias.data.cpu().numpy()
conv2_weight = model.conv2.weight.data.cpu().numpy()
conv2_bias = model.conv2.bias.data.cpu().numpy()
fc1_ weight = model.fc1.weight.data.cpu().numpy()
fc1_bias = model.fc1.bias.data.cpu().numpy()
fc2_weight = model.fc2.weight.data.cpu().numpy()
fc2_bias = model.fc2.bias.data.cpu().numpy()
fc3_weight = model.fc3.weight.data.cpu().numpy()
fc3_bias = model.fc3.bias.data.cpu().numpy()
np.savetxt("w_conv1.txt", conv1_ weight.flatten())
np.savetxt('b_conv1.txt", conv1_ bias.flatten())
np.savetxt("w_conv2.txt", conv2_weight.flatten())
np.savetxt("b_conv2.txt", conv2_bias.flatten())
np.savetxt("w_fc1.txt", fc1_weight.flatten())
np.savetxt("b_fc1.txt", fc1_ bias.flatten())
np.savetxt("w_fc2.txt", fc2_weight.flatten())
np.savetxt("b_fc2.txt", fc2_bias.flatten(})
np.savetxt("w_fc3.txt", fc3_weight.flatten())
np.savetxt("b_fc3.txt", fc3_bias.flatten(})
### Inference Phase
print('Testing ')
Trang 8
test(model, device, test_loader)
iÍ_ name_ =='_ main _':
main)
Nguyên lý hoạt động của mã nguồn này liên quan đến quá trình huấn luyện và kiểm
thử một mô hình học sâu (deep learning) sử dụng mạng LeNet5 trên tập dữ liệu
MNIST Dưới đây là mô tả chỉ tiết về cách mã nguồn thực hiện các bước quan trọng:
Định nghĩa mô hình LeNet5;
Mô hình được xây dựng bao gồm các lớp convolutional, activation (tieLU), và fully
connected
Mục tiêu của mô hình là phân loại hình ảnh của các chữ số từ 0 đến 9 trong tập dữ
liệu MNIST
Chuẩn bị dữ liệu:
Sử dụng thư viện torchvision để tải và chuẩn bị dữ liệu từ tập dữ liệu MNIST
Áp dụng các phép biến đổi (transforms) như chuyển đổi ảnh về tensor và chuẩn hóa
dữ liệu
Thiết lập thông số huấn luyện:
Sử dụng thư viện argparse để đọc thông số từ dòng lệnh như batch size, số epoch,
learning rate, v.v
Tạo DataLoader cho dữ liệu huấn luyện và kiểm thử
Trang 9Tối ưu hóa và lên lịch học tăng cường (scheduler):
Sử dụng thuật toán tối ưu hóa Adadelta để cập nhật trọng số của mô hình
Sử dụng lịch học tăng cường (scheduler) để giảm learning rate theo số epoch
fiuá trình huấn luyện:
Sử dụng hàm huấn luyện để đào tạo mô hình trên tập dữ liệu huấn luyện
Tính toán va in ra gid tri ham mat mat (loss) va các thông số quan trọng trong quá
trình huấn luyện
fiuá trình kiểm thử:
Sử dụng hàm kiểm thử để đánh giá hiệu suất của mô hình trên tập dữ liệu kiểm thử
In ra độ chính xác và giá trị mất mát trung bình trên tập kiểm thử
Lưu và tải mô hình:
Lưu trọng số của mô hình nếu được yêu cầu (thông qua tham số save-model)
Tải lại mô hình từ file nếu cần thiết
*Xuất trọng số ra file txt:
Xuất các trọng số của mô hình (weights và biases) thành các tệp tin *.txt
Kiểm thử sau khi huấn luyện:
Kiểm thử mô hình sau khi đã được huấn luyện để đánh giá hiệu suất cuối cùng
Tổng cộng, mã nguồn này thực hiện một quá trình đầy đủ từ việc chuẩn bị dữ liệu,
huấn luyện mô hình, đánh giá hiệu suất, và lưu trọng số, giúp người sử dụng hiểu rõ
các bước quan trọng trong quá trình xây dựng và đánh giá mô hình học máy sử dụng
PyTorch trên bài toán nhận diện chữ số
- _ Kết quả qua 5 train
Trang 10Train Epoch: 3 [59520/60000 (99%)] Loss: 0.001842
Test set: Average loss: 0.0411, Accuracy: 9862/10000 (99%)
Train Epoch: 4 [0/60000 (0%) ] Loss: 0.004641
Train Epoch: 2 [59520/60000 (99%)] Loss: 0.001475
Test set: Average loss: 0.0574, Accuracy: 9812/10000 (98%)
Train Epoch: 3 [0/60000 (0%) ] Loss;: 9 012657
Train Epoch: 1 [58880/60000 (98%)] Loss: 0 Eres
Train Epoch: 1 [59520/60000 (99%)] Loss: 0.002007
Test set: Average loss: 0.0825, Accuracy: 9742/10000 (97%)
Train Epoch: 2 [0/60000 (0%) ] Loss: 0.054990
Kết quả cuối cùng
Test set: Average loss: 0.0337, Accuracy: 9886/10000 (99%)
LeNet5(
(conv1): Conv2d(1, 6, kernel_size=(1, 1), stride=(1, 1)
conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
Se AvgPool2d(kernel_size=2, stride=2, padding=0)
es : Linear(in_features=120, out_features=84, bias=True)
Í
Í
(f “Hà Linear(in_features=400, out_features=120, bias=True)
Í
(fc3): Linear(in_features=84, out_features=10, bias=True)
)
Testing
Test set: Average loss: 0.0337, Accuracy: 9886/10000 (99%)
Bai 3
Lab3.c
#define _CtiT_SECUtiIE_NO_WATtININGS
#include <stdio.h>
#include <stdlib.h>
#include "tensor.h”
#include <math.h>
void Prediction(float image[28][28],
float w_conv1[6][1][1], float w_conv2[16][6][5][5], float w_fc1[120][400], float w_fc2[84][120],
Trang 11
float w_fc3[10][84], float b_conv1[6], float b_conv2[16], float b_fc1[120], float b_fc2[84], float b_fc3[10], float probs[10])
float conv1[6][28][28];
float average_pooling1[6][14][14];
float conv2[16][10][10];
float average_pooling2[16][5][5];
float flatten[400];
float fc1[120];
float fc2[84];
float fc3[10];
int channel, row, col, i, j, k, index;
/* Convolution 1 */
for (channel = 0; channel < 6; channel++)
{
for (row = 0; row < 28; row++)
{
for (col = 0; col < 28; col++)
{
conv1[channel][row][col] = image[row][col] * w_convi[channel][0][0] + b_conv1[channel];
// tieLU
if (conv1[channel][row][col] < 0) conv1[channel][row][col] = O;
}
}
}
/* Average Pooling 1 */
for (channel = 0; channel < 6; channel++)
{
for (row = 0; row < 14; row++)
{
for (col = 0; col < 14; col++)
{