یک برنامه iOS برای پیش بینی مقادیر ایجاد کنید

1. قبل از شروع

در این کد لبه، یاد می گیرید که چگونه یک استنتاج رگرسیون را از یک برنامه iOS با استفاده از سرویس TensorFlow با REST و gRPC اجرا کنید.

پیش نیازها

  • دانش اولیه توسعه iOS با Swift
  • دانش اولیه یادگیری ماشین با TensorFlow، مانند آموزش و استقرار
  • دانش پایه همکاری
  • دانش اولیه ترمینال ها، پایتون و داکر

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

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

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

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

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

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

a72f2bb4caa9a96.png

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

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

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

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

پادهای مورد نیاز را دانلود کنید

  • در پوشه starter/iOS ، اجرا کنید:
pod install

Cocoapods تمام کتابخانه های لازم را نصب می کند و یک فایل regression.xcworkspace جدید ایجاد می کند.

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

  • روی فایل regression.xcworkspace دوبار کلیک کنید تا Xcode باز شود.

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

  1. هدف دستگاه را به هر آیفونی مانند آیفون 13 تغییر دهید.

a57198a4f21f970.png

  1. کلیک cacc15c5638260ed.png 'Run' ، و سپس منتظر بمانید تا Xcode پروژه را کامپایل کند و برنامه شروع را در Simulator راه اندازی کند.

رابط کاربری بسیار ساده است. یک کادر متنی وجود دارد که در آن می توانید عددی را تایپ کنید که با REST یا gRPC به باطن سرویس TensorFlow ارسال می شود. Backend روی مقدار ورودی رگرسیون انجام می دهد و مقدار پیش بینی شده را به برنامه مشتری برمی گرداند، که نتیجه را دوباره در UI نمایش می دهد.

d2976072474ce0b1.png

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

5. یک مدل رگرسیون ساده با TensorFlow آموزش دهید

رگرسیون یکی از رایج ترین کارهای ML است. هدف آن پیش‌بینی یک کمیت پیوسته بر اساس ورودی است. برای مثال، بر اساس هوای امروز، بالاترین دما را فردا پیش بینی کنید.

یک مدل رگرسیون را آموزش دهید

  1. این لینک را در مرورگر خود باز کنید.

Colab نوت بوک پایتون را بارگذاری می کند.

  1. در نوت بوک پایتون، کتابخانه های TensorFlow و NumPy را وارد کنید و سپس شش جفت داده آموزشی با xs به عنوان ورودی و ys به عنوان برچسب ایجاد کنید.

اگر این نقاط داده را روی یک نمودار رسم کنید، در واقع در یک خط مستقیم قرار می گیرند زیرا از معادله y = 2 x -1 تولید می شوند.

56d05252cfc9df9d.png

  1. از Keras API برای ایجاد یک شبکه عصبی دو لایه ساده برای پیش بینی مقدار y بر اساس ورودی x استفاده کنید و سپس مدل را کامپایل و متناسب کنید.
xs = np.array([-1.0,  0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)

model = tf.keras.Sequential([
   tf.keras.layers.Dense(units=10, input_shape=[1]),
   tf.keras.layers.Dense(units=1),
   ])

model.compile(optimizer='sgd',
             loss='mean_squared_error')

history = model.fit(xs, ys, epochs=500, verbose=0)

print("Finished training the model")

print(model.predict([10.0]))

آموزش این مدل چند ثانیه طول می کشد و می توانید مقدار پیش بینی شده برای ورودی 10 را 18.999996 ، که پیش بینی بسیار خوبی است زیرا حقیقت زمینی 2 * 10 -1 = 19 است.

  1. صادرات مدل:
model_dir = './regression/'
version = 123
export_path = os.path.join(model_dir, str(version))
model.save(export_path, save_format="tf")
print('\nexport_path = {}'.format(export_path))
!ls -l {export_path}
  1. SavedModel صادر شده را در یک فایل regression.zip زیپ کنید:
!zip -r regression.zip ./regression
  1. روی Runtime > Run all در منوی ناوبری کلیک کنید تا نوت بوک اجرا شود و سپس منتظر بمانید تا اجرا به پایان برسد.
  2. کلیک c55600d42359f901.png فایل و سپس فایل regression.zip را دانلود کنید.

bceda15d86571583.png

6. یک مدل رگرسیون را با سرویس TensorFlow اجرا کنید

  • برای استقرار مدل با سرویس TensorFlow، فایل regression.zip دانلود شده را با یک ابزار رفع فشرده سازی، مانند 7-Zip از حالت فشرده خارج کنید.

ساختار پوشه باید مانند تصویر زیر باشد:

7faeb4f03af39646.png

می توانید به پوشه regression به عنوان پوشه SavedModel کنید. 123 یک نمونه نسخه شماره است. در صورت تمایل می توانید شماره دیگری را انتخاب کنید.

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

  • در ترمینال خود، سرویس TensorFlow را با Docker شروع کنید، اما PATH/TO/SAVEDMODEL را با مسیر مطلق پوشه regression در رایانه خود جایگزین کنید.
docker pull tensorflow/serving

docker run -it --rm -p 8500:8500 -p 8501:8501 -v "PATH/TO/SAVEDMODEL:/models/regression" -e MODEL_NAME=regression 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: regression 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. برنامه iOS را با سرویس TensorFlow از طریق REST متصل کنید

Backend اکنون آماده است، بنابراین می‌توانید درخواست‌های مشتری را برای پیش‌بینی به TensorFlow Serving ارسال کنید. دو راه برای ارسال درخواست به سرویس TensorFlow وجود دارد:

  • باقی مانده
  • gRPC

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

سه مرحله ساده وجود دارد:

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

این مراحل را در فایل iOS/regression/ViewController.swift انجام می دهید.

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

  1. در حال حاضر، تابع doInference() درخواست REST را به TensorFlow Serving ارسال نمی کند. برای ایجاد یک درخواست REST باید این شاخه REST را پیاده سازی کنید:
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
    print("Using REST")
    // TODO: Add code to send a REST request to TensorFlow Serving.
    
}

