درباره این codelab
1. قبل از اینکه شروع کنی
در این کد لبه، یاد می گیرید که چگونه یک استنتاج رگرسیون را از یک برنامه iOS با استفاده از سرویس TensorFlow با REST و gRPC اجرا کنید.
پیش نیازها
- دانش اولیه توسعه iOS با Swift
- دانش اولیه یادگیری ماشین با TensorFlow، مانند آموزش و استقرار
- دانش پایه همکاری
- دانش اولیه ترمینال ها، پایتون و داکر
چیزی که یاد خواهید گرفت
- چگونه یک مدل رگرسیون را با TensorFlow آموزش دهیم.
- چگونه یک برنامه ساده iOS بسازیم و با مدل آموزش دیده از طریق سرویس TensorFlow (REST و gRPC) پیش بینی کنیم.
- نحوه نمایش نتیجه در رابط کاربری
آنچه شما نیاز دارید
- دسترسی به Colab
- آخرین نسخه Xcode
- CocoaPods
- داکر
- ضربه شدید
- کامپایلر بافر پروتکل (فقط در صورتی لازم است که بخواهید مقاله خرد gRPC را خودتان دوباره تولید کنید)
- پلاگین تولید کننده کد gRPC-swift (فقط در صورتی لازم است که بخواهید مقاله خرد gRPC را خودتان تولید کنید)
2. راه اندازی شود
برای دانلود کد این کد لبه:
- به مخزن GitHub برای این Codelab بروید.
- روی Code > Download zip کلیک کنید تا همه کدهای این کد لبه را دانلود کنید.
- فایل زیپ دانلود شده را از حالت فشرده خارج کنید تا یک پوشه root
codelabs
با تمام منابعی که نیاز دارید باز شود.
برای این کد لبه، شما فقط به فایل های موجود در زیر شاخه TFServing/RegressioniOS
در مخزن نیاز دارید که شامل دو پوشه است:
- پوشه
starter
حاوی کد شروعی است که برای این Codelab بر اساس آن ساخته اید. - پوشه
finished
شده حاوی کد تکمیل شده برای برنامه نمونه تمام شده است.
3. وابستگی های پروژه را دانلود کنید
پادهای مورد نیاز را دانلود کنید
- در پوشه
starter/iOS
، اجرا کنید:
pod install
Cocoapods تمام کتابخانه های لازم را نصب می کند و یک فایل regression.xcworkspace
جدید ایجاد می کند.
4. برنامه استارتر را اجرا کنید
- روی فایل
regression.xcworkspace
دوبار کلیک کنید تا Xcode باز شود.
برنامه را اجرا و کاوش کنید
- هدف دستگاه را به هر آیفونی مانند آیفون 13 تغییر دهید.
- کلیک
'Run' ، و سپس منتظر بمانید تا Xcode پروژه را کامپایل کند و برنامه شروع را در Simulator راه اندازی کند.
رابط کاربری بسیار ساده است. یک کادر متنی وجود دارد که در آن می توانید عددی را تایپ کنید که با REST یا gRPC به باطن سرویس TensorFlow ارسال می شود. Backend روی مقدار ورودی رگرسیون انجام می دهد و مقدار پیش بینی شده را به برنامه مشتری برمی گرداند، که نتیجه را دوباره در UI نمایش می دهد.
اگر عددی را وارد کنید و Infer را کلیک کنید، هیچ اتفاقی نمیافتد زیرا برنامه هنوز نمیتواند با backend ارتباط برقرار کند.
5. یک مدل رگرسیون ساده با TensorFlow آموزش دهید
رگرسیون یکی از رایج ترین کارهای ML است. هدف آن پیشبینی یک کمیت پیوسته بر اساس ورودی است. برای مثال، بر اساس هوای امروز، بالاترین دما را فردا پیش بینی کنید.
یک مدل رگرسیون را آموزش دهید
- این لینک را در مرورگر خود باز کنید.
Colab نوت بوک پایتون را بارگذاری می کند.
- در نوت بوک پایتون، کتابخانه های
TensorFlow
وNumPy
را وارد کنید و سپس شش جفت داده آموزشی باxs
به عنوان ورودی وys
به عنوان برچسب ایجاد کنید.
اگر این نقاط داده را روی یک نمودار رسم کنید، در واقع در یک خط مستقیم قرار می گیرند زیرا از معادله y = 2 x -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 است.
- صادرات مدل:
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}
- SavedModel صادر شده را در یک فایل
regression.zip
زیپ کنید:
!zip -r regression.zip ./regression
- روی Runtime > Run all در منوی ناوبری کلیک کنید تا نوت بوک اجرا شود و سپس منتظر بمانید تا اجرا به پایان برسد.
- کلیک
فایل و سپس فایل
regression.zip
را دانلود کنید.
6. استقرار یک مدل رگرسیون با سرویس TensorFlow
- برای استقرار مدل با سرویس TensorFlow، فایل
regression.zip
دانلود شده را با یک ابزار رفع فشرده سازی، مانند 7-Zip از حالت فشرده خارج کنید.
ساختار پوشه باید مانند تصویر زیر باشد:
می توانید به پوشه 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
سه مرحله ساده وجود دارد:
- درخواست REST را ایجاد کنید.
- درخواست REST را به سرویس TensorFlow ارسال کنید.
- نتیجه پیشبینیشده را از پاسخ REST استخراج کنید و UI را رندر کنید.
این مراحل را در فایل iOS/regression/ViewController.swift
انجام می دهید.
درخواست REST را ایجاد کنید
- در حال حاضر، تابع
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 جاسازی کنید، که بار بار درخواست است.
- این کد را به شاخه 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 نمایش می دهد.
آن را اجرا کنید
- کلیک
را اجرا کنید و سپس منتظر بمانید تا Xcode برنامه را در Simulator راه اندازی کند.
- یک عدد را در کادر متن وارد کنید و سپس روی Infer کلیک کنید.
اکنون یک مقدار پیش بینی شده را در رابط کاربری مشاهده می کنید.
8. برنامه iOS را با سرویس TensorFlow از طریق gRPC متصل کنید
علاوه بر REST، سرویس TensorFlow از gRPC نیز پشتیبانی می کند.
gRPC یک چارچوب مدرن، متن باز و با کارایی بالا Remote Procedure Call (RPC) است که می تواند در هر محیطی اجرا شود. این می تواند به طور موثر خدمات را در مراکز داده و در سراسر آنها با پشتیبانی قابل اتصال برای تعادل بار، ردیابی، بررسی سلامت و احراز هویت متصل کند. مشاهده شده است که gRPC در عمل عملکرد بیشتری نسبت به REST دارد.
ارسال درخواست و دریافت پاسخ با gRPC
چهار مرحله ساده وجود دارد:
- اختیاری: کد خرد مشتری gRPC را ایجاد کنید.
- درخواست gRPC را ایجاد کنید.
- درخواست gRPC را به سرویس TensorFlow ارسال کنید.
- نتیجه پیشبینیشده را از پاسخ gRPC استخراج کنید و UI را رندر کنید.
این مراحل را در فایل iOS/regression/ViewController.swift
انجام می دهید.
اختیاری: کد خرد مشتری gRPC را ایجاد کنید
برای استفاده از gRPC با سرویس TensorFlow، باید گردش کار gRPC را دنبال کنید. برای کسب اطلاعات بیشتر در مورد جزئیات، به مستندات gRPC مراجعه کنید.
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:
- در ترمینال خود، به پوشه
starter/src/proto/
بروید و سپس خرد را ایجاد کنید:
bash generate_grpc_stub_swift.sh
تعدادی فایل .swift
در پوشه starter/src/proto/generated/import
.
- اگر هنوز در پروژه شما کپی نشده اند، تمام فایل های
.swift
تولید شده را در Xcode به داخل پروژه خود بکشید.
درخواست 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 نمایش می دهد.
آن را اجرا کنید
- کلیک
در منوی پیمایش «اجرا» کنید و سپس منتظر بمانید تا Xcode برنامه را در Simulator راه اندازی کند.
- یک عدد را در کادر متن وارد کنید و سپس روی Infer کلیک کنید.
اکنون یک مقدار پیش بینی شده را در رابط کاربری مشاهده می کنید.
9. تبریک می گویم
شما از TensorFlow Serving برای افزودن قابلیت های رگرسیون به برنامه خود استفاده کردید!