Tích hợp Mô hình tuỳ chỉnh vào Ứng dụng của bạn

1. Trước khi bắt đầu

Trong lớp học lập trình đầu tiên của loạt bài này, bạn đã tạo một ứng dụng rất đơn giản sử dụng tính năng Gắn nhãn hình ảnh để phân tích nội dung của một hình ảnh. Bạn đã truyền một bức ảnh hoa cúc cho ứng dụng đó và ứng dụng đã trả về thông tin rằng ứng dụng nhìn thấy những thứ như cánh hoa hoặc bầu trời. Sau đó, trong lớp học lập trình thứ hai, bạn đã chuyển sang Python để huấn luyện một mô hình mới, tuỳ chỉnh, có khả năng nhận dạng 5 loại hoa khác nhau.

Trong lớp học lập trình này, bạn sẽ cập nhật ứng dụng từ lớp học lập trình đầu tiên bằng mô hình từ lớp học lập trình thứ hai!

Bạn có thể lấy mã nguồn đầy đủ cho lớp học lập trình này bằng cách sao chép kho lưu trữ này. Bạn sẽ thấy các thư mục con cho Android và iOS. Mã của lớp học lập trình trước có dạng ImageClassifierStep1 nếu bạn muốn làm theo. Mã đã hoàn tất cho lớp học lập trình này có dạng ImageClassifierStep2.

Điều kiện tiên quyết

  • Bạn phải hoàn tất 2 lớp học lập trình đầu tiên trong lộ trình học tập này

Nội dung bạn sẽ tạo và học

  • Tích hợp một mô hình tuỳ chỉnh được huấn luyện trong lớp học lập trình trước vào một ứng dụng Android hoặc iOS

Bạn cần có

  • Android Studio, có tại developer.android.com/studio cho phần Android của lớp học lập trình
  • Xcode, có trên App Store của Apple, cho phần iOS của lớp học lập trình

2. Tải ứng dụng khởi đầu

Trước tiên, bạn sẽ cần ứng dụng từ lớp học lập trình Tạo ứng dụng Computer Vision đầu tiên trên Android hoặc iOS. Nếu bạn đã tham gia lớp học lập trình này, ứng dụng sẽ có tên là ImageClassifierStep1. Nếu không muốn tham gia lớp học lập trình này, bạn có thể sao chép phiên bản đã hoàn tất từ kho lưu trữ repo

Mở ứng dụng đó trong Android Studio, thực hiện mọi bản cập nhật cần thiết và khi ứng dụng đã sẵn sàng, hãy chạy ứng dụng để đảm bảo ứng dụng hoạt động. Bạn sẽ thấy như sau:

f3703d45d1332d1d.png

Đây là một ứng dụng khá sơ khai, nhưng chỉ với một chút mã, ứng dụng này đã thể hiện một số chức năng rất mạnh mẽ. Tuy nhiên, nếu muốn ứng dụng nhận dạng hoa này là hoa cúc chứ không chỉ là một bông hoa, bạn phải cập nhật ứng dụng để sử dụng mô hình tuỳ chỉnh từ lớp học lập trình Tạo mô hình tuỳ chỉnh cho trình phân loại hình ảnh.

3. Cập nhật build.gradle để sử dụng Mô hình Bộ công cụ học máy tuỳ chỉnh

  1. Sử dụng Android Studio, tìm tệp build.gradle ở cấp ứng dụng. Cách dễ nhất để thực hiện việc này là trong trình khám phá dự án. Đảm bảo bạn đã chọn Android ở trên cùng và bạn sẽ thấy một thư mục cho Gradle Scripts (Tập lệnh Gradle) ở dưới cùng.
  2. Mở tệp dành cho Module (Mô-đun), có tên ứng dụng của bạn, tiếp theo là ".app" như minh hoạ ở đây – (Module: ImageClassifierStep1.app):

8fe1d04b40610047.png

  1. Ở cuối tệp, hãy tìm chế độ cài đặt dependencies (phần phụ thuộc). Trong đó, bạn sẽ thấy dòng này:
implementation 'com.google.mlkit:image-labeling:17.0.1'

Số phiên bản có thể khác. Luôn tìm số phiên bản mới nhất trên trang web Bộ công cụ học máy tại: https://developers.google.com/ml-kit/vision/image-labeling/android

  1. Thay thế dòng này bằng tham chiếu thư viện gắn nhãn hình ảnh tuỳ chỉnh. Bạn có thể tìm thấy số phiên bản cho thư viện này tại: https://developers.google.com/ml-kit/vision/image-labeling/custom-models/android
implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
  1. Ngoài ra, bạn sẽ thêm một mô hình .tflite mà bạn đã tạo trong lớp học lập trình trước. Bạn không muốn mô hình này bị nén khi Android Studio biên dịch ứng dụng của bạn, vì vậy, hãy đảm bảo bạn sử dụng chế độ cài đặt này trong phần Android của cùng một tệp build.gradle:
aaptOptions{
    noCompress "tflite"
}

Đảm bảo rằng chế độ cài đặt này không nằm trong bất kỳ chế độ cài đặt nào khác. Chế độ cài đặt này phải được lồng trực tiếp bên dưới thẻ android. Ví dụ:

62d546bff11d2a50.png

4. Thêm mô hình TFLite

Trong lớp học lập trình trước, bạn đã tạo mô hình tuỳ chỉnh và tải mô hình đó xuống dưới dạng model.tflite.

Trong dự án của bạn, hãy tìm thư mục assets (tài sản) hiện chứa flower1.jpg. Sao chép mô hình vào thư mục đó như sau:

  1. Nhấp chuột phải vào thư mục Assets (Tài sản) trong Android Studio. Trong trình đơn mở ra, hãy chọn Reveal in Finder (Hiển thị trong Finder). ("Show in Explorer" (Hiển thị trong Explorer) trên Windows và "Show in Files" (Hiển thị trong Tệp) trên Linux.)

db30b47e419a326b.png

  1. Bạn sẽ được đưa đến thư mục trên hệ thống tệp. Sao chép tệp model.tflite vào thư mục đó, cùng với flower1.jpg.

36de0c51bec1c19e.png

Android Studio sẽ cập nhật để hiển thị cả hai tệp trong thư mục tài sản:

e9f4e9f394d9b357.png

Bây giờ, bạn đã sẵn sàng cập nhật mã.

5. Cập nhật mã cho mô hình tuỳ chỉnh

Bước đầu tiên là thêm một số mã để tải mô hình tuỳ chỉnh.

  1. Trong tệp MainActivity, hãy thêm nội dung sau vào onCreate, ngay bên dưới dòng có nội dung setContentView(R.layout.activity_main).

Thao tác này sẽ sử dụng LocalModel để tạo từ thành phần model.tflite. Nếu Android Studio báo lỗi bằng cách chuyển "LocalModel" thành màu đỏ, hãy nhấn ALT + Enter để nhập thư viện. Thao tác này sẽ thêm một lệnh nhập vào com.google.mlkit.common.model.LocalModel cho bạn.

val localModel = LocalModel.Builder()
        .setAssetFilePath("model.tflite")
        .build()

Trước đây, trong trình xử lý btn.setOnClickListener, bạn đã sử dụng mô hình mặc định. Mô hình này được thiết lập bằng mã sau:

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

Bạn sẽ thay thế mô hình đó để sử dụng mô hình tuỳ chỉnh.

  1. Thiết lập một đối tượng tuỳ chọn tuỳ chỉnh:
val options = CustomImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.7f)
        .setMaxResultCount(5)
        .build()

Thao tác này sẽ thay thế các tuỳ chọn mặc định bằng một tập hợp tuỳ chỉnh. Ngưỡng độ tin cậy đặt ra một giới hạn cho chất lượng của các dự đoán cần trả về. Nếu bạn xem lại mẫu ở đầu lớp học lập trình này, trong đó hình ảnh là một bông hoa cúc, bạn sẽ có 4 dự đoán, mỗi dự đoán có một giá trị bên cạnh, chẳng hạn như "Sky" (Bầu trời) là 0,7632.

Bạn có thể lọc hiệu quả các kết quả có chất lượng thấp hơn bằng cách sử dụng ngưỡng độ tin cậy cao. Ví dụ: nếu bạn đặt ngưỡng này thành 0,9, thì sẽ không có nhãn nào có mức độ ưu tiên thấp hơn ngưỡng đó được trả về. setMaxResultCount() rất hữu ích trong các mô hình có nhiều lớp, nhưng vì mô hình này chỉ có 5 lớp, nên bạn chỉ cần để nguyên là 5.

Bây giờ, bạn có các tuỳ chọn cho trình gắn nhãn, bạn có thể thay đổi quá trình tạo thực thể của trình gắn nhãn thành:

val labeler = ImageLabeling.getClient(options)

Phần còn lại của mã sẽ chạy mà không cần sửa đổi. Hãy dùng thử!

dd40c36c4edbb33.png

