TensorFlow Serving Java是作為TensorFlow Serving的Java API,可以輕鬆地將基於TensorFlow模型的服務集成到Java應用程序中。從數據預處理到模型訓練再到推理,TensorFlow Serving Java提供了完整的端到端解決方案。
一、簡介
TensorFlow是深度學習領域最受歡迎的框架之一,但它並不僅僅是一個深度學習框架,同時也是一個支持大規模機器學習的通用計算框架。TensorFlow Serving是通過一個分佈式運行的系統來服務於訓練好的模型並提供可擴展性的接口,而TensorFlow Serving Java則是為Java應用程序提供直接使用這些模型的接口。
二、使用指南
TensorFlow Serving Java的使用非常方便,下面介紹一下主要的使用方法:
1. 依賴管理
使用TensorFlow Serving Java之前,需要在項目中添加以下依賴:
<dependency>
<groupId>org.tensorflow</groupId>
<artifactId>tensorflow-serving-api</artifactId>
<version>2.4.0</version>
</dependency>
2. 創建模型Client
使用TensorFlow Serving Java,需要首先創建一個服務器連接的Client對象,可以設置許多參數來配置模型服務的行為。以下是創建客戶端的基本示例:
import org.tensorflow.framework.DataType;
import org.tensorflow.framework.TensorProto;
import org.tensorflow.servables.common.CleanupAble;
import java.util.Arrays;
import static org.tensorflow.framework.TensorProto.*;
public class TensorFlowService implements CleanupAble {
public TensorFlowService(String host, int port) {
// 創建一個指向指定端口的Stub
}
public float[][] predict(float[][] inputs) {
TensorProto.Builder builder = TensorProto.newBuilder();
builder.setDtype(DataType.DT_FLOAT);
builder.addAllFloatVal(Arrays.stream(inputs).flatMapToDouble(Arrays::stream).collect(Collectors.toList()));
builder.addDim(1);
builder.addDim(inputs.length);
builder.addDim(inputs[0].length);
TensorProto inputProto = builder.build();
// 發送請求
// 通過Stub返回結果
}
@Override
public void close() throws Exception {
// 銷毀連接
}
}
3. 加載模型
在創建客戶端之前,需要首先啟動TensorFlow Serving服務器並加載要使用的模型。以下是在本地連接到TensorFlow Serving服務器並加載預處理好的Batch Normalization的CNN模型的示例代碼:
import org.tensorflow.framework.ConfigProto;
import org.tensorflow.framework.GPUOptions;
import org.tensorflow.serving.*;
import tensorflow.serving.Model;
import tensorflow.serving.Model.VersionPolicy.LatestVersionPolicy;
import tensorflow.serving.SessionServiceGrpc.SessionServiceBlockingStub;
public TensorFlowService(ManagedChannel channel, String modelName, int modelVersion) {
// 創建stub用於與SessionService進行通信
SessionServiceBlockingStub stub = SessionServiceGrpc.newBlockingStub(channel);
// 創建請求
Model.ModelSpec modelSpec = Model.ModelSpec.newBuilder()
.setName(modelName)
.setVersionPolicy(Model.ModelVersionPolicy.newBuilder().setLatest(LatestVersionPolicy.newBuilder()).build())
.build();
GetModelMetadataRequest metadataRequest = GetModelMetadataRequest.newBuilder()
.setModelSpec(modelSpec)
.addMetadataField("signature_def")
.build();
// 獲取模型元數據信息
GetModelMetadataResponse metadataResponse = stub.getModelMetadata(metadataRequest);
// 從元數據信息中獲取模型輸入和輸出的名稱、形狀等
SignatureDefMap signatureDefMap = metadataResponse.getMetadataMap().get("signature_def");
SignatureDef signatureDef = signatureDefMap.getSignatureDefMap().entrySet().stream().findFirst().orElseThrow(RuntimeException::new)
.getValue();
Map.Entry input = signatureDef.getInputsMap().entrySet().stream().findFirst().orElseThrow(RuntimeException::new);
String inputTensorName = input.getKey();
TensorInfo inputTensorInfo = input.getValue();
Map.Entry output = signatureDef.getOutputsMap().entrySet().stream().findFirst().orElseThrow(RuntimeException::new);
String outputTensorName = output.getKey();
TensorInfo outputTensorInfo = output.getValue();
// 創建Session
SessionOptions sessionOptions = SessionOptions.newBuilder()
.setConfig(ConfigProto.newBuilder()
.setGpuOptions(GPUOptions.newBuilder()
.setPerProcessGpuMemoryFraction(0.5))
.build())
.build();
CreateSessionRequest sessionRequest = CreateSessionRequest.newBuilder()
.setSessionConfig(sessionOptions)
.setModelSpec(modelSpec)
.build();
CreateSessionResponse sessionResponse = stub.createSession(sessionRequest);
sessionHandle = sessionResponse.getSessionHandle();
}
4. 發送請求並處理結果
在創建客戶端並且加載模型之後,可以開始向模型發送請求並處理模型返回的結果:
public float[][] predict(float[][] inputs) {
TensorProto.Builder builder = TensorProto.newBuilder();
builder.setDtype(DataType.DT_FLOAT);
builder.addAllFloatVal(Arrays.stream(inputs).flatMapToDouble(Arrays::stream).collect(Collectors.toList()));
builder.addDim(1);
builder.addDim(inputs.length);
builder.addDim(inputs[0].length);
TensorProto inputProto = builder.build();
// 創建request對象
RunOptions runOptions = RunOptions.newBuilder()
.setTraceLevel(RunOptions.TraceLevel.NO_TRACE)
.build();
Map inputsMap = Map.of(inputTensorName, inputProto);
Map outputsMap = Map.of(outputTensorName, new OutputTensorInfo(TensorShape.newBuilder().addDim(TensorShape.Dim.newBuilder().setSize(-1).build()).build(), DataType.DT_FLOAT));
RunRequest request = RunRequest.newBuilder()
.setSessionHandle(sessionHandle)
.setRunOptions(runOptions)
.setInputFeed(Maps.transformValues(inputsMap, value -> TensorProtoList.newBuilder().addTensor(value).build()))
.putAllFetch(fetch)
.build();
// 發送請求
RunResponse response = stub.run(request);
// 處理結果
}
三、總結
TensorFlow Serving Java為Java應用程序提供了與TensorFlow模型服務集成的無縫體驗。它提供了簡單易用的API,使得使用TensorFlow模型服務變得更容易。開發人員只需要簡單地加載模型並使用客戶端就可以處理輸入和輸出。TensorFlow Serving Java還提供了靈活的配置選項和可擴展性,並可以與其他TensorFlow項目無縫集成。
原創文章,作者:HIVDG,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/375631.html