2.5万字 - 用TensorFlow和PyTorch分别实现五种经典模型

在深度学习领域,TensorFlow和PyTorch是两大广泛使用的框架,各有其独特的特性和优势。随着人工智能技术的快速发展,越来越多的开发者需要熟练掌握这两种工具,以便在实际项目中选择适合的框架进行高效开发。

目录

入门友好介绍

TensorFlow与PyTorch的定位与特点

为什么选择这些模型作为实践目标

主要内容

环境配置与基础知识

开发环境配置

基础概念:Tensor 和自动梯度

Tensor 创建与操作

自动梯度计算

张量与 GPU 的使用

比较与选择

模型一:线性回归

1. 理论背景

2. 数据准备

3. 模型实现

3.1 用 TensorFlow 实现线性回归

3.2 用 PyTorch 实现线性回归

4. 模型评估与可视化

5. 总结

模型二:卷积神经网络(CNN)

1. 理论背景

2. 数据准备

3. 模型实现

3.1 用 TensorFlow 实现 CNN

3.2 用 PyTorch 实现 CNN

4. 模型评估与可视化

5. 总结

模型三:循环神经网络(RNN)

1. 理论背景

2. 数据准备

数据加载与预处理

3. 模型实现

3.1 用 TensorFlow 实现 LSTM

3.2 用 PyTorch 实现 LSTM

4. 模型评估与可视化

5. 总结

模型四:生成对抗网络(GAN)

1. 理论背景

2. 数据准备

3. 模型实现

3.1 用 TensorFlow 实现 GAN

3.2 用 PyTorch 实现 GAN

4. 模型评估与生成结果

5. 总结

模型五:Transformer模型

1. 理论背景

2. 数据准备

数据加载与预处理

3. 模型实现

3.1 用 TensorFlow 实现 Transformer

3.2 用 PyTorch 实现 Transformer

4. 模型评估与翻译测试

5. 总结


入门友好介绍

TensorFlow与PyTorch的定位与特点
  • TensorFlow:由Google开发,是一个面向生产环境的高性能计算框架。TensorFlow的特点是支持分布式训练和跨平台部署,尤其在大规模模型和工业级应用场景中表现优异。此外,TensorFlow 2.0的推出使其更加易用,整合了tf.keras,降低了使用门槛。
  • PyTorch:由Facebook开发,以动态计算图和用户友好的设计闻名。PyTorch更倾向于研究和实验环境,提供了极高的灵活性,允许用户随时调试模型并修改代码。同时,PyTorch的社区非常活跃,涵盖了大量的开源资源。
为什么选择这些模型作为实践目标

深度学习模型有着丰富的多样性,不同的任务需要不同类型的网络架构。本文选择的五种经典模型具有以下意义:

  1. 线性回归:作为深度学习的起点,线性回归帮助初学者理解模型的基本构造。
  2. 卷积神经网络(CNN):广泛应用于图像处理任务,是深度学习领域的重要基石。
  3. 循环神经网络(RNN):用于序列数据处理的核心模型,特别是自然语言处理。
  4. 生成对抗网络(GAN):在生成式建模中有着广泛应用,是前沿研究的重要方向。
  5. Transformer:现代深度学习的重要突破,已成为NLP任务中的主流模型。
主要内容

本文将从零开始,分别用TensorFlow和PyTorch实现上述五种经典模型,每个模型都将包括以下内容:

  • 理论背景:简要介绍模型的工作原理和应用场景。
  • 数据准备:选择合适的数据集并进行预处理。
  • 模型构建:在TensorFlow和PyTorch中分别实现模型。
  • 模型训练:详细讨论训练过程中的技巧和优化方法。
  • 结果分析:展示模型性能,分析优缺点。

环境配置与基础知识

开发环境配置

为了确保流畅的开发体验,我们建议以下步骤配置环境。

# 创建虚拟环境(以 conda 为例)
conda create -n dl_env python=3.9 -y
conda activate dl_env

# 安装 TensorFlow(CPU 版本)
pip install tensorflow

# 安装 PyTorch(根据 CUDA 版本选择安装)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# 安装常用工具
pip install numpy pandas matplotlib scikit-learn jupyter
基础概念:Tensor 和自动梯度

Tensor 是深度学习中最基本的数据结构,类似于多维数组。两大框架都支持自动梯度计算,这对实现反向传播非常重要。

Tensor 创建与操作
# TensorFlow 和 PyTorch 创建 Tensor 的对比
import tensorflow as tf
import torch

# 创建常量和随机 Tensor
tf_tensor = tf.constant([[1.0, 2.0], [3.0, 4.0]])
pt_tensor = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
random_tf = tf.random.uniform((2, 2))
random_pt = torch.rand(2, 2)

# 基本操作
tf_sum, tf_mul = tf_tensor + random_tf, tf_tensor * random_tf
pt_sum, pt_mul = pt_tensor + random_pt, pt_tensor * random_pt
print("TensorFlow Sum:\n", tf_sum, "\nPyTorch Sum:\n", pt_sum)
print("TensorFlow Mul:\n", tf_mul, "\nPyTorch Mul:\n", pt_mul)
自动梯度计算
# TensorFlow 的自动梯度
x_tf = tf.Variable(3.0)
with tf.GradientTape() as tape:
    y_tf = x_tf**2
grad_tf = tape.gradient(y_tf, x_tf)
print("TensorFlow Gradient:", grad_tf)

# PyTorch 的自动梯度
x_pt = torch.tensor(3.0, requires_grad=True)
y_pt = x_pt**2
y_pt.backward()
grad_pt = x_pt.grad
print("PyTorch Gradient:", grad_pt)
张量与 GPU 的使用
# TensorFlow 自动使用 GPU
gpu_tensor_tf = tf.constant([1.0, 2.0], dtype=tf.float32)
print("TensorFlow GPU Tensor:", gpu_tensor_tf.device)

