Men-deploy solusi analisis ML vision dengan Dataflow dan Cloud Vision API

Last reviewed 2024-05-16 UTC

Dokumen deployment ini menjelaskan cara men-deploy pipeline Dataflow untuk memproses file gambar dalam skala besar dengan Cloud Vision API. Pipeline ini menyimpan hasil file yang diproses di BigQuery. Anda dapat menggunakan file tersebut untuk tujuan analisis atau untuk melatih model ML BigQuery.

Pipeline Dataflow yang Anda buat dalam deployment ini dapat memproses jutaan gambar per hari. Satu-satunya batas adalah kuota Vision API Anda. Anda dapat meningkatkan kuota Vision API berdasarkan persyaratan skala.

Petunjuk ini ditujukan untuk data engineer dan data scientist. Dokumen ini mengasumsikan bahwa Anda telah memiliki pengetahuan dasar tentang membangun pipeline Dataflow menggunakan Java SDK Apache Beam, GoogleSQL untuk BigQuery, dan pembuatan skrip shell dasar. Tutorial ini juga mengasumsikan bahwa Anda sudah familier dengan Vision API.

Arsitektur

Diagram berikut mengilustrasikan alur sistem untuk membangun solusi analisis visi ML.

Arsitektur yang menunjukkan alur informasi untuk menyerap dan memicu, memproses, serta menyimpan dan menganalisis proses.

Pada diagram sebelumnya, informasi mengalir melalui arsitektur sebagai berikut:

  1. Klien mengupload file gambar ke bucket Cloud Storage.
  2. Cloud Storage mengirim pesan tentang upload data ke Pub/Sub.
  3. Pub/Sub memberi tahu Dataflow tentang upload.
  4. Pipeline Dataflow mengirimkan gambar ke Vision API.
  5. Vision API memproses gambar lalu menampilkan anotasi.
  6. Pipeline mengirimkan file yang telah dianotasi ke BigQuery untuk Anda analisis.

Tujuan

  • Buat pipeline Apache Beam untuk analisis gambar dari gambar yang dimuat di Cloud Storage.
  • Gunakan Dataflow Runner v2 untuk menjalankan pipeline Apache Beam dalam mode streaming guna menganalisis gambar segera setelah diupload.
  • Menggunakan Vision API untuk menganalisis gambar berdasarkan serangkaian jenis fitur.
  • Menganalisis anotasi dengan BigQuery.

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah selesai mem-build aplikasi contoh, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  3. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  4. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  5. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  6. Di konsol Google Cloud, aktifkan Cloud Shell.

    Aktifkan Cloud Shell

    Di bagian bawah Google Cloud Console, Cloud Shell sesi akan terbuka dan menampilkan perintah command line. Cloud Shell adalah lingkungan shell dengan Google Cloud CLI yang sudah terinstal, dan dengan nilai yang sudah ditetapkan untuk project Anda saat ini. Diperlukan waktu beberapa detik untuk melakukan inisialisasi sesi.

  7. Buat clone repositori GitHub yang berisi kode sumber pipeline Dataflow:
        git clone
        https://github.com/GoogleCloudPlatform/dataflow-vision-analytics.git
        
  8. Buka folder root repositori:
        cd dataflow-vision-analytics
        
  9. Ikuti petunjuk di bagian Memulai repositori dataflow-vision-analytics di GitHub untuk menyelesaikan tugas-tugas berikut:
    • Mengaktifkan beberapa API.
    • Membuat bucket Cloud Storage.
    • Membuat topik dan langganan Pub/Sub.
    • Membuat set data BigQuery.
    • Siapkan beberapa variabel lingkungan untuk deployment ini.

Menjalankan pipeline Dataflow untuk semua fitur Vision API yang diimplementasikan

Pipeline Dataflow meminta dan memproses serangkaian fitur dan atribut Vision API tertentu dalam file teranotasi.

