Xây dựng và triển khai mô hình phát hiện đối tượng tùy chỉnh bằng TensorFlow Lite (Android)

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

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách đào tạo một mô hình phát hiện đối tượng tùy chỉnh bằng một bộ hình ảnh đào tạo với TFLite Model Maker, sau đó triển khai mô hình của bạn sang một ứng dụng Android bằng Thư viện nhiệm vụ TFLite. Bạn sẽ:

  • Tạo một ứng dụng Android phát hiện thành phần trong hình ảnh các bữa ăn.
  • Tích hợp mô hình phát hiện đối tượng được đào tạo trước TFLite và xem giới hạn về nội dung mà mô hình có thể phát hiện.
  • Đào tạo một mô hình phát hiện đối tượng tùy chỉnh để phát hiện các thành phần/thành phần của một bữa ăn bằng một tập dữ liệu tùy chỉnh có tên là salad và TFLite Model Maker.
  • Triển khai mô hình tùy chỉnh cho ứng dụng Android bằng Thư viện tác vụ TFLite.

Cuối cùng, bạn sẽ tạo một nội dung tương tự như hình ảnh bên dưới:

b9705235366ae162.png

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

Lớp học lập trình này được thiết kế cho những nhà phát triển thiết bị di động có kinh nghiệm muốn tích lũy kinh nghiệm với công nghệ máy học. Bạn cần thông thạo:

  • Phát triển Android bằng Kotlin và Android Studio
  • Cú pháp Python cơ bản

Kiến thức bạn sẽ học được

  • Cách huấn luyện một mô hình phát hiện đối tượng tùy chỉnh bằng Trình tạo mô hình TFLite.
  • Cách triển khai mô hình phát hiện đối tượng TFLite bằng Thư viện tác vụ TFLite.

Bạn cần có

  • Phiên bản Android Studio phiên bản 4.2 trở lên gần đây
  • Trình mô phỏng Android Studio hoặc thiết bị Android thực
  • Mã mẫu
  • Kiến thức cơ bản về việc phát triển Android trong Kotlin

2. Phát hiện vật thể

Phát hiện đối tượng là một tập hợp các nhiệm vụ thị giác máy tính có thể phát hiện và định vị đối tượng trong hình ảnh kỹ thuật số. Với một hình ảnh hoặc luồng video, mô hình phát hiện đối tượng có thể xác định một nhóm đối tượng đã biết có thể xuất hiện và cung cấp thông tin về vị trí của đối tượng trong hình ảnh.

TensorFlow cung cấp các mô hình được đào tạo trước, được tối ưu hóa cho thiết bị di động. Các mô hình này có thể phát hiện những đối tượng phổ biến như ô tô, màu cam, v.v. Bạn có thể tích hợp các mô hình được đào tạo trước này trong ứng dụng dành cho thiết bị di động của mình chỉ bằng vài dòng mã. Tuy nhiên, bạn có thể muốn hoặc cần phát hiện các đối tượng trong các danh mục đặc biệt hơn hoặc độc đáo hơn. Điều đó đòi hỏi bạn phải thu thập các hình ảnh huấn luyện của riêng mình, sau đó đào tạo và triển khai mô hình phát hiện đối tượng của riêng bạn.

TensorFlow Lite

TensorFlow Lite là một thư viện công nghệ máy học trên nhiều nền tảng, được tối ưu hóa để chạy các mô hình máy học trên các thiết bị biên, bao gồm cả thiết bị di động Android và iOS.

TensorFlow Lite thực sự là công cụ cốt lõi được dùng trong Bộ công cụ máy học để chạy các mô hình máy học. Có hai thành phần trong hệ sinh thái TensorFlow Lite giúp bạn dễ dàng đào tạo và triển khai các mô hình máy học trên thiết bị di động:

  • Model Maker là một thư viện Python giúp bạn dễ dàng đào tạo các mô hình TensorFlow Lite bằng dữ liệu của riêng bạn, chỉ với một vài dòng mã mà không cần phải có kiến thức chuyên môn về máy học.
  • Thư viện việc cần làm là một thư viện trên nhiều nền tảng giúp bạn dễ dàng triển khai các mô hình TensorFlow Lite chỉ bằng vài dòng mã trong ứng dụng dành cho thiết bị di động.

Lớp học lập trình này tập trung vào TFLite. Các khái niệm và khối mã không liên quan đến TFLite và phát hiện đối tượng sẽ không được giải thích và cung cấp cho bạn để bạn chỉ cần sao chép và dán.

3. Bắt đầu thiết lập

Tải mã nguồn xuống