# PyTorch 需要手动指定 GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
gpu_tensor_pt = torch.tensor([1.0, 2.0], device=device)
print("PyTorch GPU Tensor Device:", gpu_tensor_pt.device)
比较与选择
  • TensorFlow 更适合大规模、工业级应用。
  • PyTorch 在灵活性和易用性方面表现更优。
  • 新手建议根据项目需求选择一种框架进行深入学习,随后再扩展到另一种框架。

模型一:线性回归

线性回归是机器学习中最基础的模型之一。它通过拟合一条直线,找到输入特征与目标变量之间的线性关系。虽然简单,但它是理解神经网络的重要基础。

1. 理论背景

2. 数据准备

我们使用随机生成的数据来模拟线性关系:

  • 输入特征 xxx 为一维数据。
  • 目标变量 yyy 通过添加随机噪声生成。
import numpy as np
import matplotlib.pyplot as plt

# 数据生成
np.random.seed(42)
X = np.random.rand(100, 1) * 10  # 输入特征
true_w, true_b = 2.5, 5  # 真实权重和偏置
y = true_w * X + true_b + np.random.randn(100, 1) * 2  # 添加噪声的目标变量

# 可视化数据
plt.scatter(X, y, color="blue", alpha=0.6, label="Data Points")
plt.xlabel("X")
plt.ylabel("y")
plt.title("Synthetic Linear Regression Data")
plt.legend()
plt.show()
3. 模型实现
3.1 用 TensorFlow 实现线性回归

import tensorflow as tf