Ở đây, bạn có thể thấy rằng bông hoa này hiện đã được xác định là hoa cúc với xác suất là 0,959!

Giả sử bạn đã thêm một hình ảnh bông hoa thứ hai và chạy lại với hình ảnh đó:

8556a5fbea487842.png

Ứng dụng xác định đó là hoa hồng.

Bạn có thể thắc mắc tại sao ứng dụng lại nói là roses (hoa hồng) thay vì chỉ là "rose" (bông hoa hồng). Đó là vì trong tập dữ liệu, các nhãn được đặt theo tên thư mục và tiếc là tên thư mục đó hơi không nhất quán, đôi khi sử dụng số ít (như "daisy" (hoa cúc)) và đôi khi sử dụng số nhiều (như "roses" (hoa hồng)). Đừng nhầm lẫn điều này với việc mô hình cố gắng đếm số mục trong hình ảnh – mô hình này sơ khai hơn nhiều và chỉ có thể xác định các loại hoa!

6. Tải ứng dụng khởi đầu iOS

  1. Trước tiên, bạn sẽ cần ứng dụng từ lớp học lập trình đầu tiên. Nếu bạn đã tham gia lớp học lập trình này, ứng dụng sẽ có tên là ImageClassifierStep1. Nếu không muốn tham gia lớp học lập trình này, bạn có thể sao chép phiên bản đã hoàn tất từ kho lưu trữ. Xin lưu ý rằng các pod và .xcworkspace không có trong kho lưu trữ, vì vậy, trước khi tiếp tục bước tiếp theo, hãy nhớ chạy "pod install" từ cùng một thư mục với .xcproject.
  2. Mở ImageClassifierStep1.xcworkspace trong Xcode. Lưu ý rằng bạn nên sử dụng .xcworkspace chứ không phải .xcproject vì bạn đã gói Bộ công cụ học máy bằng các pod và không gian làm việc sẽ tải các pod này.

Trong phần còn lại của lớp học lập trình này, tôi sẽ chạy ứng dụng trong trình mô phỏng iPhone hỗ trợ các mục tiêu bản dựng từ lớp học lập trình. Nếu muốn sử dụng thiết bị của riêng mình, bạn có thể cần thay đổi mục tiêu bản dựng trong phần cài đặt dự án để phù hợp với phiên bản iOS.

Chạy ứng dụng và bạn sẽ thấy như sau:

9e151ed18f99fb98.png

Lưu ý các phân loại rất chung chung – cánh hoa, bông hoa, bầu trời. Mô hình bạn đã tạo trong lớp học lập trình trước được huấn luyện để phát hiện 5 loại hoa, bao gồm cả loại hoa này – hoa cúc.

Trong phần còn lại của lớp học lập trình này, bạn sẽ xem xét những gì cần thiết để nâng cấp ứng dụng bằng mô hình tuỳ chỉnh.

7. Sử dụng các pod Trình gắn nhãn hình ảnh Bộ công cụ học máy tuỳ chỉnh

Ứng dụng đầu tiên đã sử dụng một tệp pod để lấy các thư viện và mô hình Trình gắn nhãn hình ảnh Bộ công cụ học máy cơ sở. Bạn cần cập nhật tệp đó để sử dụng các thư viện gắn nhãn hình ảnh tuỳ chỉnh.

  1. Tìm tệp có tên là podfile trong thư mục dự án. Mở tệp đó và bạn sẽ thấy như sau:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. Thay đổi nội dung khai báo pod từ ImageLabeling thành ImageLabelingCustom, như sau:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabelingCustom'
end
  1. Sau khi hoàn tất, hãy sử dụng Terminal để chuyển đến thư mục chứa tệp pod (cũng như .xcworkspace) và chạy pod install.

bb5d78eb7c7ab975.png

Sau vài giây, các thư viện MLKitImageLabeling sẽ bị xoá và các thư viện tuỳ chỉnh sẽ được thêm vào. Bây giờ, bạn có thể mở .xcworkspace để chỉnh sửa mã.

8. Thêm mô hình TFLite vào Xcode