Nhấp vào đường liên kết sau đây để tải toàn bộ mã nguồn cho lớp học lập trình này:

Giải nén tệp zip đã tải xuống. Thao tác này sẽ giải nén thư mục gốc (odml-pathways-main) chứa tất cả tài nguyên mà bạn cần. Đối với lớp học lập trình này, bạn sẽ chỉ cần các nguồn trong thư mục con object-detection/codelab2/android.

Thư mục con android trong kho lưu trữ object-detection/codelab2/android chứa hai thư mục:

  • android_studio_folder.pngbắt đầu – Bắt đầu bằng mã mà bạn xây dựng dựa trên lớp học lập trình này.
  • android_studio_folder.pngfinal – Mã hoàn tất cho ứng dụng mẫu đã hoàn tất.

Nhập ứng dụng dành cho người mới bắt đầu

Hãy bắt đầu bằng cách nhập ứng dụng dành cho người mới bắt đầu vào Android Studio.

  1. Mở Android Studio và chọn Nhập dự án (Gradle, Eclipse ADT, v.v.)
  2. Mở thư mục starter từ mã nguồn mà bạn đã tải xuống trước đó.

7c0f27882a2698ac.png

Để đảm bảo tất cả các phần phụ thuộc đều có sẵn cho ứng dụng của bạn, bạn nên đồng bộ hóa dự án với các tệp gradle khi quá trình nhập hoàn tất.

  1. Chọn Đồng bộ hóa dự án với Tệp Gradle ( b451ab2d04d835f9.png) từ thanh công cụ Android Studio. Nhập start/app/build.gradle

Chạy ứng dụng dành cho người mới bắt đầu

Sau khi nhập dự án vào Android Studio, bạn có thể chạy ứng dụng lần đầu tiên.

Kết nối thiết bị Android qua USB với máy tính hoặc bắt đầu trình mô phỏng Android Studio,rồi nhấp vào Chạy ( tức thì.png) trên thanh công cụ Android Studio.

4. Tìm hiểu ứng dụng khởi động

Để giữ cho lớp học lập trình này đơn giản và tập trung vào các bit máy học, ứng dụng dành cho người mới bắt đầu chứa một số mã nguyên mẫu thực hiện được một vài việc dành cho bạn:

  • Ứng dụng này có thể chụp ảnh bằng máy ảnh của thiết bị.
  • Ứng dụng này chứa một số ảnh thương mại để bạn dùng thử tính năng phát hiện đối tượng trên trình mô phỏng Android.
  • Phương thức này có một phương thức thuận tiện để vẽ kết quả phát hiện đối tượng trên bitmap đầu vào.

Bạn hầu như sẽ tương tác với các phương pháp này trong khung ứng dụng:

  • fun runObjectDetection(bitmap: Bitmap) Phương thức này được gọi khi bạn chọn một hình ảnh đặt trước hoặc chụp ảnh. bitmap là hình ảnh đầu vào để phát hiện đối tượng. Sau này trong lớp học lập trình này, bạn sẽ thêm mã phát hiện đối tượng vào phương thức này.
  • data class DetectionResult(val boundingBoxes: Rect, val text: String) Đây là lớp dữ liệu biểu thị kết quả phát hiện đối tượng cho hình ảnh trực quan. boundingBoxes là hình chữ nhật nơi đối tượng tìm thấy và text là chuỗi kết quả phát hiện sẽ hiển thị cùng với hộp giới hạn của đối tượng\39;.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<DetectionResult>): Bitmap Phương thức này vẽ các kết quả phát hiện đối tượng trong detectionResults trên dữ liệu đầu vào bitmap và trả về bản sao đã sửa đổi của đối tượng đó.

Sau đây là ví dụ về dữ liệu đầu ra của phương thức hữu ích drawDetectionResult.

f6b1e6dad726e129.png

5. Thêm tính năng phát hiện đối tượng trên thiết bị

Bây giờ bạn sẽ xây dựng một nguyên mẫu bằng cách tích hợp một mô hình TFLite được đào tạo trước có thể phát hiện các đối tượng phổ biến vào ứng dụng dành cho người mới bắt đầu.

Tải mô hình phát hiện đối tượng TFLite đã đào tạo trước xuống

Bạn có thể sử dụng một số mô hình trình phát hiện đối tượng trên TensorFlow Hub. Đối với lớp học lập trình này, bạn sẽ tải mô hình Đối tượng hiệu quả đối tượng Det-Lite xuống, được đào tạo trên tập dữ liệu COCO 2017, được tối ưu hóa cho TFLite và được thiết kế để hoạt động với CPU trên thiết bị di động, GPU và EdgeTPU.

