Metinleri sınıflandırmak için Flutter uygulaması oluşturma

1. Başlamadan önce

Bu codelab'de, REST ve gRPC üzerinden TensorFlow Serving ile bir Flutter uygulamasından metin sınıflandırma çıkarımı çalıştırmayı öğreneceksiniz.

Ön koşullar

Neler öğreneceksiniz?

  • Basit bir Flutter uygulaması oluşturma ve TensorFlow Serving (REST ve gRPC) aracılığıyla metinleri sınıflandırma.
  • Sonuçları kullanıcı arayüzünde görüntüleme

İhtiyacınız olanlar

2. Flutter geliştirme ortamınızı kurma

Flutter geliştirme için bu laboratuvarı tamamlamak üzere iki yazılıma ihtiyacınız vardır: Flutter SDK ve bir düzenleyici.

Codelab'i aşağıdaki cihazlardan herhangi birini kullanarak çalıştırabilirsiniz:

  • iOS simülatörü (Xcode araçlarının yüklenmesi gerekir).
  • Android Emulator (Android Studio'da kurulum gerektirir).
  • Tarayıcı (hata ayıklama için Chrome gereklidir).
  • Windows, Linux veya macOS masaüstü uygulaması olarak. Dağıtmayı planladığınız platformda geliştirme yapmanız gerekir. Bu nedenle, bir Windows masaüstü uygulaması geliştirmek istiyorsanız uygun derleme zincirine erişmek için Windows'ta geliştirme yapmanız gerekir. docs.flutter.dev/desktop adresinde ayrıntılı olarak ele alınan işletim sistemine özgü gereksinimler vardır.

3. Hazırlanın

Bu codelab'in kodunu indirmek için:

  1. Bu codelab'in GitHub deposuna gidin.
  2. Bu codelab'in tüm kodunu indirmek için Code > Download zip'i (Kod > Zip dosyasını indir) tıklayın.

2cd45599f51fb8a2.png

  1. İndirilen ZIP dosyasını açarak ihtiyacınız olan tüm kaynakları içeren bir codelabs-main kök klasörü oluşturun.

Bu codelab için depodaki tfserving-flutter/codelab2 alt dizinindeki dosyalar yeterlidir. Bu dizinde iki klasör bulunur:

  • starter klasörü, bu codelab'de temel alacağınız başlangıç kodunu içerir.
  • finished klasöründe, tamamlanmış örnek uygulamanın kodu yer alır.

4. Projenin bağımlılıklarını indirme

  1. VS Code'da File > Open folder'ı (Dosya > Klasörü aç) tıklayın ve daha önce indirdiğiniz kaynak kodundan starter klasörünü seçin.
  2. Başlangıç uygulaması için gerekli paketleri indirmenizi isteyen bir iletişim kutusu görürseniz Paketleri al'ı tıklayın.
  3. Bu iletişim kutusunu görmüyorsanız terminalinizi açın ve flutter pub get komutunu starter klasöründe çalıştırın.

7ada07c300f166a6.png

5. Başlangıç uygulamasını çalıştırma

  1. VS Code'da Android Emulator veya iOS Simulator'ın düzgün şekilde ayarlandığından ve durum çubuğunda göründüğünden emin olun.

Örneğin, Pixel 5'i Android Emulator ile kullandığınızda gördüğünüz ekranı aşağıda bulabilirsiniz:

9767649231898791.png

iOS Simülasyon Aracı ile iPhone 13'ü kullandığınızda gördüğünüz ekran:

95529e3a682268b2.png

  1. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın.

Uygulamayı çalıştırıp keşfetme

Uygulama, Android Emulator veya iOS Simulator'da başlatılmalıdır. Kullanıcı arayüzü oldukça basittir. Kullanıcının metin yazmasına olanak tanıyan bir metin alanı vardır. Kullanıcı, verileri REST veya gRPC ile arka uca gönderip göndermeyeceğini seçebilir. Arka uç, önceden işlenmiş giriş üzerinde metin sınıflandırması yapmak için bir TensorFlow modeli kullanır ve sınıflandırma sonucunu istemci uygulamasına döndürür. Bu uygulama da kullanıcı arayüzünü günceller.

b298f605d64dc132.png d3ef3ccd3c338108.png

Sınıflandır'ı tıkladığınızda henüz arka uçla iletişim kurulamadığından hiçbir şey olmaz.

6. TensorFlow Serving ile metin sınıflandırma modeli dağıtma

Metin sınıflandırma, metinleri önceden tanımlanmış kategorilere göre sınıflandıran çok yaygın bir makine öğrenimi görevidir. Bu codelab'de, Train a comment-spam detection model with TensorFlow Lite Model Maker codelab'deki önceden eğitilmiş modeli TensorFlow Serving ile dağıtacak ve giriş metnini spam veya spam değil olarak sınıflandırmak için Flutter ön ucunuzdan arka ucu çağıracaksınız.

TensorFlow Serving'i başlatma

  • Terminalinizde Docker ile TensorFlow Serving'i başlatın ancak PATH/TO/SAVEDMODEL yer tutucusunu bilgisayarınızdaki mm_spam_savedmodel klasörünün mutlak yoluyla değiştirin.
docker pull tensorflow/serving

docker run -it --rm -p 8500:8500 -p 8501:8501 -v "PATH/TO/SAVEDMODEL:/models/spam-detection" -e MODEL_NAME=spam-detection tensorflow/serving

Docker, önce TensorFlow Serving görüntüsünü otomatik olarak indirir. Bu işlem bir dakika sürer. Ardından TensorFlow Serving başlatılmalıdır. Günlük, aşağıdaki kod snippet'i gibi görünmelidir:

2022-02-25 06:01:12.513231: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:206] Restoring SavedModel bundle.
2022-02-25 06:01:12.585012: I external/org_tensorflow/tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 3000000000 Hz
2022-02-25 06:01:13.395083: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:190] Running initialization op on SavedModel bundle at path: /models/ssd_mobilenet_v2_2/123
2022-02-25 06:01:13.837562: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:277] SavedModel load for tags { serve }; Status: success: OK. Took 1928700 microseconds.
2022-02-25 06:01:13.877848: I tensorflow_serving/servables/tensorflow/saved_model_warmup_util.cc:59] No warmup data file found at /models/ssd_mobilenet_v2_2/123/assets.extra/tf_serving_warmup_requests
2022-02-25 06:01:13.929844: I tensorflow_serving/core/loader_harness.cc:87] Successfully loaded servable version {name: spam-detection version: 123}
2022-02-25 06:01:13.985848: I tensorflow_serving/model_servers/server_core.cc:486] Finished adding/updating models
2022-02-25 06:01:13.985987: I tensorflow_serving/model_servers/server.cc:367] Profiler service is enabled
2022-02-25 06:01:13.988994: I tensorflow_serving/model_servers/server.cc:393] Running gRPC ModelServer at 0.0.0.0:8500 ...
[warn] getaddrinfo: address family for nodename not supported
2022-02-25 06:01:14.033872: I tensorflow_serving/model_servers/server.cc:414] Exporting HTTP/REST API at:localhost:8501 ...
[evhttp_server.cc : 245] NET_LOG: Entering the event loop ...