Trong lớp học lập trình trước, bạn đã tạo một mô hình tuỳ chỉnh và tải mô hình đó xuống dưới dạng model.tflite. Nếu bạn không có mô hình này, hãy quay lại và chạy lớp học lập trình đó hoặc xem mã colab tại đây. Nếu bạn không có quyền truy cập vào Google Colab, thì sổ tay có tại liên kết này

  1. Khi không gian làm việc đang mở trong Xcode, hãy kéo model.tflite vào dự án của bạn. Tệp này phải nằm trong cùng thư mục với các tệp còn lại của bạn, chẳng hạn như ViewController.swift hoặc Main.storyboard.
  2. Một hộp thoại sẽ bật lên với các tuỳ chọn để thêm tệp. Đảm bảo bạn đã chọn Add to Targets (Thêm vào mục tiêu), nếu không, mô hình sẽ không được gói cùng với ứng dụng khi ứng dụng được triển khai đến một thiết bị.

Lưu ý rằng mục "Add to Targets" (Thêm vào mục tiêu) sẽ có ImageClassifierStep1 nếu bạn bắt đầu từ đó và tiếp tục từng bước trong lớp học lập trình này hoặc ImageClassifierStep2 (như minh hoạ) nếu bạn chuyển thẳng đến mã đã hoàn tất.

5b6a7f40c73f0f1f.png

Thao tác này sẽ đảm bảo rằng bạn có thể tải mô hình. Bạn sẽ thấy cách thực hiện việc đó trong bước tiếp theo.

9. Cập nhật mã cho mô hình tuỳ chỉnh

  1. Mở tệp ViewController.swift. Bạn có thể thấy lỗi trên "import MLKitImageLabeling" ở đầu tệp. Điều này là do bạn đã xoá các thư viện gắn nhãn hình ảnh chung khi cập nhật tệp pod. Bạn có thể xoá dòng này và cập nhật bằng nội dung sau:
import MLKitVision
import MLKit
import MLKitImageLabelingCommon
import MLKitImageLabelingCustom

Bạn có thể dễ dàng đọc nhanh các dòng này và nghĩ rằng chúng đang lặp lại cùng một mã! Nhưng đó là "Common" (Chung) và "Custom" (Tuỳ chỉnh) ở cuối!

  1. Tiếp theo, bạn sẽ tải mô hình tuỳ chỉnh mà bạn đã thêm ở bước trước. Tìm hàm getLabels(). Bên dưới dòng có nội dung visionImage.orientation = image.imageOrientation, hãy thêm các dòng sau:
// Add this code to use a custom model
let localModelFilePath = Bundle.main.path(forResource: "model", ofType: "tflite")
let localModel = LocalModel(path: localModelFilePath!)
  1. Tìm mã để chỉ định các tuỳ chọn cho ImageLabeler chung. Có thể mã này đang báo lỗi vì các thư viện đó đã bị xoá:
let options = ImageLabelerOptions()

Thay thế mã đó bằng mã này để sử dụng CustomImageLabelerOptions và chỉ định mô hình cục bộ:

let options = CustomImageLabelerOptions(localModel: localModel)

...và thế là xong! Hãy thử chạy ứng dụng của bạn ngay! Khi bạn cố gắng phân loại hình ảnh, ứng dụng sẽ chính xác hơn và cho bạn biết rằng bạn đang nhìn vào một bông hoa cúc với xác suất cao!

238cd21748a97cf4.png

Giả sử bạn đã thêm một hình ảnh bông hoa thứ hai và chạy lại với hình ảnh đó:

75f3970a6b509bfe.png

Ứng dụng đã phát hiện thành công rằng hình ảnh này khớp với nhãn "roses" (hoa hồng)!

10. Xin chúc mừng!

Bây giờ, bạn đã chuyển từ việc tạo một ứng dụng sử dụng mô hình chung để nhận dạng nội dung của một hình ảnh sang việc tạo mô hình học máy của riêng bạn để nhận dạng những thứ cụ thể, chẳng hạn như hoa, rồi cập nhật ứng dụng để sử dụng mô hình tuỳ chỉnh.

Tất nhiên, ứng dụng kết quả rất hạn chế vì ứng dụng này dựa vào các thành phần hình ảnh được gói. Tuy nhiên, phần học máy hoạt động tốt. Ví dụ: bạn có thể sử dụng AndroidX Camera để lấy các khung hình từ nguồn cấp dữ liệu trực tiếp và phân loại các khung hình đó để xem điện thoại của bạn nhận dạng được những loại hoa nào!

Từ đây, khả năng là vô tận – và nếu bạn có dữ liệu của riêng mình cho một thứ gì đó khác ngoài hoa, thì bạn đã có nền tảng của những gì cần thiết để tạo một ứng dụng nhận dạng các dữ liệu đó bằng thị giác máy tính. Đây chỉ là một vài bước đầu tiên vào một thế giới rộng lớn hơn nhiều và hy vọng bạn đã thích thú khi thực hiện các bước này!