- vừa được xem lúc

[AWS Serverless] - Sử dụng Golang và Amazon Rekognition để xây dựng API tìm kiếm khuôn mặt bằng hình ảnh

0 0 26

Người đăng: Trần Tấn Thành

Theo Viblo Asia

Serverless là gì

Hãy xem lại bài viết này của mình để nắm căn bản phần Serverless này.

Mô hình hệ thống chúng ta sẽ xây dựng hôm nay

image.png

Giới thiệu Amazon Rekognition (Nhân vân chính của bài viết)

Amazon Rekognition là một dịch vụ Serverless của AWS hỗ trợ chúng ta xây dựng các chương trình cần sử dụng đến AI về phân tích hình ảnh, phân tích video, nhận diện vật thể trong hình mà hoàn toàn không yêu cầu người sử dụng có kiến thức về Machine Learning hoặc AI. Chỉ cần gọi dịch vụ thông qua AWS SDK hoặc API là chúng ta có thể tương tác với AI model mà AWS xây dựng sẵn.

Trong bài viết này mình sử dụng Amazon Rekognition để xây một thư viện hình ảnh các khuôn mặt của người dùng. Chúng ta sẽ có 2 API, một dùng để Index(tức là thêm khuôn mặt vào thư viện) và hai là chức năng tìm kiếm khuôn mặt bằng hình ảnh. API sẽ cho chúng ta biết username của khuôn mặt mà chúng ta truyền vào khi tìm kiếm và % trùng khớp giữa hình truyền vào và hình gốc trong thư viện ảnh.

Ứng dụng này có thể áp dụng cho các tình huống như là máy chấm công bằng khuôn mặt tại công ty, hoặc là cho khách hàng đăng nhập bằng cách mở camera chụp hình khuôn mặt. Vì đây là Serverless nên các bạn không phải lo về tốc độ và cỗ máy xử lý bên dưới. Qua tìm hiểu của mình thì thư viện khuôn mặt có thể xử lý thoải mái trong khoảng 10 triệu khuôn mặt, còn hơn thế nữa thì mình chưa thử hihi.

Chuẩn bị môi trường

  1. Cài đặt Nodejs(Vì mục 2 cài bằng NPM), chi tiết ở link này
  2. Cài đặt Serverless Framework, chi tiết ở link này
  3. Cài đặt AWS CLI, chi tiết ở link này
  4. Cài đặt Golang, chi tiết ở link này
  5. Do ví dụ sử dụng lệnh make nên mình sử dụng Ubuntu/MacOS.

Cài đặt AWS CLI để kết nối tài khoản AWS của bạn

aws configure

Các bạn cài đặt Client ID và Client Secret như bên dưới, 2 thông số còn lại optional bạn không cài cũng được.

AWS Access Key ID [****]:
AWS Secret Access Key [****]:
Default region name [us-west-1]: Default output format [None]:

Tạo Amazon Rekognition và AWS S3 để lưu ảnh khuôn mặt và file hình

  1. Hãy tạo kho khuôn mặt(face collection) bằng câu lệnh CLI bên dưới. Tên collection này mình đặt là "viblo", nếu các bạn đổi thì nhớ vào file serverless.yml đổi lại cho khớp nhé(dòng 26).
aws rekognition create-collection --collection-id "viblo" 
  1. Tiếp theo chạy câu lệnh CLI bên dưới để tạo S3 Bucket lưu trữ hình ảnh khuôn mặt. Tên S3 bucket này mình đặt là "viblo-facecollection", nếu các bạn đổi thì nhớ vào file serverless.yml đổi lại cho khớp nhé(dòng 27).
aws s3api create-bucket --bucket viblo-facecollection --region ap-southeast-1 

Hãy xem cấu trúc chính của sourcecode nào !

Các bạn clone sourcecode mình viết về máy bằng lệnh bên dưới (hãy cho mình một star để ủng hộ mình ra thêm nhiều bài viết và source mẫu nhé):

git clone https://github.com/tanthanhkid/serverless-aws-golang-face-collection-with-aws-rekognition.git

Đầu tiên chúng ta xem file serverless.yml để xem các thành phần mà source Serverless này sẽ tạo trên account AWS của chúng ta.

serverless.yml

Đoạn này nói cho chúng ta biết sourcecode này sẽ deploy lên tài khoản AWS với runtime của Golang và version 1.x ở Region ap-southeast-1(Singapore). Ngoài ra, bên dưới còn cho chúng ta điền thêm một biến môi trường của Lambda, nơi chúng ta sẽ để connection string và để khi code chạy sẽ lấy connection string từ đây ra để kết nối vào DB Instance.

provider: name: aws runtime: go1.x region: ap-southeast-1 environment: RDS_CONN_STRING: postgres://<username>:<password>@<db url> # các bạn thay thế connection string ở bước 6 phía trên vào đây nhé