# 构建模型
class LinearRegressionTF(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.w = tf.Variable(tf.random.normal([1]))
        self.b = tf.Variable(tf.random.normal([1]))

    def call(self, x):
        return self.w * x + self.b

# 模型训练
def train_tf_model(X, y, epochs=100, lr=0.01):
    model = LinearRegressionTF()
    optimizer = tf.keras.optimizers.SGD(learning_rate=lr)
    mse_loss = tf.keras.losses.MeanSquaredError()

    for epoch in range(epochs):
        with tf.GradientTape() as tape:
            predictions = model(X)
            loss = mse_loss(y, predictions)
        gradients = tape.gradient(loss, [model.w, model.b])
        optimizer.apply_gradients(zip(gradients, [model.w, model.b]))

        if (epoch + 1) % 10 == 0:
            print(f"Epoch {epoch+1}: Loss = {loss.numpy():.4f}")

    return model

# 数据转换为 TensorFlow 张量
X_tf = tf.constant(X, dtype=tf.float32)
y_tf = tf.constant(y, dtype=tf.float32)

# 训练模型
model_tf = train_tf_model(X_tf, y_tf)
print(f"Trained Weights: w = {model_tf.w.numpy()[0]:.2f}, b = {model_tf.b.numpy()[0]:.2f}")
3.2 用 PyTorch 实现线性回归
import torch
from torch import nn
from torch.optim import SGD

# 构建模型
class LinearRegressionPT(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(1, 1)

    def forward(self, x):
        return self.linear(x)

# 模型训练
def train_pt_model(X, y, epochs=100, lr=0.01):
    model = LinearRegressionPT()
    criterion = nn.MSELoss()
    optimizer = SGD(model.parameters(), lr=lr)

    for epoch in range(epochs):
        model.train()
        optimizer.zero_grad()
        predictions = model(X)
        loss = criterion(predictions, y)
        loss.backward()
        optimizer.step()

        if (epoch + 1) % 10 == 0:
            print(f"Epoch {epoch+1}: Loss = {loss.item():.4f}")

    return model

# 数据转换为 PyTorch 张量
X_pt = torch.tensor(X, dtype=torch.float32)
y_pt = torch.tensor(y, dtype=torch.float32)

# 训练模型
model_pt = train_pt_model(X_pt, y_pt)
trained_weights = model_pt.linear.weight.item()
trained_bias = model_pt.linear.bias.item()
print(f"Trained Weights: w = {trained_weights:.2f}, b = {trained_bias:.2f}")
4. 模型评估与可视化

我们使用训练好的模型对新数据进行预测,并可视化拟合效果。

# 生成预测数据
X_new = np.linspace(0, 10, 100).reshape(-1, 1)
X_new_tf = tf.constant(X_new, dtype=tf.float32)
X_new_pt = torch.tensor(X_new, dtype=torch.float32)

y_pred_tf = model_tf(X_new_tf).numpy()
y_pred_pt = model_pt(X_new_pt).detach().numpy()

# 可视化结果
plt.scatter(X, y, color="blue", alpha=0.6, label="Data Points")
plt.plot(X_new, y_pred_tf, color="red", label="TensorFlow Prediction")
plt.plot(X_new, y_pred_pt, color="green", linestyle="--", label="PyTorch Prediction")
plt.xlabel("X")
plt.ylabel("y")
plt.title("Linear Regression Fit")
plt.legend()
plt.show()
5. 总结
  1. 实现对比
    • TensorFlow 使用自定义模型类(tf.keras.Model),代码相对简洁。
    • PyTorch 的 nn.Module 提供了灵活性,尤其在复杂模型中表现突出。
  2. 性能与结果
    • 两种框架均能高效完成线性回归任务,最终权重和偏置与真实值接近。
  3. 适用场景
    • TensorFlow 更适合快速开发和生产部署。
    • PyTorch 更适合研究和复杂模型的实验。

模型二:卷积神经网络(CNN)

卷积神经网络(Convolutional Neural Network, CNN)是深度学习中处理图像数据的核心模型。它通过卷积操作提取空间特征,在图像分类、目标检测等领域具有广泛的应用。

1. 理论背景

CNN 的核心组件包括:

  1. 卷积层(Convolution Layer):通过卷积核提取图像的局部特征。
  2. 池化层(Pooling Layer):降低特征图的维度,同时保留重要信息。
  3. 全连接层(Fully Connected Layer):将提取的特征映射到分类任务。

经典的 CNN 网络结构如下:

  • 输入层:输入原始图像数据(如 MNIST 手写数字图片)。
  • 卷积 + 激活函数:提取特征并非线性化。
  • 池化层:降低维度,减少计算量。
  • 多层卷积 + 池化。
  • 全连接层:用于分类。
2. 数据准备

我们使用 MNIST 数据集进行分类任务,目标是识别手写数字(0-9)。

import tensorflow as tf
from tensorflow.keras.datasets import mnist
import torch
from torchvision import datasets, transforms

# TensorFlow 数据加载
(X_train_tf, y_train_tf), (X_test_tf, y_test_tf) = mnist.load_data()
X_train_tf, X_test_tf = X_train_tf / 255.0, X_test_tf / 255.0  # 归一化
X_train_tf = X_train_tf[..., tf.newaxis]  # 添加通道维度
X_test_tf = X_test_tf[..., tf.newaxis]

# PyTorch 数据加载
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset_pt = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset_pt = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader_pt = torch.utils.data.DataLoader(train_dataset_pt, batch_size=64, shuffle=True)
test_loader_pt = torch.utils.data.DataLoader(test_dataset_pt, batch_size=64, shuffle=False)
3. 模型实现
3.1 用 TensorFlow 实现 CNN
from tensorflow.keras import layers, models

# 构建 CNN 模型
def build_cnn_tf():
    model = models.Sequential([
        layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
        layers.MaxPooling2D((2, 2)),
        layers.Conv2D(64, (3, 3), activation='relu'),
        layers.MaxPooling2D((2, 2)),
        layers.Conv2D(64, (3, 3), activation='relu'),
        layers.Flatten(),
        layers.Dense(64, activation='relu'),
        layers.Dense(10, activation='softmax')
    ])
    return model

# 编译和训练模型
def train_cnn_tf(model, X_train, y_train, X_test, y_test, epochs=5):
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    model.fit(X_train, y_train, epochs=epochs, validation_data=(X_test, y_test))
    return model

# 训练模型
model_tf = build_cnn_tf()
train_cnn_tf(model_tf, X_train_tf, y_train_tf, X_test_tf, y_test_tf)
3.2 用 PyTorch 实现 CNN
import torch.nn as nn
import torch.optim as optim

# 构建 CNN 模型
class CNNPT(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv_layers = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3, activation='relu'),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(32, 64, kernel_size=3, activation='relu'),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(64, 64, kernel_size=3, activation='relu')
        )
        self.fc_layers = nn.Sequential(
            nn.Flatten(),
            nn.Linear(64 * 3 * 3, 64),
            nn.ReLU(),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        x = self.conv_layers(x)
        x = self.fc_layers(x)
        return x

# 模型训练
def train_cnn_pt(model, train_loader, test_loader, epochs=5, lr=0.001):
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=lr)

    for epoch in range(epochs):
        model.train()
        for images, labels in train_loader:
            optimizer.zero_grad()
            outputs = model(images)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

        # 测试模型
        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for images, labels in test_loader:
                outputs = model(images)
                _, predicted = torch.max(outputs, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()

        print(f"Epoch {epoch+1}, Accuracy: {correct / total:.4f}")

# 训练模型
model_pt = CNNPT()
train_cnn_pt(model_pt, train_loader_pt, test_loader_pt)
4. 模型评估与可视化
# TensorFlow 测试集评估
loss_tf, acc_tf = model_tf.evaluate(X_test_tf, y_test_tf)
print(f"TensorFlow Test Accuracy: {acc_tf:.4f}")

# PyTorch 测试集评估
correct, total = 0, 0
model_pt.eval()
with torch.no_grad():
    for images, labels in test_loader_pt:
        outputs = model_pt(images)
        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
print(f"PyTorch Test Accuracy: {correct / total:.4f}")
5. 总结
  1. 实现对比
    • TensorFlow 的高层 API(如 SequentialConv2D)简化了代码实现。
    • PyTorch 的 nn.Module 提供了灵活的构造方式,更适合复杂的自定义网络。
  2. 性能分析
    • 两种框架都能达到较高的测试集准确率(>98%)。
    • TensorFlow 适合快速原型开发,PyTorch 则在调试和灵活性方面表现更优。
  3. 学习提升
    • 深入理解 CNN 的核心概念(卷积、池化、全连接)。
    • 掌握两种框架在图像处理任务中的基本用法。

模型三:循环神经网络(RNN)

循环神经网络(Recurrent Neural Network, RNN)是处理序列数据的核心模型。它通过循环结构捕捉数据的时间依赖性,在自然语言处理、时间序列预测等领域广泛应用。

1. 理论背景

2. 数据准备

我们以 IMDb 数据集为例,构建一个基于 RNN 的情感分类模型:

  • 输入:电影评论(文本序列)。
  • 输出:情感标签(正面或负面)。
数据加载与预处理
# TensorFlow 数据加载
import tensorflow as tf
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 加载 IMDb 数据集
vocab_size = 10000
maxlen = 200
(X_train_tf, y_train_tf), (X_test_tf, y_test_tf) = imdb.load_data(num_words=vocab_size)

# 填充序列
X_train_tf = pad_sequences(X_train_tf, maxlen=maxlen, padding='post')
X_test_tf = pad_sequences(X_test_tf, maxlen=maxlen, padding='post')

# PyTorch 数据加载
from torchtext.datasets import IMDB
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
from torch.utils.data import DataLoader

tokenizer = get_tokenizer('basic_english')
train_iter = IMDB(split='train')

# 构建词汇表
def yield_tokens(data_iter):
    for _, text in data_iter:
        yield tokenizer(text)

vocab = build_vocab_from_iterator(yield_tokens(train_iter), specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"])

# 文本转数字序列
text_pipeline = lambda x: vocab(tokenizer(x))
label_pipeline = lambda x: 1 if x == "pos" else 0

# 数据加载器
def collate_batch(batch):
    label_list, text_list, lengths = [], [], []
    for _label, _text in batch:
        label_list.append(label_pipeline(_label))
        processed_text = torch.tensor(text_pipeline(_text), dtype=torch.int64)
        text_list.append(processed_text)
        lengths.append(len(processed_text))
    return torch.tensor(label_list, dtype=torch.int64), text_list, torch.tensor(lengths)

train_loader_pt = DataLoader(IMDB(split='train'), batch_size=64, shuffle=True, collate_fn=collate_batch)
test_loader_pt = DataLoader(IMDB(split='test'), batch_size=64, shuffle=False, collate_fn=collate_batch)
3. 模型实现
3.1 用 TensorFlow 实现 LSTM
from tensorflow.keras import layers, models

# 构建 LSTM 模型
def build_rnn_tf():
    model = models.Sequential([
        layers.Embedding(input_dim=vocab_size, output_dim=128, input_length=maxlen),
        layers.LSTM(128, return_sequences=False),
        layers.Dense(1, activation='sigmoid')
    ])
    return model

# 编译和训练模型
def train_rnn_tf(model, X_train, y_train, X_test, y_test, epochs=5):
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    model.fit(X_train, y_train, epochs=epochs, validation_data=(X_test, y_test))
    return model

# 训练模型
model_tf = build_rnn_tf()
train_rnn_tf(model_tf, X_train_tf, y_train_tf, X_test_tf, y_test_tf)
3.2 用 PyTorch 实现 LSTM
import torch.nn as nn
import torch.optim as optim

# 构建 LSTM 模型
class RNNPT(nn.Module):
    def __init__(self, vocab_size, embed_dim, hidden_dim, output_dim):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embed_dim)
        self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x, lengths):
        embedded = self.embedding(x)
        packed = nn.utils.rnn.pack_padded_sequence(embedded, lengths, batch_first=True, enforce_sorted=False)
        _, (hidden, _) = self.lstm(packed)
        return torch.sigmoid(self.fc(hidden[-1]))

# 模型训练
def train_rnn_pt(model, train_loader, test_loader, epochs=5, lr=0.001):
    criterion = nn.BCELoss()
    optimizer = optim.Adam(model.parameters(), lr=lr)

    for epoch in range(epochs):
        model.train()
        for labels, texts, lengths in train_loader:
            optimizer.zero_grad()
            padded_texts = nn.utils.rnn.pad_sequence(texts, batch_first=True)
            outputs = model(padded_texts, lengths)
            loss = criterion(outputs.squeeze(), labels.float())
            loss.backward()
            optimizer.step()

        # 测试模型
        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for labels, texts, lengths in test_loader:
                padded_texts = nn.utils.rnn.pad_sequence(texts, batch_first=True)
                outputs = model(padded_texts, lengths)
                predicted = (outputs.squeeze() > 0.5).long()
                total += labels.size(0)
                correct += (predicted == labels).sum().item()

        print(f"Epoch {epoch+1}, Accuracy: {correct / total:.4f}")

# 训练模型
model_pt = RNNPT(vocab_size=len(vocab), embed_dim=128, hidden_dim=128, output_dim=1)
train_rnn_pt(model_pt, train_loader_pt, test_loader_pt)
4. 模型评估与可视化
# TensorFlow 测试集评估
loss_tf, acc_tf = model_tf.evaluate(X_test_tf, y_test_tf)
print(f"TensorFlow Test Accuracy: {acc_tf:.4f}")

# PyTorch 测试集评估
correct, total = 0, 0
model_pt.eval()
with torch.no_grad():
    for labels, texts, lengths in test_loader_pt:
        padded_texts = nn.utils.rnn.pad_sequence(texts, batch_first=True)
        outputs = model_pt(padded_texts, lengths)
        predicted = (outputs.squeeze() > 0.5).long()
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
print(f"PyTorch Test Accuracy: {correct / total:.4f}")
5. 总结
  1. 实现对比
    • TensorFlow 的高层 API(如 EmbeddingLSTM)使实现过程非常直观。
    • PyTorch 提供了更底层的控制选项,适合复杂场景。
  2. 性能分析
    • 两种框架均能在 IMDb 数据集上达到较高准确率(>85%)。
    • PyTorch 的灵活性在自定义序列处理中更占优势。
  3. 学习提升
    • 掌握序列模型的基本概念(如嵌入层、时间步)。
    • 深入理解 LSTM 和文本分类任务中的关键技术点。

模型四:生成对抗网络(GAN)

生成对抗网络(Generative Adversarial Network, GAN)是一类生成模型,通过两个网络(生成器和判别器)之间的对抗性训练,生成高质量的合成数据。GAN 被广泛用于图像生成、图像修复、风格迁移等任务。

1. 理论背景

2. 数据准备

我们使用 MNIST 数据集作为真实数据,生成类似手写数字的图像。

# TensorFlow 数据加载
import tensorflow as tf
from tensorflow.keras.datasets import mnist

(X_train_tf, _), (_, _) = mnist.load_data()
X_train_tf = (X_train_tf / 127.5) - 1.0  # 归一化到 [-1, 1]
X_train_tf = X_train_tf[..., tf.newaxis].astype('float32')  # 添加通道维度

# PyTorch 数据加载
import torch
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset_pt = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader_pt = DataLoader(train_dataset_pt, batch_size=64, shuffle=True)
3. 模型实现
3.1 用 TensorFlow 实现 GAN
from tensorflow.keras import layers

# 生成器模型
def build_generator_tf():
    model = tf.keras.Sequential([
        layers.Dense(256, activation='relu', input_dim=100),
        layers.BatchNormalization(),
        layers.LeakyReLU(0.2),
        layers.Dense(512, activation='relu'),
        layers.BatchNormalization(),
        layers.LeakyReLU(0.2),
        layers.Dense(28 * 28 * 1, activation='tanh'),
        layers.Reshape((28, 28, 1))
    ])
    return model

# 判别器模型
def build_discriminator_tf():
    model = tf.keras.Sequential([
        layers.Flatten(input_shape=(28, 28, 1)),
        layers.Dense(512, activation='relu'),
        layers.LeakyReLU(0.2),
        layers.Dense(256, activation='relu'),
        layers.LeakyReLU(0.2),
        layers.Dense(1, activation='sigmoid')
    ])
    return model

# GAN 训练
def train_gan_tf(generator, discriminator, epochs=10000, batch_size=128):
    # 优化器和损失函数
    cross_entropy = tf.keras.losses.BinaryCrossentropy()
    generator_optimizer = tf.keras.optimizers.Adam(1e-4)
    discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

    @tf.function
    def train_step(real_images):
        noise = tf.random.normal([batch_size, 100])

        # 生成假数据
        with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
            fake_images = generator(noise, training=True)
            real_output = discriminator(real_images, training=True)
            fake_output = discriminator(fake_images, training=True)

            gen_loss = cross_entropy(tf.ones_like(fake_output), fake_output)
            disc_loss = cross_entropy(tf.ones_like(real_output), real_output) + \
                        cross_entropy(tf.zeros_like(fake_output), fake_output)

        # 更新生成器和判别器
        gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
        gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

        generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
        discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

        return gen_loss, disc_loss

    # 开始训练
    for epoch in range(epochs):
        for batch in range(0, len(X_train_tf), batch_size):
            real_images = X_train_tf[batch:batch + batch_size]
            g_loss, d_loss = train_step(real_images)
        if epoch % 1000 == 0:
            print(f"Epoch {epoch}: Generator Loss: {g_loss:.4f}, Discriminator Loss: {d_loss:.4f}")

# 构建和训练模型
generator_tf = build_generator_tf()
discriminator_tf = build_discriminator_tf()
train_gan_tf(generator_tf, discriminator_tf)
3.2 用 PyTorch 实现 GAN
import torch.nn as nn
import torch.optim as optim

# 生成器模型
class GeneratorPT(nn.Module):
    def __init__(self):
        super().__init__()
        self.model = nn.Sequential(
            nn.Linear(100, 256),
            nn.ReLU(True),
            nn.BatchNorm1d(256),
            nn.Linear(256, 512),
            nn.ReLU(True),
            nn.BatchNorm1d(512),
            nn.Linear(512, 28 * 28),
            nn.Tanh()
        )

    def forward(self, x):
        return self.model(x).view(-1, 1, 28, 28)

# 判别器模型
class DiscriminatorPT(nn.Module):
    def __init__(self):
        super().__init__()
        self.model = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 512),
            nn.LeakyReLU(0.2),
            nn.Linear(512, 256),
            nn.LeakyReLU(0.2),
            nn.Linear(256, 1),
            nn.Sigmoid()
        )

    def forward(self, x):
        return self.model(x)

