Bắt đầu nhanh cho Android

Hướng dẫn này chỉ cho bạn cách tạo ứng dụng Android bằng TensorFlow Lite để phân tích nguồn cấp dữ liệu camera trực tiếp và xác định các đối tượng bằng mô hình máy học, sử dụng một lượng mã tối thiểu. Nếu bạn đang cập nhật một dự án hiện có, bạn có thể sử dụng mẫu mã làm tài liệu tham khảo và chuyển sang phần hướng dẫn sửa đổi dự án của mình .

Phát hiện đối tượng với học máy

Bản demo động phát hiện đối tượng Mô hình học máy trong hướng dẫn này thực hiện phát hiện đối tượng. Mô hình phát hiện đối tượng lấy dữ liệu hình ảnh ở một định dạng cụ thể, phân tích nó và cố gắng phân loại các mục trong hình ảnh như một trong một tập hợp các lớp đã biết mà nó được đào tạo để nhận ra. Tốc độ mà mô hình có thể xác định một đối tượng đã biết (được gọi là dự đoán hoặc suy luận đối tượng) thường được đo bằng mili giây. Trong thực tế, tốc độ suy luận thay đổi dựa trên phần cứng lưu trữ mô hình, kích thước dữ liệu đang được xử lý và kích thước của mô hình học máy.

Thiết lập và chạy ví dụ

Đối với phần đầu tiên của hướng dẫn này, hãy tải xuống mẫu từ GitHub và chạy nó bằng Android Studio . Các phần sau của hướng dẫn này khám phá các phần có liên quan của ví dụ mã, vì vậy bạn có thể áp dụng chúng cho các ứng dụng Android của riêng mình. Bạn cần cài đặt các phiên bản sau của các công cụ này:

  • Android Studio 4.2.2 trở lên
  • SDK Android phiên bản 31 trở lên

Lấy mã mẫu

Tạo một bản sao cục bộ của mã ví dụ. Bạn sẽ sử dụng mã này để tạo một dự án trong Android Studio và chạy ứng dụng mẫu.

Để sao chép và thiết lập mã ví dụ:

  1. Sao chép kho lưu trữ git
    git clone https://github.com/android/camera-samples.git
    
  2. Định cấu hình phiên bản git của bạn để sử dụng kiểm tra thưa thớt, vì vậy bạn chỉ có các tệp cho ứng dụng ví dụ phát hiện đối tượng:

    cd camera-samples
    git sparse-checkout init --cone
    git sparse-checkout set CameraXAdvanced
    

Nhập và chạy dự án

Tạo một dự án từ mã ví dụ đã tải xuống, xây dựng dự án và sau đó chạy nó.

Để nhập và xây dựng dự án mã mẫu:

  1. Khởi động Android Studio .
  2. Từ trang Chào mừng của Android Studio, chọn Nhập dự án hoặc chọn Tệp> Mới> Nhập dự án .
  3. Điều hướng đến thư mục mã ví dụ chứa tệp build.gradle ( .../android/camera-samples/CameraXAdvanced/build.gradle ) và chọn thư mục đó.

Nếu bạn chọn đúng thư mục, Android Studio sẽ tạo một dự án mới và xây dựng nó. Quá trình này có thể mất vài phút, tùy thuộc vào tốc độ máy tính của bạn và nếu bạn đã sử dụng Android Studio cho các dự án khác. Khi quá trình xây dựng hoàn tất, Android Studio hiển thị thông báo BUILD SUCCESSFUL trong bảng trạng thái Đầu ra bản dựng .

Tùy chọn: Để sửa lỗi bản dựng bằng cách cập nhật phiên bản plugin Android:

  1. Mở tệp build.gradle trong thư mục dự án.
  2. Thay đổi phiên bản công cụ Android như sau:

    // from:
    classpath 'com.android.tools.build:gradle:4.2.2'
    // to:
    classpath 'com.android.tools.build:gradle:4.1.2'
    
  3. Đồng bộ hóa dự án bằng cách chọn: File> Sync Project with Gradle Files .

Để chạy dự án:

  1. Từ Android Studio, chạy dự án bằng cách chọn Run> Run…CameraActivity .
  2. Chọn một thiết bị Android được đính kèm có camera để kiểm tra ứng dụng.

Các phần tiếp theo cho bạn thấy những sửa đổi bạn cần thực hiện đối với dự án hiện có của mình để thêm chức năng này vào ứng dụng của riêng bạn, sử dụng ứng dụng mẫu này làm điểm tham chiếu.

