TensorFlow (由Google开发): 更像一个工业化、高度优化的精密生产工具包。它设计严谨,适合大规模部署和生产环境,最初需要先定义好整个计算图再运行(静态图)。因其完整的生态系统(如TensorFlow Serving, TensorFlow Lite)而拥有强大优势。适合工业界/生产部署
PyTorch (由Facebook开发): 更像一个灵活、易用的科研实验工具包。它非常符合Python的直觉,支持动态定义计算图(更易调试),深受研究人员和初学者的喜爱。
共同功能:
- 提供张量计算:强大的N维数组(称为张量)操作,支持GPU加速。
- 自动求导(Autograd):自动计算梯度,这是训练神经网络的核心。
- 预构建的神经网络层:提供了大量现成的层(如卷积层、LSTM层),让你像搭积木一样构建网络。
- 丰富的生态系统:提供从数据加载、模型训练到部署的全套工具。
用PyTorch训练一个图像分类器
一、环境准备,安装PyTorch。通常使用pip或conda安装
pip install torch torchvision
二、定义数据转换,加载训练数据集
- 深度学习项目大量时间花在数据准备上。PyTorch提供了Dataset和DataLoader来高效处理数据。
- transforms.Compose() 将图像数据转换为Tensor,并做归一化
- datasets.MNIST()
- DataLoader()
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision.datasets as datasets
import torchvision.transforms as transforms
# 定义数据转换:将图像数据转换为Tensor,并做归一化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) # MNIST数据集的均值和标准差
])
# 下载并加载训练数据集
train_dataset = datasets.MNIST(
root='./data',
train=True,
download=True,
transform=transform
)
train_loader = DataLoader(
dataset=train_dataset,
batch_size=64, # 每次训练64张图片
shuffle=True # 打乱数据顺序
)
# 下载并加载测试数据集
test_dataset = datasets.MNIST(
root='./data',
train=False,
download=True,
transform=transform
)
test_loader = DataLoader(
dataset=test_dataset,
batch_size=64,
shuffle=False
)
三、构建神经网络模型 (nn.Module)
- 通过继承nn.Module类来定义我们自己的网络结构
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
# 定义网络层
self.fc1 = nn.Linear(28*28, 128) # 全连接层1: 输入28*28=784, 输出128
self.fc2 = nn.Linear(128, 64) # 全连接层2: 输入128, 输出64
self.fc3 = nn.Linear(64, 10) # 全连接层3: 输入64, 输出10 (10个类别)
def forward(self, x):
# 定义数据如何向前传播
x = x.view(-1, 28*28) # 将图片展平 [batch_size, 784]
x = F.relu(self.fc1(x)) # 通过第一层后使用ReLU激活函数
x = F.relu(self.fc2(x)) # 通过第二层后使用ReLU激活函数
x = self.fc3(x) # 最后一层不需要激活函数(配合CrossEntropyLoss)
return x
# 创建模型实例,并移至GPU(如果可用)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = SimpleNN().to(device)
四、定义损失函数和优化器
criterion = nn.CrossEntropyLoss() # 损失函数:对于多分类问题常用交叉熵损失
optimizer = optim.Adam(model.parameters(), lr=0.001) # 优化器:使用Adam来更新权重
五、训练模型
- 前向传播 -> 计算损失 -> 反向传播 -> 更新权重
num_epochs = 5
for epoch in range(num_epochs):
model.train() # 设置模型为训练模式
for batch_idx, (data, targets) in enumerate(train_loader):
# 将数据移至设备(GPU/CPU)
data = data.to(device=device)
targets = targets.to(device=device)
# 前向传播
scores = model(data)
loss = criterion(scores, targets)
# 反向传播
optimizer.zero_grad() # 清零上一轮的梯度
loss.backward() # 自动计算梯度(反向传播)
# 更新模型参数
optimizer.step() # 根据梯度更新权重
六、评估模型性能
- 训练完成后,我们需要在测试集上检查模型的表现
def check_accuracy(loader, model):
model.eval() # 设置模型为评估模式
num_correct = 0
num_samples = 0
with torch.no_grad(): # 在评估时不需要计算梯度,节省内存和计算
for x, y in loader:
x = x.to(device=device)
y = y.to(device=device)
scores = model(x)
_, predictions = scores.max(1) # 获取概率最高的类别作为预测结果
num_correct += (predictions == y).sum()
num_samples += predictions.size(0)
accuracy = float(num_correct) / float(num_samples) * 100
print(f'Got {num_correct} / {num_samples} with accuracy {accuracy:.2f}%')
check_accuracy(test_loader, model)
七、进行预测
# 取一个批次的数据进行演示
data_iter = iter(test_loader)
images, labels = next(data_iter)
img = images[0] # 取第一张图片
# 需要添加一个批次维度 [1, 1, 28, 28]
img = img.unsqueeze(0).to(device)
# 预测
model.eval()
with torch.no_grad():
output = model(img)
_, predicted = torch.max(output.data, 1)
print(f'Predicted digit: {predicted.item()}')
用TensorFlow 2.x的高级API Keras 来实现
import tensorflow as tf
from tensorflow.keras import layers, models
# 1. 加载数据
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # 归一化
# 2. 构建模型 (极其简洁的API)
model = models.Sequential([
layers.Flatten(input_shape=(28, 28)),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(10)
])
# 3. 编译模型 (定义损失和优化器)
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 4. 训练模型
model.fit(x_train, y_train, epochs=5)
# 5. 评估模型
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print(f'\nTest accuracy: {test_acc}')
T
TensorFlow 与 PyTorch 的协作与共存
项目:电商个性化推荐系统
根据用户的实时行为(点击、浏览、加购),快速预测其可能感兴趣的商品并展示
架构设计:
- PyTorch:用于研究和快速迭代推荐系统的核心深度学习模型(如基于 Transformer的深度兴趣网络)。其动态图特性方便调试和实验新想法。
- TensorFlow:用于大规模特征处理(使用 TFX 组件)和高性能线上推理服务(使用 TensorFlowServing)。其静态图和在部署端的优化能保证线上服务的稳定性与效率。
- 协作方式:模型服务化接口。将 PyTorch 训练好的最终模型转换为 ONNX 或 TorchScript 格式,并在TensorFlow Serving 的定制化Docker 镜像中集成 ONNX Runtime 来加载和服务,对外提供统一的gRPC/REST API。
一、模型研发与训练 (PyTorch 环境)
- 环境:安装 PyTorch, TorchVision, ONNX, pandas, scikit-learn 等库
- 数据预处理与特征工程:使用 PyTorch 的 DataLoader 和 Pandas 处理用户和商品数据,构建特征
- 模型构建与训练:在 PyTorch 中定义、训练并验证推荐模型
- 模型导出:训练完成后,将模型导出为 ONNX 格式,以便在其他环境中使用
#conda create -n reco_research python=3.10
#conda activate reco_research
#pip install torch torchvision onnx pandas scikit-learn
# 示例:简单的特征处理
import pandas as pd
import torch
from torch.utils.data import Dataset
class RecoDataset(Dataset):
def __init__(self, data_path):
self.data = pd.read_parquet(data_path)
self.user_features = ... # 处理用户特征
self.item_features = ... # 处理商品特征
self.labels = self.data['label'].values
def __getitem__(self, index):
return (torch.tensor(self.user_features[index], dtype=torch.float),
torch.tensor(self.item_features[index], dtype=torch.float),
torch.tensor(self.labels[index], dtype=torch.float))
def __len__(self):
return len(self.data)
# 示例:定义一个简单的神经网络
import torch.nn as nn
class DIN(nn.Module):
def __init__(self, input_dim):
super().__init__()
self.encoder = nn.Sequential(
nn.Linear(input_dim, 128),
nn.ReLU(),
nn.Linear(128, 64),
nn.ReLU(),
nn.Linear(64, 1),
nn.Sigmoid()
)
def forward(self, user_feat, item_feat):
x = torch.cat([user_feat, item_feat], dim=1)
return self.encoder(x)
# 训练循环(伪代码)
model = DIN(input_dim=user_dim + item_dim)
criterion = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters())
# ... 在DataLoader上循环进行训练和评估 ...
# 导出模型为ONNX格式
dummy_user_input = torch.randn(1, user_dim)
dummy_item_input = torch.randn(1, item_dim)
torch.onnx.export(model,
(dummy_user_input, dummy_item_input),
"din_model.onnx",
input_names=["user_input", "item_input"],
output_names=["output"],
dynamic_axes={"user_input": {0: "batch_size"},
"item_input": {0: "batch_size"},
"output": {0: "batch_size"}})
二、生产环境部署 (TensorFlow 生态系统)
①、环境准备:准备生产环境,可能需要使用 Docker。在镜像中同时安装 TensorFlow Serving 和 ONNX Runtime
# 基于TensorFlow Serving的官方镜像,安装ONNX Runtime
FROM tensorflow/serving:latest
# ... 安装ONNX Runtime的步骤 ...
②、配置 TensorFlow Serving:将导出的 din_model.onnx 模型放入 TensorFlow Serving 的模型仓库目录,并编写配置文件 (models.config) 指定模型名称、路径等
model_config_list: {
config: {
name: "dIN_model",
base_path: "/models/din_model",
model_platform: "onnx", # 表明是ONNX模型
}
}
③、启动服务:启动 TensorFlow Serving 容器,并指定配置文件和端口映射
docker run -p 8501:8501 \
--mount type=bind,source=/path/to/your/model_repo/,target=/models \
-t tensorflow/serving:latest \
--model_config_file=/models/models.config
三、线上推理 (应用端)
①、客户端请求:线上的应用服务(如 Java, Go 或 Python 编写)通过 HTTP/REST 或 gRPC 向 TensorFlow Serving 服务发起推理请求。请求体中需要包含序列化后的特征数据(格式需要与导出 ONNX 模型时的输入一致)
# 示例:使用Python客户端发送请求
import requests
import json
# 准备请求数据
data = {
"signature_name": "serving_default",
"inputs": {
"user_input": user_feat_list.tolist(), # 用户特征向量
"item_input": item_feat_list.tolist() # 商品特征向量
}
}
# 发送请求到TensorFlow Serving
headers = {"content-type": "application/json"}
response = requests.post('http://localhost:8501/v1/models/dIN_model:predict',
data=json.dumps(data), headers=headers)
predictions = response.json()['outputs'] # 获取预测结果
2、结果返回与处理:应用端接收到预测结果后,根据得分进行排序、过滤等后续业务逻辑处理,最终将推荐列表展示给用户。