Tiếp theo, hãy sử dụng Thư viện tác vụ TFLite để tích hợp mô hình TFLite đã đào tạo trước vào ứng dụng dành cho người mới bắt đầu của bạn. Thư viện công việc TFLite giúp bạn dễ dàng tích hợp các mô hình máy học được tối ưu hóa cho thiết bị di động vào một ứng dụng dành cho thiết bị di động. Thư viện này hỗ trợ nhiều trường hợp sử dụng máy học phổ biến, bao gồm cả phát hiện đối tượng, phân loại hình ảnh và phân loại văn bản. Bạn có thể tải mô hình TFLite và chạy mô hình đó chỉ bằng một vài dòng mã.

Thêm mô hình vào ứng dụng dành cho người mới bắt đầu

  1. Sao chép mô hình mà bạn vừa tải xuống thư mục assets của ứng dụng dành cho người mới bắt đầu. Bạn có thể tìm thấy thư mục này trong bảng điều hướng Dự án trong Android Studio.

c2609599b7d22641.png

  1. Đặt tên model.tflite cho tệp.

c83e9397177c4561.png

Cập nhật các phần phụ thuộc của Thư viện tác vụ Gradle

Hãy chuyển đến tệp app/build.gradle và thêm dòng này vào cấu hình dependencies:

implementation 'org.tensorflow:tensorflow-lite-task-vision:0.3.1'

Đồng bộ hóa dự án của bạn với các tệp gradle

Để đảm bảo rằng tất cả các phần phụ thuộc đều có sẵn cho ứng dụng của bạn, bạn nên đồng bộ hóa dự án của mình với các tệp gradle tại thời điểm này. Chọn Đồng bộ hóa dự án với Tệp Gradle ( b451ab2d04d835f9.png) từ thanh công cụ Android Studio.

(Nếu nút này bị tắt, hãy nhớ chỉ nhập điều kiện khởi động/ứng dụng/build.gradle, chứ không phải toàn bộ kho lưu trữ.)

Thiết lập và chạy tính năng phát hiện đối tượng trên thiết bị trên hình ảnh

Chỉ có 3 bước đơn giản với 3 API để tải và chạy mô hình phát hiện đối tượng:

  • chuẩn bị hình ảnh/luồng: TensorImage
  • tạo đối tượng trình phát hiện: ObjectDetector
  • kết nối 2 đối tượng ở trên: detect(image)

Bạn thực hiện các bước này bên trong hàm runObjectDetection(bitmap: Bitmap)trong tệp MainActivity.kt.

/**
* TFLite Object Detection Function
*/
private fun runObjectDetection(bitmap: Bitmap) {
    //TODO: Add object detection code here
}

Hiện tại, hàm đang trống. Hãy chuyển sang các bước sau để triển khai trình phát hiện đối tượng TFLite. Trong quá trình thực hiện, Android Studio sẽ nhắc bạn thêm các dữ liệu nhập cần thiết:

  • org.tensorflow.lite.support.image.TensorImage
  • org.tensorflow.lite.task.vision.detector.ObjectDetector

Tạo đối tượng hình ảnh

Những hình ảnh bạn sẽ sử dụng cho lớp học lập trình này sẽ lấy từ máy ảnh trên thiết bị hoặc hình ảnh đặt sẵn mà bạn chọn trên giao diện người dùng của ứng dụng. Hình ảnh đầu vào được giải mã thành định dạng Bitmap và chuyển vào phương thức runObjectDetection.

TFLite cung cấp một API đơn giản để tạo TensorImage từ Bitmap. Thêm mã bên dưới vào đầu runObjectDetection(bitmap:Bitmap):

// Step 1: create TFLite's TensorImage object
val image = TensorImage.fromBitmap(bitmap)

Tạo thực thể của Trình phát hiện

Thư viện nhiệm vụ TFLite tuân theo Mẫu thiết kế trình tạo. Bạn chuyển cấu hình cho trình tạo, sau đó lấy trình phát hiện từ cấu hình đó. Có một số tùy chọn để định cấu hình, bao gồm cả những tùy chọn để điều chỉnh độ nhạy của trình phát hiện đối tượng:

  • kết quả tối đa (số lượng đối tượng tối đa mà mô hình sẽ phát hiện)
  • ngưỡng điểm số (mức độ tin cậy của trình phát hiện đối tượng để trả về đối tượng được phát hiện)
  • danh sách cho phép/từ chối nhãn (cho phép/từ chối các đối tượng trong một danh sách được xác định trước)

Khởi tạo phiên bản trình phát hiện đối tượng bằng cách chỉ định tên tệp mô hình TFLite và tùy chọn cấu hình:

// Step 2: Initialize the detector object
val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setMaxResults(5)
    .setScoreThreshold(0.5f)
    .build()
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "model.tflite", // must be same as the filename in assets folder
    options
)

(Các) hình ảnh trong nguồn cấp dữ liệu đến trình phát hiện

Thêm mã sau vào fun runObjectDetection(bitmap:Bitmap). Thao tác này sẽ cung cấp hình ảnh của bạn cho trình phát hiện.

// Step 3: feed given image to the model and print the detection result
val results = detector.detect(image)

Sau khi hoàn tất, trình phát hiện trả về danh sách Detection, mỗi danh sách chứa thông tin về một đối tượng mà mô hình đã tìm thấy trong hình ảnh. Mỗi đối tượng được mô tả bằng:

  • boundingBox: hình chữ nhật khai báo sự hiện diện của một đối tượng và vị trí của đối tượng đó trong hình ảnh
  • categories: loại đối tượng và mức độ tin cậy của mô hình đối với kết quả phát hiện. Mô hình này trả về nhiều danh mục và mô hình tự tin nhất là hạng mục đầu tiên.
  • label: tên của danh mục đối tượng.
  • classificationConfidence: số thực nằm trong khoảng từ 0 đến 1, trong đó 1,0 biểu thị 100%

Thêm mã sau vào fun runObjectDetection(bitmap:Bitmap). Thao tác này sẽ gọi một phương thức để in kết quả phát hiện đối tượng vào Logcat.

// Step 4: Parse the detection result and show it
debugPrint(results)

Sau đó, thêm phương thức debugPrint() này vào lớp MainActivity:

private fun debugPrint(results : List<Detection>) {
    for ((i, obj) in results.withIndex()) {
        val box = obj.boundingBox

        Log.d(TAG, "Detected object: ${i} ")
        Log.d(TAG, "  boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")

        for ((j, category) in obj.categories.withIndex()) {
            Log.d(TAG, "    Label $j: ${category.label}")
            val confidence: Int = category.score.times(100).toInt()
            Log.d(TAG, "    Confidence: ${confidence}%")
        }
    }
} 

Bây giờ, trình phát hiện đối tượng của bạn đã sẵn sàng! Biên dịch và chạy ứng dụng bằng cách nhấp vào Chạy (tức thì.png) trong thanh công cụ Android Studio. Sau khi ứng dụng xuất hiện trên thiết bị, hãy nhấn vào bất kỳ hình ảnh đặt trước nào để khởi động trình phát hiện vật thể. Sau đó, xem cửa sổ Logcat*(* 16bd6ea224cf8cf1.png.*)* bên trong IDE và bạn sẽ thấy nội dung tương tự như sau:

D/TFLite-ODT: Detected object: 0 
D/TFLite-ODT:   boundingBox: (0.0, 15.0) - (2223.0,1645.0)
D/TFLite-ODT:     Label 0: dining table
D/TFLite-ODT:     Confidence: 77%
D/TFLite-ODT: Detected object: 1 
D/TFLite-ODT:   boundingBox: (702.0, 3.0) - (1234.0,797.0)
D/TFLite-ODT:     Label 0: cup
D/TFLite-ODT:     Confidence: 69%

Thông báo này cho bạn biết rằng trình phát hiện thấy 2 đối tượng. Sự kiện đầu tiên là:

  • Một đối tượng nằm trong hình chữ nhật của (0, 15) - (2223, 1645)
  • Nhãn là bảng ăn
  • Mô hình này chắc chắn rằng kết quả đầu tiên là bảng ăn (77%)

Về mặt kỹ thuật là tất cả những gì bạn cần để khiến Thư viện việc cần làm của TFLite hoạt động: bạn đã hoàn thành mọi việc vào lúc này! Chúc mừng bạn!

Tuy nhiên, về phía giao diện người dùng, bạn vẫn đang ở điểm bắt đầu. Bây giờ, bạn phải sử dụng các kết quả đã phát hiện được trên giao diện người dùng bằng cách xử lý sau các kết quả đã phát hiện.

6. Vẽ kết quả phát hiện trên hình ảnh nhập vào

Trong các bước trước, bạn đã in kết quả phát hiện thành logcat: đơn giản và nhanh chóng. Trong bước này, bạn sẽ sử dụng phương thức tiện ích đã được triển khai cho bạn trong ứng dụng dành cho người mới bắt đầu, để:

  • vẽ một ô giới hạn trên hình ảnh
  • vẽ tên danh mục và tỷ lệ phần trăm độ tin cậy trong hộp giới hạn
  1. Thay thế lệnh gọi debugPrint(results) bằng đoạn mã sau:
