یک برنامه Flutter برای طبقه بندی متون ایجاد کنید

1. قبل از شروع

در این کد لبه، شما یاد می گیرید که چگونه یک استنتاج طبقه بندی متن را از یک برنامه Flutter با سرویس TensorFlow از طریق REST و gRPC اجرا کنید.

پیش نیازها

چیزی که یاد خواهید گرفت

  • چگونه یک برنامه Flutter ساده بسازیم و متون را از طریق سرویس TensorFlow (REST و gRPC) طبقه بندی کنیم.
  • نحوه نمایش نتایج در رابط کاربری

آنچه شما نیاز دارید

2. محیط توسعه Flutter خود را تنظیم کنید

برای توسعه Flutter، برای تکمیل این آزمایشگاه به دو نرم افزار نیاز دارید - Flutter SDK و یک ویرایشگر .

شما می توانید کدلب را با استفاده از هر یک از این دستگاه ها اجرا کنید:

  • شبیه ساز iOS (نیاز به نصب ابزار Xcode دارد).
  • شبیه ساز اندروید (نیاز به نصب در Android Studio دارد).
  • یک مرورگر (Chrome برای اشکال زدایی لازم است).
  • به عنوان یک برنامه دسکتاپ Windows ، Linux ، یا macOS . شما باید روی پلتفرمی که قصد استقرار در آن را دارید توسعه دهید. بنابراین، اگر می خواهید یک برنامه دسکتاپ ویندوز توسعه دهید، باید در ویندوز توسعه دهید تا به زنجیره ساخت مناسب دسترسی داشته باشید. الزامات خاص سیستم عامل وجود دارد که به طور مفصل در docs.flutter.dev/desktop پوشش داده شده است.

3. راه اندازی شوید

برای دانلود کد این کد لبه:

  1. به مخزن GitHub برای این Codelab بروید.
  2. روی Code > Download zip کلیک کنید تا همه کدهای این کد لبه را دانلود کنید.

2cd45599f51fb8a2.png

  1. فایل فشرده دانلود شده را از حالت فشرده خارج کنید تا یک پوشه codelabs-main با تمام منابعی که نیاز دارید باز شود.

برای این کد لبه، شما فقط به فایل های موجود در زیر شاخه tfserving-flutter/codelab2 در مخزن نیاز دارید که شامل دو پوشه است:

  • پوشه starter حاوی کد شروعی است که برای این کد لبه ایجاد می کنید.
  • پوشه finished حاوی کد تکمیل شده برای برنامه نمونه تمام شده است.

4. وابستگی های پروژه را دانلود کنید

  1. در VS Code، روی File > Open folder کلیک کنید و سپس پوشه starter را از کد منبعی که قبلا دانلود کرده اید انتخاب کنید.
  2. اگر گفتگویی ظاهر می‌شود که از شما می‌خواهد بسته‌های مورد نیاز برنامه شروع را دانلود کنید، روی دریافت بسته‌ها کلیک کنید.
  3. اگر این گفتگو را نمی بینید، ترمینال خود را باز کنید و سپس دستور flutter pub get در پوشه starter اجرا کنید.

7ada07c300f166a6.png

5. برنامه استارتر را اجرا کنید

  1. در VS Code، مطمئن شوید که شبیه ساز اندروید یا شبیه ساز iOS به درستی تنظیم شده و در نوار وضعیت ظاهر می شود.

برای مثال، وقتی از Pixel 5 با شبیه‌ساز اندروید استفاده می‌کنید، این چیزی است که می‌بینید:

9767649231898791.png

در اینجا چیزی است که هنگام استفاده از iPhone 13 با شبیه ساز iOS مشاهده می کنید:

95529e3a682268b2.png

  1. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید .

برنامه را اجرا و کاوش کنید

این برنامه باید در شبیه ساز اندروید یا شبیه ساز iOS شما راه اندازی شود. رابط کاربری بسیار ساده است. یک فیلد متنی وجود دارد که به کاربر اجازه می دهد متن را تایپ کند. کاربر می تواند انتخاب کند که داده ها را با REST یا gRPC به backend ارسال کند. پشتیبان از یک مدل TensorFlow برای انجام طبقه‌بندی متن در ورودی از پیش پردازش شده استفاده می‌کند و نتیجه طبقه‌بندی را به برنامه مشتری برمی‌گرداند، که به نوبه خود UI را به‌روزرسانی می‌کند.

