Krótkie wprowadzenie do Androida

Ten samouczek pokazuje, jak zbudować aplikację na Androida przy użyciu TensorFlow Lite, aby analizować obraz z kamery na żywo i identyfikować obiekty przy użyciu modelu uczenia maszynowego przy użyciu minimalnej ilości kodu. Jeśli aktualizujesz istniejący projekt, możesz użyć przykładowego kodu jako odniesienia i przejść do instrukcji dotyczących modyfikowania projektu .

Wykrywanie obiektów za pomocą uczenia maszynowego

Animowane demo wykrywania obiektów Model uczenia maszynowego w tym samouczku wykonuje wykrywanie obiektów. Model wykrywania obiektów pobiera dane obrazu w określonym formacie, analizuje je i próbuje kategoryzować elementy obrazu jako jedną ze zbioru znanych klas, w rozpoznawaniu których został nauczony. Szybkość, z jaką model może zidentyfikować znany obiekt (tzw. przewidywanie obiektu lub wnioskowanie ) jest zwykle mierzona w milisekundach. W praktyce szybkość wnioskowania różni się w zależności od sprzętu obsługującego model, rozmiaru przetwarzanych danych oraz rozmiaru modelu uczenia maszynowego.

Przykład konfiguracji i uruchomienia

W pierwszej części tego samouczka pobierz próbkę z GitHub i uruchom ją za pomocą Android Studio . W poniższych sekcjach tego samouczka omówiono odpowiednie sekcje przykładowego kodu, dzięki czemu można je zastosować do własnych aplikacji na Androida. Musisz zainstalować następujące wersje tych narzędzi:

  • Android Studio 4.2.2 lub nowszy
  • Android SDK w wersji 31 ​​lub nowszej

Pobierz przykładowy kod

Utwórz lokalną kopię przykładowego kodu. Użyjesz tego kodu, aby utworzyć projekt w Android Studio i uruchomić przykładową aplikację.

Aby sklonować i skonfigurować przykładowy kod:

  1. Sklonuj repozytorium git
    git clone https://github.com/android/camera-samples.git
    
  2. Skonfiguruj swoją instancję git tak, aby używała sparse checkout, aby mieć tylko pliki dla przykładowej aplikacji do wykrywania obiektów:

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

Zaimportuj i uruchom projekt

Utwórz projekt z pobranego przykładowego kodu, skompiluj projekt, a następnie uruchom go.

Aby zaimportować i zbudować przykładowy projekt kodu:

  1. Uruchom Android Studio .
  2. Na stronie powitalnej Android Studio wybierz Importuj projekt lub wybierz Plik > Nowy > Importuj projekt .
  3. Przejdź do przykładowego katalogu kodu zawierającego plik build.gradle ( .../android/camera-samples/CameraXAdvanced/build.gradle ) i wybierz ten katalog.

Jeśli wybierzesz właściwy katalog, Android Studio utworzy nowy projekt i zbuduje go. Ten proces może potrwać kilka minut, w zależności od szybkości komputera i tego, czy używałeś Android Studio do innych projektów. Po zakończeniu kompilacji Android Studio wyświetla komunikat BUILD SUCCESSFUL w panelu stanu Build Output .

Opcjonalnie: aby naprawić błędy kompilacji, aktualizując wersję wtyczki Androida:

  1. Otwórz plik build.gradle w katalogu projektu.
  2. Zmień wersję narzędzi Androida w następujący sposób:

    // from:
    classpath 'com.android.tools.build:gradle:4.2.2'
    // to:
    classpath 'com.android.tools.build:gradle:4.1.2'
    
  3. Zsynchronizuj projekt, wybierając: Plik > Synchronizuj projekt z plikami Gradle .

Aby uruchomić projekt:

  1. W Android Studio uruchom projekt, wybierając opcję Uruchom > Uruchom… i CameraActivity .
  2. Wybierz podłączone urządzenie z systemem Android z aparatem, aby przetestować aplikację.

W następnych sekcjach przedstawiono modyfikacje, które należy wprowadzić w istniejącym projekcie, aby dodać tę funkcję do własnej aplikacji, używając tej przykładowej aplikacji jako punktu odniesienia.

Dodaj zależności projektu

We własnej aplikacji musisz dodać określone zależności projektu, aby uruchomić modele uczenia maszynowego TensorFlow Lite i uzyskać dostęp do funkcji narzędziowych, które konwertują dane, takie jak obrazy, na format danych tensor, który może być przetwarzany przez używany model.

