Create pytorch_module_class_method.py
This commit is contained in:
parent
f28a409307
commit
a9254b09eb
@ -0,0 +1,144 @@
|
||||
"""
|
||||
This code is supported by the website: https://www.guanjihuan.com
|
||||
The newest version of this code is on the web page: https://www.guanjihuan.com/archives/37753
|
||||
"""
|
||||
|
||||
import torch
|
||||
|
||||
# 第一部分:torch.nn.Linear,线性变换层。公式为:y = x A^T + b
|
||||
|
||||
linear_layer = torch.nn.Linear(20, 3) # (in_size, out_size),其中权重(weight)和偏置(bias)默认是从均匀分布(uniform distribution)中进行初始化的。
|
||||
input = torch.randn(128, 20) # 128个样本
|
||||
output = linear_layer(input) # 获取线性层的输出数据
|
||||
print(input.size())
|
||||
print(output.size())
|
||||
print()
|
||||
|
||||
|
||||
|
||||
# 第二部分:torch.nn.ReLU,修正线性单元(Rectified Linear Unit,ReLU)激活函数 。公式为:y = max(0,x)
|
||||
|
||||
relu_layer = torch.nn.ReLU()
|
||||
x = torch.tensor([-1.0, 2.0, -3.0])
|
||||
y = relu_layer(x)
|
||||
print(y)
|
||||
print()
|
||||
|
||||
|
||||
|
||||
# 第三部分:torch.nn.MSELoss,均方误差损失(Mean Squared Error Loss),也被称为 L2 损失。公式为:MSE Loss = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
|
||||
|
||||
target = torch.tensor([3.0, 4.0, 5.0], requires_grad=True) # 目标值。requires_grad 被设置为True,PyTorch会自动追踪对该张量的操作,并构建一个计算图,以便在反向传播过程中计算梯度。
|
||||
predictions = torch.tensor([2.9, 4.1, 5.3], requires_grad=True) # 预测值
|
||||
criterion = torch.nn.MSELoss() # 创建 MSELoss 对象
|
||||
loss = criterion(predictions, target) # 计算均方误差
|
||||
print('MSE Loss:', loss.item()) # 打印损失值
|
||||
loss.backward() # 反向传播。loss.backward() 仅仅负责计算梯度,不负责模型参数的更新。
|
||||
# 补充说明:反向传播通过求导的链式法则进行计算。如果没有链式法则,计算梯度需要重新进行每个参数的正向传播,这就意味着每个参数的梯度计算都要单独进行一次前向传播,计算量会特别大。
|
||||
print('Gradients w.r.t. target:', target.grad) # 查看目标值的梯度
|
||||
print('Gradients w.r.t. predictions:', predictions.grad) # 查看预测值的梯度
|
||||
print()
|
||||
|
||||
|
||||
|
||||
|
||||
# 第四部分:以下为一个神经网络的例子。其中,torch.optim.SGD为优化器,用于实现随机梯度下降(Stochastic Gradient Descent,SGD)
|
||||
|
||||
import torch
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
class LinearRegressionModel(torch.nn.Module): # 定义模型,继承torch.nn.Module类
|
||||
def __init__(self, input_size, hidden_size, output_size):
|
||||
super().__init__() # 调用父类的的初始化内容
|
||||
self.hidden_layer = torch.nn.Linear(input_size, hidden_size) # 定义一个隐藏层
|
||||
self.output_layer = torch.nn.Linear(hidden_size, output_size) # 定义一个输出层
|
||||
self.relu_layer = torch.nn.ReLU()
|
||||
|
||||
def forward(self, x):
|
||||
hidden_output = self.relu_layer(self.hidden_layer(x)) # 第一个隐藏层的输出,并使用ReLU激活函数
|
||||
# hidden_output = torch.nn.functional.relu(self.hidden_layer(x)) # 激活函数也可以用torch.nn.functional.relu()
|
||||
output = self.output_layer(hidden_output) # 输出层的输出
|
||||
return output
|
||||
|
||||
# 训练的数据
|
||||
import numpy as np
|
||||
x_data = np.linspace(-1, 1, 300, dtype=np.float32)[:, np.newaxis] # 产生数据,作为神经网络的输入数据。注:[:, np.newaxis]是用来增加一个轴,变成一个矩阵。
|
||||
noise = np.random.normal(0, 0.05, x_data.shape).astype(np.float32) # 产生噪声
|
||||
y_data = np.square(x_data) - 0.5 + noise # x_data加上噪声,作为神经网络的输出数据。
|
||||
print(x_data.shape)
|
||||
print(noise.shape)
|
||||
print(y_data.shape)
|
||||
x_data = torch.from_numpy(x_data) # 转换成tensor
|
||||
y_data = torch.from_numpy(y_data) # 转换成tensor
|
||||
print(x_data.shape)
|
||||
print(x_data.shape)
|
||||
print(x_data.size())
|
||||
print(x_data.size())
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1)
|
||||
ax.scatter(x_data, y_data)
|
||||
plt.ion() # 开启交互模式
|
||||
plt.show() # 显示图像
|
||||
|
||||
# 创建模型,定义损失函数和优化器
|
||||
input_size = 1
|
||||
hidden_size = 50
|
||||
output_size = 1
|
||||
model = LinearRegressionModel(input_size, hidden_size, output_size) # 创建模型
|
||||
criterion = torch.nn.MSELoss() # 定义损失函数
|
||||
learning_rate = 0.01 # 梯度下降的学习速率
|
||||
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) # 定义优化器。其中.parameters()是torch.nn.Module类中的方法
|
||||
|
||||
# 训练模型
|
||||
num_epochs = 3000 # 迭代次数
|
||||
losses = [] # 用于收集损失值
|
||||
for epoch in range(num_epochs): # 开始训练
|
||||
outputs = model.forward(x_data) # 前向传播。由于继承了torch.nn.Module类,默认使用forward方法,因此这里无需显式写出forward方法
|
||||
loss = criterion(outputs, y_data) # 计算损失值
|
||||
optimizer.zero_grad() # 在每次训练的迭代,梯度清零
|
||||
loss.backward() # 反向传播,计算梯度
|
||||
optimizer.step() # 更新参数
|
||||
losses.append(loss.item()) # 记录损失值
|
||||
if (epoch + 1) % 50 == 0: # 迭代一定周期后显示一次
|
||||
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
|
||||
try:
|
||||
ax.lines.remove(lines[0])
|
||||
except Exception:
|
||||
pass
|
||||
with torch.no_grad(): # 在推断或预测时,这个可以防止PyTorch 记录梯度信息,从而减小内存占用。这里不用也可以。
|
||||
predictions = model(x_data) # 当前迭代模型的预测结果
|
||||
lines = ax.plot(x_data.detach().numpy(), predictions.detach().numpy(), 'ro-', lw=3) # 画出预测的值,用线连起来。其中,.detach() 是 PyTorch 中的一个方法,它用于创建一个新的张量,该张量与原始张量共享相同的数据,但不再具有梯度计算的历史。
|
||||
plt.pause(.1) # 暂停0.1秒
|
||||
|
||||
plt.ioff()
|
||||
lines = ax.plot(x_data.detach().numpy(), predictions.detach().numpy(), 'ro-', lw=3)
|
||||
plt.show()
|
||||
|
||||
plt.plot(losses, 'o-', label='Loss') # 绘制训练过程中的损失曲线
|
||||
plt.xlabel('Epoch')
|
||||
plt.ylabel('Loss')
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
torch.save(model.state_dict(), 'model.pth') # 使用 torch.save 函数来保存模型。其中,model.state_dict()返回模型的权重字典
|
||||
torch.save(model, 'full_model.pth') # 保存整个模型,包括模型的结构和权重
|
||||
|
||||
model_2 = LinearRegressionModel(input_size, hidden_size, output_size) # 创建模型
|
||||
model_2.load_state_dict(torch.load('model.pth')) # 加载模型参数
|
||||
with torch.no_grad():
|
||||
predictions_2 = model_2(x_data)
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1)
|
||||
ax.scatter(x_data, y_data)
|
||||
lines = ax.plot(x_data.detach().numpy(), predictions_2.detach().numpy(), 'bo-', lw=3)
|
||||
plt.show()
|
||||
|
||||
model_3 = torch.load('full_model.pth') # 加载完整模型
|
||||
with torch.no_grad():
|
||||
predictions_3 = model_3(x_data)
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(1, 1, 1)
|
||||
ax.scatter(x_data, y_data)
|
||||
lines = ax.plot(x_data.detach().numpy(), predictions_3.detach().numpy(), 'go-', lw=3)
|
||||
plt.show()
|
Loading…
x
Reference in New Issue
Block a user