Thêm phụ thuộc dự án

Trong ứng dụng của riêng bạn, bạn phải thêm các phụ thuộc dự án cụ thể để chạy mô hình học máy TensorFlow Lite và truy cập các chức năng tiện ích chuyển đổi dữ liệu như hình ảnh sang định dạng dữ liệu tensor có thể được xử lý bởi mô hình bạn đang sử dụng.

Ứng dụng mẫu sử dụng một số thư viện TensorFlow Lite để cho phép thực thi mô hình học máy phát hiện đối tượng:

  • Thư viện chính của TensorFlow Lite - Cung cấp các lớp đầu vào dữ liệu cần thiết, thực thi mô hình học máy và kết quả đầu ra từ quá trình xử lý mô hình.
  • Thư viện hỗ trợ TensorFlow Lite - Thư viện này cung cấp một lớp trợ giúp để dịch hình ảnh từ máy ảnh thành đối tượng dữ liệu TensorImage có thể được xử lý bằng mô hình học máy.
  • Thư viện GPU TensorFlow Lite - Thư viện này cung cấp hỗ trợ để tăng tốc thực thi mô hình bằng cách sử dụng bộ xử lý GPU trên thiết bị, nếu chúng có sẵn.

Các hướng dẫn sau giải thích cách thêm các phụ thuộc dự án và mô-đun bắt buộc vào dự án ứng dụng Android của riêng bạn.

Để thêm các phụ thuộc mô-đun:

  1. Trong mô-đun sử dụng TensorFlow Lite, hãy cập nhật tệp build.gradle của mô-đun để bao gồm các phần phụ thuộc sau. Trong mã ví dụ, tệp này nằm ở đây: .../android/camera-samples/CameraXAdvanced/tflite/build.gradle ( tham chiếu mã )

    ...
    dependencies {
    ...
        // Tensorflow lite dependencies
        implementation 'org.tensorflow:tensorflow-lite:2.8.0'
        implementation 'org.tensorflow:tensorflow-lite-gpu:2.8.0'
        implementation 'org.tensorflow:tensorflow-lite-support:2.8.0'
    ...
    }
    
  2. Trong Android Studio, đồng bộ hóa các phần phụ thuộc của dự án bằng cách chọn: Tệp> Đồng bộ hóa Dự án với Tệp Gradle .

Khởi tạo trình thông dịch mô hình ML

Trong ứng dụng Android của mình, bạn phải khởi tạo trình thông dịch mô hình học máy TensorFlow Lite với các tham số trước khi chạy dự đoán với mô hình. Các tham số khởi tạo này phụ thuộc vào mô hình bạn đang sử dụng và có thể bao gồm các cài đặt như ngưỡng độ chính xác tối thiểu cho các dự đoán và nhãn cho các lớp đối tượng đã xác định.

Mô hình TensorFlow Lite bao gồm tệp .tflite chứa mã mô hình và thường bao gồm tệp nhãn chứa tên của các lớp mà mô hình dự đoán. Trong trường hợp phát hiện đối tượng, các lớp là các đối tượng như người, chó, mèo hoặc ô tô. Các mô hình thường được lưu trữ trong thư mục src/main/assets của mô-đun chính, như trong ví dụ mã:

  • CameraXAdvanced / tflite / src / main / asset / coco_ssd_mobilenet_v1_1.0_quant.tflite
  • CameraXAdvanced / tflite / src / main / asset / coco_ssd_mobilenet_v1_1.0_labels.txt

Để thuận tiện và dễ đọc mã, ví dụ khai báo một đối tượng đồng hành xác định cài đặt cho mô hình.

Để khởi tạo mô hình trong ứng dụng của bạn:

  1. Tạo một đối tượng đồng hành để xác định cài đặt cho mô hình: ( tham chiếu mã )

    companion object {
       private val TAG = CameraActivity::class.java.simpleName
    
       private const val ACCURACY_THRESHOLD = 0.5f
       private const val MODEL_PATH = "coco_ssd_mobilenet_v1_1.0_quant.tflite"
       private const val LABELS_PATH = "coco_ssd_mobilenet_v1_1.0_labels.txt"
    }
    
  2. Sử dụng cài đặt từ đối tượng này để tạo đối tượng Trình thông dịch TensorFlow Lite có chứa mô hình: ( tham chiếu mã )

    private val tflite by lazy {
       Interpreter(
           FileUtil.loadMappedFile(this, MODEL_PATH),
           Interpreter.Options().addDelegate(nnApiDelegate))
    }
    