# 训练 GAN
def train_gan_pt(generator, discriminator, train_loader, epochs=50, batch_size=64, lr=0.0002):
    criterion = nn.BCELoss()
    optimizer_g = optim.Adam(generator.parameters(), lr=lr)
    optimizer_d = optim.Adam(discriminator.parameters(), lr=lr)

    for epoch in range(epochs):
        for real_images, _ in train_loader:
            # 判别器训练
            noise = torch.randn(batch_size, 100)
            fake_images = generator(noise)
            real_labels = torch.ones(batch_size, 1)
            fake_labels = torch.zeros(batch_size, 1)

            optimizer_d.zero_grad()
            real_loss = criterion(discriminator(real_images), real_labels)
            fake_loss = criterion(discriminator(fake_images.detach()), fake_labels)
            d_loss = real_loss + fake_loss
            d_loss.backward()
            optimizer_d.step()

            # 生成器训练
            optimizer_g.zero_grad()
            g_loss = criterion(discriminator(fake_images), real_labels)
            g_loss.backward()
            optimizer_g.step()

        print(f"Epoch {epoch+1}, Generator Loss: {g_loss.item():.4f}, Discriminator Loss: {d_loss.item():.4f}")

# 构建和训练模型
generator_pt = GeneratorPT()
discriminator_pt = DiscriminatorPT()
train_gan_pt(generator_pt, discriminator_pt, train_loader_pt)
4. 模型评估与生成结果
# 生成新图像(TensorFlow)
import matplotlib.pyplot as plt

