### TensorFlow Serving
TensorFlow Serving提供了一個高效的方式來部署和提供TensorFlow模型的預測服務。您可以將訓練好的TensorFlow模型保存為SavedModel格式,然後將其部署到TensorFlow Serving中。
以下是使用TensorFlow Serving的一般步驟:
1. 訓練TensorFlow模型:使用TensorFlow進行模型訓練,並保存為SavedModel格式。
2. 安裝和啟動TensorFlow Serving:在伺服器上安裝TensorFlow Serving,並啟動TensorFlow Serving服務。
3. 部署模型:將訓練好的SavedModel部署到TensorFlow Serving中,並指定一個或多個服務端點。
4. 使用API進行預測:通過REST API使用TensorFlow Serving來進行預測。您可以使用HTTP POST請求向服務端點發送輸入數據,然後接收預測結果。
以下是一個使用TensorFlow Serving進行預測的簡單示例:
```python
# 假設您已經訓練並保存了一個TensorFlow模型
# 假設您已經安裝並啟動了TensorFlow Serving
import requests
# 定義服務端點的URL
url = "http://localhost:8501/v1/models/my_model:predict"
# 構建請求數據,這裡假設輸入是一個包含一個特徵的JSON數據
data = {"instances": [{"feature": 1.0}]}
# 發送HTTP POST請求
response = requests.post(url, json=data)
# 解析預測結果
result = response.json()
print(result)
```
上述示例中,`my_model`是您保存的模型的名稱,`feature`是模型的輸入特徵。您可以根據您的模型和數據進行調整。通過這樣的方式,您可以使用API的方式設定計算圖並進行預測。
### 在Docker中架設TensorFlow Serving
在Docker中架設TensorFlow Serving的一般步驟:
1. 安裝Docker:如果您尚未安裝Docker,請先在您的系統上安裝Docker。您可以按照Docker官方網站的說明進行安裝:https://www.docker.com/
2. 下載TensorFlow Serving Docker映像:在終端或命令提示字元中運行以下命令,下載TensorFlow Serving的Docker映像:
```
docker pull tensorflow/serving
```
3. 啟動TensorFlow Serving容器:運行以下命令來啟動TensorFlow Serving容器。在這個命令中,您需要指定模型的位置和服務端口:
```
docker run -p 8501:8501 --name=tf_serving --mount type=bind,source=/path/to/model/directory,target=/models/my_model -e MODEL_NAME=my_model -t tensorflow/serving
```
- `-p 8501:8501`:將Docker容器的8501端口映射到主機的8501端口,這是TensorFlow Serving的預設端口。
- `--name=tf_serving`:為容器指定一個名稱。
- `--mount type=bind,source=/path/to/model/directory,target=/models/my_model`:將您訓練好並保存的SavedModel目錄掛載到容器中,替換`/path/to/model/directory`為實際目錄的路徑。
- `-e MODEL_NAME=my_model`:指定您的模型的名稱,這裡使用`my_model`作為示例。
4. 測試TensorFlow Serving:容器成功運行後,TensorFlow Serving會在8501端口上提供預測服務。您可以使用curl或任何HTTP客戶端來測試預測服務。以下是一個測試的示例:
```
curl -d '{"instances": [{"feature": 1.0}]}' -H "Content-Type: application/json" -X POST http://localhost:8501/v1/models/my_model:predict
```
上述示例中,`my_model`是您保存的模型的名稱,`feature`是模型的輸入特徵。您可以根據您的模型和數據進行調整。
請注意,上述命令中的路徑和名稱僅作為示例,請根據您的實際情況進行調整。通過使用Docker,您可以快速部署並運行TensorFlow Serving,方便地提供預測服務。
### TensorFlow Java 訓練MNIST數據集
```java
package org.tensorflow.model.examples.dense;
import org.tensorflow.Graph;
import org.tensorflow.Operand;
import org.tensorflow.Session;
import org.tensorflow.framework.optimizers.GradientDescent;
import org.tensorflow.framework.optimizers.Optimizer;
import org.tensorflow.model.examples.datasets.ImageBatch;
import org.tensorflow.model.examples.datasets.mnist.MnistDataset;
import org.tensorflow.ndarray.ByteNdArray;
import org.tensorflow.ndarray.Shape;
import org.tensorflow.op.Op;
import org.tensorflow.op.Ops;
import org.tensorflow.op.core.Placeholder;
import org.tensorflow.op.core.Variable;
import org.tensorflow.op.math.Mean;
import org.tensorflow.op.nn.Softmax;
import org.tensorflow.types.TFloat32;
import org.tensorflow.types.TInt64;
public class SimpleMnist implements Runnable {
// 訓練過程中的一些參數設定
private static final int VALIDATION_SIZE = 0;
private static final int TRAINING_BATCH_SIZE = 100;
private static final float LEARNING_RATE = 0.2f;
// MNIST 數據集的路徑
private static final String TRAINING_IMAGES_ARCHIVE = "mnist/train-images-idx3-ubyte.gz";
private static final String TRAINING_LABELS_ARCHIVE = "mnist/train-labels-idx1-ubyte.gz";
private static final String TEST_IMAGES_ARCHIVE = "mnist/t10k-images-idx3-ubyte.gz";
private static final String TEST_LABELS_ARCHIVE = "mnist/t10k-labels-idx1-ubyte.gz";
// main 方法
public static void main(String[] args) {
// 創建 MNIST 數據集
MnistDataset dataset = MnistDataset.create(VALIDATION_SIZE, TRAINING_IMAGES_ARCHIVE, TRAINING_LABELS_ARCHIVE,
TEST_IMAGES_ARCHIVE, TEST_LABELS_ARCHIVE);
try (Graph graph = new Graph()) {
SimpleMnist mnist = new SimpleMnist(graph, dataset);
mnist.run(); // 開始訓練
}
}
// 簡單 MNIST 訓練的 run 方法
@Override
public void run() {
// 創建 TensorFlow 的 Ops 物件,用於定義計算圖
Ops tf = Ops.create(graph);
// 創建 Placeholder 來代表輸入和目標數據
Placeholder<TFloat32> images = tf.placeholder(TFloat32.class);
Placeholder<TFloat32> labels = tf.placeholder(TFloat32.class);
// 創建權重 (weights) 和偏差 (biases) 的變數 (variables),並初始化為 0
Shape weightShape = Shape.of(dataset.imageSize(), MnistDataset.NUM_CLASSES);
Variable<TFloat32> weights = tf.variable(tf.zeros(tf.constant(weightShape), TFloat32.class));
Shape biasShape = Shape.of(MnistDataset.NUM_CLASSES);
Variable<TFloat32> biases = tf.variable(tf.zeros(tf.constant(biasShape), TFloat32.class));
// 進行預測和計算損失
Softmax<TFloat32> softmax =
tf.nn.softmax(
tf.math.add(
tf.linalg.matMul(images, weights),
biases
)
);
Mean<TFloat32> crossEntropy =
tf.math.mean(
tf.math.neg(
tf.reduceSum(
tf.math.mul(labels, tf.math.log(softmax)),
tf.array(1)
)
),
tf.array(0)
);
// 使用梯度下降優化算法來最小化損失
Optimizer optimizer = new GradientDescent(graph, LEARNING_RATE);
Op minimize = optimizer.minimize(crossEntropy);
// 計算模型的準確率
Operand<TInt64> predicted = tf.math.argMax(softmax, tf.constant(1));
Operand<TInt64> expected = tf.math.argMax(labels, tf.constant(1));
Operand<TFloat32> accuracy = tf.math.mean(tf.dtypes.cast(tf.math.equal(predicted, expected), TFloat32.class), tf.array(0));
// 開始運行計算圖
try (Session session = new Session(graph)) {
// 訓練模型
for (ImageBatch trainingBatch : dataset.trainingBatches(TRAINING_BATCH_SIZE)) {
try (TFloat32 batchImages = preprocessImages(trainingBatch.images());
TFloat32 batchLabels = preprocessLabels(trainingBatch.labels())) {
session.runner()
.addTarget(minimize)
.feed(images.asOutput(), batchImages)
.feed(labels.asOutput(), batchLabels)
.run();
}
}
// 測試模型
ImageBatch testBatch = dataset.testBatch();
try (TFloat32 testImages = preprocessImages(testBatch.images());
TFloat32 testLabels = preprocessLabels(testBatch.labels());
TFloat32 accuracyValue = (TFloat32)session.runner()
.fetch(accuracy)
.feed(images.asOutput(), testImages)
.feed(labels.asOutput(), testLabels)
.run()
.get(0)) {
System.out.println("Accuracy: " + accuracyValue.getFloat());
}
}
}
// 輔助方法:將原始圖像進行預處理,將像素值轉換為浮點數並進行標準化
private static TFloat32 preprocessImages(ByteNdArray rawImages) {
Ops tf = Ops.create();
// 將圖像展平為單一維度,並將像素值標準化為浮點數
long imageSize = rawImages.get(0).shape().size();
return tf.math.div(
tf.reshape(
tf.dtypes.cast(tf.constant(rawImages), TFloat32.class),
tf.array(-1L, imageSize)
),
tf.constant(255.0f)
).asTensor();
}
// 輔助方法:將原始標籤進行預處理,將標籤轉換為 one-hot 向量形式
private static TFloat32 preprocessLabels(ByteNdArray rawLabels) {
Ops tf = Ops.create();
// 將標籤轉換為 one-hot 向量形式,其中只有預期的標籤值為 1.0,其餘為 0.0
return tf.oneHot(
tf.constant(rawLabels),
tf.constant(MnistDataset.NUM_CLASSES),
tf.constant(1.0f),
tf.constant(0.0f)
).asTensor();
}
private final Graph graph;
private final MnistDataset dataset;
// 建構函式
private SimpleMnist(Graph graph, MnistDataset dataset) {
this.graph = graph;
this.dataset = dataset;
}
}
```
---
### [Install-TensorFlow-on-Mac-M1-GPU](https://github.com/deganza/Install-TensorFlow-on-Mac-M1-GPU/blob/main/Install-TensorFlow-on-Mac-M1-GPU.ipynb)
### [How to use GPU with Tensorflow and PyTorch libraries on MacBook pro M2(Apple Silicon)](https://www.linkedin.com/pulse/how-use-gpu-tensorflow-pytorch-libraries-macbook-pro-m2apple-kashyap)
```bash
# Create a virtual environment
pip install --user virtualenv
virtualenv myenv
source myenv/bin/activate
# Installing TensorFlow for MacOS
brew install hdf5
pip install "grpcio>=1.37.0,<2.0" "h5py>=3.6.0,<3.7" "numpy>=1.22.3,<1.23.0"
pip install tensorflow-macos
```
Now you have successfully installed Tensorflow on Apple silicon but the GPU support is still not available.
```python
import tensorflow as tf
print("GPU: ", tf.config.list_physical_devices('GPU'))
# GPU: []
```
```bash
pip install tensorflow-metal
# GPU: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
```