TensorFlow Serving انتظار دارد یک درخواست POST حاوی یک مقدار واحد باشد، بنابراین باید مقدار ورودی را در JSON جاسازی کنید، که بار بار درخواست است.

  1. این کد را به شاخه REST اضافه کنید:
//Create the REST request.
let json: [String: Any] = ["signature_name" : "serving_default", "instances" : [[value]]]

let jsonData = try? JSONSerialization.data(withJSONObject: json)

let url = URL(string: "http://localhost:8501/v1/models/regression:predict")!
var request = URLRequest(url: url)
request.httpMethod = "POST"

// Insert JSON data into the request.
request.httpBody = jsonData

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

  • این کد را بلافاصله بعد از کد در شاخه REST اضافه کنید:
// Send the REST request.
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {
        print(error?.localizedDescription ?? "No data")
        return
    }
    
    // TODO: Add code to process the response.
}

task.resume()

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

  • این کد را بلافاصله بعد از TODO: Add code to process the response. اظهار نظر:
// Process the REST response.
let results: RESTResults = try! JSONDecoder().decode(RESTResults.self, from: data)
DispatchQueue.main.async{
    self.txtOutput.text = String(results.predictions[0][0])
}

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

آن را اجرا کنید

  1. کلیک cacc15c5638260ed.png را اجرا کنید و سپس منتظر بمانید تا Xcode برنامه را در Simulator راه اندازی کند.
  2. یک عدد را در کادر متن وارد کنید و سپس روی Infer کلیک کنید.

اکنون یک مقدار پیش بینی شده را در رابط کاربری مشاهده می کنید.

df9bcb9aa21bb30e.png

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

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

b6f4449c2c850b0e.png

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

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

چهار مرحله ساده وجود دارد:

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

این مراحل را در فایل iOS/regression/ViewController.swift انجام می دهید.

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

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

a9d0e5cb543467b4.png

TensorFlow Serving و .proto فایل های .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

برای تولید کد خرد مشتری gRPC:

  1. در ترمینال خود، به پوشه starter/src/proto/ بروید و سپس خرد را ایجاد کنید:
bash generate_grpc_stub_swift.sh

تعدادی فایل .swift در پوشه starter/src/proto/generated/import .

  1. اگر هنوز در پروژه شما کپی نشده اند، تمام فایل های .swift تولید شده را در Xcode به داخل پروژه خود بکشید.

9e65705cf6be7aac.png

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

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

if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
    
}
else {
    print("Using gRPC")
    // TODO: add code to send a gRPC request to TF Serving
    
}
  • برای ایجاد درخواست gRPC، این کد را به شاخه gRPC اضافه کنید:
//Create the gRPC request.
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let channel = ClientConnection.insecure(group: group).connect(host: "localhost", port: 8500)
let stub = Tensorflow_Serving_PredictionServiceClient(channel: channel)

var modelSpec = Tensorflow_Serving_ModelSpec()
modelSpec.name = "regression"
modelSpec.signatureName = "serving_default"

// Prepare the input tensor.
var batchDim = Tensorflow_TensorShapeProto.Dim()
batchDim.size = 1
var inputDim = Tensorflow_TensorShapeProto.Dim()
inputDim.size = 1
var inputTensorShape = Tensorflow_TensorShapeProto()
inputTensorShape.dim = [batchDim, inputDim]
var inputTensor = Tensorflow_TensorProto()
inputTensor.dtype = Tensorflow_DataType.dtFloat
inputTensor.tensorShape = inputTensorShape
inputTensor.floatVal = [Float(value)]

var request = Tensorflow_Serving_PredictRequest()
request.modelSpec = modelSpec
request.inputs = ["dense_input" : inputTensor]

let callOptions = CallOptions(timeLimit: .timeout(.seconds(15)))

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

  • بلافاصله پس از کد موجود در قطعه کد قبلی، این کد را به شاخه gRPC اضافه کنید:
// Send the gRPC request.
let call = stub.predict(request, callOptions: callOptions)

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

  • این کد را بلافاصله بعد از کد موجود در قطعه کد قبلی اضافه کنید:
// Process the response.
call.response.whenSuccess { response in
    let result = response.outputs["dense_1"]?.floatVal[0]
    DispatchQueue.main.async{
        self.txtOutput.text = String(describing: result!)
    }
}
call.response.whenFailure { error in
    print("Call failed with error\n\(error)")
}

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

آن را اجرا کنید

  1. کلیک cacc15c5638260ed.png در منوی پیمایش «اجرا» کنید و سپس منتظر بمانید تا Xcode برنامه را در Simulator راه اندازی کند.
  2. یک عدد را در کادر متن وارد کنید و سپس روی Infer کلیک کنید.

اکنون یک مقدار پیش بینی شده را در رابط کاربری مشاهده می کنید.

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

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

بیشتر بدانید