函数介绍
1.张量操作
创建张量:
import torch
# 创建一个全零张量
zeros = torch.zeros(3, 3)
# 创建一个全一张量
ones = torch.ones(3, 3)
# 创建一个随机张量
random_tensor = torch.rand(3, 3)
# 从数据创建张量
data_tensor = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32, requires_grad=True, device='cuda:0')
张量属性:
shape = data_tensor.shape
size = data_tensor.size()
dtype = data_tensor.dtype
device = data_tensor.device
索引和切片:
# 获取特定元素
element = data_tensor[0, 1] # 访问第0行第1列的元素
# 切片
slice_tensor = data_tensor[:, 1] # 访问所有行的第1列
数学运算:
# 基本运算
sum_tensor = data_tensor + data_tensor
product_tensor = data_tensor * data_tensor
# 矩阵乘法
matmul_tensor = torch.matmul(data_tensor, data_tensor)
# 求和
sum_all = data_tensor.sum()
转置和形状变换:
transposed_tensor = data_tensor.T
reshaped_tensor = data_tensor.view(4, 1)
2.自动求导
-
创建计算图:
x = torch.tensor([2.0], requires_grad=True) y = x ** 2
-
反向传播:
-
y.backward() print(x.grad) # 输出 x 的梯度
-
梯度操作:
# 清除梯度 x.grad.data.zero_()
3. 优化器
-
创建优化器:
import torch.optim as optim
model = torch.nn.Linear(10, 2)
optimizer = optim.SGD(model.parameters(), # 创建一个SGD(随机梯度下降)优化器,传递模型的参数
lr=0.01, # 设置学习率(learning rate)为0.01,用于控制每次参数更新的步长
momentum=0.5) # 设置动量(momentum)为0.5,用于加速收敛和减少震荡
-
更新模型参数:
optimizer.zero_grad() #清空之前的梯度,以避免累积。 loss = model(x).mean() # 假设有损失函数 optimizer.step() #更新参数
4. 数据加载和预处理
- 使用
DataLoader
和Dataset
:from torch.utils.data import Dataset, DataLoader class CustomDataset(Dataset): def __init__(self, data): self.data = data def __len__(self): return len(self.data) def __getitem__(self, idx): return self.data[idx] dataset = CustomDataset([1, 2, 3, 4]) dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
5. 模型构建
-
定义模型:
import torch.nn as nn class SimpleModel(nn.Module): def __init__(self): super(SimpleModel, self).__init__() self.fc = nn.Linear(10, 2) def forward(self, x): return self.fc(x) model = SimpleModel()
-
损失函数:
criterion = nn.MSELoss()
6. 设备操作
- 使用 GPU:
if torch.cuda.is_available(): device = torch.device('cuda') tensor = tensor.to(device)
7. 保存和加载模型
-
保存模型:
torch.save(model.state_dict(), 'model.pth')
8.构建卷积层,卷积核
Conv2d()参数详解:
torch.nn.Conv2d(
in_channels, # 输入图像的通道数
out_channels, # 卷积操作的输出通道数
kernel_size, # 卷积核的大小,可以是单个整数或 (height, width)
stride=1, # 卷积核在每个维度上移动的步长,默认值为1
padding=0, # 输入的每一边的填充像素数,默认值为0
dilation=1, # 卷积核的扩张系数,默认值为1
groups=1, # 控制输入和输出的连接模式,默认值为1
bias=True # 是否在卷积层中添加偏置,默认值为True
)
9.张量的拼接
import torch
# 定义两个形状为 (2, 3) 的张量
tensor1 = torch.tensor([[1, 2, 3], [4, 5, 6]])
tensor2 = torch.tensor([[7, 8, 9], [10, 11, 12]])
# 沿着第0维(行方向)拼接
concat_dim0 = torch.cat((tensor1, tensor2), dim=0)
print("Concatenation along dimension 0:")
print(concat_dim0)
# 输出:
# tensor([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 11, 12]])
# 沿着第1维(列方向)拼接
concat_dim1 = torch.cat((tensor1, tensor2), dim=1)
print("Concatenation along dimension 1:")
print(concat_dim1)
# 输出:
# tensor([[ 1, 2, 3, 7, 8, 9],
# [ 4, 5, 6, 10, 11, 12]])
实际操作
1.定义模型&&进行正向传播
import torch
import torch.nn as nn
# 定义模型
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 5) # 线性层:输入 10 个特征,输出 5 个特征
self.relu = nn.ReLU() # ReLU 激活函数
self.fc2 = nn.Linear(5, 2) # 线性层:输入 5 个特征,输出 2 个特征
def forward(self, x):
x = self.fc1(x) # 通过第一层线性层
x = self.relu(x) # 应用 ReLU 激活函数
x = self.fc2(x) # 通过第二层线性层
return x
# 创建模型实例
model = SimpleModel()
# 创建一个样本输入张量,形状为 [batch_size, 10]
input_tensor = torch.randn(4, 10) # 4 个样本,每个样本 10 个特征
# 通过模型进行前向传播
output_tensor = model(input_tensor)
# 打印输出张量的形状
print(output_tensor.shape) # 输出形状为 [4, 2]
2.损失函数的计算
import torch
import torch.nn as nn
# 创建一个均方误差损失函数实例
criterion = nn.MSELoss(reduction='sum') # 对所有样本的损失进行总和
# 示例数据
output = torch.tensor([0.5, 0.7], requires_grad=True)
target = torch.tensor([1.0, 1.0])
# 计算损失
loss = criterion(output, target)
print(loss) # 输出总损失
reduction
参数(新版本对size_average的替代品):
reduction
参数控制输出的损失形式。可以取以下值:'mean'
(默认值):计算平均损失。'sum'
:计算总损失。'none'
:返回每个元素的损失,不做汇总。
3.使用优化器优化训练参数w
import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的神经网络模型
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 5)
self.fc2 = nn.Linear(5, 2)
def forward(self, x):
x = self.fc1(x)
x = torch.relu(x)
x = self.fc2(x)
return x
# 创建模型实例
model = SimpleModel()
# 定义均方误差损失函数
criterion = nn.MSELoss()
# 定义优化器
optimizer = optim.SGD(model.parameters(), lr=0.01) #这里使用了SGD方法来优化参数
# 示例数据
inputs = torch.randn(4, 10) # 4 个样本,每个样本 10 个特征
targets = torch.randn(4, 2) # 4 个样本,每个样本 2 个目标值
# 训练步骤
optimizer.zero_grad() # 清空之前的梯度
outputs = model(inputs) # 进行前向传播
loss = criterion(outputs, targets) # 计算损失
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新参数
4.使用logistics回归训练
import torch
# 定义数据
# x_data 是输入数据,要求计算梯度,放置在 CUDA 设备上
x_data = torch.tensor([[1.0], [2.0], [3.0]], requires_grad=True, device='cuda:0')
# y_data 是目标数据,确保数据类型为 float,并放置在 CUDA 设备上
y_data = torch.tensor([[0.0], [0.0], [1.0]], device='cuda:0') # 数据类型已更改为 float
# 定义模型
class MyModel(torch.nn.Module):
def __init__(self):
super(MyModel, self).__init__()
# 定义一个线性层,将输入的特征维度和输出的特征维度都设置为 1
self.fd1 = torch.nn.Linear(1, 1)
def forward(self, x):
# 前向传播:应用线性层,并使用 sigmoid 激活函数
out = torch.sigmoid(self.fd1(x))
return out
# 创建模型实例并移动到 GPU 上
model = MyModel().to(device='cuda:0')
# 定义损失函数和优化器
# 使用 Binary Cross Entropy Loss 作为损失函数
criterion = torch.nn.BCELoss(reduction='mean')
# 使用随机梯度下降(SGD)作为优化器,学习率设置为 0.1
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
# 训练循环
for i in range(2000):
# 清零梯度,以避免累积梯度
optimizer.zero_grad()
# 前向传播,获取模型输出
outputs = model(x_data)
# 计算损失
loss = criterion(outputs, y_data)
# 反向传播,计算梯度
loss.backward()
# 更新模型参数
optimizer.step()
# 每 100 次迭代打印一次当前的损失值,以减少输出的冗余
if i % 100 == 0:
print(i, loss.item())
5.使用激活函数模块进行多次非线性变换
import torch
class Model(torch.nn.Module):
def __init__(self):
super(Model, self).__init__()
# 定义第一个全连接层,将8维输入映射到6维
self.linear1 = torch.nn.Linear(8, 6)
# 定义第二个全连接层,将6维输入映射到4维
self.linear2 = torch.nn.Linear(6, 4)
# 定义第三个全连接层,将4维输入映射到1维
self.linear3 = torch.nn.Linear(4, 1)
# 定义Sigmoid激活函数
self.sigmoid = torch.nn.Sigmoid()
# 定义前向传播函数
def forward(self, x):
# 将输入x通过第一个全连接层和Sigmoid激活函数
x = self.sigmoid(self.linear1(x))
# 将前一步的输出通过第二个全连接层和Sigmoid激活函数
x = self.sigmoid(self.linear2(x))
# 将前一步的输出通过第三个全连接层和Sigmoid激活函数
x = self.sigmoid(self.linear3(x))
return x
model = Model()
其中的 torch.nn.Sigmoid()也是一个类,用它创建一个实例对象
6.加载数据集的训练
import torch # 导入 PyTorch 库
import numpy as np # 导入 NumPy 库
from torch.utils.data import DataLoader, Dataset # 从 PyTorch 导入 DataLoader 和 Dataset
# 自定义数据集类
class MyData(Dataset):
def __init__(self, filepath):
xy = np.loadtxt(filepath, delimiter=",", dtype=np.float32) # 从文件中加载数据
self.len = xy.shape[0] # 记录数据集的样本数量
self.x_data = torch.from_numpy(xy[:, :-1]) # 提取特征数据,并转换为 PyTorch 张量
self.y_data = torch.from_numpy(xy[:, [-1]]) # 提取标签数据,并转换为 PyTorch 张量
def __getitem__(self, index):
return self.x_data[index], self.y_data[index] # 根据索引返回数据和标签
def __len__(self):
return self.len # 返回数据集的样本数量
mydata = MyData("path") # 创建数据集实例
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 设置设备为 GPU(如果可用),否则使用 CPU
# 创建数据加载器
train_loader = DataLoader(dataset=mydata, batch_size=32, shuffle=True, num_workers=2)
# 定义神经网络模型
class MyModel(torch.nn.Module):
def __init__(self):
super(MyModel, self).__init__() # 调用父类的初始化方法
self.fd1 = torch.nn.Linear(8, 6) # 定义第一个全连接层,输入 8 维,输出 6 维
self.fd2 = torch.nn.Linear(6, 4) # 定义第二个全连接层,输入 6 维,输出 4 维
self.fd3 = torch.nn.Linear(4, 1) # 定义第三个全连接层,输入 4 维,输出 1 维
self.sigmoid = torch.nn.Sigmoid() # 定义 Sigmoid 激活函数
def forward(self, x):
out = torch.sigmoid(self.fd1(x)) # 通过第一个全连接层并应用 Sigmoid 激活函数
out = torch.sigmoid(self.fd2(out)) # 通过第二个全连接层并应用 Sigmoid 激活函数
out = self.sigmoid(self.fd3(out)) # 通过第三个全连接层并应用 Sigmoid 激活函数
return out # 返回最终的输出
model = MyModel().to(device) # 创建模型实例,并将其移动到指定设备(GPU 或 CPU)
criterion = torch.nn.BCELoss(reduction='mean') # 定义二元交叉熵损失函数
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 定义随机梯度下降优化器
for epoch in range(2001): # 训练 2001 个 epoch
for i, data in enumerate(train_loader, 0): # 遍历数据加载器中的每个批次
inputs, labels = data # 获取输入数据和标签
inputs, labels = inputs.to(device), labels.to(device) # 将数据和标签移动到指定设备
outputs = model(inputs) # 前向传播计算模型输出
optimizer.zero_grad() # 清除之前的梯度
loss = criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新模型参数
if i % 100 == 0: # 每 100 个批次打印一次损失
print(i, loss.item()) # 输出当前批次的索引和损失值
- 使用NumPy库方便进行数据读取,再引入torch.utils.data模块导入Dataset和DataLoader类,然后将数据转为tensor格式,进行torch库的操作
xy[:, :-1]
使用 NumPy 切片操作选择所有样本的特征数据。:-1
表示选择除了最后一列之外的所有列,即所有特征列。xy[:, [-1]]
使用 NumPy 切片操作选择所有样本的标签数据。[-1]
表示选择最后一列,即标签列。
注:上示代码中数据集路径用"path"代替了
7.多分类
import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim
batch_size = 64 # 批处理大小设置为64
transform = transforms.Compose([ # 定义数据预处理的变换
transforms.ToTensor(), # 将图像转换为Tensor
transforms.Normalize((0.1307, ), (0.3081, )) # 进行标准化处理
])
train_dataset = datasets.MNIST(root='../dataset/mnist/', # 定义训练集数据集
train=True, # 设置为训练集
download=True, # 如果数据集不存在则下载
transform=transform) # 应用之前定义的变换
train_loader = DataLoader(train_dataset, # 创建训练集的数据加载器
shuffle=True, # 打乱数据顺序
batch_size=batch_size) # 使用定义的批处理大小
test_dataset = datasets.MNIST(root='../dataset/mnist/', # 定义测试集数据集
train=False, # 设置为测试集
download=True, # 如果数据集不存在则下载
transform=transform) # 应用之前定义的变换
test_loader = DataLoader(test_dataset, # 创建测试集的数据加载器
shuffle=False, # 不打乱数据顺序
batch_size=batch_size) # 使用定义的批处理大小
首先进行数据集和测试集的导入
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.l1 = torch.nn.Linear(784, 512)
self.l2 = torch.nn.Linear(512, 256)
self.l3 = torch.nn.Linear(256, 128)
self.l4 = torch.nn.Linear(128, 64)
self.l5 = torch.nn.Linear(64, 10)
def forward(self, x):
x = x.view(-1, 784)
x = F.relu(self.l1(x))
x = F.relu(self.l2(x))
x = F.relu(self.l3(x))
x = F.relu(self.l4(x))
return self.l5(x)
model = Net()
criterion = torch.nn.CrossEntropyLoss() # 定义损失函数为交叉熵损失,适用于分类任务
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5) # 定义优化器为随机梯度下降(SGD),使用学习率0.01和动量0.5
构建神经网络
def train(epoch): # 定义训练函数,接收一个参数 epoch 表示当前训练的轮次
running_loss = 0.0 # 初始化累计损失为0
for batch_idx, data in enumerate(train_loader, 0): # 遍历训练数据集,enumerate从0开始计数
inputs, target = data # 从数据中获取输入图像和对应的标签
optimizer.zero_grad() # 将优化器的梯度缓存清零,以免与之前的梯度混淆
# forward + backward + update
outputs = model(inputs) # 通过模型进行前向传播,得到输出结果
loss = criterion(outputs, target) # 计算损失值
loss.backward() # 反向传播计算梯度
optimizer.step() # 使用优化器更新模型参数
running_loss += loss.item() # 累加当前批次的损失
if batch_idx % 300 == 299: # 每训练300个批次输出一次损失
print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300)) # 打印当前轮次和平均损失
running_loss = 0.0 # 重置累计损失为0
进行数据集的训练
def test(): # 定义测试函数
correct = 0 # 初始化正确预测的数量为0
total = 0 # 初始化总样本数量为0
with torch.no_grad(): # 在不计算梯度的上下文中执行,减少内存使用
for data in test_loader: # 遍历测试数据加载器
images, labels = data # 获取测试图像和对应的标签
outputs = model(images) # 通过模型进行前向传播,得到输出结果
_, predicted = torch.max(outputs.data, dim=1) # 取得预测的类别
total += labels.size(0) # 更新总样本数量
correct += (predicted == labels).sum().item() # 更新正确预测的数量
print('Accuracy on test set: %d %%' % (100 * correct / total)) # 打印测试集上的准确率
在测试集中测试效果
对于 _, predicted = torch.max(outputs.data, dim=1) 这一句,解析如下:
对于 correct += (predicted == labels).sum().item() 这一句:
在这个多分类模型中有一个注意点:
- 在模型的输出阶段,
outputs
通常是 logits,未经 softmax。 - 在计算损失时,例如使用
CrossEntropyLoss
,softmax 会被内部应用。
对于logits的解释:
总结:BCELoss适用于二分类任务,CrossEntropyLoss适用于多分类任务,且softmax是在CEL中实现的,具体如下图:
8.卷积神经网络基础
(1)一些基础操作,包括创建卷积层,为卷积层的卷积核手动赋值,得到卷积后的输出
import torch # 导入 PyTorch 库
input = [3, 4, 6, 5, 7, # 定义一个 5x5 的输入数据列表(单通道图像)
2, 4, 6, 8, 2,
1, 6, 7, 8, 4,
9, 7, 4, 6, 2,
3, 7, 5, 4, 1]
input = torch.Tensor(input).view(1, 1, 5, 5) # 将输入数据转换为 PyTorch 张量,并重塑为形状 (1, 1, 5, 5),其中 1 表示批量大小和通道数,5x5 表示图像的高和宽
conv_layer = torch.nn.Conv2d(1, 1, kernel_size=3, padding=1, bias=False) # 创建一个二维卷积层,输入通道数为1,输出通道数为1,卷积核大小为3x3,填充为1,不使用偏置
kernel = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9]).view(1, 1, 3, 3) # 定义一个 3x3 的卷积核,权重为 1 到 9 的数字,重塑为形状 (1, 1, 3, 3),表示单个卷积核的权重
conv_layer.weight.data = kernel.data # 将定义的卷积核权重赋值给卷积层的权重
output = conv_layer(input) # 将输入张量通过卷积层进行卷积操作,计算输出特征图
print(output) # 打印卷积操作的输出结果
(2)初始化一整个卷积神经网络,包括卷积,池化
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module): # 定义一个继承自 nn.Module 的神经网络类
def __init__(self): # 初始化方法
super(Net, self).__init__() # 调用父类 nn.Module 的初始化方法
self.conv1 = nn.Conv2d(1, 10, kernel_size=5) # 定义第一个卷积层:输入通道为1,输出通道为10,卷积核大小为5x5
self.conv2 = nn.Conv2d(10, 20, kernel_size=5) # 定义第二个卷积层:输入通道为10,输出通道为20,卷积核大小为5x5
self.pooling = nn.MaxPool2d(2) # 定义最大池化层,池化窗口大小为2x2
self.fc = nn.Linear(320, 10) # 定义全连接层:输入特征维度为320,输出特征维度为10
def forward(self, x): # 前向传播方法
batch_size = x.size(0) # 获取批量大小
x = F.relu(self.pooling(self.conv1(x))) # 通过第一个卷积层,使用 ReLU 激活函数,经过最大池化层
x = F.relu(self.pooling(self.conv2(x))) # 通过第二个卷积层,使用 ReLU 激活函数,经过最大池化层
x = x.view(batch_size, -1) # 展平数据,将 (n, 20, 4, 4) 转换为 (n, 320)
x = self.fc(x) # 通过全连接层得到最后的输出
return x # 返回模型输出
model = Net() # 实例化模型
PS:为什么在上面这段代码中不需要为每个卷积层的卷积核赋值?
9.卷积神经网络高级
(1)Inception
import torch
import torch.nn as nn
import torch.nn.functional as F
class InceptionModule(nn.Module):
def __init__(self, in_channels):
super(InceptionModule, self).__init__()
# 分支1:1x1卷积
self.branch1x1 = nn.Sequential(
nn.Conv2d(in_channels, 64, kernel_size=1),
nn.ReLU()
)
# 分支2:1x1卷积后接3x3卷积
self.branch3x3 = nn.Sequential(
nn.Conv2d(in_channels, 128, kernel_size=1),
nn.ReLU(),
nn.Conv2d(128, 128, kernel_size=3, padding=1),
nn.ReLU()
)
# 分支3:1x1卷积后接5x5卷积
self.branch5x5 = nn.Sequential(
nn.Conv2d(in_channels, 32, kernel_size=1),
nn.ReLU(),
nn.Conv2d(32, 64, kernel_size=5, padding=2),
nn.ReLU()
)
# 分支4:最大池化后接1x1卷积
self.branch_pool = nn.Sequential(
nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
nn.Conv2d(in_channels, 32, kernel_size=1),
nn.ReLU()
)
def forward(self, x):
# 通过每个分支
branch1x1 = self.branch1x1(x)
branch3x3 = self.branch3x3(x)
branch5x5 = self.branch5x5(x)
branch_pool = self.branch_pool(x)
# 沿着通道维度拼接
outputs = [branch1x1, branch3x3, branch5x5, branch_pool]
return torch.cat(outputs, 1)
# 示例用法
inception_module = InceptionModule(in_channels=256)
input_tensor = torch.randn(1, 256, 64, 64) # 假设输入是一个批量大小为1,256个通道,64x64的特征图
output_tensor = inception_module(input_tensor)
print(output_tensor.shape) # 输出的形状将是 (1, 通道数总和, 64, 64)
优点:
上图即为加入1*1卷积核后的运算减少现象
(2)Residual Network(残差网络)
import torch
import torch.nn as nn
class ResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super(ResidualBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)
# 如果输入和输出的通道数不一致,使用1x1卷积来调整通道数
self.shortcut = nn.Sequential()
if stride != 1 or in_channels != out_channels:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_channels)
)
def forward(self, x):
identity = x # 保存输入,用于跳跃连接
out = self.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(identity) # 加入跳跃连接
out = self.relu(out)
return out
# 示例用法
res_block = ResidualBlock(in_channels=64, out_channels=64)
input_tensor = torch.randn(1, 64, 32, 32) # 批量大小为1,64个通道,32x32特征图
output_tensor = res_block(input_tensor)
print(output_tensor.shape) # 输出的形状将是 (1, 64, 32, 32)
PS:梯度消失是什么?
10.循环神经网络基础
(1)使用单层RNN
import torch # 导入PyTorch库
batch_size = 1 # 批量大小
seq_len = 3 # 序列长度
input_size = 4 # 输入特征的维度
hidden_size = 2 # 隐藏层的维度
cell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size) # 定义一个RNNCell,输入特征维度为input_size,隐藏层维度为hidden_size
dataset = torch.randn(seq_len, batch_size, input_size) # 创建一个形状为(seq_len, batch_size, input_size)的随机数据集
hidden = torch.zeros(batch_size, hidden_size) # 初始化隐藏状态,形状为(batch_size, hidden_size)
for idx, input in enumerate(dataset): # 遍历数据集的每一帧
print('=' * 20, idx, '=' * 20) # 打印分隔线和当前索引
print('Input size: ', input.shape) # 打印当前输入的形状
hidden = cell(input, hidden) # 使用RNNCell处理输入数据,更新隐藏状态
print('outputs size: ', hidden.shape) # 打印输出的形状
print(hidden) # 打印当前隐藏状态
其中torch.nn.RNN()的参数:
import torch
# 创建一个 RNNCell
rnn_cell = torch.nn.RNNCell(
input_size=10, # 输入特征的维度
hidden_size=20, # 隐藏层的维度
bias=True # 使用偏置项
)
(2)使用多层RNN
import torch # 导入PyTorch库
batch_size = 1 # 批量大小
seq_len = 3 # 序列长度
input_size = 4 # 输入特征的维度
hidden_size = 2 # 隐藏层的维度
num_layers = 1 # RNN的层数
# 定义一个RNN,输入特征维度为input_size,隐藏层维度为hidden_size,层数为num_layers
cell = torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)
inputs = torch.randn(seq_len, batch_size, input_size) # 创建一个形状为(seq_len, batch_size, input_size)的随机输入数据集
hidden = torch.zeros(num_layers, batch_size, hidden_size) # 初始化隐藏状态,形状为(num_layers, batch_size, hidden_size)
out, hidden = cell(inputs, hidden) # 通过RNN处理输入数据,得到输出和新的隐藏状态
print('Output size:', out.shape) # 打印输出的形状
print('Output:', out) # 打印输出数据
print('Hidden size: ', hidden.shape) # 打印隐藏状态的形状
print('Hidden: ', hidden) # 打印隐藏状态
其中torch.nn.RNN()的参数:
import torch
rnn = torch.nn.RNN(
input_size=10, # 输入特征的维度
hidden_size=20, # 隐藏层的维度
num_layers=2, # RNN的层数
nonlinearity='relu', # 非线性激活函数类型
batch_first=True, # 输入和输出张量的形状为 (batch_size, seq_len, input_size)
dropout=0.5, # dropout 概率
bidirectional=True # 使用双向RNN
)
11.循环神经网络高级
嵌入层
下面代码是一个对于嵌入层的简单应用:
# TensorFlow/Keras中的嵌入层
from tensorflow.keras.layers import Embedding
# 假设词汇表大小为 10000,嵌入维度为 300
embedding_layer = Embedding(input_dim=10000, output_dim=300)
# 输入词索引(假设是批量输入,大小为 32)
import numpy as np
input_data = np.random.randint(10000, size=(32, 10))
# 输出的嵌入向量
embedded_output = embedding_layer(input_data)
嵌入层作用图示:
一些函数,数学方法的附录
SGD:
Softmax:
Sigmoid:
BCELoss:
p就是y_predict
CrossEntrofyLoss:
独热向量
一些符号的附录
1.