Parameter yang tercantum dalam tabel berikut bersifat khusus untuk pipeline Dataflow dalam deployment ini. Untuk mengetahui daftar lengkap parameter eksekusi Dataflow standar, lihat Menetapkan opsi pipeline Dataflow.

Nama parameter Deskripsi

batchSize

Jumlah gambar yang akan disertakan dalam permintaan ke Vision API. Nilai defaultnya adalah 1. Anda dapat meningkatkan nilai ini hingga maksimum 16.

datasetName

Nama set data BigQuery output.

features

Daftar fitur pemrosesan gambar. Pipeline mendukung fitur label, tempat terkenal, logo, wajah, petunjuk pangkas, dan properti gambar.

keyRange

Parameter yang menentukan jumlah panggilan paralel maksimum ke Vision API. Nilai defaultnya adalah 1.

labelAnnottationTable,
landmarkAnnotationTable,
logoAnnotationTable,
faceAnnotationTable,
imagePropertiesTable,
cropHintAnnotationTable,
errorLogTable

Parameter string dengan menggunakan nama tabel untuk berbagai anotasi. Nilai default diberikan untuk setiap tabel—misalnya, label_annotation.

maxBatchCompletionDurationInSecs

Lama waktu tunggu sebelum memproses gambar jika ada kumpulan gambar yang tidak lengkap. Defaultnya adalah 30 detik.

subscriberId

ID langganan Pub/Sub yang menerima notifikasi Cloud Storage input.

visionApiProjectId