noise_tf = tf.random.normal([16, 100])
generated_images_tf = generator_tf(noise_tf).numpy()
plt.figure(figsize=(8, 8))
for i in range(16):
    plt.subplot(4, 4, i + 1)
    plt.imshow(generated_images_tf[i, :, :, 0], cmap='gray')
    plt.axis('off')
plt.show()

# 生成新图像(PyTorch)
noise_pt = torch.randn(16, 100)
generated_images_pt = generator_pt(noise_pt).detach().numpy()
plt.figure(figsize=(8, 8))
for i in range(16):
    plt.subplot(4, 4, i + 1)
    plt.imshow(generated_images_pt[i, 0, :, :], cmap='gray')
    plt.axis('off')
plt.show()
5. 总结
  1. 实现对比
    • TensorFlow 的高层 API 简化了实现过程,适合快速开发。
    • PyTorch 提供了更灵活的训练流程,适合深入研究和复杂任务。
  2. 性能分析
    • 两种框架均能生成清晰的伪造图片。
  3. 学习提升
    • 掌握 GAN 的训练原理和技巧。
    • 理解生成器和判别器的博弈过程以及优化方法。

模型五:Transformer模型

Transformer 模型是近年来深度学习领域的重大突破,尤其在自然语言处理(NLP)任务中表现卓越。它使用自注意力机制代替传统 RNN 的序列处理方式,极大提升了训练效率和任务性能。

