SinhVienCNTT.Net
Thứ Sáu, Tháng 10 10, 2025
  • Login
No Result
View All Result
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ
Gửi email
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ
No Result
View All Result
SinhVienCNTT.Net
No Result
View All Result
Home Machine Learning

Ví dụ huấn luyện mô hình phân loại chữ viết tay cơ bản sử dụng Python

admin by admin
4 Tháng 5, 2025
in Machine Learning
0

Ở các bài trước các bạn đã hình dung được mạng nơ-ron có gì. Mô hình phân loại chữ viết tay được tạo thành từ các layer được kết nối với nhau, ánh xạ dữ liệu đầu vào thành các dự đoán. Hàm mất mát sau đó so sánh những dự đoán này với mục tiêu, tạo ra một giá trị mất mát – là một hàm đo lường về mức độ mà dự đoán của mô hình khớp với những gì được mong đợi. Bộ tối ưu hóa sử dụng giá trị mất mát này để cập nhật trọng số của mô hình.

Mục lục ẩn
1. Nhắc lại mô hình
2. Triển khai mô hình phân loại chữ viết tay với Tensorflow
2.1. Layer Dense cơ bản
2.2. Sequential đơn giản
2.3. Batch generator
2.4. Chạy bước huấn luyện
2.5. Đào tạo toàn bộ
2.6. Đánh giá mô hình
3. Tóm tắt
mô hình phân loại chữ viết tay
Relationship between the network, layers, loss function, and optimizer

Nhắc lại mô hình

Đây là dữ liệu đầu vào:

Python
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255

Nhìn vào đoạn code trên, ta có thể thấy dữ liệu là các hình ảnh đầu vào được lưu trữ dưới dạng tensors NumPy, được định dạng ở đây là tensors float32 có shape của dữ liệu huấn luyện là (60000, 784), còn dữ liệu kiểm thử là (10000, 784).

Mô hình của chúng ta:

Python
model = keras.Sequential([
 layers.Dense(512, activation="relu"),
 layers.Dense(10, activation="softmax")
])

Mô hình này bao gồm một chuỗi của hai layer Dense, mỗi layer áp dụng một số phép toán tensor đơn giản cho dữ liệu đầu vào và rằng những phép toán này liên quan đến các tensor trọng số. Các tensor trọng số, là các thuộc tính của các lớp, là nơi kiến thức của mô hình được lưu trữ.

Bước biên dịch mô hình:

Python
model.compile(optimizer="rmsprop",
 loss="sparse_categorical_crossentropy",
 metrics=["accuracy"])

Trong đó sparse_categorical_crossentropy là hàm mất mát được sử dụng làm tín hiệu phản hồi để học các tensor trọng số, và trong quá trình huấn luyện, mục tiêu là giảm thiểu hàm mất mát này. Ta cũng biết rằng việc giảm thiểu mất mát xảy ra thông qua phương pháp mini-batch stochastic gradient descent. Các quy tắc cụ thể được định nghĩa bởi bộ tối ưu hóa rmsprop. Cuối cùng, đây là vòng lặp huấn luyện:

Python
model.fit(train_images, train_labels, epochs=5, batch_size=128)

Khi gọi hàm fit(), mô hình sẽ bắt đầu lặp lại trên dữ liệu huấn luyện theo các mini-batch có 128 mẫu, lặp lại quá trình này 5 lần (mỗi lần lặp qua toàn bộ dữ liệu huấn luyện được gọi là một epoch). Đối với mỗi batch, mô hình sẽ tính toán độ dốc của hàm mất mát đối với trọng số (sử dụng thuật toán Backpropagation, có nguồn gốc từ quy tắc chuỗi trong giải tích như trình bày ở phần trước) và di chuyển trọng số theo hướng sẽ giảm giá trị mất mát cho batch này.

Sau 5 epoch, mô hình sẽ thực hiện 2,345 cập nhật độ dốc (469 mỗi epoch), và giá trị mất mát của mô hình sẽ đủ thấp để mô hình có khả năng phân loại chữ số viết tay với độ chính xác cao.

Triển khai mô hình phân loại chữ viết tay với Tensorflow

Layer Dense cơ bản