Định cấu hình trình tăng tốc phần cứng

Khi khởi tạo mô hình TensorFlow Lite trong ứng dụng của mình, bạn có thể sử dụng các tính năng tăng tốc phần cứng để tăng tốc độ tính toán dự đoán của mô hình. Ví dụ mã ở trên sử dụng NNAPI Delegate để xử lý việc tăng tốc phần cứng của việc thực thi mô hình:

Interpreter.Options().addDelegate(nnApiDelegate)

Đại biểu của TensorFlow Lite là các mô-đun phần mềm giúp tăng tốc việc thực thi các mô hình học máy bằng cách sử dụng phần cứng xử lý chuyên dụng trên thiết bị di động, chẳng hạn như GPU, TPU hoặc DSP. Bạn nên sử dụng các đại diện để chạy các mô hình TensorFlow Lite, nhưng không bắt buộc.

Để biết thêm thông tin về cách sử dụng đại biểu với TensorFlow Lite, hãy xem Đại biểu TensorFlow Lite .

Cung cấp dữ liệu cho mô hình

Trong ứng dụng Android, mã của bạn cung cấp dữ liệu cho mô hình để diễn giải bằng cách chuyển đổi dữ liệu hiện có, chẳng hạn như hình ảnh thành định dạng dữ liệu Tensor mà mô hình của bạn có thể xử lý. Dữ liệu trong Tensor phải có kích thước hoặc hình dạng cụ thể phù hợp với định dạng dữ liệu được sử dụng để đào tạo mô hình.

Để xác định hình dạng tensor cần thiết cho một mô hình:

  • Sử dụng đối tượng Trình thông dịch được khởi tạo để xác định hình dạng của tensor được sử dụng bởi mô hình của bạn, như được hiển thị trong đoạn mã bên dưới: ( tham chiếu mã )

    private val tfInputSize by lazy {
       val inputIndex = 0
       val inputShape = tflite.getInputTensor(inputIndex).shape()
       Size(inputShape[2], inputShape[1]) // Order of axis is: {1, height, width, 3}
    }
    

Mô hình phát hiện đối tượng được sử dụng trong mã ví dụ mong đợi hình ảnh vuông có kích thước 300 x 300 pixel.

Trước khi bạn có thể cung cấp hình ảnh từ máy ảnh, ứng dụng của bạn phải lấy hình ảnh, làm cho hình ảnh phù hợp với kích thước mong đợi, điều chỉnh xoay và chuẩn hóa dữ liệu hình ảnh. Khi xử lý hình ảnh bằng mô hình TensorFlow Lite, bạn có thể sử dụng lớp ImageProcessor của Thư viện hỗ trợ TensorFlow Lite để xử lý việc xử lý trước dữ liệu này, như minh họa bên dưới.

Để chuyển đổi dữ liệu hình ảnh cho một mô hình:

  1. Sử dụng Bộ xử lý Hình ảnh Thư viện Hỗ trợ để tạo một đối tượng để chuyển đổi dữ liệu hình ảnh thành một định dạng mà mô hình của bạn có thể sử dụng để chạy các dự đoán: ( tham chiếu mã )

    private val tfImageProcessor by lazy {
       val cropSize = minOf(bitmapBuffer.width, bitmapBuffer.height)
       ImageProcessor.Builder()
           .add(ResizeWithCropOrPadOp(cropSize, cropSize))
           .add(ResizeOp(
               tfInputSize.height, tfInputSize.width, ResizeOp.ResizeMethod.NEAREST_NEIGHBOR))
           .add(Rot90Op(-imageRotationDegrees / 90))
           .add(NormalizeOp(0f, 1f))
           .build()
    }
    
  2. Sao chép dữ liệu hình ảnh từ hệ thống camera Android và chuẩn bị để phân tích với đối tượng ImageProcessor của bạn: ( tham chiếu mã )

    // Copy out RGB bits to the shared buffer
    image.use { bitmapBuffer.copyPixelsFromBuffer(image.planes[0].buffer)  }
    
    // Process the image in Tensorflow
    val tfImage =  tfImageProcessor.process(tfImageBuffer.apply { load(bitmapBuffer) })
    

Chạy dự đoán