1. 理论背景

Transformer 的核心组件包括:

  1. 自注意力机制(Self-Attention):通过计算输入序列中各元素之间的依赖关系,捕捉全局信息。
  2. 多头注意力机制(Multi-Head Attention):通过并行的多个注意力头,学习输入序列的多样性特征。
  3. 位置编码(Positional Encoding):补充位置信息,使模型能够感知序列顺序。

Transformer 的基本结构包括:

  • 编码器(Encoder):由多层堆叠的注意力机制和前馈网络组成。
  • 解码器(Decoder):结合目标序列和编码器输出生成预测。
2. 数据准备

我们使用一个翻译任务(如英语到德语)作为示例,利用 TensorFlow 和 PyTorch 构建 Transformer 模型。

数据加载与预处理
# TensorFlow 数据加载
import tensorflow_datasets as tfds

# 加载 WMT 英德翻译数据集
train_data, val_data = tfds.load('wmt14_translate/de-en', split=['train', 'validation'], as_supervised=True)

# 文本预处理
tokenizer_en = tfds.features.text.SubwordTextEncoder.build_from_corpus(
    (en.numpy() for de, en in train_data), target_vocab_size=2**13)
tokenizer_de = tfds.features.text.SubwordTextEncoder.build_from_corpus(
    (de.numpy() for de, en in train_data), target_vocab_size=2**13)

def encode(de, en):
    de = [tokenizer_de.vocab_size] + tokenizer_de.encode(de.numpy()) + [tokenizer_de.vocab_size+1]
    en = [tokenizer_en.vocab_size] + tokenizer_en.encode(en.numpy()) + [tokenizer_en.vocab_size+1]
    return de, en

# PyTorch 数据加载
from torchtext.datasets import Multi30k
from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
from torch.utils.data import DataLoader

# 加载数据
tokenizer_en = get_tokenizer('spacy', language='en_core_web_sm')
tokenizer_de = get_tokenizer('spacy', language='de_core_news_sm')

# 构建词汇表
def yield_tokens(data_iter, tokenizer):
    for src, tgt in data_iter:
        yield tokenizer(src)

vocab_en = build_vocab_from_iterator(yield_tokens(Multi30k(split='train'), tokenizer_en), specials=["<unk>"])
vocab_de = build_vocab_from_iterator(yield_tokens(Multi30k(split='train'), tokenizer_de), specials=["<unk>"])

# 数据迭代器
def collate_batch(batch):
    src_list, tgt_list = [], []
    for src, tgt in batch:
        src_list.append(torch.tensor([vocab_de[token] for token in tokenizer_de(src)], dtype=torch.int64))
        tgt_list.append(torch.tensor([vocab_en[token] for token in tokenizer_en(tgt)], dtype=torch.int64))
    return nn.utils.rnn.pad_sequence(src_list, batch_first=True), nn.utils.rnn.pad_sequence(tgt_list, batch_first=True)

train_loader_pt = DataLoader(Multi30k(split='train'), batch_size=64, shuffle=True, collate_fn=collate_batch)
3. 模型实现
3.1 用 TensorFlow 实现 Transformer
from tensorflow.keras.layers import Input, Dense, Embedding, MultiHeadAttention, LayerNormalization, Dropout

# 定义 Transformer 层
class TransformerBlock(tf.keras.layers.Layer):
    def __init__(self, embed_dim, num_heads, ff_dim, rate=0.1):
        super(TransformerBlock, self).__init__()
        self.att = MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
        self.ffn = tf.keras.Sequential([Dense(ff_dim, activation="relu"), Dense(embed_dim)])
        self.layernorm1 = LayerNormalization(epsilon=1e-6)
        self.layernorm2 = LayerNormalization(epsilon=1e-6)
        self.dropout1 = Dropout(rate)
        self.dropout2 = Dropout(rate)

    def call(self, inputs, training):
        attn_output = self.att(inputs, inputs)
        attn_output = self.dropout1(attn_output, training=training)
        out1 = self.layernorm1(inputs + attn_output)
        ffn_output = self.ffn(out1)
        ffn_output = self.dropout2(ffn_output, training=training)
        return self.layernorm2(out1 + ffn_output)

# 构建完整模型
def build_transformer_tf(embed_dim=128, num_heads=4, ff_dim=512, vocab_size=8000):
    inputs = Input(shape=(None,))
    x = Embedding(input_dim=vocab_size, output_dim=embed_dim)(inputs)
    x = TransformerBlock(embed_dim, num_heads, ff_dim)(x)
    outputs = Dense(vocab_size, activation="softmax")(x)
    return tf.keras.Model(inputs, outputs)

