探究
实验室
计算
公开
3.3 PyTorch基础:
《机器学习辅助材料设计》书籍
《机器学习辅助材料设计》书籍
爱学习的王一博
更新于 2025-02-16
推荐镜像 :Basic Image:bohrium-notebook:2023-04-07
推荐机型 :c2_m4_cpu
赞 1
3.3.3 PyTorch安装与导入
3.3.4 PyTorch基础:Tensor与简单计算
3.3.6 使用PyTorch构建多层感知机
3.3.6.2 多层感知机构建的常规做法
3.3.6.3 使用nn.Sequential快速构建网络
3.3.7 数据集构建与加载
3.3.7.1 使用Dataset类自定义数据集
3.3.7.2 使用DataLoader类进行数据加载
3.3.8 训练网络
3.3.8.1 选择损失函数
3.3.8.2 选择优化器
3.3.8.3 训练网络
3.3.9 使用GPU
[ ]

代码
文本
双击即可修改
代码
文本

3.3.3 PyTorch安装与导入

代码
文本

在玻尔科研空间站,安装过程可以省去,直接使用对应镜像即可

代码
文本
[1]
import torch
import torch.nn as nn
代码
文本

3.3.4 PyTorch基础:Tensor与简单计算

代码
文本
[2]
import torch
import numpy as np

# 从 Python 列表创建 Tensor
tensor_from_list = torch.tensor([1, 2, 3, 4])

# 从 NumPy 数组创建 Tensor
numpy_array = np.array([1, 2, 3, 4])
tensor_from_numpy = torch.tensor(numpy_array)

zero_tensor = torch.zeros(2, 3) # 创建一个 2x3 的全零 Tensor
one_tensor = torch.ones(3, 3) # 创建一个 3x3 的全一 Tensor

random_tensor = torch.randn(2, 3) # 创建一个 2x3 的随机 Tensor(符合正态分布)

代码
文本
[3]
# 创建两个简单的 Tensor
tensor1 = torch.tensor([1, 2, 3, 4])
tensor2 = torch.tensor([5, 6, 7, 8])

# 加法:对应元素相加
result_add = tensor1 + tensor2
print("加法结果:", result_add)

# 乘法:对应元素相乘
result_mul = tensor1 * tensor2
print("乘法结果:", result_mul)

# 访问元素:访问第一个元素
first_element = tensor1[0]
print("tensor1 第一个元素:", first_element)

# 切片操作:访问第二到第四个元素
sub_tensor = tensor1[1:4]
print("tensor1 从第二到第四个元素:", sub_tensor)

# 修改元素:将 tensor1 的第三个元素改为 10
tensor1[2] = 10
print("修改后的 tensor1:", tensor1)

加法结果: tensor([ 6,  8, 10, 12])
乘法结果: tensor([ 5, 12, 21, 32])
tensor1 第一个元素: tensor(1)
tensor1 从第二到第四个元素: tensor([2, 3, 4])
修改后的 tensor1: tensor([ 1,  2, 10,  4])
代码
文本

3.3.6 使用PyTorch构建多层感知机

代码
文本

3.3.6.2 多层感知机构建的常规做法

代码
文本
[4]
import torch
import torch.nn as nn
import torch.nn.functional as F

# 定义一个简单的多层感知机
class SimpleMLP(nn.Module):
# __init__函数对模型进行初始化
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # 第一层
self.fc2 = nn.Linear(hidden_size, output_size) # 输出层
# forward函数定义如何进行前向传播
def forward(self, x):
x = self.fc1(x) # 经过第一个全连接层
x = F.relu(x) # 使用 F.relu 进行激活
x = self.fc2(x) # 经过输出层
return x

代码
文本
[5]
# 设置参数
input_size = 3 # 输入特征数
hidden_size = 4 # 隐藏层神经元数
output_size = 1 # 输出结果

# 创建模型实例
model = SimpleMLP(input_size, hidden_size, output_size)
# 打印模型结构
print(model)

# 前向传播
x = torch.randn(3) # 生成随机输入数据
output = model(x)
print("模型输出:", output)
print(output.shape) # 结果:torch.Size([2])

SimpleMLP(
  (fc1): Linear(in_features=3, out_features=4, bias=True)
  (fc2): Linear(in_features=4, out_features=1, bias=True)
)
模型输出: tensor([0.3716], grad_fn=<AddBackward0>)
torch.Size([1])
代码
文本