Przykładowa aplikacja wykorzystuje kilka bibliotek TensorFlow Lite, aby umożliwić wykonanie modelu uczenia maszynowego wykrywania obiektów:

  • Biblioteka główna TensorFlow Lite — zapewnia wymagane klasy wprowadzania danych, wykonanie modelu uczenia maszynowego i wyniki wyjściowe z przetwarzania modelu.
  • Biblioteka TensorFlow Lite Support — ta biblioteka zapewnia klasę pomocniczą do tłumaczenia obrazów z kamery na obiekt danych TensorImage , który może być przetwarzany przez model uczenia maszynowego.
  • Biblioteka TensorFlow Lite GPU — ta biblioteka zapewnia obsługę przyspieszania wykonywania modeli przy użyciu procesorów GPU na urządzeniu, jeśli są one dostępne.

Poniższe instrukcje wyjaśniają, jak dodać wymagane zależności projektu i modułu do własnego projektu aplikacji dla systemu Android.

Aby dodać zależności modułu:

  1. W module, który używa TensorFlow Lite, zaktualizuj plik build.gradle modułu, aby uwzględnić następujące zależności. W przykładowym kodzie ten plik znajduje się tutaj: .../android/camera-samples/CameraXAdvanced/tflite/build.gradle ( kod referencyjny )

    ...
    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. W Android Studio zsynchronizuj zależności projektu, wybierając: Plik > Synchronizuj projekt z plikami Gradle .

Zainicjuj interpreter modelu ML

W aplikacji na Androida musisz zainicjować interpreter modelu uczenia maszynowego TensorFlow Lite z parametrami przed uruchomieniem prognoz z modelem. Te parametry inicjalizacji zależą od używanego modelu i mogą obejmować ustawienia, takie jak minimalne progi dokładności prognoz i etykiety dla zidentyfikowanych klas obiektów.

Model TensorFlow Lite zawiera plik .tflite zawierający kod modelu i często zawiera plik etykiet zawierający nazwy klas przewidywanych przez model. W przypadku wykrywania obiektów klasami są obiekty takie jak osoba, pies, kot czy samochód. Modele są zazwyczaj przechowywane w katalogu src/main/assets modułu podstawowego, tak jak w przykładzie kodu:

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

Dla wygody i czytelności kodu przykład deklaruje obiekt towarzyszący, który definiuje ustawienia modelu.

Aby zainicjować model w swojej aplikacji:

  1. Utwórz obiekt towarzyszący, aby zdefiniować ustawienia modelu: ( odniesienie do kodu )

    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. Użyj ustawień z tego obiektu, aby skonstruować obiekt interpretera TensorFlow Lite, który zawiera model: ( kod referencyjny )

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

Skonfiguruj akcelerator sprzętowy

Podczas inicjowania modelu TensorFlow Lite w aplikacji można użyć funkcji akceleracji sprzętowej, aby przyspieszyć obliczenia predykcyjne modelu. Powyższy przykład kodu używa delegata NNAPI do obsługi przyspieszenia sprzętowego wykonywania modelu:

Interpreter.Options().addDelegate(nnApiDelegate)

Delegaci TensorFlow Lite to moduły oprogramowania, które przyspieszają wykonywanie modeli uczenia maszynowego przy użyciu wyspecjalizowanego sprzętu przetwarzającego na urządzeniu mobilnym, takiego jak procesory GPU, TPU lub DSP. Korzystanie z delegatów do uruchamiania modeli TensorFlow Lite jest zalecane, ale nie jest wymagane.

Aby uzyskać więcej informacji na temat używania delegatów z TensorFlow Lite, zobacz delegatów TensorFlow Lite .

Podaj dane modelowi

W Twojej aplikacji na Androida Twój kod dostarcza dane do modelu do interpretacji, przekształcając istniejące dane, takie jak obrazy, na format danych Tensor , który może być przetwarzany przez Twój model. Dane w tensorze muszą mieć określone wymiary lub kształt, które pasują do formatu danych używanych do uczenia modelu.

Aby określić wymagany kształt tensora dla modelu:

  • Użyj zainicjowanego obiektu Interpreter , aby określić kształt tensora używanego przez model, jak pokazano w poniższym fragmencie kodu: ( kod referencyjny )

    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}
    }
    

Model wykrywania obiektów użyty w przykładowym kodzie oczekuje kwadratowych obrazów o rozmiarze 300 na 300 pikseli.