# 编译和训练模型
model_tf = build_transformer_tf()
model_tf.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
3.2 用 PyTorch 实现 Transformer
import torch.nn as nn
import torch.optim as optim

class TransformerBlockPT(nn.Module):
    def __init__(self, embed_dim, num_heads, ff_dim):
        super().__init__()
        self.att = nn.MultiheadAttention(embed_dim, num_heads)
        self.ffn = nn.Sequential(nn.Linear(embed_dim, ff_dim), nn.ReLU(), nn.Linear(ff_dim, embed_dim))
        self.layernorm1 = nn.LayerNorm(embed_dim)
        self.layernorm2 = nn.LayerNorm(embed_dim)

    def forward(self, x):
        attn_output, _ = self.att(x, x, x)
        x = self.layernorm1(x + attn_output)
        ffn_output = self.ffn(x)
        return self.layernorm2(x + ffn_output)

class TransformerPT(nn.Module):
    def __init__(self, vocab_size, embed_dim, num_heads, ff_dim):
        super().__init__()
        self.embedding = nn.Embedding(vocab_size, embed_dim)
        self.transformer = TransformerBlockPT(embed_dim, num_heads, ff_dim)
        self.fc = nn.Linear(embed_dim, vocab_size)

    def forward(self, x):
        x = self.embedding(x)
        x = self.transformer(x)
        return self.fc(x)

model_pt = TransformerPT(vocab_size=8000, embed_dim=128, num_heads=4, ff_dim=512)
optimizer_pt = optim.Adam(model_pt.parameters(), lr=0.001)
4. 模型评估与翻译测试
# TensorFlow 翻译测试
input_seq = tokenizer_en.encode("Translate this sentence into German")
predicted_seq = model_tf.predict(input_seq)
decoded_seq = tokenizer_de.decode(predicted_seq)
print("Translated Sentence (TensorFlow):", decoded_seq)

# PyTorch 翻译测试
input_seq_pt = torch.tensor([vocab_en[token] for token in tokenizer_en("Translate this sentence into German")])
output_seq_pt = model_pt(input_seq_pt.unsqueeze(0))
predicted_seq_pt = torch.argmax(output_seq_pt, dim=-1)
decoded_seq_pt = " ".join([vocab_de.itos[idx] for idx in predicted_seq_pt])
print("Translated Sentence (PyTorch):", decoded_seq_pt)
5. 总结
  1. 实现对比
    • TensorFlow 提供了高层次的 MultiHeadAttention,构建方便。
    • PyTorch 的 nn.MultiheadAttention 模块灵活性更高,适合复杂应用。
  2. 性能分析
    • 在翻译任务中,Transformer 生成的文本更符合语义,表现优于传统 RNN。
  3. 学习提升
    • 理解自注意力机制和多头注意力的工作原理。
    • 掌握 Transformer 模型在翻译任务中的实现与应用技巧。

        在深度学习的世界里,TensorFlow 和 PyTorch 就像编程界的罗密欧与朱丽叶,各自美丽,却时常被用来比较。我们带着这两位“主角”,完成了从线性回归到 Transformer 的五大经典模型旅程,这不仅是技术的碰撞,更是思维方式的启发。

        TensorFlow 是工业化流水线的典范,适合“快准稳”的生产环境;PyTorch 是实验室里的自由艺术家,适合研究探索和复杂自定义任务。它们不是竞争关系,而是互补的工具。

        继续加油,成为深度学习界的六边形战士!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945851.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】2029:【例4.15】水仙花数

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;我的做法思路分析优势不足之处 &#x1f4af;老师的做法思路分析优势不足 &#x1f4af;对比和优化实现方式对比优化思路和操作1. 直接分解数字的各位…

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中的应用前景

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中具有广泛的应用前景。如有滤波、导航方面的代码定制需求,可通过文末卡片联系作者获得帮助 文章目录 结合LSTM和UKF的背景结合LSTM和UKF的优势应用实例研究现状MATLAB代码示例结论结合LSTM和…

Android14 CTS-R6和GTS-12-R2不能同时测试的解决方法

背景 Android14 CTS r6和GTS 12-r1之后&#xff0c;tf-console默认会带起OLC Server&#xff0c;看起来olc server可能是想适配ATS(android-test-station)&#xff0c;一种网页版可视化、可配置的跑XTS的方式。这种网页版ATS对测试人员是比较友好的&#xff0c;网页上简单配置下…

告别Kibana:Elasticsearch 桌面客户端的新变革

告别Kibana&#xff1a;Elasticsearch 桌面客户端的新变革 在大数据处理与分析领域&#xff0c;Elasticsearch 及其相关技术的应用日益广泛。长期以来&#xff0c;Kibana 在数据可视化与查询管理方面占据重要地位&#xff0c;但随着技术的不断发展&#xff0c;用户对于更高效、…

HTML5实现喜庆的新年快乐网页源码

HTML5实现喜庆的新年快乐网页源码 前言一、设计来源1.1 主界面1.2 关于新年界面1.3 新年庆祝活动界面1.4 新年活动组织界面1.5 新年祝福订阅界面1.6 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现喜庆的新年快乐网页源码&#xff0c;春节新年网…

【广州计算机学会、广州互联网协会联合主办 | ACM独立出版 | 高录用】第四届大数据、信息与计算机网络国际学术会议(BDICN 2025)

第四届大数据、信息与计算机网络国际学术会议&#xff08;BDICN 2025&#xff09;定于2025年01月10-12日在中国广州举行。会议旨在为从事“大数据”、“计算机网络”与“信息”研究的专家学者、工程技术人员、技术研发人员提供一个共享科研成果和前沿技术&#xff0c;了解学术发…

C语言函数栈帧的创建和销毁