7. Giriş cümlesini belirteçlere ayırma

Arka uç artık hazır. Bu nedenle, istemci isteklerini TensorFlow Serving'e göndermeye neredeyse hazırsınız. Ancak önce giriş cümlesini belirteçleştirmeniz gerekir. Modelin giriş tensörünü incelerseniz ham dizeler yerine 20 tam sayıdan oluşan bir liste beklediğini görebilirsiniz. Tokenleştirme, uygulamaya yazdığınız kelimeleri sınıflandırma için arka uca göndermeden önce bir sözlük sözlüğüne göre tamsayı listesine eşlemenizdir. Örneğin, buy book online to learn more yazarsanız belirteçleştirme işlemi bunu [32, 79, 183, 10, 224, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ile eşler. Belirli sayılar, kelime dağarcığı sözlüğüne göre değişiklik gösterebilir.

  1. lib/main.dart dosyasında, _vocabMap kelime dağarcığı sözlüğünü oluşturmak için predict() yöntemine şu kodu ekleyin.
// Build _vocabMap if empty.
if (_vocabMap.isEmpty) {
  final vocabFileString = await rootBundle.loadString(vocabFile);
  final lines = vocabFileString.split('\n');
  for (final l in lines) {
    if (l != "") {
      var wordAndIndex = l.split(' ');
      (_vocabMap)[wordAndIndex[0]] = int.parse(wordAndIndex[1]);
    }
  }
} 
  1. Önceki kod snippet'inden hemen sonra, jetonlaştırmayı uygulamak için bu kodu ekleyin:
// Tokenize the input sentence.
final inputWords = _inputSentenceController.text
    .toLowerCase()
    .replaceAll(RegExp('[^a-z ]'), '')
    .split(' ');
// Initialize with padding token.
_tokenIndices = List.filled(maxSentenceLength, 0);
var i = 0;
for (final w in inputWords) {
  if ((_vocabMap).containsKey(w)) {
    _tokenIndices[i] = (_vocabMap)[w]!;
    i++;
  }

  // Truncate the string if longer than maxSentenceLength.
  if (i >= maxSentenceLength - 1) {
    break;
  }
}

