Hal yang akan Anda buat
Dalam tutorial ini, Anda akan mendownload model TensorFlow Lite kustom yang diekspor dari AutoML Vision Edge. Kemudian, Anda akan menjalankan aplikasi iOS bawaan yang menggunakan model untuk mengidentifikasi gambar bunga.
Tujuan
Dalam panduan pengantar menyeluruh ini, Anda akan menggunakan kode untuk:
- Jalankan model terlatih dalam aplikasi iOS menggunakan penafsir TFLite.
Sebelum memulai
Menginstal TensorFlow
Sebelum memulai tutorial, Anda perlu menginstal beberapa software:
- instal tensorflow versi 1.7
- instal PILLOW
Jika Anda memiliki penginstalan Python yang berfungsi, jalankan perintah berikut untuk mendownload software ini:
pip install --upgrade "tensorflow==1.7.*" pip install PILLOW
Meng-clone repositori Git
Dengan menggunakan command line, clone repositori Git dengan perintah berikut:
git clone https://github.com/googlecodelabs/tensorflow-for-poets-2
Buka direktori clone lokal repositori
(direktori tensorflow-for-poets-2
). Anda akan menjalankan semua contoh kode berikut dari direktori ini:
cd tensorflow-for-poets-2
Menyiapkan aplikasi iOS
Aplikasi iOS demo memerlukan beberapa alat tambahan:
- Xcode
- Alat command line Xcode
- Cocoapods
Mendownload Xcode
Gunakan link berikut untuk mendownload Xcode di komputer Anda.
Menginstal alat command line Xcode
Instal alat command line Xcode dengan menjalankan perintah berikut:
xcode-select --install
Menginstal Cocoapods
Cocoapods menggunakan Ruby, yang diinstal secara default di macOS.
Untuk menginstal cocoapods, jalankan perintah ini:
sudo gem install cocoapods Install TFLite Cocoapod
Navigasikan ke file.xcworkspace
Bagian lainnya dari codelab ini harus dijalankan langsung di macOS, jadi tutup docker sekarang (Ctrl-D akan keluar dari Docker).
Gunakan perintah berikut untuk menginstal TensorFlow Lite dan membuat
file .xcworkspace
menggunakan cocoapods:
pod install --project-directory=ios/tflite/
Buka project dengan Xcode. Anda dapat membuka project melalui command line atau UI.
Untuk membuka project melalui command line, jalankan perintah berikut:
open ios/tflite/tflite_photos_example.xcworkspace
Untuk membuka project melalui UI, luncurkan Xcode dan pilih tombol "Open another Project".
Setelah membuka project, buka file .xcworkspace
(bukan file .xcproject
).
Menjalankan aplikasi asli
Aplikasi ini adalah contoh sederhana yang menjalankan model pengenalan gambar di Simulator iOS. Aplikasi membaca dari galeri foto, karena Simulator tidak mendukung input kamera.
Sebelum memasukkan model yang disesuaikan, uji versi dasar aplikasi yang menggunakan "mobilenet" dasar yang dilatih pada 1.000 kategori ImageNet.
Untuk meluncurkan aplikasi di Simulator, pilih tombol play di sudut kanan atas jendela Xcode.
Tombol "Foto Berikutnya" akan muncul di antara foto-foto di perangkat.
Anda dapat menambahkan foto ke galeri foto perangkat dengan menarik lalu melepasnya ke jendela Simulator
Hasilnya akan menampilkan anotasi yang mirip dengan gambar ini:
Menjalankan aplikasi yang disesuaikan
Penyiapan aplikasi asli mengklasifikasikan gambar ke dalam salah satu class 1.000 ImageNet, menggunakan MobileNet standar.
Ubah aplikasi agar akan menggunakan model yang dilatih ulang dengan kategori gambar kustom.
Menambahkan file model Anda ke project
Project demo dikonfigurasi untuk menelusuri file graph.lite
dan labels.txt
dalam direktori android/tflite/app/src/main/assets/
.
Untuk mengganti kedua file tersebut dengan versi Anda, jalankan perintah berikut:
cp tf_files/optimized_graph.lite ios/tflite/data/graph.lite cp tf_files/retrained_labels.txt ios/tflite/data/labels.txt
Jalankan aplikasi Anda
Untuk meluncurkan aplikasi di Simulator, pilih tombol play di sudut kanan atas jendela Xcode.
Untuk menguji modifikasi, tambahkan file gambar dari direktori flower_photos/
dan dapatkan prediksinya.
Hasilnya akan terlihat seperti ini:
Perlu diketahui bahwa gambar default bukan bunga.
Untuk benar-benar mencoba model tersebut, tambahkan beberapa gambar data pelatihan yang Anda download sebelumnya, atau download beberapa gambar dari penelusuran Google untuk digunakan dalam prediksi.
Bagaimana cara kerjanya?
Setelah aplikasi berjalan, lihat kode khusus TensorFlow Lite.
Pod TensorFlowLite
Aplikasi ini menggunakan TFLite Cocoapod yang telah dikompilasi sebelumnya. Podfile berisi cocoapod dalam project:
platform :ios, '8.0' inhibit_all_warnings! target 'tflite_photos_example' pod 'TensorFlowLite'
Kode yang berinteraksi ke TFLite terdapat di dalam
file CameraExampleViewController.mm
.
Penyiapan
Blok pertama yang diinginkan (setelah impor yang diperlukan) adalah metode
viewDidLoad
:
CameraExampleViewController.mm
#include "tensorflow/contrib/lite/kernels/register.h" #include "tensorflow/contrib/lite/model.h" #include "tensorflow/contrib/lite/string_util.h" #include "tensorflow/contrib/lite/tools/mutable_op_resolver.h" ... - (void)viewDidLoad { [super viewDidLoad]; labelLayers = [[NSMutableArray alloc] init]; NSString* graph_path = FilePathForResourceName(model_file_name, model_file_type); model = tflite::FlatBufferModel::BuildFromFile([graph_path UTF8String]); if (!model) { LOG(FATAL) << "Failed to mmap model " << graph_path; } LOG(INFO) << "Loaded model " << graph_path; model->error_reporter(); LOG(INFO) << "resolved reporter"; ...
Baris kunci di paruh pertama metode ini adalah
baris
model = tflite::FlatBufferModel::BuildFromFile([graph_path UTF8String]);
.
Kode ini membuat FlatBufferModel dari file grafik.
FlatBuffer adalah struktur data yang dapat dipetakan memori. Ini adalah fitur utama TFLite karena memungkinkan sistem mengelola memori yang digunakan oleh model dengan lebih baik. Sistem dapat menukar bagian model secara transparan ke dalam atau ke luar memori sesuai kebutuhan.
Bagian kedua metode ini mem-build penafsir untuk model, dengan melampirkan implementasi Op ke struktur data grafik yang telah dimuat sebelumnya:
CameraExampleViewController.mm
- (void)viewDidLoad { ... tflite::ops::builtin::BuiltinOpResolver resolver; LoadLabels(labels_file_name, labels_file_type, &labels); tflite::InterpreterBuilder(*model, resolver)(&interpreter); if (!interpreter) { LOG(FATAL) << "Failed to construct interpreter"; } if (interpreter->AllocateTensors() != kTfLiteOk) { LOG(FATAL) << "Failed to allocate tensors!"; } [self attachPreviewLayer]; }
Jika Anda terbiasa dengan TensorFlow di python, ini kira-kira setara
dengan mem-build tf.Session()
.
Menjalankan model
Metode UpdatePhoto
menangani semua detail pengambilan foto berikutnya,
memperbarui jendela pratinjau, dan menjalankan model pada foto.
CameraExampleViewController.mm
- (void)UpdatePhoto{ PHAsset* asset; if (photos==nil || photos_index >= photos.count){ [self updatePhotosLibrary]; photos_index=0; } if (photos.count){ asset = photos[photos_index]; photos_index += 1; input_image = [self convertImageFromAsset:asset targetSize:CGSizeMake(wanted_input_width, wanted_input_height) mode:PHImageContentModeAspectFill]; display_image = [self convertImageFromAsset:asset targetSize:CGSizeMake(asset.pixelWidth,asset.pixelHeight) mode:PHImageContentModeAspectFit]; [self DrawImage]; } if (input_image != nil){ image_data image = [self CGImageToPixels:input_image.CGImage]; [self inputImageToModel:image]; [self runModel]; } }
Ada tiga baris terakhir yang menjadi perhatian kita.
Metode CGImageToPixels
mengonversi CGImage yang ditampilkan oleh galeri Foto
iOS menjadi struktur sederhana yang berisi data lebar, tinggi, saluran, dan
piksel.
typedef struct {
int width;
int height;
int channels;
std::vector<uint8_t> data;
} image_data;
Metode inputImageToModel
menangani penyisipan gambar ke dalam memori
penafsir. Ini termasuk mengubah ukuran gambar dan menyesuaikan nilai piksel agar
sesuai dengan yang diharapkan oleh model.
CameraExampleViewController.mm
- (void)inputImageToModel:(image_data)image{
float* out = interpreter->typed_input_tensor<float>(0);
const float input_mean = 127.5f;
const float input_std = 127.5f;
assert(image.channels >= wanted_input_channels);
uint8_t* in = image.data.data();
for (int y = 0; y < wanted_input_height; ++y) {
const int in_y = (y * image.height) / wanted_input_height;
uint8_t* in_row = in + (in_y * image.width * image.channels);
float* out_row = out + (y * wanted_input_width * wanted_input_channels);
for (int x = 0; x < wanted_input_width; ++x) {
const int in_x = (x * image.width) / wanted_input_width;
uint8_t* in_pixel = in_row + (in_x * image.channels);
float* out_pixel = out_row + (x * wanted_input_channels);
for (int c = 0; c < wanted_input_channels; ++c) {
out_pixel[c] = (in_pixel[c] - input_mean) / input_std;
}
}
}
}
Kita mengetahui bahwa model hanya memiliki satu input, sehingga baris
float* out = interpreter->typed_input_tensor<float>(0);
akan meminta
penafsir pointer ke memori untuk input 0. Metode lainnya
menangani aritmetika pointer dan penskalaan piksel untuk menyalin data ke dalam
array input tersebut.
Terakhir, metode runModel
akan menjalankan model:
CameraExampleViewController.mm
- (void)runModel { double startTimestamp = [[NSDate new] timeIntervalSince1970]; if (interpreter->Invoke() != kTfLiteOk) { LOG(FATAL) << "Failed to invoke!"; } double endTimestamp = [[NSDate new] timeIntervalSince1970]; total_latency += (endTimestamp - startTimestamp); total_count += 1; NSLog(@"Time: %.4lf, avg: %.4lf, count: %d", endTimestamp - startTimestamp, total_latency / total_count, total_count); ... }
runModel
berikutnya akan membaca kembali hasilnya. Untuk melakukan ini, kode ini meminta penafsir
untuk memberikan pointer ke data array output. Output-nya adalah array sederhana
dari float. Metode GetTopN
menangani ekstraksi dari 5 hasil
teratas (menggunakan antrean prioritas).
CameraExampleViewController.mm
- (void)runModel {
...
const int output_size = (int)labels.size();
const int kNumResults = 5;
const float kThreshold = 0.1f;
std::vector<std::pair<float, int>> top_results;
float* output = interpreter->typed_output_tensor<float>(0);
GetTopN(output, output_size, kNumResults, kThreshold, &top_results);
...
}
Beberapa baris berikutnya hanya mengonversi 5 pasangan (probability, class_id)
teratas tersebut menjadi pasangan (probability, label)
, lalu meneruskan hasil tersebut,
secara asinkron, ke metode setPredictionValues
yang memperbarui
laporan layar:
CameraExampleViewController.mm
- (void)runModel {
...
std::vector<std::pair<float, std::string>> newValues;
for (const auto& result : top_results) {
std::pair<float, std::string> item;
item.first = result.first;
item.second = labels[result.second];
newValues.push_back(item);
}
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self setPredictionValues:newValues];
});
}
Apa Selanjutnya
Sekarang Anda telah menyelesaikan panduan aplikasi klasifikasi bunga iOS menggunakan menggunakan model Edge. Anda telah menggunakan model Edge Tensorflow Lite terlatih untuk menguji aplikasi klasifikasi gambar sebelum memodifikasi dan mendapatkan anotasi contoh. Anda kemudian memeriksa kode khusus TensorFlow Lite untuk memahami fungsionalitas yang mendasarinya.
Referensi berikut dapat membantu Anda terus mempelajari model TensorFlow dan AutoML Vision Edge:
- Pelajari TFLite lebih lanjut dari dokumentasi resmi dan repositori kode.
- Coba versi kamera dari aplikasi demo ini, yang menggunakan versi model terkuantifikasi. Hal ini memberikan kekuatan yang sama dalam paket yang lebih kecil dan lebih efisien.
- Coba model siap TFLite lainnya untuk kasus penggunaan tertentu.
- Pelajari lebih lanjut TensorFlow secara umum dengan dokumentasi memulai TensorFlow.