文章目录 一、寄存器二、函数栈帧的创建和销毁1.什么是函数栈帧&#xff1f;2.案例代码-讲解3.总结函数栈帧 一、寄存器 寄存器(Register)是中央处理机、主存储器和其他数字设备中某些特定用途的存储单元。寄存器是集成电路中非常重要的一种存储单元&#xff1b;其可用来暂存指…

我的博客年度之旅:感恩、成长与展望

目录 感恩有你 技能满点 新年新征程 嘿&#xff0c;各位技术大佬、数码潮咖还有屏幕前超爱学习的小伙伴们&#xff01;当新年的钟声即将敲响&#xff0c;我们站在时光的交汇点上&#xff0c;回首过往&#xff0c;满心感慨&#xff1b;展望未来&#xff0c;豪情满怀。过去的这…

【数据库初阶】MySQL数据类型

&#x1f389;博主首页&#xff1a; 有趣的中国人 &#x1f389;专栏首页&#xff1a; 数据库初阶 &#x1f389;其它专栏&#xff1a; C初阶 | C进阶 | 初阶数据结构 亲爱的小伙伴们&#xff0c;大家好&#xff01;在这篇文章中&#xff0c;我们将深入浅出地为大家讲解 MySQL…

webrtc 源码阅读 make_ref_counted模板函数用法

目录 1. 模板参数解析 1.1 typename T 1.2 typename... Args 1.3 typename std::enable_if::value, T>::type* nullptr 2. scoped_refptr 3. new RefCountedObject(std::forward(args)...); 4. 综合说明 5.在webrtc中的用法 5.1 peerConnectionFactory对象的构建过…

python参数传递不可变对象含可变子对象

当传递不可变对象时。不可变对象里面包含的子对象是可变的。则方法内修改了这个可变对象&#xff0c;源对象也发生了变化。 a (10, 20, [5, 6]) print("a", id(a))def test01(m):print("m", id(m))m[2][0] 888print("修改m后m的值为{}".forma…

qt5.15.2+visual studio2022 免安装版环境配置

1.环境准备 visual studio2022qt5.15.2&#xff08;免安装版本&#xff09; 2.环境配置 2.1 打开首选项 2.2 添加Qt版本 2.3 构建套件手动添加Qt 5.15.2&#xff08;msvc2019_64&#xff09;并配置如下 3.新建项目 问题1&#xff1a;qt creator 没有欢迎界面 解决办法&#…

KOI技术-事件驱动编程(Sping后端)

1 “你日渐平庸&#xff0c;甘于平庸&#xff0c;将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的&#xff0c;那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人&#xff0c;和他们斗了那么久&#xff0c;最终却要变得和他们一样&#xff0c;…

华为消费级QLC SSD来了

近日&#xff0c;有关消息显示&#xff0c;华为的消费级SSD产品线&#xff0c;eKitStor Xtreme 200E系列&#xff0c;在韩国一家在线零售商处首次公开销售&#xff0c;引起了业界的广泛关注。 尽管华为已经涉足服务器级别的SSD制造多年&#xff0c;但直到今年6月才正式推出面向…

007-构建工具大进步:Amper Amper Amper!

Amper Amper Amper! 今天天气不好&#xff0c;送孩子上少年宫之后就在茶馆里坐着。突然看到一个帖子&#xff1a;Project configuration with Amper&#xff0c;看得心情大好。 用Kotlin也有个大概几年的时间&#xff0c;开发了几个小工具&#xff0c;感觉很是不错。但是配置…

STM32 高级 物联网通讯之LoRa通讯

目录 LoRa通讯基础知识 常见的3种通讯协议 远距离高速率的传输协议 近距离高速率传输技术 近距离低功耗传输技术 低功耗广域网 采用授权频段技术 非授权频段 LoRa简介 LoRa的特点 远距离 低功耗 安全 标准化 地理定位 移动性 高性能 低成本 LoRa应用 LoRa组…

SAP月结、年结前重点检查事项(后勤与财务模块)

文章目录 一、PP生产模块相关的事务检查二、SD销售模块相关的事务检查:三、MM物料管理模块相关的事务检查四、FICO财务模块相关的事务检查五、年结前若干注意事项【SAP系统PP模块研究】 #SAP #生产订单 #月结 #年结 一、PP生产模块相关的事务检查 1、月末盘点后,生产用料的…

重装操作系统后 Oracle 11g 数据库数据还原

场景描述&#xff1a; 由于SSD系统盘损坏&#xff0c;更换硬盘后重装了操作系统&#xff0c;Oracle数据库之前安装在D盘(另一个硬盘)&#xff0c;更换硬盘多添加一个盘符重装系统后盘符从D变成E&#xff0c;也就是之前的D:/app/... 变成了现在的 E:/app/...&#xff0c;重新安装…

2D图像测量到3D点云之物体三维尺寸测量!!!!

0&#xff0c;引言 本文将从双目采集的2D图像到3D点云进行转化&#xff0c;并进行物体尺寸测量&#xff0c;旨在为读者展示2D图像如何关联3D点云&#xff0c;并进行相关工业应用。 将2D图像转化为3D点云&#xff0c;并进行物体尺寸测量的技术&#xff0c;在工业领域有着广泛的…

python 渗透开发工具之SQLMapApi Server不同IP服务启动方式处理 解决方案SqlMapApiServer外网不能访问的情况

目录 说在前面 什么是 SQLMapAPI 说明 sqlmapApi能干什么 sqlmapApi 服务安装相关 kali-sqlmap存放位置 正常启动sqlmap-api server SqlMapApi-Server 解决外网不能访问情况 说在前面 什么是sqlmap 这个在前面已经说过了&#xff0c;如果这个不知道&#xff0c;就可以…