val resultToDisplay = results.map {
    // Get the top-1 category and craft the display text
    val category = it.categories.first()
    val text = "${category.label}, ${category.score.times(100).toInt()}%"

    // Create a data object to display the detection result
    DetectionResult(it.boundingBox, text)
}
// Draw the detection result on the bitmap and show it.
val imgWithResult = drawDetectionResult(bitmap, resultToDisplay)
runOnUiThread {
    inputImageView.setImageBitmap(imgWithResult)
}
  1. Giờ hãy nhấp vào Chạy ( tức thì.png) trong thanh công cụ Android Studio.
  2. Sau khi tải, hãy nhấn vào một trong các hình ảnh đặt trước để xem kết quả phát hiện.

Bạn muốn dùng thử ảnh của riêng mình? Nhấn vào nút Chụp ảnh và chụp một số ảnh của các đối tượng xung quanh bạn.

8b024362b15096a6.png

7. Đào tạo một mô hình phát hiện đối tượng tùy chỉnh

Ở bước trước, bạn đã tích hợp mô hình phát hiện đối tượng TFLite đã được đào tạo trước vào ứng dụng Android và tự phát hiện rằng mô hình này có thể phát hiện các vật thể phổ biến (chẳng hạn như bát hoặc bàn ăn) trong hình ảnh mẫu. Tuy nhiên, mục tiêu của bạn là phát hiện các thành phần của món ăn trong hình ảnh, vì vậy, tính năng phát hiện vật thể nói chung không phù hợp với trường hợp sử dụng của bạn. Bạn muốn đào tạo một mô hình phát hiện đối tượng tùy chỉnh bằng một tập dữ liệu đào tạo có các thành phần mà chúng tôi muốn phát hiện.

Đây là một tập dữ liệu chứa các hình ảnh và nhãn mà bạn có thể dùng để thực hành đào tạo mô hình tùy chỉnh của riêng mình. Tệp này được tạo bằng cách sử dụng hình ảnh từ Tập dữ liệu hình ảnh mở phiên bản 4.

Colaboratory

Tiếp theo, hãy truy cập Google Colab để đào tạo mô hình tùy chỉnh.

Bạn sẽ mất khoảng 30 phút để đào tạo mô hình tùy chỉnh.

Nếu đang vội, bạn có thể tải xuống một mô hình mà chúng tôi đã đào tạo trước cho bạn trong tập dữ liệu đã cung cấp và tiếp tục bước tiếp theo.

8. Tích hợp mô hình TFLite tùy chỉnh vào ứng dụng Android

Giờ đây, bạn đã đào tạo một mô hình phát hiện salad, tích hợp mô hình đó và biến ứng dụng của bạn từ một trình phát hiện đối tượng thông thường thành một trình phát hiện salad.

  1. Sao chép mô hình TFLite salad vào thư mục assets. Đặt tên cho mô hình mới là salad.tflite.

91e8d37c4f78eddb.png

  1. Mở tệp MainActivity.kt và tìm mã khởi chạy ObjectDetector.
  2. Thay thế mô hình efficiencyDet-Lite (model.tflite) bằng mô hình salad (salad.tflite)
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "salad.tflite", // must be same as the filename in assets folder
    options
)
  1. Nhấp vào Chạy (tức thì.png) trong thanh công cụ Android Studio để chạy lại ứng dụng bằng mô hình mới. Như thế đấy! Ứng dụng này hiện có thể nhận dạng phô mai, salad, đồ nướng.

b9705235366ae162.png

9. Xin chúc mừng!

Bạn đã dùng TFLite để đào tạo một mô hình tùy chỉnh và thêm các tính năng Phát hiện đối tượng vào ứng dụng của bạn. Đó là tất cả những gì bạn cần làm để thiết lập và chạy mô hình này!

Những điều chúng tôi đã đề cập

  • Cách tìm các mô hình phát hiện đối tượng TFLite được đào tạo trước trên TensorFlow Hub
  • Cách tích hợp các mô hình phát hiện phản đối vào ứng dụng Android bằng cách sử dụng Thư viện nhiệm vụ TFLite
  • Cách huấn luyện mô hình phát hiện đối tượng tùy chỉnh bằng Trình tạo mô hình TFLite

Bước tiếp theo

  • Sử dụng Firebase để cải thiện việc triển khai mô hình TFLite
  • Thu thập dữ liệu đào tạo để đào tạo mô hình của riêng bạn
  • Áp dụng tính năng phát hiện đối tượng trong ứng dụng Android của riêng bạn

Tìm hiểu thêm