Zanim będzie można przesyłać obrazy z aparatu, aplikacja musi wykonać obraz, dostosować go do oczekiwanego rozmiaru, dostosować jego obrót i znormalizować dane obrazu. Podczas przetwarzania obrazów za pomocą modelu TensorFlow Lite można użyć klasy ImageProcessor biblioteki obsługi TensorFlow Lite, aby obsłużyć to wstępne przetwarzanie danych, jak pokazano poniżej.

Aby przekształcić dane obrazu dla modelu:

  1. Użyj narzędzia ImageProcessor biblioteki pomocy technicznej, aby utworzyć obiekt do przekształcania danych obrazu do formatu, którego model może używać do uruchamiania prognoz: ( odwołanie do kodu )

    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. Skopiuj dane obrazu z systemu kamery Android i przygotuj je do analizy za pomocą obiektu ImageProcessor : ( kod referencyjny )

    // 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) })
    

Uruchom prognozy

W aplikacji na Androida, po utworzeniu obiektu TensorImage z danymi obrazu w poprawnym formacie, możesz uruchomić model na podstawie tych danych, aby uzyskać prognozę lub wnioskowanie . Przykładowy kod tego samouczka używa klasy ObjectDetectionHelper , która hermetyzuje ten kod w metodzie predict() .

Aby uruchomić prognozę na zestawie danych obrazu:

  1. Uruchom prognozę, przekazując dane obrazu do funkcji prognozowania: ( odwołanie do kodu )

    // Perform the object detection for the current frame
    val predictions = detector.predict(tfImage)
    
  2. Wywołaj metodę run w instancji obiektu tflite z danymi obrazu, aby wygenerować prognozy: ( odwołanie do kodu )

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

Obiekt TensorFlow Lite Interpreter otrzymuje te dane, analizuje je w modelu i tworzy listę predykcji. W przypadku ciągłego przetwarzania danych przez model należy użyć metody runForMultipleInputsOutputs() , aby obiekty interpretera nie były tworzone, a następnie usuwane przez system dla każdego przebiegu prognozowania.

Wyjście modelu uchwytu

W aplikacji dla systemu Android po uruchomieniu danych obrazu w modelu wykrywania obiektów tworzona jest lista przewidywań, które musi obsłużyć kod aplikacji, wykonując dodatkową logikę biznesową, wyświetlając wyniki użytkownikowi lub wykonując inne działania.

Dane wyjściowe dowolnego modelu TensorFlow Lite różnią się pod względem liczby generowanych prognoz (jedna lub wiele) oraz informacji opisowych dla każdej prognozy. W przypadku modelu wykrywania obiektów predykcje zazwyczaj zawierają dane dotyczące ramki ograniczającej, która wskazuje, gdzie obiekt został wykryty na obrazie. W przykładowym kodzie zwrócone dane są sformatowane jako lista obiektów ObjectPrediction , jak pokazano poniżej: ( odwołanie do kodu )

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]
   )
}

Zrzut ekranu wykrywania obiektów W modelu użytym w tym przykładzie każda predykcja zawiera lokalizację obwiedni obiektu, etykietę obiektu oraz wynik predykcji od 0 do 1 jako zmiennoprzecinkowy reprezentujący ufność predykcji, przy czym 1 oznacza najwyższą ocenę ufności . Ogólnie prognozy z wynikiem poniżej 50% (0,5) są uważane za niejednoznaczne. Jednak sposób obsługi wyników prognoz o niskiej wartości zależy od Ciebie i potrzeb Twojej aplikacji.

Gdy model zwróci wynik prognozy, aplikacja może działać na podstawie tej prognozy, przedstawiając wynik użytkownikowi lub wykonując dodatkową logikę. W przypadku przykładowego kodu aplikacja rysuje obwiednię wokół zidentyfikowanego obiektu i wyświetla na ekranie nazwę klasy. Zapoznaj się z CameraActivity.reportPrediction() w przykładowym kodzie, aby uzyskać szczegółowe informacje.

Następne kroki

  • Zapoznaj się z różnymi zastosowaniami TensorFlow Lite w przykładach .
  • Dowiedz się więcej o korzystaniu z modeli uczenia maszynowego z TensorFlow Lite w sekcji Modele .
  • Dowiedz się więcej o wdrażaniu uczenia maszynowego w aplikacji mobilnej w Przewodniku programisty TensorFlow Lite .