b298f605d64dc132.pngd3ef3ccd3c338108.png

اگر روی Classify کلیک کنید، هیچ اتفاقی نمی افتد زیرا هنوز نمی تواند با backend ارتباط برقرار کند.

6. یک مدل طبقه‌بندی متن را با سرویس TensorFlow اجرا کنید

طبقه بندی متن یک کار یادگیری ماشینی بسیار رایج است که متون را به دسته های از پیش تعریف شده طبقه بندی می کند. در این کد لبه، شما مدل از پیش آموزش‌دیده‌شده Train یک مدل تشخیص هرزنامه-نظر را با کد لبه TensorFlow Lite Model Maker با سرویس TensorFlow اجرا می‌کنید و باطن را از Flutter frontend خود فراخوانی می‌کنید تا متن ورودی را به عنوان هرزنامه یا غیر هرزنامه طبقه‌بندی کنید.

سرویس TensorFlow را شروع کنید

  • در ترمینال خود، سرویس TensorFlow را با Docker شروع کنید، اما مکان‌دار PATH/TO/SAVEDMODEL را با مسیر مطلق پوشه mm_spam_savedmodel در رایانه خود جایگزین کنید.
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 به طور خودکار ابتدا تصویر TensorFlow Serving را دانلود می کند که یک دقیقه طول می کشد. پس از آن، سرویس TensorFlow باید شروع شود. گزارش باید شبیه این قطعه کد باشد:

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. جمله ورودی را نشانه گذاری کنید

Backend اکنون آماده است، بنابراین شما تقریبا آماده ارسال درخواست های مشتری به TensorFlow Serving هستید، اما ابتدا باید جمله ورودی را نشانه گذاری کنید. اگر تانسور ورودی مدل را بررسی کنید، می بینید که به جای رشته های خام، لیستی از 20 عدد صحیح را انتظار دارد. توکن‌سازی زمانی است که کلمات جداگانه‌ای را که در برنامه تایپ می‌کنید به فهرستی از اعداد صحیح بر اساس فرهنگ لغات قبل از ارسال آنها به باطن برای طبقه‌بندی نگاشت می‌کنید. به عنوان مثال، اگر buy book online to learn more را تایپ کنید، فرآیند توکن سازی آن را به [32, 79, 183, 10, 224, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] . اعداد خاص می توانند بر اساس فرهنگ لغات متفاوت باشند.

  1. در فایل lib/main.dart ، این کد را به متد predict() اضافه کنید تا فرهنگ لغات _vocabMap بسازید.
// 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. بلافاصله پس از قطعه کد قبلی، این کد را برای پیاده سازی توکن سازی اضافه کنید:
// 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;
  }
}

این کد رشته جمله را کوچک می کند، کاراکترهای غیر الفبا را حذف می کند و کلمات را بر اساس جدول واژگان به 20 شاخص عدد صحیح نگاشت می کند.

8. برنامه Flutter را با سرویس TensorFlow از طریق REST وصل کنید

دو راه برای ارسال درخواست به سرویس TensorFlow وجود دارد:

  • استراحت
  • gRPC

ارسال درخواست و دریافت پاسخ از طریق REST

سه مرحله ساده برای ارسال درخواست و دریافت پاسخ از طریق REST وجود دارد:

  1. درخواست REST را ایجاد کنید.
  2. درخواست REST را به سرویس TensorFlow ارسال کنید.
  3. نتیجه پیش‌بینی‌شده را از پاسخ REST استخراج کنید و UI را رندر کنید.

این مراحل را در فایل main.dart کامل می کنید.

ایجاد و ارسال درخواست REST به TensorFlow Serving

  1. در حال حاضر، تابع predict() درخواست REST را به TensorFlow Serving ارسال نمی کند. برای ایجاد یک درخواست REST باید شاخه REST را پیاده سازی کنید:
if (_connectionMode == ConnectionModeType.rest) {
  // TODO: Create and send the REST request.

}
  1. این کد را به شاخه REST اضافه کنید:
//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],
  }),
);

پاسخ REST را از سرویس TensorFlow پردازش کنید

  • این کد را درست بعد از قطعه کد قبلی اضافه کنید تا پاسخ REST را مدیریت کنید:
// 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');
}

