Topik ini menjelaskan cara membuat permintaan untuk layanan TensorFlow yang didasarkan pada prosesor universal.
Catatan tentang data input
Elastic Algorithm Service (EAS) menyediakan prosesor TensorFlow bawaan untuk digunakan dalam menerapkan model TensorFlow sebagai layanan. Untuk memastikan performa optimal, pastikan bahwa data input dan output berada dalam format Protocol Buffers.
Contoh
Model uji publik telah diterapkan sebagai layanan di wilayah Tiongkok (Shanghai). Nama layanan adalah mnist_saved_model_example. Layanan ini dapat diakses oleh semua pengguna di VPC di wilayah tersebut tanpa token akses. Anda dapat mengirim permintaan ke titik akhir http://pai-eas-vpc.cn-shanghai.aliyuncs.com/api/predict/mnist_saved_model_example untuk memanggil layanan tersebut. Berikut ini adalah langkah-langkah untuk memanggil layanan:
Peroleh Informasi Model.
Kirim permintaan GET untuk mendapatkan informasi model, termasuk signature_name, name, type, dan shape. Berikut ini adalah contoh respons:
$curl http://pai-eas-vpc.cn-shanghai.aliyuncs.com/api/predict/mnist_saved_model_example | python -mjson.tool { "inputs": [ { "name": "images", "shape": [ -1, 784 ], "type": "DT_FLOAT" } ], "outputs": [ { "name": "scores", "shape": [ -1, 10 ], "type": "DT_FLOAT" } ], "signature_name": "predict_images" }Model ini merupakan model klasifikasi yang menggunakan dataset Mixed National Institute of Standards and Technology (MNIST). Unduh dataset MNIST. Tipe data input adalah DT_FLOAT. Sebagai contoh, bentuk input shape adalah [-1,784]. Dimensi pertama adalah batch_size. Jika permintaan hanya mencakup satu gambar, batch_size diatur menjadi 1. Dimensi kedua adalah vektor 784 dimensi. Saat melatih model uji, input diratakan menjadi vektor satu dimensi. Oleh karena itu, gambar dengan ukuran 28 x 28 piksel harus diratakan menjadi vektor satu dimensi dengan panjang 784, yaitu 28 x 28. Saat membuat input, ratakan menjadi vektor satu dimensi terlepas dari nilai shape. Dalam contoh ini, jika Anda memasukkan sebuah gambar, gambar tersebut diratakan menjadi vektor satu dimensi dengan ukuran 1 x 784. Jika shape input yang ditentukan saat melatih model adalah [-1,28, 28], ratakan input permintaan menjadi vektor satu dimensi dengan ukuran 1 x 28 x 28. Jika shape input yang ditentukan dalam permintaan tidak sesuai dengan shape input model, permintaan akan gagal.
Instal Protocol Buffers dan Panggil Layanan. Topik ini menjelaskan cara menggunakan klien Python 2 untuk memanggil layanan TensorFlow.
EAS menyediakan paket Protocol Buffers untuk klien Python. Jalankan perintah berikut untuk menginstalnya:
$ pip install http://eas-data.oss-cn-shanghai.aliyuncs.com/sdk/pai_tf_predict_proto-1.0-py2.py3-none-any.whlBerikut ini adalah kode sampel untuk memanggil layanan dan membuat prediksi:
#! /usr/bin/env python # -*- coding: UTF-8 -*- import json from urlparse import urlparse from com.aliyun.api.gateway.sdk import client from com.aliyun.api.gateway.sdk.http import request from com.aliyun.api.gateway.sdk.common import constant from pai_tf_predict_proto import tf_predict_pb2 import cv2 import numpy as np with open('2.jpg', 'rb') as infile: buf = infile.read() # Gunakan NumPy untuk mengonversi byte ke array NumPy. x = np.fromstring(buf, dtype='uint8') # Dekode array menjadi matriks 28 x 28. img = cv2.imdecode(x, cv2.IMREAD_UNCHANGED) # API untuk prediksi memerlukan vektor satu dimensi dengan panjang 784. Oleh karena itu, Anda harus membentuk ulang matriks menjadi vektor seperti itu. img = np.reshape(img, 784) def predict(url, app_key, app_secret, request_data): cli = client.DefaultClient(app_key=app_key, app_secret=app_secret) body = request_data url_ele = urlparse(url) host = 'http://' + url_ele.hostname path = url_ele.path req_post = request.Request(host=host, protocol=constant.HTTP, url=path, method="POST", time_out=6000) req_post.set_body(body) req_post.set_content_type(constant.CONTENT_TYPE_STREAM) stat,header, content = cli.execute(req_post) return stat, dict(header) if header is not None else {}, content def demo(): # Masukkan informasi model. Klik nama model untuk mendapatkan informasi tersebut. app_key = 'YOUR_APP_KEY' app_secret = 'YOUR_APP_SECRET' url = 'YOUR_APP_URL' # Buat layanan. request = tf_predict_pb2.PredictRequest() request.signature_name = 'predict_images' request.inputs['images'].dtype = tf_predict_pb2.DT_FLOAT # Tipe parameter images. request.inputs['images'].array_shape.dim.extend([1, 784]) # Bentuk parameter images. request.inputs['images'].float_val.extend(img) # Data tentang parameter images. request.inputs['keep_prob '].dtype = tf_predict_pb2.DT_FLOAT # Tipe parameter keep_prob. request.inputs['keep_prob'].float_val.extend([0.75]) # Nilai default shape adalah 1. # Serialisasi data dalam format Protocol Buffers ke string dan transfer string tersebut. request_data = request.SerializeToString() stat, header, content = predict(url, app_key, app_secret, request_data) if stat != 200: print 'Kode status HTTP: ', stat print 'Pesan kesalahan di header: ', header['x-ca-error-message'] if 'x-ca-error-message' in header else '' print 'Pesan kesalahan di body: ', content else: response = tf_predict_pb2.PredictResponse() response.ParseFromString(content) print(response) if __name__ == '__main__': demo()Berikut ini adalah hasil keluaran:
outputs { key: "scores" value { dtype: DT_FLOAT array_shape { dim: 1 dim: 10 } float_val: 0.0 float_val: 0.0 float_val: 1.0 float_val: 0.0 float_val: 0.0 float_val: 0.0 float_val: 0.0 float_val: 0.0 float_val: 0.0 float_val: 0.0 } }Skor dari 10 kategori terdaftar di
outputs. Keluaran menunjukkan bahwa ketika gambar input adalah 2.jpg, semua nilainya adalah 0 kecuali value[2]. Hasil prediksi akhir adalah 2, yang benar.
Gunakan klien dalam bahasa lain untuk memanggil layanan
Jika Anda menggunakan klien dalam bahasa selain Python, Anda harus secara manual menghasilkan file kode permintaan prediksi berdasarkan file .proto. Berikut ini adalah kode sampel:
Siapkan file kode permintaan, seperti tf.proto, yang berisi konten berikut:
syntax = "proto3"; option cc_enable_arenas = true; option java_package = "com.aliyun.openservices.eas.predict.proto"; option java_outer_classname = "PredictProtos"; enum ArrayDataType { // Bukan nilai legal untuk DataType. Digunakan untuk menunjukkan bidang DataType belum disetel. DT_INVALID = 0; // Tipe data yang diharapkan semua perangkat komputasi mampu mendukung. DT_FLOAT = 1; DT_DOUBLE = 2; DT_INT32 = 3; DT_UINT8 = 4; DT_INT16 = 5; DT_INT8 = 6; DT_STRING = 7; DT_COMPLEX64 = 8; // Kompleks presisi tunggal. DT_INT64 = 9; DT_BOOL = 10; DT_QINT8 = 11; // int8 terkuantisasi. DT_QUINT8 = 12; // uint8 terkuantisasi. DT_QINT32 = 13; // int32 terkuantisasi. DT_BFLOAT16 = 14; // Float32 dipotong menjadi 16 bit. Hanya untuk operasi cast. DT_QINT16 = 15; // int16 terkuantisasi. DT_QUINT16 = 16; // uint16 terkuantisasi. DT_UINT16 = 17; DT_COMPLEX128 = 18; // Kompleks presisi ganda. DT_HALF = 19; DT_RESOURCE = 20; DT_VARIANT = 21; // Tipe data C++ arbitrer. } // Dimensi array. message ArrayShape { repeated int64 dim = 1 [packed = true]; } // Buffer protokol yang merepresentasikan array. message ArrayProto { // Tipe Data. ArrayDataType dtype = 1; // Bentuk array. ArrayShape array_shape = 2; // DT_FLOAT. repeated float float_val = 3 [packed = true]; // DT_DOUBLE. repeated double double_val = 4 [packed = true]; // DT_INT32, DT_INT16, DT_INT8, DT_UINT8. repeated int32 int_val = 5 [packed = true]; // DT_STRING. repeated bytes string_val = 6; // DT_INT64. repeated int64 int64_val = 7 [packed = true]; // DT_BOOL. repeated bool bool_val = 8 [packed = true]; } // PredictRequest menentukan model TensorFlow mana yang akan dijalankan, serta // bagaimana input dipetakan ke tensor dan bagaimana output difilter sebelum // dikembalikan ke pengguna. message PredictRequest { // Nama tanda tangan bernama untuk dievaluasi. Jika tidak ditentukan, tanda tangan default // akan digunakan. string signature_name = 1; // Tensor input. // Nama tensor input adalah nama alias. Pemetaan dari alias ke nama tensor input nyata // diharapkan disimpan sebagai tanda tangan generik bernama di bawah kunci "inputs" dalam ekspor model. // Setiap alias yang terdaftar dalam tanda tangan generik bernama "inputs" harus disediakan // tepat sekali agar prediksi dapat dijalankan. map<string, ArrayProto> inputs = 2; // Filter output. // Nama yang ditentukan adalah nama alias. Pemetaan dari alias ke nama tensor output nyata // diharapkan disimpan sebagai tanda tangan generik bernama di bawah kunci "outputs" dalam ekspor model. // Hanya tensor yang ditentukan di sini yang akan dijalankan/diambil dan dikembalikan, dengan pengecualian bahwa // ketika tidak ada yang ditentukan, semua tensor yang ditentukan dalam tanda tangan bernama akan dijalankan/diambil dan dikembalikan. repeated string output_filter = 3; } // Respons untuk PredictRequest pada pelaksanaan sukses. message PredictResponse { // Tensor output. map<string, ArrayProto> outputs = 1; }Dalam file tersebut,
PredictRequestmendefinisikan format input layanan TensorFlow, danPredictResponsemendefinisikan format output layanan. Untuk informasi lebih lanjut tentang Protocol Buffers, lihat Protocol Buffers.Instal protoc.
#/bin/bash PROTOC_ZIP=protoc-3.3.0-linux-x86_64.zip curl -OL https://github.com/google/protobuf/releases/download/v3.3.0/$PROTOC_ZIP unzip -o $PROTOC_ZIP -d ./ bin/protoc rm -f $PROTOC_ZIPHasilkan File Kode Permintaan.
Java
$ bin/protoc --java_out=./ tf.protoSetelah perintah selesai, file kode permintaan com/aliyun/openservices/eas/predict/proto/PredictProtos.java dihasilkan di direktori saat ini. Impor file tersebut ke proyek.
Python
$ bin/protoc --python_out=./ tf.protoSetelah perintah selesai, file kode permintaan tf_pb2.py dihasilkan di direktori saat ini. Jalankan perintah
importuntuk mengimpor file tersebut ke proyek.C++
$ bin/protoc --cpp_out=./ tf.protoSetelah perintah selesai, file kode permintaan termasuk tf.pb.cc dan tf.pb.h dihasilkan di direktori saat ini. Tambahkan perintah
include tf.pb.hke kode dan tambahkan tf.pb.cc ke daftar compile.