3.3.6.3 使用nn.Sequential快速构建网络

代码
文本
[6]
# 使用 nn.Sequential 快速构建多层感知机
model_seq = nn.Sequential(
nn.Linear(3, 4), # 第一层全连接层:输入特征数3,输出隐藏层神经元数4
nn.ReLU(), # ReLU 激活函数
nn.Linear(4, 1) # 第二层全连接层:从隐藏层到输出层,输出神经元数2
)

print("\n使用 nn.Sequential 构建的多层感知机模型:")
print(model_seq)
使用 nn.Sequential 构建的多层感知机模型:
Sequential(
  (0): Linear(in_features=3, out_features=4, bias=True)
  (1): ReLU()
  (2): Linear(in_features=4, out_features=1, bias=True)
)
代码
文本
[7]
# 依然使用之前的数据集

# 生成随机输入数据,维度为input_size
x2 = torch.randn(3)

# 前向传播,最终输出维度为output_size
output2 = model_seq(x2)
print("模型输出:", output2)
print(output2.shape) # 结果:torch.Size([2])
模型输出: tensor([-0.0187], grad_fn=<AddBackward0>)
torch.Size([1])
代码
文本

3.3.7 数据集构建与加载

代码
文本

3.3.7.1 使用Dataset类自定义数据集

代码
文本
[8]
import torch
from torch.utils.data import Dataset
import numpy as np

# 定义一个自定义数据集类,继承自 torch.utils.data.Dataset
class MyDataset(Dataset):
def __init__(self, data, labels): # 初始化数据集
self.data = data
self.labels = labels
def __len__(self): # 返回数据集样本总数
return len(self.data)

def __getitem__(self, idx): # 根据索引返回对应数据和标签
sample = self.data[idx]
label = self.labels[idx]
return sample, label
代码
文本
[9]
# 构造100个样本,每个样本3个特征
data = np.random.randn(100, 3).astype(np.float32)
# 构造对应的结果,假设结果就是简单求和
labels = data.sum(axis = -1) + 2

# 将 NumPy 数组转换为 PyTorch 的 Tensor
data_tensor = torch.tensor(data)
labels_tensor = torch.tensor(labels)

# 创建数据集实例
dataset = MyDataset(data_tensor, labels_tensor)
print("数据集样本数:", len(dataset))

# 查看某具体样本
tmpData, tmpLabel = dataset[0]
print("第一个样本的数据是:" + str(tmpData))
print("第一个样本的标签是:" + str(tmpLabel))
数据集样本数: 100
第一个样本的数据是:tensor([-1.1504, -1.6199, -0.2337])
第一个样本的标签是:tensor(-1.0040)
代码
文本

3.3.7.2 使用DataLoader类进行数据加载

代码
文本
[10]
from torch.utils.data import DataLoader

# 创建 DataLoader 对象,设置每个批次加载32个样本,并在每个 epoch 时打乱数据
dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=0)

# 遍历 DataLoader,获取每个批次的数据和标签
for batch_idx, (batch_data, batch_labels) in enumerate(dataloader):
print(f"批次 {batch_idx}:")
print("数据尺寸:", batch_data.size())
print("标签尺寸:", batch_labels.size())
# 在这里可以进一步处理 batch_data 和 batch_labels,如送入模型训练

批次 0:
数据尺寸: torch.Size([32, 3])
标签尺寸: torch.Size([32])
批次 1:
数据尺寸: torch.Size([32, 3])
标签尺寸: torch.Size([32])
批次 2:
数据尺寸: torch.Size([32, 3])
标签尺寸: torch.Size([32])
批次 3:
数据尺寸: torch.Size([4, 3])
标签尺寸: torch.Size([4])
代码
文本

3.3.8 训练网络

代码
文本

3.3.8.1 选择损失函数

代码
文本
[11]
criterion = nn.MSELoss()
代码
文本

3.3.8.2 选择优化器

代码
文本
[12]
import torch.optim as optim

# 选择 SGD 优化器,模型参数由 model.parameters() 返回
optimizer = optim.SGD(model.parameters(), lr=0.01)
代码
文本

3.3.8.3 训练网络