Trong ứng dụng Android của bạn, sau khi bạn tạo đối tượng TensorImage với dữ liệu hình ảnh ở định dạng chính xác, bạn có thể chạy mô hình dựa trên dữ liệu đó để đưa ra dự đoán hoặc suy luận . Mã ví dụ cho hướng dẫn này sử dụng lớp ObjectDetectionHelper đóng gói mã này trong một phương thức predict() .

Để chạy dự đoán trên một tập hợp dữ liệu hình ảnh:

  1. Chạy dự đoán bằng cách chuyển dữ liệu hình ảnh đến chức năng dự đoán của bạn: ( tham chiếu mã )

    // Perform the object detection for the current frame
    val predictions = detector.predict(tfImage)
    
  2. Gọi phương thức chạy trên cá thể đối tượng tflite của bạn với dữ liệu hình ảnh để tạo dự đoán: ( tham chiếu mã )

    fun predict(image: TensorImage): List<ObjectPrediction> {
       tflite.runForMultipleInputsOutputs(arrayOf(image.buffer), outputBuffer)
       return predictions
    }
    

Đối tượng TensorFlow Lite Interpreter nhận dữ liệu này, chạy nó dựa trên mô hình và tạo ra một danh sách các dự đoán. Để mô hình xử lý dữ liệu liên tục, hãy sử dụng phương thức runForMultipleInputsOutputs() để các đối tượng Thông dịch viên không được tạo và sau đó bị hệ thống loại bỏ cho mỗi lần chạy dự đoán.

Xử lý đầu ra mô hình

Trong ứng dụng Android của bạn, sau khi bạn chạy dữ liệu hình ảnh dựa trên mô hình phát hiện đối tượng, nó sẽ tạo ra một danh sách các dự đoán mà mã ứng dụng của bạn phải xử lý bằng cách thực thi logic nghiệp vụ bổ sung, hiển thị kết quả cho người dùng hoặc thực hiện các hành động khác.

Đầu ra của bất kỳ mô hình TensorFlow Lite nhất định nào khác nhau về số lượng dự đoán mà nó tạo ra (một hoặc nhiều) và thông tin mô tả cho mỗi dự đoán. Trong trường hợp của một mô hình phát hiện đối tượng, các dự đoán thường bao gồm dữ liệu cho một hộp giới hạn cho biết vị trí một đối tượng được phát hiện trong hình ảnh. Trong mã ví dụ, dữ liệu trả về được định dạng dưới dạng danh sách các đối tượng ObjectPrediction , như được hiển thị bên dưới: ( tham chiếu mã )

val predictions get() = (0 until OBJECT_COUNT).map {
   ObjectPrediction(

       // The locations are an array of [0, 1] floats for [top, left, bottom, right]
       location = locations[0][it].let {
           RectF(it[1], it[0], it[3], it[2])
       },

       // SSD Mobilenet V1 Model assumes class 0 is background class
       // in label file and class labels start from 1 to number_of_classes + 1,
       // while outputClasses correspond to class index from 0 to number_of_classes
       label = labels[1 + labelIndices[0][it].toInt()],

       // Score is a single value of [0, 1]
       score = scores[0][it]
   )
}

Ảnh chụp màn hình phát hiện đối tượng Đối với mô hình được sử dụng trong ví dụ này, mỗi dự đoán bao gồm vị trí hộp giới hạn cho đối tượng, nhãn cho đối tượng và điểm dự đoán từ 0 đến 1 dưới dạng Dấu nổi thể hiện độ tin cậy của dự đoán, với 1 là xếp hạng độ tin cậy cao nhất . Nhìn chung, các dự đoán có điểm dưới 50% (0,5) được coi là bất phân thắng bại. Tuy nhiên, cách bạn xử lý các kết quả dự đoán có giá trị thấp là tùy thuộc vào bạn và nhu cầu của ứng dụng của bạn.

Khi mô hình đã trả về kết quả dự đoán, ứng dụng của bạn có thể hoạt động dựa trên dự đoán đó bằng cách trình bày kết quả cho người dùng của bạn hoặc thực hiện logic bổ sung. Trong trường hợp của mã ví dụ, ứng dụng vẽ một hộp giới hạn xung quanh đối tượng được xác định và hiển thị tên lớp trên màn hình. Xem lại CameraActivity.reportPrediction() trong mã ví dụ để biết chi tiết.

Bước tiếp theo