Создайте приложение iOS для прогнозирования значений

Создайте приложение iOS для прогнозирования значений

О практической работе

subjectПоследнее обновление: апр. 8, 2022
account_circleАвторы: Wei Wei

1. Прежде чем вы начнете

В этой лабораторной работе вы узнаете, как выполнить вывод регрессии из приложения iOS, используя TensorFlow Serving с REST и gRPC.

Предпосылки

  • Базовые знания iOS-разработки на Swift.
  • Базовые знания машинного обучения с TensorFlow, такие как обучение и развертывание
  • Базовые знания Колаборатории
  • Базовые знания терминалов, Python и Docker

Что вы узнаете

  • Как обучить регрессионную модель с помощью TensorFlow.
  • Как создать простое приложение для iOS и делать прогнозы с помощью обученной модели с помощью TensorFlow Serving (REST и gRPC).
  • Как отобразить результат в пользовательском интерфейсе.

Что вам понадобится

2. Настроить

Чтобы скачать код для этой кодлабы:

  1. Перейдите в репозиторий GitHub для этой лаборатории кода.
  2. Нажмите « Код» > «Загрузить zip» , чтобы загрузить весь код для этой лаборатории кода.

a72f2bb4caa9a96.png

  1. Разархивируйте загруженный zip-файл, чтобы распаковать корневую папку codelabs со всеми необходимыми ресурсами.

Для этой лаборатории кода вам нужны только файлы в подкаталоге TFServing/RegressioniOS в репозитории, который содержит две папки:

  • starter папка содержит начальный код, на основе которого вы строите эту лабораторию кода.
  • finished папка содержит завершенный код для готового примера приложения.

3. Скачать зависимости для проекта

Загрузите необходимые модули

  • В папке starter/iOS запустите:
pod install

Cocoapods установит все необходимые библиотеки и создаст новый файл regression.xcworkspace .

4. Запустите стартовое приложение

  • Дважды щелкните файл regression.xcworkspace , чтобы открыть Xcode.

Запустите и исследуйте приложение

  1. Измените целевое устройство на любой iPhone, например iPhone 13.

a57198a4f21f970.png

  1. Нажмите cacc15c5638260ed.png 'Run' , а затем подождите, пока Xcode скомпилирует проект и запустит начальное приложение в симуляторе.

Пользовательский интерфейс довольно прост. Есть текстовое поле, в котором вы можете ввести число, которое отправляется на серверную часть TensorFlow Serving с помощью REST или gRPC. Серверная часть выполняет регрессию для входного значения и возвращает прогнозируемое значение клиентскому приложению, которое снова отображает результат в пользовательском интерфейсе.

d2976072474ce0b1.png

Если вы введете число и нажмете Infer , ничего не произойдет, потому что приложение еще не может взаимодействовать с серверной частью.

5. Обучите простую модель регрессии с помощью TensorFlow

Регрессия — одна из самых распространенных задач машинного обучения. Его цель состоит в том, чтобы предсказать одну непрерывную величину на основе входных данных. Например, исходя из сегодняшней погоды, предсказать самую высокую температуру завтра.

Обучить регрессионную модель

  1. Откройте эту ссылку в своем браузере.

Colab загружает блокнот Python.

  1. В записной книжке Python импортируйте библиотеки 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 Files , а затем загрузите файл regression.zip .

bceda15d86571583.png

6. Развертывание модели регрессии с помощью TensorFlow Serving

  • Чтобы развернуть модель с помощью TensorFlow Serving, распакуйте загруженный файл regression.zip с помощью инструмента распаковки, например 7-Zip.

Структура папок должна выглядеть так:

7faeb4f03af39646.png

Вы можете ссылаться на папку regression как на папку SavedModel . 123 — пример номера версии. Если хотите, можете выбрать другой номер.

Запустить обслуживание TensorFlow

  • В терминале запустите TensorFlow Serving с 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 Serving. Журнал должен выглядеть как этот фрагмент кода:

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 Serving через REST.

Теперь серверная часть готова, поэтому вы можете отправлять клиентские запросы в TensorFlow Serving, чтобы делать прогнозы. Есть два способа отправки запросов в TensorFlow Serving:

  • ОТДЫХАТЬ
  • gRPC

Отправляйте запросы и получайте ответы с помощью REST

Есть три простых шага:

  1. Создайте REST-запрос.
  2. Отправьте запрос REST в TensorFlow Serving.
  3. Извлеките прогнозируемый результат из ответа REST и визуализируйте пользовательский интерфейс.

Вы выполняете эти шаги в файле 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 Serving.

  • Добавьте этот код сразу после кода в ветке 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 Serving

  • Добавьте этот код к предыдущему фрагменту кода сразу после 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])
}

Теперь функция постобработки извлекает предсказанные значения из ответа и отображает результат в пользовательском интерфейсе.

Запустить его

  1. Нажмите cacc15c5638260ed.png «Запустить», а затем подождите, пока Xcode запустит приложение в симуляторе.
  2. Введите число в текстовое поле и нажмите Infer .

Теперь вы видите прогнозируемое значение в пользовательском интерфейсе.

df9bcb9aa21bb30e.png

8. Подключите приложение iOS к TensorFlow Serving через gRPC.

Помимо REST, TensorFlow Serving также поддерживает gRPC .

b6f4449c2c850b0e.png

gRPC — это современная высокопроизводительная платформа удаленного вызова процедур (RPC) с открытым исходным кодом, которая может работать в любой среде. Он может эффективно подключать службы в центрах обработки данных и между ними с подключаемой поддержкой балансировки нагрузки, трассировки, проверки работоспособности и аутентификации. Было замечено, что на практике gRPC более эффективен, чем REST.

Отправляйте запросы и получайте ответы с помощью gRPC

Всего четыре простых шага:

  1. Необязательно: сгенерируйте код-заглушку клиента gRPC.
  2. Создайте запрос gRPC.
  3. Отправьте запрос gRPC в TensorFlow Serving.
  4. Извлеките прогнозируемый результат из ответа gRPC и визуализируйте пользовательский интерфейс.

Вы выполняете эти шаги в файле iOS/regression/ViewController.swift .

Необязательно: сгенерируйте код-заглушку клиента gRPC.

Чтобы использовать gRPC с TensorFlow Serving, вам необходимо следовать рабочему процессу 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

Чтобы сгенерировать код-заглушку клиента gRPC:

  1. В терминале перейдите в папку starter/src/proto/ и сгенерируйте заглушку:
bash generate_grpc_stub_swift.sh

Несколько файлов .swift в папке start 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 Serving.

  • Добавьте этот код в ветку gRPC сразу после кода в предыдущем фрагменте кода:
// Send the gRPC request.
let call
= stub.predict(request, callOptions: callOptions)

Обработка ответа gRPC от TensorFlow Serving

  • Добавьте этот код сразу после кода в предыдущем фрагменте кода:
// 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)")
}

Теперь функция постобработки извлекает предсказанные значения из ответа и отображает результат в пользовательском интерфейсе.

Запустить его

  1. Нажмите cacc15c5638260ed.png «Выполнить» в меню навигации, а затем подождите, пока Xcode запустит приложение в симуляторе.
  2. Введите число в текстовое поле и нажмите Infer .

Теперь вы видите прогнозируемое значение в пользовательском интерфейсе.

9. Поздравления

Вы использовали TensorFlow Serving, чтобы добавить возможности регрессии в свое приложение!

Учить больше