代码
文本
[13]
num_epochs = 100 # 训练的总 epoch 数
loss_list = []

for epoch in range(num_epochs):
running_loss = 0.0 # 用于累计本 epoch 的总损失
# 遍历每个批次
for batch_idx, (inputs, labels) in enumerate(dataloader):
# 前向传播:计算预测输出
outputs = model(inputs).squeeze(-1) # 保证输出和标签形状一致
# 计算当前批次的损失
loss = criterion(outputs, labels)
# 在反向传播前清零梯度,防止梯度累加
optimizer.zero_grad()
# 反向传播:自动计算梯度
loss.backward()
# 更新参数:依据梯度信息调整模型参数
optimizer.step()
# 累计当前批次损失
running_loss += loss.item()
# 计算本 epoch 的平均损失
avg_loss = running_loss / len(dataloader)
loss_list.append(avg_loss)
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {avg_loss:.4f}")

Epoch [1/100], Loss: 5.7042
Epoch [2/100], Loss: 4.5726
Epoch [3/100], Loss: 4.1831
Epoch [4/100], Loss: 5.9128
Epoch [5/100], Loss: 3.3498
Epoch [6/100], Loss: 3.8564
Epoch [7/100], Loss: 2.7457
Epoch [8/100], Loss: 1.8149
Epoch [9/100], Loss: 2.0803
Epoch [10/100], Loss: 1.4319
Epoch [11/100], Loss: 1.4462
Epoch [12/100], Loss: 1.0616
Epoch [13/100], Loss: 0.8244
Epoch [14/100], Loss: 1.0793
Epoch [15/100], Loss: 0.8297
Epoch [16/100], Loss: 0.5428
Epoch [17/100], Loss: 0.5329
Epoch [18/100], Loss: 0.4181
Epoch [19/100], Loss: 0.4500
Epoch [20/100], Loss: 0.3665
Epoch [21/100], Loss: 0.2837
Epoch [22/100], Loss: 0.5459
Epoch [23/100], Loss: 0.2329
Epoch [24/100], Loss: 0.2378
Epoch [25/100], Loss: 0.3651
Epoch [26/100], Loss: 0.2033
Epoch [27/100], Loss: 0.1914
Epoch [28/100], Loss: 0.1758
Epoch [29/100], Loss: 0.3979
Epoch [30/100], Loss: 0.1552
Epoch [31/100], Loss: 0.1546
Epoch [32/100], Loss: 0.1760
Epoch [33/100], Loss: 0.1655
Epoch [34/100], Loss: 0.3349
Epoch [35/100], Loss: 0.2340
Epoch [36/100], Loss: 0.3066
Epoch [37/100], Loss: 0.1282
Epoch [38/100], Loss: 0.1079
Epoch [39/100], Loss: 0.1200
Epoch [40/100], Loss: 0.1229
Epoch [41/100], Loss: 0.1081
Epoch [42/100], Loss: 0.1056
Epoch [43/100], Loss: 0.1132
Epoch [44/100], Loss: 0.2413
Epoch [45/100], Loss: 0.1003
Epoch [46/100], Loss: 0.1002
Epoch [47/100], Loss: 0.0973
Epoch [48/100], Loss: 0.1034
Epoch [49/100], Loss: 0.0914
Epoch [50/100], Loss: 0.0936
Epoch [51/100], Loss: 0.0830
Epoch [52/100], Loss: 0.0826
Epoch [53/100], Loss: 0.0840
Epoch [54/100], Loss: 0.1883
Epoch [55/100], Loss: 0.0731
Epoch [56/100], Loss: 0.0716
Epoch [57/100], Loss: 0.0685
Epoch [58/100], Loss: 0.0736
Epoch [59/100], Loss: 0.0728
Epoch [60/100], Loss: 0.0690
Epoch [61/100], Loss: 0.1696
Epoch [62/100], Loss: 0.0679
Epoch [63/100], Loss: 0.0745
Epoch [64/100], Loss: 0.0724
Epoch [65/100], Loss: 0.0613
Epoch [66/100], Loss: 0.1108
Epoch [67/100], Loss: 0.0577
Epoch [68/100], Loss: 0.0571
Epoch [69/100], Loss: 0.0603
Epoch [70/100], Loss: 0.0584
Epoch [71/100], Loss: 0.0582
Epoch [72/100], Loss: 0.0568
Epoch [73/100], Loss: 0.0643
Epoch [74/100], Loss: 0.1383
Epoch [75/100], Loss: 0.0612
Epoch [76/100], Loss: 0.0554
Epoch [77/100], Loss: 0.0517
Epoch [78/100], Loss: 0.0604
Epoch [79/100], Loss: 0.0519
Epoch [80/100], Loss: 0.0514
Epoch [81/100], Loss: 0.0554
Epoch [82/100], Loss: 0.0494
Epoch [83/100], Loss: 0.0523
Epoch [84/100], Loss: 0.0578
Epoch [85/100], Loss: 0.0775
Epoch [86/100], Loss: 0.0521
Epoch [87/100], Loss: 0.0483
Epoch [88/100], Loss: 0.0800
Epoch [89/100], Loss: 0.0460
Epoch [90/100], Loss: 0.1395
Epoch [91/100], Loss: 0.0470
Epoch [92/100], Loss: 0.0625
Epoch [93/100], Loss: 0.0492
Epoch [94/100], Loss: 0.0525
Epoch [95/100], Loss: 0.0433
Epoch [96/100], Loss: 0.0655
Epoch [97/100], Loss: 0.0677
Epoch [98/100], Loss: 0.0416
Epoch [99/100], Loss: 0.0688
Epoch [100/100], Loss: 0.0591
代码
文本
[21]
import matplotlib.pyplot as plt