کد پس پردازش احتمال اینکه جمله ورودی یک پیام هرزنامه باشد را از پاسخ استخراج می کند و نتیجه طبقه بندی را در UI نمایش می دهد.

اجراش کن

  1. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید و سپس منتظر بمانید تا برنامه بارگیری شود.
  2. متنی را وارد کنید و سپس REST > Classify را انتخاب کنید.

8e21d795af36d07a.pnge79a0367a03c2169.png

9. برنامه Flutter را با سرویس TensorFlow از طریق gRPC متصل کنید

علاوه بر REST، سرویس TensorFlow از gRPC نیز پشتیبانی می کند.

b6f4449c2c850b0e.png

gRPC یک چارچوب مدرن، متن باز و با کارایی بالا Remote Procedure Call (RPC) است که می تواند در هر محیطی اجرا شود. این می تواند به طور موثر خدمات را در مراکز داده و در سراسر آنها با پشتیبانی قابل اتصال برای تعادل بار، ردیابی، بررسی سلامت و احراز هویت متصل کند. مشاهده شده است که gRPC در عمل عملکرد بیشتری نسبت به REST دارد.

ارسال درخواست و دریافت پاسخ با gRPC

چهار مرحله ساده برای ارسال درخواست و دریافت پاسخ با gRPC وجود دارد:

  1. اختیاری: کد خرد مشتری gRPC را ایجاد کنید.
  2. درخواست gRPC را ایجاد کنید.
  3. درخواست gRPC را به سرویس TensorFlow ارسال کنید.
  4. نتیجه پیش‌بینی‌شده را از پاسخ gRPC استخراج کنید و UI را رندر کنید.

این مراحل را در فایل main.dart کامل می کنید.

اختیاری: کد خرد مشتری gRPC را ایجاد کنید

برای استفاده از gRPC با سرویس TensorFlow، باید گردش کار gRPC را دنبال کنید. برای کسب اطلاعات بیشتر در مورد جزئیات، به مستندات gRPC مراجعه کنید.

a9d0e5cb543467b4.png

TensorFlow Serving و TensorFlow فایل های .proto را برای شما تعریف می کنند. در مورد TensorFlow و TensorFlow Serving 2.8، این فایل‌های .proto موارد مورد نیاز هستند:

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
  • در ترمینال خود، به پوشه starter/lib/proto/ بروید و خرد را ایجاد کنید:
bash generate_grpc_stub_dart.sh

درخواست gRPC را ایجاد کنید

مشابه درخواست REST، شما درخواست gRPC را در شاخه gRPC ایجاد می کنید.

if (_connectionMode == ConnectionModeType.rest) {

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

}
  • این کد را برای ایجاد درخواست gRPC اضافه کنید:
//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});

توجه: نام تانسور ورودی و خروجی ممکن است از مدلی به مدل دیگر متفاوت باشد، حتی اگر معماری مدل یکسان باشد. اگر مدل خود را آموزش می دهید، مطمئن شوید که آنها را به روز کنید.

درخواست gRPC را به سرویس TensorFlow ارسال کنید

  • این کد را بعد از قطعه کد قبلی اضافه کنید تا درخواست gRPC به سرویس TensorFlow ارسال شود:
// Send the gRPC request.
PredictResponse response = await _stub.predict(request);

پاسخ gRPC را از سرویس TensorFlow پردازش کنید

  • این کد را پس از قطعه کد قبلی اضافه کنید تا توابع پاسخ به تماس را برای مدیریت پاسخ اجرا کنید:
// 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');
}

اکنون کد پس پردازش، نتیجه طبقه بندی را از پاسخ استخراج کرده و در UI نمایش می دهد.

اجراش کن

  1. کلیک کنید a19a0c68bc4046e6.png اشکال زدایی را شروع کنید و سپس منتظر بمانید تا برنامه بارگیری شود.
  2. مقداری متن را وارد کنید و سپس gRPC > Classify را انتخاب کنید.

e44e6e9a5bde2188.png92644d723f61968c.png

10. تبریک می گویم

شما از TensorFlow Serving برای افزودن قابلیت های طبقه بندی متن به برنامه خود استفاده کردید!

در کدهای بعدی، مدل را بهبود می‌بخشید تا بتوانید پیام‌های هرزنامه خاصی را شناسایی کنید که توسط برنامه فعلی قابل شناسایی نیستند.

بیشتر بدانید