Bu kod, cümle dizesini küçük harfe dönüştürür, alfabede olmayan karakterleri kaldırır ve kelimeleri sözcük tablosuna göre 20 tam sayı dizinine eşler.

8. Flutter uygulamasını REST üzerinden TensorFlow Serving'e bağlama

TensorFlow Serving'e istek göndermenin iki yolu vardır:

  • REST
  • gRPC

REST üzerinden istek gönderme ve yanıt alma

REST üzerinden istek göndermek ve yanıt almak için üç basit adım vardır:

  1. REST isteğini oluşturun.
  2. REST isteğini TensorFlow Serving'e gönderin.
  3. Tahmin edilen sonucu REST yanıtından çıkarın ve kullanıcı arayüzünü oluşturun.

Bu adımları main.dart dosyasında tamamlarsınız.

REST isteğini oluşturup TensorFlow Serving'e gönderme

  1. Şu anda predict() işlevi, REST isteğini TensorFlow Serving'e göndermiyor. REST isteği oluşturmak için REST dalını uygulamanız gerekir:
if (_connectionMode == ConnectionModeType.rest) {
  // TODO: Create and send the REST request.

}
  1. Bu kodu REST dalına ekleyin:
//Create the REST request.
final response = await http.post(
  Uri.parse('http://' +
      _server +
      ':' +
      restPort.toString() +
      '/v1/models/' +
      modelName +
      ':predict'),
  body: jsonEncode(<String, List<List<int>>>{
    'instances': [_tokenIndices],
  }),
);

TensorFlow Serving'den gelen REST yanıtını işleme

  • REST yanıtını işlemek için bu kodu önceki kod snippet'inin hemen sonrasına ekleyin:
// Process the REST response.
if (response.statusCode == 200) {
  Map<String, dynamic> result = jsonDecode(response.body);
  if (result['predictions']![0][1] >= classificationThreshold) {
    return 'This sentence is spam. Spam score is ' +
        result['predictions']![0][1].toString();
  }
  return 'This sentence is not spam. Spam score is ' +
      result['predictions']![0][1].toString();
} else {
  throw Exception('Error response');
}

Sonraki işlem kodu, giriş cümlesinin spam mesaj olma olasılığını yanıttan çıkarır ve sınıflandırma sonucunu kullanıcı arayüzünde gösterir.

Çalıştırın

  1. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.
  2. Bir metin girin ve REST > Classify'ı (REST > Sınıflandır) seçin.

8e21d795af36d07a.png e79a0367a03c2169.png

9. Flutter uygulamasını gRPC aracılığıyla TensorFlow Serving'e bağlama

TensorFlow Serving, REST'in yanı sıra gRPC'yi de destekler.

b6f4449c2c850b0e.png

gRPC, herhangi bir ortamda çalışabilen modern, açık kaynaklı ve yüksek performanslı bir Uzak Prosedür Çağrısı (RPC) çerçevesidir. Yük dengeleme, izleme, sağlık kontrolü ve kimlik doğrulama için takılabilir destekle veri merkezlerindeki ve veri merkezleri arasındaki hizmetleri verimli bir şekilde bağlayabilir. gRPC'nin pratikte REST'ten daha iyi performans gösterdiği gözlemlenmiştir.

gRPC ile istek gönderme ve yanıt alma

gRPC ile istek göndermek ve yanıt almak için dört basit adım vardır:

  1. İsteğe bağlı: gRPC istemci taslağı kodunu oluşturun.
  2. gRPC isteğini oluşturun.
  3. gRPC isteğini TensorFlow Serving'e gönderin.
  4. Tahmin edilen sonucu gRPC yanıtından çıkarın ve kullanıcı arayüzünü oluşturun.

Bu adımları main.dart dosyasında tamamlarsınız.

İsteğe bağlı: gRPC istemci taslağı kodunu oluşturma

TensorFlow Serving ile gRPC'yi kullanmak için gRPC iş akışını uygulamanız gerekir. Ayrıntılar hakkında daha fazla bilgi edinmek için gRPC belgelerine bakın.

a9d0e5cb543467b4.png

TensorFlow Serving ve TensorFlow, .proto dosyalarını sizin için tanımlar. TensorFlow ve TensorFlow Serving 2.8'den itibaren şu .proto dosyaları gereklidir:

