Lab Introduction
- AWS experience: Intermediate
- Time to complete: 60 ~90 minutes
- AWS Region: Singapore (ap-southeast-1)
- Cost to complete: 1~2$
- Services used: S3, Lambda, Rekonition, DynamoDB, SNS
Giới thiệu kiến trúc

Tóm tắt luồng xử lý tổng thể:
- Người dùng tải lên hình ảnh vào S3.
- S3 kích hoạt Lambda, xử lý hình ảnh bằng Rekognition.
- Lambda lưu trữ kết quả vào DynamoDB.
- Lambda gửi thông báo đến đội cứu hộ thông qua SNS/SQS.
Lợi ích của kiến trúc này:
- Tự động hóa: Không cần can thiệp thủ công trong quy trình phân tích và thông báo.
- Serverless: Giảm chi phí bằng cách chỉ sử dụng tài nguyên khi cần thiết.
- Độ tin cậy cao: AWS cung cấp khả năng mở rộng và dự phòng dữ liệu tốt.
- Phản hồi nhanh: Xử lý sự kiện theo thời gian thực để kịp thời hỗ trợ cứu hộ.
Tổng Quan Bài Lab
Bài lab này sẽ hướng dẫn bạn qua các bước sau:
- Thiết Lập Amazon S3 Bucket
- Chuẩn Bị và Huấn Luyện Mô Hình Amazon Rekognition Custom Labels
- Tạo Chủ Đề Amazon SNS cho Thông Báo
- Phát Triển Hàm AWS Lambda
- Cấu Hình S3 để Kích Hoạt Lambda khi Tải Ảnh lên
- Kiểm Tra Hệ Thống bằng Cách Tải Ảnh
- Xem Lại Thông Báo Email
Yêu Cầu Trước Khi Thực Hành
Trước khi bắt đầu bài lab này, hãy đảm bảo bạn có những yêu cầu sau:
- Một Tài khoản AWS hoạt động với các quyền truy cập cần thiết vào Amazon S3, Amazon Rekognition, AWS Lambda, và Amazon SNS.
- Kiến thức cơ bản về các dịch vụ AWS và AWS Management Console.
- Bộ sưu tập hình ảnh đã được gán nhãn về chó và mèo để huấn luyện mô hình Rekognition Custom Labels. ( download dataset tại https://www.kaggle.com/datasets/tongpython/cat-and-dog )
- Một địa chỉ email để nhận thông báo SNS.
Bước 1: Thiết Lập Amazon S3 Bucket
Cách 1: Khi tạo dự án lần đầu trên Rekognition, sẽ mặc định Rekognition sẽ yêu cầu tạo một S3 bucket default để lưu trữ các thông tin metadata cho dự án, có thể tái sử dụng luôn bucket này để upload datasets.

Cách 2: Tạo một Amazon S3 bucket riêng biệt để lưu trữ các hình ảnh được tải lên bởi người dùng.
- Đăng nhập vào AWS Management Console và điều hướng đến Amazon S3 Console.
- Tạo Bucket Mới:
- Nhấn "Create bucket".
- Bucket Name: Nhập tên duy nhất, ví dụ
rescuepaws-japan-images
. - Region: Chọn vùng AWS gần nhất với hoạt động của bạn, chẳng hạn
Asia Pacific (Tokyo)
. - Nhấn "Create bucket".
Upload datasets sau khi download và giải nén lên S3:
- folder test_set: chứa các hình ảnh dùng để chạy testing sau khi training hoàn thành.
- folder training_set: chứa các hình ảnh dùng để training cho model.

Bước 2: Chuẩn Bị và Huấn Luyện Mô Hình Amazon Rekognition Custom Labels
Amazon Rekognition Custom Labels cho phép bạn xây dựng các mô hình phân loại hình ảnh tùy chỉnh phù hợp với nhu cầu cụ thể.
- Điều Hướng đến Amazon Rekognition Console:
- Từ AWS Management Console, tìm kiếm "Rekognition" và chọn nó.
- Truy Cập Custom Labels:
- Trong bảng điều khiển Rekognition, nhấn vào "Custom Labels".
- Tạo Dự Án:
- Nhấn "Create project".
- Project Name: Nhập
RescuePawsImageRecognition
. - Nhấn "Create project".

- Tạo Dataset:
- Trong dự án của bạn, nhấn "Create dataset".
- Tab Start configuartion: Chọn option "Start with a training dataset and a test dataset"

- Tab Training dataset details: Chọn option "Import images from S3 bucket"
- S3 url: Copy S3 url của folder training set ( ví dụ s3://custom-labels-console-ap-southeast-1-f678481e82/training_set/training_set/ )
- Automatic labeling: ticked


- Tương tự cho tab Test dataset details
- S3 url: Copy S3 url của folder test set ( ví dụ s3://custom-labels-console-ap-southeast-1-f678481e82/test_set/test_set/)
- Automatic labeling: ticked

- Nhấn nút Create dataset
- Rekognition sẽ xử lý những hình ảnh này và chuẩn bị chúng để đào tạo. ( gán label)


- Huấn Luyện Mô Hình:
- Sau khi dataset sẵn sàng, nhấn "Train model".
- Training Parameters: Sử dụng cài đặt mặc định hoặc tùy chỉnh theo nhu cầu.
- Nhấn "Start training".
- Bạn có thể giám sát trạng thái đào tạo từ Bảng điều khiển Rekognition. Khi quá trình đào tạo hoàn tất, Rekognition sẽ đánh giá mô hình và cung cấp cho bạn các số liệu hiệu suất của mô hình.
- Lưu Ý: Quá trình huấn luyện có thể mất một thời gian (15-60p) tùy thuộc vào kích thước của dataset.
- Đánh Giá Mô Hình:
- Khi huấn luyện hoàn tất, xem lại các chỉ số hiệu suất và kết quả test của mô hình.

- Deploy model:
- Nhấn tab "Use model", nhấn nút "Start"
- Sau khi Start thành công, Rekognition sẽ cung cấp 1 endpoint để sử dụng. Chúng ta sẽ sử dụng endpoint này trong Lambda function.

Dưới đây là giải thích chi tiết về các chỉ số trong kết quả đánh giá của mô hình:
1. F1 Score
- Giá trị: 1.000
- Ý nghĩa: F1 score là trung bình điều hòa của độ chính xác (precision) và độ nhạy (recall). Giá trị 1.000 có nghĩa là mô hình đạt hiệu suất hoàn hảo trong việc phân loại hình ảnh, không có sai sót nào.Công thức tính F1 score:

- Nếu F1 score = 1.000, điều này cho thấy mô hình có cả precision và recall đạt mức tối đa (1.000).
2. Average Precision
- Giá trị: 1.000
- Ý nghĩa: Trung bình độ chính xác trên toàn bộ các lớp (labels). Với giá trị 1.000, có nghĩa là mô hình không có bất kỳ dự đoán sai nào, mọi dự đoán đều chính xác.
3. Overall Recall
- Giá trị: 1.000
- Ý nghĩa: Recall đo lường khả năng của mô hình trong việc nhận diện đúng tất cả các mẫu thực tế. Giá trị 1.000 có nghĩa là mô hình có thể phát hiện hoàn toàn tất cả các mẫu trong dữ liệu thử nghiệm mà không bỏ sót trường hợp nào.
4. Training và Testing Dataset
- Training dataset: 2 labels, 100 images
- Testing dataset: 2 labels, 100 images
- Ý nghĩa:
- Mô hình được huấn luyện với 2 nhãn (cats và dogs), sử dụng 100 hình ảnh.
- Dữ liệu kiểm tra cũng bao gồm 2 nhãn với 100 hình ảnh, đảm bảo sự phân phối đồng đều.
5. Per Label Performance (Hiệu suất theo từng nhãn)
Nhãn: cats
- F1 score: 1.000
- Test images: 50
- Precision: 1.000 (Tất cả dự đoán về mèo đều đúng)
- Recall: 1.000 (Mô hình nhận diện tất cả các hình mèo chính xác)
- Assumed threshold: 0.238 (Ngưỡng quyết định để phân loại hình ảnh vào nhóm "cats")
Nhãn: dogs
- F1 score: 1.000
- Test images: 50
- Precision: 1.000 (Tất cả dự đoán về chó đều đúng)
- Recall: 1.000 (Mô hình nhận diện tất cả các hình chó chính xác)
- Assumed threshold: 0.764 (Ngưỡng quyết định để phân loại hình ảnh vào nhóm "dogs")
6. Assumed Threshold
- Đây là ngưỡng xác suất mà mô hình sử dụng để xác định một hình ảnh thuộc về một nhãn cụ thể.
- Ví dụ:
- Đối với nhãn cats, mô hình sử dụng ngưỡng là 0.238, có nghĩa là nếu xác suất dự đoán cao hơn 0.238, hình ảnh sẽ được gán vào nhãn "cats".
- Đối với nhãn dogs, ngưỡng cao hơn (0.764), nghĩa là mô hình cần chắc chắn hơn để phân loại một hình là "dogs".
Tổng kết:
- Mô hình hiện tại đạt hiệu suất hoàn hảo với F1 score, Precision và Recall đều đạt 1.000, nghĩa là không có lỗi phân loại nào.
- Dữ liệu kiểm tra có sự cân bằng giữa các nhãn (50 mèo, 50 chó).
- Các ngưỡng dự đoán khác nhau giữa các nhãn, cho thấy mô hình có thể nhận diện sự khác biệt giữa chúng một cách chắc chắn.
Bước 3: Tạo Chủ Đề Amazon SNS cho Thông Báo
Amazon Simple Notification Service (SNS) sẽ xử lý việc gửi thông báo email với kết quả phân tích.
- Điều Hướng đến Amazon SNS Console:
- Từ AWS Management Console, tìm kiếm "SNS" và chọn nó.
- Tạo Topic mới:
- Nhấn vào "Topics" trong thanh bên trái.
- Nhấn "Create topic".
- Topic Type: Chọn "Standard".
- Name: Nhập
RescuePawsNotifications
. - Nhấn "Create topic".

- Đăng Ký cho Chủ Đề:
- Trong chủ đề vừa tạo, nhấn "Create subscription".
- Protocol: Chọn "Email".
- Endpoint: Nhập địa chỉ email của bạn.
- Nhấn "Create subscription".
- Confirm Subscription: Kiểm tra email của bạn và xác nhận đăng ký bằng cách nhấp vào liên kết do AWS SNS gửi.

Bước 4: Viết logic xử lý cho AWS Lambda
Hàm Lambda sẽ xử lý các hình ảnh tải lên, phân loại chúng bằng Rekognition, trích xuất dữ liệu địa lý từ metadata, và gửi thông báo qua SNS.
- Điều Hướng đến AWS Lambda Console:
- Từ AWS Management Console, tìm kiếm "Lambda" và chọn nó.
- Tạo Hàm Mới:
- Nhấn "Create function".
- Function Name: Nhập
RescuePawsImageProcessor
. - Runtime: Chọn "Python 3.13".
- Permissions: Chọn "Create a new role with basic Lambda permissions".
- Nhấn "Create function".
- Thêm quyền truy cập cho Lambda connect Rekognition, SNS & S3.
- Ở tab Configuration, nhấn vào Role Name.

- Nhấn "Attach policies" và gắn chính sách
AmazonRekognitionFullAccess
và AmazonS3ReadOnlyAccess
, AmazonSNSFullAccess

- Cấu Hình Mã Hàm Lambda:
- Trong console hàm Lambda, dưới phần "Code", thay thế mã mặc định bằng đoạn script Python sau:
import json
import boto3
import os
import mimetypes
rekognition = boto3.client('rekognition')
sns = boto3.client('sns')
s3 = boto3.client('s3')
def is_valid_image(key):
mime_type, _ = mimetypes.guess_type(key)
return mime_type in ['image/jpeg', 'image/png']
def lambda_handler(event, context):
try:
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
print(f"Processing image from bucket: {bucket}, key: {key}")
if not is_valid_image(key):
print("Unsupported image format.")
return {
'statusCode': 400,
'body': json.dumps('Unsupported image format. Please upload a valid JPEG or PNG file.')
}
try:
s3.head_object(Bucket=bucket, Key=key)
except s3.exceptions.NoSuchKey:
print("Image not found in S3 bucket.")
return {
'statusCode': 404,
'body': json.dumps('Image not found in S3 bucket.')
}
project_arn = /*Replace AWS Rekognition Arn*/
print(f"Using project ARN: {project_arn}")
response = rekognition.detect_custom_labels(
ProjectVersionArn=project_arn,
Image={'S3Object': {'Bucket': bucket, 'Name': key}},
MinConfidence=80
)
labels = response.get('CustomLabels', [])
animal = 'Unknown'
confidence_score = 0.0
for label in labels:
if label['Name'].lower() in ['dogs', 'cats']:
animal = label['Name']
confidence_score = label['Confidence']
break
print(f"Detected animal: {animal} with confidence: {confidence_score:.2f}%")
image_url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': bucket, 'Key': key},
ExpiresIn=3600
)
rescue_location = 'Tokyo, Japan' if animal != 'Unknown' else 'Chưa xác định'
email_content = f"""
Kết quả Phân Tích Hình Ảnh
Loài Động Vật Phát Hiện: {animal}
Độ Chính Xác: {confidence_score:.2f}%
Địa Điểm Cứu Hộ: {rescue_location}
Hình ảnh đã tải lên:
<img src="{image_url}" alt="Uploaded Image" width="500">
"""
message = {
"default": "Kết quả phân tích hình ảnh.",
"email": email_content
}
sns.publish(
TopicArn=/*Replace SNS Arn*/,
Subject='RescuePaws Image Analysis Notification',
Message=json.dumps(message),
MessageStructure='json'
)
print("SNS HTML email notification sent successfully.")
return {
'statusCode': 200,
'body': json.dumps('Image processed successfully.')
}
except rekognition.exceptions.InvalidImageFormatException as e:
print(f"Invalid image format error: {str(e)}")
return {
'statusCode': 400,
'body': json.dumps('Invalid image format. Please upload a valid JPEG or PNG file.')
}
except Exception as e:
print(f"Error processing image: {str(e)}")
return {
'statusCode': 500,
'body': json.dumps(f"An error occurred: {str(e)}")
}
- project_arn = /*Replace AWS Rekognition Arn*/: thay thế bằng ARN Rekognition của bạn (ví dụ: arn:aws:rekognition:ap-southeast-1:123456789012:project/dog-cat-recognition/version/dog-cat-recognition.2024-12-28T10.00.15/1735347458992 )
- TopicArn=/*Replace SNS Arn*/ : thay thế bằng ARN SNS topic của bạn ( ví dụ: arn:aws:sns:ap-northeast-1:123456789012:RescuePawsNotifications)
- Nhấn "Deploy" để lưu các thay đổi.
Bước 5: Cấu Hình S3 để Kích Hoạt Lambda khi Tải Ảnh lên
Để tự động hóa quy trình, cấu hình S3 bucket để gọi hàm Lambda khi có hình ảnh mới được tải lên.
- Điều Hướng đến S3 Bucket của Bạn:
- Truy cập Amazon S3 Console.
- Nhấn vào tên bucket của bạn, ví dụ
custom-labels-console-ap-southeast-1-f678481e82
. - Tạo folder dùng để upload hình ảnh test, ví dụ: folder finally_testing

- Thiết Lập Thông Báo Sự Kiện:
- Nhấn vào tab "Properties".
- Kéo xuống phần "Event notifications" và nhấn "Create event notification".
- Name: Nhập
ImageUploadTrigger
. - Event Types: Chọn "All object create events".
- Prefix (Tuỳ Chọn): Nếu bạn có thư mục cụ thể, nhập tiền tố (ví dụ:
finally_testing/
). - Suffix (Tuỳ Chọn): Nhập các phần mở rộng file để lọc (ví dụ:
.jpg
, .png
). - Destination: Chọn "Lambda Function" và chọn hàm
RescuePawsImageProcessor
bạn đã tạo trước đó. - Nhấn "Save changes".


- Mở rộng: chúng ta sẽ sử dụng presigned url s3 đã được code trong lambda fucntion, cho phép nhân viên cứu hộ xem hình ảnh trực tiếp được truy cập an toàn mà không cần cấp quyền công khai. URL sẽ hết hạn sau 1 giờ (3600 giây), đảm bảo bảo mật.
- Chọn tab Permission -> Edit bucket policy -> Thêm đoạn json cấp quyền cho phép đọc hình ảnh trong folder finally_testing ( sửa lại tên bucket name cho phù hợp )
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::custom-labels-console-ap-southeast-1-f678481e82/finally_testing/*"
}

Bước 6: Kiểm Tra Hệ Thống bằng Cách Tải Ảnh
Bây giờ, hãy kiểm tra thiết lập bằng cách tải lên các hình ảnh mẫu của chó và mèo vào S3 bucket.
- Chuẩn Bị Hình Ảnh: Bạn có thể download hình ảnh dog/cat trên mạng (định dạng png, jpg) để test.
- Tải Ảnh lên S3:
- Upload hình ảnh lên folder finally_testing.


- Giám Sát Việc Thực Thi Lambda:
- Khi upload hình ảnh lên S3, Event Notification của S3 sẽ được kích hoạt và call đến Lambda function.
- Mở dịch vụ CloudWatch Console.
- Nhấn vào hàm
RescuePawsImageProcessor
, chọn Log Event để xem log của Lambda thực thi. 
Bước 7: Xem Lại Thông Báo Email
Sau khi tải lên hình ảnh, bạn sẽ nhận được các thông báo email với kết quả phân tích.
Kiểm Tra Email của Bạn:
- Mở hộp thư đến liên kết với đăng ký SNS của bạn.
- Tìm các email với tiêu đề "RescuePaws Image Analysis Notification".
Xem Lại Nội Dung Thông Báo: Email sẽ chứa các chi tiết như:
- Loài Động Vật Phát Hiện:
Chó
, Mèo
hoặc thông báo hệ thống không hỗ trợ nhận dạng loài khác. - Độ Chính Xác: Ví dụ:
97.73%
. - Địa Điểm Cứu Hộ: Ví dụ:
Tokyo, Japan
. - Hình ảnh tải lên: Khi nhấn vào link, sẽ lấy được hình ảnh người dùng upload. ( sử dụng presigned url s3 nên link sẽ hết hạn sau 1 giờ )


Kiểm tra với trường hợp upload hình ảnh là Mèo


Clean up resources
- Delete model Rekognition
- Delete Lambda Function
- Delete SNS Topic
- Delete S3 bucket