Project ID yang akan digunakan untuk Vision API.
  1. Di Cloud Shell, jalankan perintah berikut untuk memproses gambar untuk semua jenis fitur yang didukung oleh pipeline Dataflow:

    ./gradlew run --args=" \
    --jobName=test-vision-analytics \
      --streaming \
      --runner=DataflowRunner \
      --enableStreamingEngine \
      --diskSizeGb=30 \
      --project=${PROJECT} \
      --datasetName=${BIGQUERY_DATASET} \
      --subscriberId=projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION} \
      --visionApiProjectId=${PROJECT} \
      --features=IMAGE_PROPERTIES,LABEL_DETECTION,LANDMARK_DETECTION,LOGO_DETECTION,CROP_HINTS,FACE_DETECTION"
    

    Akun layanan khusus harus memiliki akses baca ke bucket yang berisi image. Dengan kata lain, akun tersebut harus diberi peran roles/storage.objectViewer di bucket tersebut.

    Untuk mengetahui informasi selengkapnya tentang cara menggunakan akun layanan khusus, lihat Keamanan dan izin Dataflow.

  2. Buka URL yang ditampilkan di tab browser baru, atau buka halaman Tugas Dataflow, lalu pilih pipeline test-vision-analytics.

    Setelah beberapa detik, grafik untuk tugas Dataflow akan muncul:

    Diagram alur kerja untuk tugas Dataflow.

    Pipeline Dataflow kini sedang berjalan dan menunggu untuk menerima notifikasi input dari langganan Pub/Sub.

  3. Picu pemrosesan gambar Dataflow dengan mengupload enam file sampel ke dalam bucket input:

    gcloud storage cp data-sample/* gs://${IMAGE_BUCKET}
    
  4. Di konsol Google Cloud, cari panel Penghitung Kustom dan gunakan untuk meninjau penghitung kustom di Dataflow dan untuk memverifikasi bahwa Dataflow telah memproses keenam gambar tersebut. Anda dapat menggunakan fungsi filter di panel untuk melihat metrik yang benar. Untuk hanya menampilkan penghitung yang dimulai dengan awalan numberOf, ketik numberOf dalam filter.

    Daftar penghitung difilter agar hanya menampilkan penghitung yang dimulai dengan `numberof`.

  5. Di Cloud Shell, validasikan bahwa tabel tersebut dibuat secara otomatis:

    bq query --nouse_legacy_sql "SELECT table_name FROM ${BIGQUERY_DATASET}.INFORMATION_SCHEMA.TABLES ORDER BY table_name"
    

    Outputnya adalah sebagai berikut:

    +----------------------+
    |      table_name      |
    +----------------------+
    | crop_hint_annotation |
    | face_annotation      |
    | image_properties     |
    | label_annotation     |
    | landmark_annotation  |
    | logo_annotation      |
    +----------------------+
    
  6. Lihat skema untuk tabel landmark_annotation. Fitur LANDMARK_DETECTION menangkap atribut yang ditampilkan dari panggilan API.

    bq show --schema --format=prettyjson ${BIGQUERY_DATASET}.landmark_annotation
    

    Outputnya adalah sebagai berikut:

    [
       {
          "name":"gcs_uri",
          "type":"STRING"
       },
       {
          "name":"feature_type",
          "type":"STRING"
       },
       {
          "name":"transaction_timestamp",
          "type":"STRING"
       },
       {
          "name":"mid",
          "type":"STRING"
       },
       {
          "name":"description",
          "type":"STRING"
       },
       {
          "name":"score",
          "type":"FLOAT"
       },
       {
          "fields":[
             {
                "fields":[
                   {
                      "name":"x",
                      "type":"INTEGER"
                   },
                   {
                  "name":"y",
                  "type":"INTEGER"
               }
            ],
            "mode":"REPEATED",
            "name":"vertices",
            "type":"RECORD"
         }
      ],
      "name":"boundingPoly",
      "type":"RECORD"
    },
    {
      "fields":[
         {
            "fields":[
               {
                  "name":"latitude",
                  "type":"FLOAT"
               },
               {
                  "name":"longitude",
                  "type":"FLOAT"
               }
            ],
                "name":"latLon",
                "type":"RECORD"
              }
            ],
          "mode":"REPEATED",
          "name":"locations",
          "type":"RECORD"
       }
    ]
    
  7. Lihat data anotasi yang dihasilkan oleh API dengan menjalankan perintah bq query berikut untuk melihat semua tempat terkenal yang ditemukan dalam keenam gambar ini yang diurutkan berdasarkan skor yang paling mungkin:

    bq query --nouse_legacy_sql "SELECT SPLIT(gcs_uri, '/')[OFFSET(3)] file_name, description, score, locations FROM ${BIGQUERY_DATASET}.landmark_annotation ORDER BY score DESC"
    

    Outputnya mirip dengan hal berikut ini:

    +------------------+-------------------+------------+---------------------------------+
    |    file_name     |    description    |   score    |            locations            |
    +------------------+-------------------+------------+---------------------------------+
    | eiffel_tower.jpg | Eiffel Tower      |  0.7251996 | ["POINT(2.2944813 48.8583701)"] |
    | eiffel_tower.jpg | Trocadéro Gardens | 0.69601923 | ["POINT(2.2892823 48.8615963)"] |
    | eiffel_tower.jpg | Champ De Mars     |  0.6800974 | ["POINT(2.2986304 48.8556475)"] |
    +------------------+-------------------+------------+---------------------------------+
    

    Untuk deskripsi mendetail dari semua kolom yang khusus untuk anotasi, lihat AnnotateImageResponse.

  8. Untuk menghentikan pipeline streaming, jalankan perintah berikut. Pipeline akan terus berjalan meskipun tidak ada lagi notifikasi Pub/Sub yang harus diproses.

      gcloud dataflow jobs cancel
        --region ${REGION} $(gcloud dataflow jobs list
        --region ${REGION} --filter="NAME:test-vision-analytics AND STATE:Running"
        --format="get(JOB_ID)")
    

    Bagian berikut berisi lebih banyak contoh kueri yang menganalisis berbagai fitur gambar gambar.

Menganalisis set data Flickr30K

Di bagian ini, Anda akan mendeteksi label dan tempat terkenal di set data gambar Flickr30k publik yang dihosting di Kaggle.

  1. Di Cloud Shell, ubah parameter pipeline Dataflow agar dioptimalkan untuk set data besar. Untuk memungkinkan throughput yang lebih tinggi, tingkatkan juga nilai batchSize dan keyRange. Dataflow menskalakan jumlah pekerja sesuai kebutuhan:

    ./gradlew run --args=" \
      --runner=DataflowRunner \
      --jobName=vision-analytics-flickr \
      --streaming \
      --enableStreamingEngine \
      --diskSizeGb=30 \
      --autoscalingAlgorithm=THROUGHPUT_BASED \
      --maxNumWorkers=5 \
      --project=${PROJECT} \
      --region=${REGION} \
      --subscriberId=projects/${PROJECT}/subscriptions/${GCS_NOTIFICATION_SUBSCRIPTION} \
      --visionApiProjectId=${PROJECT} \
      --features=LABEL_DETECTION,LANDMARK_DETECTION \
      --datasetName=${BIGQUERY_DATASET} \
      --batchSize=16 \
      --keyRange=5"
    

    Karena set data berukuran besar, Anda tidak dapat menggunakan Cloud Shell untuk mengambil gambar dari Kaggle dan mengirimkannya ke bucket Cloud Storage. Anda harus menggunakan VM dengan ukuran disk yang lebih besar untuk melakukannya.

  2. Untuk mengambil gambar berbasis Kaggle dan mengirimkannya ke bucket Cloud Storage, ikuti petunjuk di bagian Simulasikan gambar yang diupload ke bucket penyimpanan di repositori GitHub.

  3. Untuk mengamati progres proses penyalinan dengan melihat metrik kustom yang tersedia di UI Dataflow, buka halaman Tugas Dataflow, lalu pilih pipeline vision-analytics-flickr. Penghitung pelanggan akan berubah secara berkala hingga pipeline Dataflow memproses semua file.

    Output-nya mirip dengan screenshot panel Penghitung Kustom berikut. Salah satu file dalam set data memiliki jenis yang salah, dan penghitung rejectedFiles menunjukkan hal itu. Nilai penghitung ini merupakan perkiraan. Anda mungkin melihat jumlah yang lebih tinggi. Selain itu, jumlah anotasi kemungkinan besar akan berubah karena peningkatan akurasi pemrosesan oleh Vision API.

    Daftar penghitung yang terkait dengan pemrosesan gambar berbasis Kaggle.

    Untuk menentukan apakah Anda mendekati atau melebihi resource yang tersedia, lihat halaman kuota Vision API.

    Dalam contoh ini, pipeline Dataflow hanya menggunakan sekitar 50% dari kuotanya. Berdasarkan persentase kuota yang digunakan, Anda dapat memutuskan untuk meningkatkan paralelisme pipeline dengan meningkatkan nilai parameter keyRange.

  4. Menghentikan pipeline:

    gcloud dataflow jobs list --region $REGION --filter="NAME:vision-analytics-flickr AND STATE:Running" --format="get(JOB_ID)"
    

Menganalisis anotasi di BigQuery

Dalam deployment ini, Anda telah memproses lebih dari 30.000 gambar untuk anotasi label dan tempat terkenal. Di bagian ini, Anda akan mengumpulkan statistik tentang file tersebut. Anda dapat menjalankan kueri ini di GoogleSQL untuk ruang kerja BigQuery atau menggunakan alat command line bq.

Perhatikan bahwa angka yang Anda lihat dapat berbeda dari contoh hasil kueri dalam deployment ini. Vision API terus meningkatkan akurasi analisisnya; tetapi dapat memberikan hasil yang lebih kaya dengan menganalisis gambar yang sama setelah Anda pertama kali menguji solusi.

  1. Di konsol Google Cloud, buka halaman Query editor BigQuery dan jalankan perintah berikut untuk melihat 20 label teratas dalam set data:

    Buka Editor kueri

    SELECT  description, count(*)ascount \
      FROM vision_analytics.label_annotation
      GROUP BY description ORDER BY count DESC LIMIT 20
    

    Outputnya mirip dengan hal berikut ini:

    +------------------+-------+
    |   description    | count |
    +------------------+-------+
    | Leisure          |  7663 |
    | Plant            |  6858 |
    | Event            |  6044 |
    | Sky              |  6016 |
    | Tree             |  5610 |
    | Fun              |  5008 |
    | Grass            |  4279 |
    | Recreation       |  4176 |
    | Shorts           |  3765 |
    | Happy            |  3494 |
    | Wheel            |  3372 |
    | Tire             |  3371 |
    | Water            |  3344 |
    | Vehicle          |  3068 |
    | People in nature |  2962 |
    | Gesture          |  2909 |
    | Sports equipment |  2861 |
    | Building         |  2824 |
    | T-shirt          |  2728 |
    | Wood             |  2606 |
    +------------------+-------+
    
  2. Tentukan label lain yang ada pada gambar dengan label tertentu, yang diurutkan berdasarkan frekuensi:

    DECLARE label STRING DEFAULT 'Plucked string instruments';
    
    WITH other_labels AS (
       SELECT description, COUNT(*) count
    FROM vision_analytics.label_annotation
    WHERE gcs_uri IN (
        SELECT gcs_uri FROM vision_analytics.label_annotation WHERE description = label )
      AND description != label
    GROUP BY description)
    SELECT description, count, RANK() OVER (ORDER BY count DESC) rank
    FROM other_labels ORDER BY rank LIMIT 20;
    

    Outputnya adalah sebagai berikut. Untuk label Instrumen string yang dipetik yang digunakan dalam perintah sebelumnya, Anda akan melihat:

    +------------------------------+-------+------+
    |         description          | count | rank |
    +------------------------------+-------+------+
    | String instrument            |   397 |    1 |
    | Musical instrument           |   236 |    2 |
    | Musician                     |   207 |    3 |
    | Guitar                       |   168 |    4 |
    | Guitar accessory             |   135 |    5 |
    | String instrument accessory  |    99 |    6 |
    | Music                        |    88 |    7 |
    | Musical instrument accessory |    72 |    8 |
    | Guitarist                    |    72 |    8 |
    | Microphone                   |    52 |   10 |
    | Folk instrument              |    44 |   11 |
    | Violin family                |    28 |   12 |
    | Hat                          |    23 |   13 |
    | Entertainment                |    22 |   14 |
    | Band plays                   |    21 |   15 |
    | Jeans                        |    17 |   16 |
    | Plant                        |    16 |   17 |
    | Public address system        |    16 |   17 |
    | Artist                       |    16 |   17 |
    | Leisure                      |    14 |   20 |
    +------------------------------+-------+------+
    
  3. Lihat 10 penanda teratas yang terdeteksi:

      SELECT description, COUNT(description) AS count
      FROM vision_analytics.landmark_annotation
      GROUP BY description ORDER BY count DESC LIMIT 10
    

    Outputnya adalah sebagai berikut:

      +--------------------+-------+
      |    description     | count |
      +--------------------+-------+
      | Times Square       |    55 |
      | Rockefeller Center |    21 |
      | St. Mark's Square  |    16 |
      | Bryant Park        |    13 |
      | Millennium Park    |    13 |
      | Ponte Vecchio      |    13 |
      | Tuileries Garden   |    13 |
      | Central Park       |    12 |
      | Starbucks          |    12 |
      | National Mall      |    11 |
      +--------------------+-------+
      

  4. Tentukan gambar yang kemungkinan besar berisi waterfall:

    SELECT SPLIT(gcs_uri, '/')[OFFSET(3)] file_name, description, score
    FROM vision_analytics.landmark_annotation
    WHERE LOWER(description) LIKE '%fall%'
    ORDER BY score DESC LIMIT 10
    

    Outputnya adalah sebagai berikut:

    +----------------+----------------------------+-----------+
    |   file_name    |        description         |   score    |
    +----------------+----------------------------+-----------+
    | 895502702.jpg  | Waterfall Carispaccha      |  0.6181358 |
    | 3639105305.jpg | Sahalie Falls Viewpoint    | 0.44379658 |
    | 3672309620.jpg | Gullfoss Falls             | 0.41680416 |
    | 2452686995.jpg | Wahclella Falls            | 0.39005348 |
    | 2452686995.jpg | Wahclella Falls            |  0.3792498 |
    | 3484649669.jpg | Kodiveri Waterfalls        | 0.35024035 |
    | 539801139.jpg  | Mallela Thirtham Waterfall | 0.29260656 |
    | 3639105305.jpg | Sahalie Falls              |  0.2807213 |
    | 3050114829.jpg | Kawasan Falls              | 0.27511594 |
    | 4707103760.jpg | Niagara Falls              | 0.18691841 |
    +----------------+----------------------------+-----------+
    
  5. Temukan gambar tempat terkenal dalam jarak 3 kilometer dari Colosseum di Roma (fungsi ST_GEOPOINT menggunakan bujur dan lintang Colosseum):

    WITH
      landmarksWithDistances AS (
      SELECT
        gcs_uri,
        description,
        location,
        ST_DISTANCE(location,
          ST_GEOGPOINT(12.492231,
            41.890222)) distance_in_meters,
      FROM
        `vision_analytics.landmark_annotation` landmarks
      CROSS JOIN
        UNNEST(landmarks.locations) AS location )
    SELECT
      SPLIT(gcs_uri,"/")[OFFSET(3)] file,
      description,
        ROUND(distance_in_meters) distance_in_meters,
      location,
      CONCAT("https://storage.cloud.google.com/", SUBSTR(gcs_uri, 6)) AS image_url
    FROM
      landmarksWithDistances
    WHERE
      distance_in_meters < 3000
    ORDER BY
      distance_in_meters
    LIMIT
      100
    

    Saat menjalankan kueri, Anda akan melihat bahwa ada beberapa gambar Colosseum, tetapi juga gambar Arch Of Constantine, Palatine Hill, dan sejumlah tempat lainnya yang sering difoto.

    Anda dapat memvisualisasikan data di BigQuery Geo Viz dengan menempelkan di kueri sebelumnya. Pilih sebuah titik di peta untuk melihat detailnya. Atribut Image_url berisi link ke file gambar.

    Peta lokasi dan jaraknya dari Colosseum.

Satu catatan tentang hasil kueri. Informasi lokasi biasanya tersedia untuk landmark. Gambar yang sama dapat berisi beberapa lokasi untuk landmark yang sama. Fungsi ini dijelaskan dalam jenis AnnotateImageResponse.

Karena satu lokasi dapat menunjukkan lokasi adegan dalam gambar, beberapa elemen LocationInfo dapat muncul. Lokasi lain dapat menunjukkan tempat gambar diambil.

Pembersihan

Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam panduan ini, hapus project yang berisi resource tersebut, atau pertahankan project dan hapus resource individual.

Menghapus project Google Cloud

Cara termudah untuk menghilangkan penagihan adalah dengan menghapus project Google Cloud yang Anda buat untuk tutorial.

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Jika Anda memutuskan untuk menghapus resource satu per satu, ikuti langkah-langkah di bagian Membersihkan repositori GitHub.

Langkah selanjutnya

  • Untuk mengetahui lebih banyak tentang arsitektur referensi, diagram, dan praktik terbaik lainnya, jelajahi Pusat Arsitektur Cloud.

Kontributor

Penulis:

Kontributor lainnya:

Untuk melihat profil LinkedIn non-publik, login ke LinkedIn.