tensorflow/core/example/example.proto
tensorflow/core/example/feature.proto
tensorflow/core/protobuf/struct.proto
tensorflow/core/protobuf/saved_object_graph.proto
tensorflow/core/protobuf/saver.proto
tensorflow/core/protobuf/trackable_object_graph.proto
tensorflow/core/protobuf/meta_graph.proto
tensorflow/core/framework/node_def.proto
tensorflow/core/framework/attr_value.proto
tensorflow/core/framework/function.proto
tensorflow/core/framework/types.proto
tensorflow/core/framework/tensor_shape.proto
tensorflow/core/framework/full_type.proto
tensorflow/core/framework/versions.proto
tensorflow/core/framework/op_def.proto
tensorflow/core/framework/graph.proto
tensorflow/core/framework/tensor.proto
tensorflow/core/framework/resource_handle.proto
tensorflow/core/framework/variable.proto

tensorflow_serving/apis/inference.proto
tensorflow_serving/apis/classification.proto
tensorflow_serving/apis/predict.proto
tensorflow_serving/apis/regression.proto
tensorflow_serving/apis/get_model_metadata.proto
tensorflow_serving/apis/input.proto
tensorflow_serving/apis/prediction_service.proto
tensorflow_serving/apis/model.proto

google/protobuf/any.proto
google/protobuf/wrappers.proto
  • Terminalinizde starter/lib/proto/ klasörüne gidin ve sap oluşturun:
bash generate_grpc_stub_dart.sh

gRPC isteğini oluşturma

REST isteğine benzer şekilde, gRPC isteğini gRPC dalında oluşturursunuz.

if (_connectionMode == ConnectionModeType.rest) {

} else {
  // TODO: Create and send the gRPC request.

}
  • gRPC isteğini oluşturmak için bu kodu ekleyin:
//Create the gRPC request.
final channel = ClientChannel(_server,
    port: grpcPort,
    options:
        const ChannelOptions(credentials: ChannelCredentials.insecure()));
_stub = PredictionServiceClient(channel,
    options: CallOptions(timeout: const Duration(seconds: 10)));

ModelSpec modelSpec = ModelSpec(
  name: 'spam-detection',
  signatureName: 'serving_default',
);

TensorShapeProto_Dim batchDim = TensorShapeProto_Dim(size: Int64(1));
TensorShapeProto_Dim inputDim =
    TensorShapeProto_Dim(size: Int64(maxSentenceLength));
TensorShapeProto inputTensorShape =
    TensorShapeProto(dim: [batchDim, inputDim]);
TensorProto inputTensor = TensorProto(
    dtype: DataType.DT_INT32,
    tensorShape: inputTensorShape,
    intVal: _tokenIndices);

// If you train your own model, update the input and output tensor names.
const inputTensorName = 'input_3';
const outputTensorName = 'dense_5';
PredictRequest request = PredictRequest(
    modelSpec: modelSpec, inputs: {inputTensorName: inputTensor});

Not: Model mimarileri aynı olsa bile giriş ve çıkış tensör adları modelden modele farklılık gösterebilir. Kendi modelinizi eğitirseniz bunları güncellediğinizden emin olun.

gRPC isteğini TensorFlow Serving'e gönderme

  • TensorFlow Serving'e gRPC isteği göndermek için bu kodu önceki kod snippet'inden sonra ekleyin:
// Send the gRPC request.
PredictResponse response = await _stub.predict(request);

TensorFlow Serving'den gelen gRPC yanıtını işleme

  • Yanıtı işlemek için geri çağırma işlevlerini uygulamak üzere bu kodu önceki kod snippet'inin sonrasına ekleyin:
// Process the response.
if (response.outputs.containsKey(outputTensorName)) {
  if (response.outputs[outputTensorName]!.floatVal[1] >
      classificationThreshold) {
    return 'This sentence is spam. Spam score is ' +
        response.outputs[outputTensorName]!.floatVal[1].toString();
  } else {
    return 'This sentence is not spam. Spam score is ' +
        response.outputs[outputTensorName]!.floatVal[1].toString();
  }
} else {
  throw Exception('Error response');
}

Şimdi de son işleme kodu, sınıflandırma sonucunu yanıttan çıkarıp kullanıcı arayüzünde gösteriyor.

Çalıştırın

  1. a19a0c68bc4046e6.png Hata ayıklamayı başlat'ı tıklayın ve uygulamanın yüklenmesini bekleyin.
  2. Bir metin girin ve gRPC > Classify'ı (gRPC > Sınıflandır) seçin.

e44e6e9a5bde2188.png 92644d723f61968c.png

10. Tebrikler

Uygulamanıza metin sınıflandırma özellikleri eklemek için TensorFlow Serving'i kullandınız.

Bir sonraki codelab'de, mevcut uygulama tarafından algılanamayan belirli spam mesajları algılayabilmek için modeli geliştireceksiniz.

Daha fazla bilgi