Đoạn code bên dưới mình có bổ sung thêm phần bảo mật so với bài trước, Bởi vì API của chúng ta public internet, nên việc vô tình lộ URL và Request có thể dẫn tới bị tấn công từ các bên có chủ đích phá hoại. Hậu quả có thể xảy ra là dịch vụ của chúng ta bị dừng hoạt động hoặc quá tải, bill AWS tăng đột biến.

Cách xử lý là chúng ta phải có một x-api-key(được in ra trong console sau khi deploy serverless hoặc các bạn vào AWS Console để lấy) gắn vào header như sau:

image.png

plugins: - serverless-add-api-key custom: apiKeys: dev: - name: facecollection usagePlan: name: "facecollection" description: "Description of first plan" quota: limit: 100000 # ở đây mình cho 10k request/tháng, nếu vô tình client làm lộ key thì chỉ mất 10k request và chúng ta hoàn toàn có thể kiểm soát tình hình bằng nhiều cách phản ứng khác nhau, ví dụ disable và tạo key mới period: MONTH throttle: # cấu hình này cho phép chúng ta kiểm soát số lượng request được xử lý cùng lúc burstLimit: 100 rateLimit: 20 

Đến phần cuối cùng của file serverless.yml chúng ta sẽ phân tích đoạn code dùng để tạo AWS Lambda bằng Golang, sau đó code Golang sẽ gọi tiếp tới Amazon Rekognition và AWS S3, chúng ta có 2 API là index và search được mô tả như bên dưới.

 postindex: # API này dùng để đưa hình vào thư viện ảnh khuôn mặt handler: bin/postIndex # các bạn xem file MakeFile sẽ thấy code Go được build ra bin và chỗ này lấy file build và đẩy lên AWS package: include: - ./bin/postIndex events: - http: path: index # các bạn gọi vào thông qua path /insert method: post # HTTP Method là POST private: true # true để bật chức năng xác thực x-api-key trước khi xử lý tiếp postsearch: # API này dùng để tìm kiếm khuôn mặt trong thư viện ảnh bằng hình ảnh do người dùng truyền vào handler: bin/postSearch package: include: - ./bin/postSearch events: - http: path: search method: post private: true

Tiếp theo đến phần code chính, xử lý các tương tác với AWS SDK để sử dụng Amazon Rekognition và AWS S3

postIndex/postIndex.go

Đầu tiên ở API /index, chúng ta sẽ parse hình ảnh được upload lên bằng dạng Base64 và upload file hình này lên S3, vì Rekognition sẽ lấy hình từ S3 về đẩy vào kho hình khi mình phát lệnh cho nó.

# từ dòng 136 //parse image from base 64 and upload to S3 bucket decodedSignature, err := base64.StdEncoding.DecodeString(image) if err != nil { log.Fatalf("decode base64 failed, %v", err) } r := bytes.NewReader(decodedSignature) //create s3 input s3ObjectName := userName + ".jpg" s3Input := &s3.PutObjectInput{ Body: r, Bucket: &facesBucket, Key: &s3ObjectName, } //create new session sess, err := createSession() if err != nil { log.Fatalf("failed to create AWS session, %v", err) } s3 := s3.New(sess) //upload image file to s3 s3output, err := s3.PutObject(s3Input)

Sau đó, chúng ta sẽ phát lệnh cho Amazon Rekognition là index tấm hình khuôn mặt này, lưu ý hình up lên nên là đuôi jpg hoặc jpeg. Thỉnh thoảng up file png hoặc chất lượng quá kém thì bị Error lỗi invalid image format.

# từ dòng 168 //get image from S3 bucket and index with rekognition input := &rekognition.IndexFacesInput{ Image: &types.Image{ S3Object: &types.S3Object{ Bucket: &facesBucket, Name: &s3ObjectName, }, }, CollectionId: &collectionId, ExternalImageId: &userName, } output, err := client.IndexFaces(context.TODO(), input)

Vậy là xong, chúng ta chỉ việc gọi hàm indexFace() trong Handler của Lambda là kết thúc API này.

# từ dòng 85 // call AWS Rekognition to index face output, err := indexFace(bodyRequest.Data.UserName, bodyRequest.Data.Image)

postSearch/postSearch.go

Tiếp theo, khi khuôn mặt đã được lưu trữ trong collection, mình xây dựng tiếp API /search để tìm kiếm khuôn mặt bằng hình ảnh(bạn nghĩ tới ví dụ máy chấm công hoặc FaceID trên iphone là sẽ dễ hiểu).

Tương tự ở trên, đầu tiên chúng ta phải upload file ảnh lên S3 trước.

# từ dòng 129 //parse image from base 64 and upload to S3 bucket decodedSignature, err := base64.StdEncoding.DecodeString(image) if err != nil { log.Fatalf("decode base64 failed, %v", err) } r := bytes.NewReader(decodedSignature) //create s3 input s3ObjectName := uuid.NewString() + ".jpg" s3Input := &s3.PutObjectInput{ Body: r, Bucket: &facesBucket, Key: &s3ObjectName, } //create new session sess, err := createSession() if err != nil { log.Fatalf("failed to create AWS session, %v", err) } s3 := s3.New(sess) //upload image file to s3 s3output, err := s3.PutObject(s3Input)