plt.figure(figsize=(8, 6))
plt.plot(loss_list, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss Curve During Training')
plt.legend()
plt.grid('True')
plt.show()

代码
文本

3.3.9 使用GPU

代码
文本
[15]

# 检查是否有可用的 GPU
if torch.cuda.is_available():
device = torch.device("cuda")
print("GPU 可用,使用 GPU 进行训练。")
else:
device = torch.device("cpu")
print("GPU 不可用,使用 CPU 进行训练。")

GPU 不可用,使用 CPU 进行训练。
代码
文本
[16]
# 将模型移动到指定设备上(通常是 GPU)
model = model.to(device)
代码
文本
[17]
num_epochs = 20 # 训练的总 epoch 数

for epoch in range(num_epochs):
running_loss = 0.0 # 用于累计本 epoch 的总损失
# 遍历每个批次
for batch_idx, (inputs, labels) in enumerate(dataloader):
# 将数据移动到GPU
inputs = inputs.to(device)
labels = labels.to(device)
# 前向传播:计算预测输出
outputs = model(inputs).squeeze(-1) # 保证输出和标签形状一致
# 计算当前批次的损失
loss = criterion(outputs, labels)
# 在反向传播前清零梯度,防止梯度累加
optimizer.zero_grad()
# 反向传播:自动计算梯度
loss.backward()
# 更新参数:依据梯度信息调整模型参数
optimizer.step()
# 累计当前批次损失
running_loss += loss.item()
# 计算本 epoch 的平均损失
avg_loss = running_loss / len(dataloader)
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {avg_loss:.4f}")

Epoch [1/20], Loss: 0.0437
Epoch [2/20], Loss: 0.0416
Epoch [3/20], Loss: 0.0463
Epoch [4/20], Loss: 0.0407
Epoch [5/20], Loss: 0.0385
Epoch [6/20], Loss: 0.0390
Epoch [7/20], Loss: 0.0387
Epoch [8/20], Loss: 0.0392
Epoch [9/20], Loss: 0.0385
Epoch [10/20], Loss: 0.0551
Epoch [11/20], Loss: 0.0407
Epoch [12/20], Loss: 0.0406
Epoch [13/20], Loss: 0.0406
Epoch [14/20], Loss: 0.0357
Epoch [15/20], Loss: 0.0494
Epoch [16/20], Loss: 0.0391
Epoch [17/20], Loss: 0.0405
Epoch [18/20], Loss: 0.0355
Epoch [19/20], Loss: 0.0367
Epoch [20/20], Loss: 0.0365
代码
文本
《机器学习辅助材料设计》书籍
《机器学习辅助材料设计》书籍
已赞1
本文被以下合集收录
机器学习辅助材料设计教材
爱学习的王一博
更新于 2025-02-16
1 篇0 人关注