Như các bài trước mình đã nói, Dense thực hiện phép biến đổi đầu vào như sau, trong đó W và b là các tham số của mô hình, và activation là một hàm tích lũy theo phần tử (thường là relu, nhưng có thể là softmax cho layer cuối cùng):

Python
output = activation(dot(W, input) + b)

Ta xây dựng một class Python đơn giản, NaiveDense, tạo ra hai biến TensorFlow là W và b, và hiển thị một phương thức call() áp dụng phép biến đổi đã nói trước đó.

Python
import tensorflow as tf
class NaiveDense:

   def __init__(self, input_size, output_size, activation):
     self.activation = activation
     w_shape = (input_size, output_size) 
     w_initial_value = tf.random.uniform(w_shape, minval=0, maxval=1e-1)
     self.W = tf.Variable(w_initial_value)
   
     b_shape = (output_size, 
     b_initial_value = tf.zeros(b_shape)
     self.b = tf.Variable(b_initial_value)
     
   def __call__(self, inputs):: 
     return self.activation(tf.matmul(inputs, self.W) + self.b)
     
   @property
   def weights(self): 
     return [self.W, self.b]

Sequential đơn giản

Tiếp theo, tạo một class NaiveSequential để kết nối những layer này. Nó bao bọc một danh sách các layer và hiển thị một phương thức call() đơn giản gọi các layer cơ bản trên đầu vào theo thứ tự. Nó cũng có một thuộc tính weights để dễ dàng theo dõi các tham số của các lớp.

Python
class NaiveSequential:
   def __init__(self, layers):
       self.layers = layers
   
   def __call__(self, inputs):
       x = inputs
       for layer in self.layers:
           x = layer(x)
       return x
   
   @property
   def weights(self):
       weights = []
       for layer in self.layers:
           weights += layer.weights
       return weights

Sử dụng lớp NaiveDense và lớp NaiveSequential này, chúng ta có thể tạo ra một mô hình giả Keras như sau:

Python
model = NaiveSequential([
   NaiveDense(input_size=28 * 28, output_size=512, activation=tf.nn.relu),
   NaiveDense(input_size=512, output_size=10, activation=tf.nn.softmax)
]) 
assert len(model.weights) == 4

Batch generator

Tiếp theo, ta cần lặp qua dữ liệu MNIST theo các mini-batch.

Python
import math
class BatchGenerator:
   def __init__(self, images, labels, batch_size=128):
       assert len(images) == len(labels)
       self.index = 0
       self.images = images
       self.labels = labels
       self.batch_size = batch_size
       self.num_batches = math.ceil(len(images) / batch_size)
   def next(self):
       images = self.images[self.index : self.index + self.batch_size]
       labels = self.labels[self.index : self.index + self.batch_size]
       self.index += self.batch_size
       return images, labels

Chạy bước huấn luyện

Chúng ta cần thực hiện các bước sau:

  1. Tính toán dự đoán của mô hình cho các hình ảnh trong lô dữ liệu.
  2. Tính toán giá trị mất mát cho những dự đoán này, dựa trên các nhãn thực tế.
  3. Tính toán độ dốc của mất mát đối với trọng số của mô hình.
  4. Di chuyển trọng số một lượng nhỏ theo hướng ngược lại với độ dốc.

Để tính toán độ dốc, ta sẽ sử dụng đối tượng GradientTape trong TensorFlow:

Python
def one_training_step(model, images_batch, labels_batch):
   with tf.GradientTape() as tape: 
      predictions = model(images_batch) 
          per_sample_losses = tf.keras.losses.sparse_categorical_crossentropy( 
      labels_batch, predictions) 
      average_loss = tf.reduce_mean(per_sample_losses) 
   gradients = tape.gradient(average_loss, model.weights) 
   update_weights(gradients, model.weights) 
   return average_loss

Mục đích của bước cập nhật trọng số (được đại diện bởi hàm update_weights) là di chuyển trọng số “một chút” theo một hướng sẽ giảm mất mát trên lô dữ liệu này. Độ lớn của bước di chuyển được xác định bởi “tốc độ học” thường là một lượng nhỏ. Cách đơn giản nhất để triển khai hàm update_weights này là trừ gradient * learning rate từ mỗi trọng số:

Python
learning_rate = 1e-3
def update_weights(gradients, weights):
   for g, w in zip(gradients, weights):
   w.assign_sub(g * learning_rate)

Trong thực tế, ta sẽ sử dụng một Optimizer từ Keras như sau:

Python
from tensorflow.keras import optimizers
optimizer = optimizers.SGD(learning_rate=1e-3)

def update_weights(gradients, weights):
    optimizer.apply_gradients(zip(gradients, weights))

Khi bước đào tạo từng lô đã sẵn sàng, ta có thể tiếp tục triển khai một epoch đào tạo toàn bộ.

Đào tạo toàn bộ

Một epoch đào tạo đơn giản chỉ bao gồm việc lặp lại bước đào tạo cho mỗi lô trong dữ liệu đào tạo, và vòng lặp đào tạo đầy đủ đơn giản chỉ là sự lặp lại của một epoch:

Python
def fit(model, images, labels, epochs, batch_size=128):
   for epoch_counter in range(epochs):
       print(f"Epoch {epoch_counter}")
       batch_generator = BatchGenerator(images, labels)
       for batch_counter in range(batch_generator.num_batches):
           images_batch, labels_batch = batch_generator.next()
           loss = one_training_step(model, images_batch, labels_batch)
           if batch_counter % 100 == 0:
               print(f"loss at batch {batch_counter}: {loss:.2f}")

Thử nghiệm:

Python
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype("float32") / 255 
test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype("float32") / 255
fit(model, train_images, train_labels, epochs=10, batch_size=128)

Đánh giá mô hình

Chúng ta có thể đánh giá mô hình bằng cách lấy giá trị lớn nhất của các dự đoán trên các hình ảnh kiểm thử và so sánh nó với các nhãn mong đợi:

Python
predictions = model(test_images)
predictions = predictions.numpy() 
predicted_labels = np.argmax(predictions, axis=1)
matches = predicted_labels == test_labels
print(f"accuracy: {matches.mean():.2f}")

Vậy là xong, trong thực tế chúng ta sẽ sử dụng các hàm có sẵn của Keras, tuy nhiên việc build các bước bằng tay như vậy cho ta hiểu biết rõ ràng hơn về những gì diễn ra bên trong một mạng neural khi gọi hàm fit().

Tóm tắt

  • Tensor là nền tảng của các hệ thống học máy hiện đại. Chúng xuất hiện dưới nhiều dạng khác nhau về dtype, rank và shape.
  • Bạn có thể thao tác trên tensor số học thông qua các phép toán tensor (như cộng, tích tensor hoặc nhân từng phần tử), có thể được hiểu như là mã hóa các biến đổi hình học. Nói chung, mọi thứ trong học sâu có thể được hiểu bằng cách hình học.
  • Mô hình học sâu bao gồm chuỗi các phép toán tensor đơn giản, được tham số hóa bằng trọng số, chính chúng là tensor. Trọng số của một mô hình là nơi “kiến thức” của nó được lưu trữ.
  • Học nghĩa là tìm một bộ giá trị cho trọng số của mô hình sao cho giảm thiểu một hàm mất mát đối với một bộ mẫu dữ liệu đào tạo cụ thể và các mục tiêu tương ứng của chúng. Học diễn ra bằng cách rút ra các lô ngẫu nhiên của mẫu dữ liệu và mục tiêu của chúng, sau đó tính độ dốc của các tham số mô hình đối với mất mát trên lô. Các tham số mô hình sau đó được di chuyển một chút (độ lớn của chuyển động được xác định bởi tốc độ học) theo hướng ngược lại từ độ dốc. Điều này được gọi là hạ gradient ngẫu nhiên theo mini-batch (mini-batch stochastic gradient descent).
  • Toàn bộ quá trình học là có thể nhờ vào việc tất cả các phép toán tensor trong mạng neural đều có thể được đạo hàm, và do đó có thể áp dụng quy tắc chuỗi đạo hàm để tìm hàm đạo hàm ánh xạ từ các tham số hiện tại và lô dữ liệu hiện tại đến một giá trị độ dốc. Điều này được gọi là lan truyền ngược.
  • Hai khái niệm quan trọng các bạn sẽ thường xuyên thấy trong các bài viết sau là mất mát và bộ tối ưu hóa. Đây là hai điều ta cần định nghĩa trước khi bắt đầu đưa dữ liệu vào một mô hình.
    • Mất mát là lượng bạn sẽ cố gắng giảm thiểu trong quá trình đào tạo, nên nó phải đại diện cho một độ đo thành công cho nhiệm vụ mà ta đang cố gắng giải quyết.
    • Bộ tối ưu hóa chỉ định cách chính xác mà độ dốc của mất mát sẽ được sử dụng để cập nhật các tham số: ví dụ, nó có thể là bộ tối ưu hóa RMSProp, SGD với đà động, và vân vân.
Tags: Machine Learning
Share64Tweet40
Previous Post

CEH Module 11 – Phần 2: Application-Level Session Hijacking

admin

admin

A Winner Never Stops Trying.

Related Posts

Thuật toán lan truyền ngược – Backpropagation
Machine Learning

Thuật toán lan truyền ngược – Backpropagation

6 Tháng 3, 2024
Cách tiếp cận dễ hiểu nhất về Gradient Descent
Machine Learning

Cách tiếp cận dễ hiểu nhất về Gradient Descent

6 Tháng 3, 2024
Lý thuyết toán cơ bản trong Deep Learning
Machine Learning

Lý thuyết toán cơ bản trong Deep Learning (phần 2)

6 Tháng 3, 2024
Lý thuyết toán cơ bản trong Deep Learning
Machine Learning

Lý thuyết toán cơ bản trong Deep Learning

6 Tháng 3, 2024
Lịch sử của phát triển của học sâu – Deep Learning
Machine Learning

Lịch sử của phát triển của học sâu – Deep Learning

2 Tháng 3, 2024
Học sâu và nguyên lý của học sâu
Machine Learning

Học sâu và nguyên lý của học sâu

1 Tháng 3, 2024

Để lại một bình luận Hủy

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Danh mục

  • Các môn học đại học
  • CCNA 200-301
  • CEH Tiếng Việt – CEH v13
  • Chưa phân loại
  • Digital Forensics
  • Machine Learning
  • Network
  • Nổi bật
  • Phân tích mã độc
  • Security
  • Tài liệu CNTT
  • Từ vựng IELTS

Series

  • CHFI Tiếng Việt (1)
  • Cơ sở dữ liệu (2)
  • [2023] Share 1200 câu dump CCNA 200-301 mới nhất (3)
  • 1000 collocations IELTS phổ biến nhất (1)
  • Hệ điều hành (5)
  • Series cấu hình Firewall Cisco ASA (2)
  • Nhập môn lập trình (1)
  • 22 Lab thực hành Amazon Web Service (AWS) từ cơ bản đến nâng cao (4)
  • Nhập môn mạng máy tính (20)
  • Lập trình hệ thống (3)

logo sinhviencntt.net

Blog Sinh viên CNTT chia sẻ kiến thức, tài liệu liên quan đến nhóm ngành Công nghệ thông tin.

Chúng tôi sẵn sàng đón những ý kiến đóng góp, cũng như bài viết của các bạn gửi đến SinhVienCNTT.Net.

Giới thiệu

Blog Sinh viên CNTT chia sẻ kiến thức, tài liệu liên quan đến nhóm ngành Công nghệ thông tin.

Liên hệ

Email: sinhviencntt.net@gmail.com

Tìm kiếm

No Result
View All Result

Danh mục

  • Các môn học đại học
  • CCNA 200-301
  • CEH Tiếng Việt – CEH v13
  • Chưa phân loại
  • Digital Forensics
  • Machine Learning
  • Network
  • Nổi bật
  • Phân tích mã độc
  • Security
  • Tài liệu CNTT
  • Từ vựng IELTS
  • Home
  • Liên hệ
  • Privacy & Policy
  • Other Links

© 2023 SinhVienCNTT.Net - Blog Sinh viên Công nghệ thông tin.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • Bài viết nổi bật
  • Security
    • Kỹ thuật phân tích mã độc
    • CEH v13
  • Các môn học đại học
    • Các môn đại cương
      • Nhập môn mạng máy tính
      • Nhập môn lập trình
      • Hệ điều hành
    • Ngành An toàn thông tin
      • Lập trình hệ thống
    • Ngành Mạng máy tính & Truyền thông dữ liệu
  • Tài liệu CNTT
  • Liên hệ

© 2023 SinhVienCNTT.Net - Blog Sinh viên Công nghệ thông tin.