Sau đó, chúng ta gọi Amazon Rekognition để truyền khuôn mặt này vào để xem có khuôn mặt nào trong collection trùng khớp không.

# từ dòng 161 client := rekognition.NewFromConfig(cfg) input := &rekognition.SearchFacesByImageInput{ Image: &types.Image{ S3Object: &types.S3Object{ Bucket: &facesBucket, Name: &s3ObjectName, }, }, CollectionId: &collectionId, } output, err := client.SearchFacesByImage(context.TODO(), input)

Chúng ta gọi hàm searchface() ở Handler của Lambda.

# từ dòng 80 ouput, err := searchface(bodyRequest.Data.Image) 

Tiếp theo đó tới phần build code và đẩy lên AWS. khi chạy lệnh make deploy thì MakeFile sẽ lần lượt chạy vào các folder và build source Go thành các gói và để trong folder /bin. Cuối cùng, chạy lệnh sls deploy để bắt đầu quá trình build và deploy lên AWS.

MakeFile

.PHONY: build clean deploy build: cd postIndex && env GOARCH=amd64 GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -o ../bin/postIndex ./postIndex.go && cd .. cd postSearch && env GOARCH=amd64 GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -o ../bin/postSearch ./postSearch.go && cd .. clean: rm -rf ./bin ./vendor Gopkg.lock deploy: clean build sls deploy --verbose

Chạy thôi nào!

Nếu các bạn sử dụng Ubuntu và MacOS thì chỉ cần chạy lệnh bên dưới ở ngoài root:

make deploy

Các bạn truy cập vào tài khoản AWS của mình, sau đó vào Cloudformation và chọn stack có tên bắt đầu bằng "goservice".

Vào tab Output để lấy API Endpoint.

image.png

Hãy thử nào dùng AI của chúng ta nào !

Đầu tiên mình sẽ lấy ảnh Mỹ Tâm để parse ra base64 bằng web này như bên dưới:

image.png

Sau đó gọi Postman như hình dưới: image.png

Tiếp, theo mình lặp lại với ảnh Hồ Ngọc Hà.

image.png

Gọi Postman như hình dưới: image.png

OK! Bây giờ thử lấy 1 tấm ảnh khác của Mỹ Tâm để truyền vào tìm kiếm xem AI tìm ra kết quả như thế nào nhé:

image.png

image.png

Như các bạn thấy, AI đã xác định được khuôn mặt trùng khớp trong thư viện ảnh. Các bạn hãy thử thêm với Hồ Ngọc Hà và kiểm chứng AI này thêm ở máy mình.

Chúc các bạn thành công !

Bình luận

Bài viết tương tự

- vừa được xem lúc

Các thuật toán cơ bản trong AI - Phân biệt Best First Search và Uniform Cost Search (UCS)

Nếu bạn từng đọc các thuật toán trong AI (Artificial Intelligence - Trí tuệ nhân tạo), rất có thể bạn từng nghe qua về các thuật toán tìm kiếm cơ bản: UCS (thuộc chiến lược tìm kiếm mù) và Best First Search (thuộc chiến lược tìm kiếm kinh nghiệm). Khác nhau rõ từ khâu phân loại rồi, thế nhưng hai th

0 0 169

- vừa được xem lúc

Con đường AI của tôi

Gần đây, khá nhiều bạn nhắn tin hỏi mình những câu hỏi đại loại như: có nên học AI, bắt đầu học AI như nào, làm sao tự học cho đúng, cho nhanh, học không bị nản, lộ trình học AI như nào... Sau nhiều lần trả lời, mình nghĩ rằng nên viết hẳn một bài để trả lời chi tiết hơn, cũng như để các bạn sau này

0 0 157

- vừa được xem lúc

[ChatterBot] Thư viện chatbot hay ho dành cho Python| phần 3

Trong bài trước mình đã trình bày về Training data cho chatbot và tiền xử lý dữ liệu. Trong phần này sẽ trình bày với các bạn về logic adapter.

0 0 62

- vừa được xem lúc

[Deep Learning] Kỹ thuật Dropout (Bỏ học) trong Deep Learning

. Trong bài viết này, mình xin phép giới thiệu về Dropout (Bỏ học) trong mạng Neural, sau đó là mình sẽ có 1 số đoạn code để xem Dropout ảnh hưởng thế nào đến hiệu suất của mạng Neural. 1.1. Dropout trong mạng Neural là gì.

0 0 69

- vừa được xem lúc

Kỹ thuật Dropout (Bỏ học) trong Deep Learning

Trong bài viết này, mình xin phép giới thiệu về Dropout (Bỏ học) trong mạng Neural, sau đó là mình sẽ có 1 số đoạn code để xem Dropout ảnh hưởng thế nào đến hiệu suất của mạng Neural. 1.

0 1 82

- vừa được xem lúc

Blockchain dưới con mắt làng Vũ Đại 4.0

Mở bài. Hey nhô các bạn, lại là mình đây .

0 0 51