Informacje o tym ćwiczeniu (w Codelabs)
1. Zanim zaczniesz
Z tego ćwiczenia dowiesz się, jak uruchomić wnioskowanie regresji w aplikacji na iOS przy użyciu TensorFlow Serving with REST i gRPC.
Wymagania wstępne
- Podstawowe informacje o programowaniu iOS w Swift
- Podstawowa wiedza dotycząca systemów uczących się z TensorFlow, np. szkolenia i wdrażanie
- Podstawowe informacje o Colaboratory
- Podstawowa znajomość terminali, Pythona i Dockera
Czego się nauczysz
- Jak wytrenować model regresji za pomocą TensorFlow.
- Jak utworzyć prostą aplikację na iOS i tworzyć prognozy na podstawie wytrenowanego modelu przy użyciu TensorFlow Serving (REST i gRPC).
- Sposób wyświetlania wyniku w interfejsie.
Czego potrzebujesz
- Dostęp do Colab
- Najnowsza wersja Xcode
- CocoaPods,
- Docker
- Bash
- Kompilator bufora protokołu (wymagany tylko w przypadku, gdy chcesz samodzielnie wygenerować wycinek z gRPC)
- Wtyczka do generowania kodu gRPC-swift (wymagana tylko wtedy, gdy chcesz samodzielnie wygenerować kod wewnętrzny gRPC)
2. Konfiguracja
Aby pobrać kod tych ćwiczeń z programowania:
- Przejdź do repozytorium GitHub dla tych ćwiczeń z programowania.
- Kliknij Kod > Pobierz plik ZIP, aby pobrać cały kod do tych ćwiczeń z programowania.
- Rozpakuj pobrany plik ZIP, aby rozpakować folder główny aplikacji
codelabs
ze wszystkimi potrzebnymi zasobami.
Na potrzeby tego ćwiczenia z programu potrzebujesz tylko plików z podkatalogu TFServing/RegressioniOS
repozytorium, które zawiera 2 foldery:
- Folder
starter
zawiera kod początkowy, który wykorzystasz w tym ćwiczeniu z programowania. - Folder
finished
zawiera pełny kod gotowej aplikacji.
3. Pobierz zależności dla projektu
Pobierz wymagane bloki reklamowe
- W folderze
starter/iOS
uruchom polecenie:
pod install
Cocoapods zainstaluje wszystkie niezbędne biblioteki i wygeneruje nowy plik regression.xcworkspace
.
4. Uruchom aplikację startową
- Kliknij dwukrotnie plik
regression.xcworkspace
, aby otworzyć Xcode.
Uruchamianie i poznawanie aplikacji
- Zmień urządzenie docelowe na dowolnego iPhone'a, na przykład iPhone'a 13.
- Kliknij
„Uruchom'”, a następnie zaczekaj na skompilowanie projektu przez Xcode i uruchomienie aplikacji startowej w symulatorze.
Interfejs jest bardzo prosty. Jest pole tekstowe, w którym możesz wpisać liczbę, która jest wysyłana do backendu TensorFlow Udostępniającego REST lub gRPC. Backend wykonuje regresję wartości wejściowej i zwraca przewidywaną wartość do aplikacji klienckiej, która ponownie wyświetla wynik w interfejsie.
Jeśli wpiszesz liczbę i klikniesz Wnioskuj, nic się nie stanie, ponieważ aplikacja nie może jeszcze nawiązać komunikacji z backendem.
5. Wytrenuj prosty model regresji za pomocą TensorFlow
Regresja jest jednym z najczęstszych zadań ML. Jego celem jest przewidywanie pojedynczej ciągłej ilości na podstawie danych wejściowych. Na przykład na podstawie dzisiejszej pogody prognozowana jest najwyższa temperatura jutro.
Wytrenuj model regresji
- Otwórz ten link w przeglądarce.
Colab wczytuje notatki w języku Python.
- W notatniku Python zaimportuj biblioteki
TensorFlow
iNumPy
, a następnie utwórz 6 par danych treningowych z danymixs
iys
jako etykietami.
Jeśli nanosisz te punkty na wykres, występują one w linii prostej, ponieważ są generowane na podstawie równania y = 2x –1.
- Użyj interfejsu API Keras, aby utworzyć prostą dwuwarstwową sieć neuronową, aby przewidzieć wartość
y
na podstawie danych wejściowychx
. Następnie skompiluj i dopasuj model.
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]))
Model trenuje się w ciągu kilku sekund. Widać, że przewidywana wartość danych wejściowych 10
to 18.999996
, co jest całkiem niezłym wynikiem, ponieważ rzeczywistość jest: 2 * 10 -1 = 19.
- Wyeksportuj model:
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}
- Spakuj wyeksportowany plik SavedModel do jednego pliku
regression.zip
:
!zip -r regression.zip ./regression
- Kliknij Runtime > Run all (Uruchom wszystko) w menu nawigacyjnym, by uruchomić notatki, a następnie poczekaj na zakończenie uruchomienia.
- Kliknij
Pliki, a następnie pobierz plik
regression.zip
.
6. Wdróż model regresji za pomocą udostępniania TensorFlow
- Aby wdrożyć model za pomocą Narzędzia TensorFlow, zdekompresuj pobrany plik
regression.zip
za pomocą narzędzia do dekompresji, takiego jak 7-Zip.
Struktura folderów powinna wyglądać tak:
Folder regression
można nazywać folderem SavedModel
. 123
to przykładowy numer wersji. Jeśli chcesz, możesz wybrać inny numer.
Rozpocznij udostępnianie TensorFlow
- W terminalu uruchom udostępnianie TensorFlow z Dockerem, zastępując zmienną
PATH/TO/SAVEDMODEL
ścieżką bezwzględną folderuregression
na komputerze.
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 automatycznie pobiera najpierw obraz związany z wyświetlaniem TensorFlow, co zajmuje minutę. Po tym czasie powinno rozpocząć się udostępnianie TensorFlow. Dziennik powinien wyglądać jak ten fragment kodu:
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. Łączenie aplikacji na iOS z TensorFlow Serving przez REST
Backend jest już gotowy, więc możesz wysyłać żądania klienta do usługi TensorFlow, aby tworzyć prognozy. Istnieją dwa sposoby wysyłania żądań do obsługi TensorFlow:
- REST
- gRPC
Wysyłaj żądania i odbieraj odpowiedzi za pomocą REST
Aby to zrobić:
- Utwórz żądanie REST.
- Wyślij żądanie REST do serwera TensorFlow Serving.
- Wyodrębnij przewidywany wynik z odpowiedzi REST i wyrenderuj interfejs użytkownika.
Te kroki możesz wykonać w pliku iOS/regression/ViewController.swift
.
Utwórz żądanie REST
- Obecnie funkcja
doInference()
nie wysyła żądania REST do serwera TensorFlow. Aby utworzyć żądanie REST, musisz wdrożyć tę gałąź REST:
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
print("Using REST")
// TODO: Add code to send a REST request to TensorFlow Serving.
}
Udostępnianie w TensorFlow oczekuje na żądanie POST zawierające jedną wartość, dlatego musisz umieścić wartość wejściową w formacie JSON, który jest ładunkiem żądania.
- Dodaj ten kod do gałęzi 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
Wyślij żądanie REST do serwera TensorFlow
- Dodaj ten kod bezpośrednio po kodzie w gałęzi 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()
Przetwórz odpowiedź REST z wyświetlania w TensorFlow
- Dodaj ten kod do poprzedniego fragmentu kodu zaraz po komentarzu:
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])
}
Teraz funkcja przetwarzania końcowego wyodrębnia przewidywane wartości z odpowiedzi i wyświetla wynik w interfejsie użytkownika.
Uruchom
- Kliknij
Uruchom', a następnie poczekaj, aż Xcode uruchomi aplikację w Symulatorze.
- Wpisz liczbę w polu tekstowym, a następnie kliknij Wnioskuj.
Teraz zobaczysz w interfejsie przewidywaną wartość.
8. Łączenie aplikacji na iOS z TensorFlow Serving przez gRPC
Oprócz REST, TensorFlow Serving obsługuje też gRPC.
gRPC to nowoczesna platforma RPC o wysokiej wydajności, która może działać w dowolnym środowisku. Może skutecznie łączyć usługi w centrach danych i z innych, a także korzystać z wtyczek z obsługą równoważenia obciążenia, śledzenia, kontroli stanu i uwierzytelniania. Zaobserwowano, że gRPC jest w praktyce bardziej wydajny niż REST.
Wysyłanie żądań i odbieranie odpowiedzi za pomocą gRPC
Wystarczą 4 proste kroki:
- Opcjonalnie: wygeneruj kod śledzenia klienta gRPC.
- Utwórz żądanie gRPC.
- Wyślij żądanie gRPC do wyświetlania przez TensorFlow.
- Wyodrębnij przewidywany wynik z odpowiedzi gRPC i wyrenderuj interfejs użytkownika.
Te kroki możesz wykonać w pliku iOS/regression/ViewController.swift
.
Opcjonalnie: wygeneruj kod wewnętrzny klienta gRPC
Aby używać gRPC z udostępnianiem za pomocą TensorFlow, musisz wykonać przepływ pracy gRPC. Więcej informacji znajdziesz w dokumentacji gRPC.
Pliki TensorFlow i TensorFlow definiują pliki .proto
. Od TensorFlow 2.8 i TensorFlow 2.8 potrzebne są te pliki .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
Aby wygenerować kod wewnętrzny klienta gRPC:
- W terminalu przejdź do folderu
starter/src/proto/
i wygeneruj fragment:
bash generate_grpc_stub_swift.sh
W folderze starter/src/proto/generated/import
zostanie wygenerowanych kilka plików .swift
.
- Jeśli nie zostały one jeszcze skopiowane do projektu, przeciągnij wszystkie wygenerowane pliki
.swift
do projektu w Xcode.
Utwórz żądanie gRPC
Podobnie jak w przypadku żądania REST, żądanie gRPC tworzy się w gałęzi gRPC.
if (connectionMode[picker.selectedRow(inComponent: 0)] == "REST") {
}
else {
print("Using gRPC")
// TODO: add code to send a gRPC request to TF Serving
}
- Aby utworzyć żądanie gRPC, dodaj ten kod do gałęzi 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)))
Wyślij żądanie gRPC do udostępniania w TensorFlow
- Dodaj ten kod do gałęzi gRPC tuż za kodem w poprzednim fragmencie kodu:
// Send the gRPC request.
let call = stub.predict(request, callOptions: callOptions)
Przetwórz odpowiedź gRPC z udostępniania w TensorFlow
- Dodaj ten kod bezpośrednio po kodzie w poprzednim fragmencie kodu:
// 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)")
}
Teraz funkcja przetwarzania końcowego wyodrębnia przewidywane wartości z odpowiedzi i wyświetla wynik w interfejsie użytkownika.
Uruchom
- Kliknij
Uruchom' w menu nawigacyjnym, a następnie poczekaj, aż Xcode uruchomi aplikację w Symulatorze.
- Wpisz liczbę w polu tekstowym, a następnie kliknij Wnioskuj.
Teraz zobaczysz w interfejsie przewidywaną wartość.
9. Gratulacje
Dzięki udostępnianiu danych TensorFlow dodano funkcje regresji do aplikacji.