X
是 100 个随机样本,每个样本一个特征,目标值 y
基于线性关系并添加了噪声。numpy
数转换为Paddlepaddle张量,方便后续在模型中使用。nn.Sequential
组网代码解释
① 数据生成与转换:
X
和目标值向量 y
,并添加高斯噪声模拟真实数据。paddle.to_tensor
将 numpy
数组转换为 PaddlePaddle 张量。② 模型组网:
nn.Sequential
快速构建线性回归模型,只包含一个 nn.Linear
层。③ 损失函数和优化器:
nn.MSELoss
和随机梯度下降优化器 paddle.optimizer.SGD
。④ 模型训练:
⑤ 损失曲线绘制:
matplotlib
绘制训练损失随轮次的变化曲线,直观展示模型的训练过程。⑥ 模型评估:
⑦ 输出模型参数:
import paddle
import paddle.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
# 自定义数据集
# 生成 100 个样本,每个样本有 1 个特征
X = np.random.rand(100, 1).astype(np.float32)
# 根据特征生成目标值,添加一些噪声
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)
# 将 numpy 数组转换为 PaddlePaddle 张量
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 使用 nn.Sequential 组网
model = nn.Sequential(
nn.Linear(1, 1)
)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
# 训练模型
num_epochs = 1000
losses = []
for epoch in range(num_epochs):
# 前向传播
outputs = model(X)
loss = criterion(outputs, y)
losses.append(loss.numpy()[0])
# 反向传播和优化
optimizer.clear_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy()[0]:.4f}')
# 绘制训练损失曲线
plt.plot(range(num_epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()
# 模型评估
with paddle.no_grad():
y_pred = model(X).numpy()
mse = mean_squared_error(y.numpy(), y_pred)
r2 = r2_score(y.numpy(), y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")
# 输出模型的系数和截距
weights = model[0].weight.numpy()[0][0]
bias = model[0].bias.numpy()[0]
print(f"模型系数: {weights}")
print(f"模型截距: {bias}")
class nn.Layer
组网代码解释
此方案与方案 1 的主要区别在于模型的组网方式,具体如下:
模型组网:
① 定义一个继承自 nn.Layer
的自定义模型类 LinearRegression
。
② 在 __init__
方法中初始化 nn.Linear
层。
③ 在 forward
方法中定义前向传播逻辑。
后续步骤:
损失函数、优化器的选择,模型训练、评估以及参数输出等步骤与方案 1 基本相同。
import paddle
import paddle.nn as nn
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
# 自定义数据集
# 生成 100 个样本,每个样本有 1 个特征
X = np.random.rand(100, 1).astype(np.float32)
# 根据特征生成目标值,添加一些噪声
y = 2 * X + 1 + 0.3 * np.random.randn(100, 1).astype(np.float32)
# 将 numpy 数组转换为 PaddlePaddle 张量
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 自定义模型类,继承自 nn.Layer
class LinearRegression(nn.Layer):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1)
def forward(self, x):
return self.linear(x)
# 创建模型实例
model = LinearRegression()
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters())
# 训练模型
num_epochs = 1000
losses = []
for epoch in range(num_epochs):
# 前向传播
outputs = model(X)
loss = criterion(outputs, y)
losses.append(loss.numpy()[0])
# 反向传播和优化
optimizer.clear_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy()[0]:.4f}')
# 绘制训练损失曲线
plt.plot(range(num_epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()
# 模型评估
with paddle.no_grad():
y_pred = model(X).numpy()
mse = mean_squared_error(y.numpy(), y_pred)
r2 = r2_score(y.numpy(), y_pred)
print(f"均方误差 (MSE): {mse}")
print(f"决定系数 (R²): {r2}")
# 输出模型的系数和截距
weights = model.linear.weight.numpy()[0][0]
bias = model.linear.bias.numpy()[0]
print(f"模型系数: {weights}")
print(f"模型截距: {bias}")
train_losses
列表记录每一轮训练的损失值,方便后续绘制训练损失曲线,直观观察模型的训练过程。scikit-learn
中的 mean_squared_error
和 r2_score
计算测试集的均方误差和决定系数。以下将分别详细介绍使用 PaddlePaddle 框架通过基础 API、fit
方法以及 paddle.Model
类这三种方式来保存模型,同时会给出完整的代码示例和相应的解释。
基础 API 保存主要是保存模型的参数(state_dict
),也可以保存检查点信息。下面是一个逻辑回归模型的完整示例:
import paddle
import paddle.nn as nn
import numpy as np
# 自定义数据集
X = np.random.randn(1000, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
outputs = model(X)
loss = criterion(outputs, y)
optimizer.clear_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy()[0]:.4f}')
# 保存模型的参数
paddle.save(model.state_dict(), './基础API/model.pdparams')
# 保存检查点信息
final_checkpoint = {
'epoch': num_epochs,
'model_state_dict': model.state_dict(),
'optimizer_state_dict': optimizer.state_dict(),
'loss': loss.numpy()[0]
}
paddle.save(final_checkpoint, "./基础API/final_checkpoint.pkl")
paddle.save(model.state_dict(), './基础API/model.pdparams')
保存模型的参数,这些参数可以在后续加载到相同结构的模型中。final_checkpoint
,使用 paddle.save
将其保存为 final_checkpoint.pkl
文件,方便后续恢复训练。fit
进行保存fit
方法是 PaddlePaddle 提供的一种方便的训练接口,在训练过程中可以设置保存模型的参数。
import paddle
import paddle.nn as nn
import numpy as np
from paddle.io import TensorDataset, DataLoader
# 自定义数据集
X = np.random.randn(1000, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 创建数据集和数据加载器
dataset = TensorDataset([X, y])
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
# 使用 fit 方法进行训练并保存模型
paddle.Model(model).fit(
dataloader,
epochs=100,
optimizer=optimizer,
loss=criterion,
save_dir='./fit保存模型',
save_freq=10
)
TensorDataset
,并使用 DataLoader
进行批量加载。fit
方法训练并保存:使用 paddle.Model(model).fit
方法进行训练,save_dir
参数指定保存模型的目录,save_freq
参数指定每多少个轮次保存一次模型。paddle.Model
类进行保存paddle.Model
类提供了更高级的封装,方便进行模型的训练、评估和保存。
import paddle
import paddle.nn as nn
import numpy as np
from paddle.io import TensorDataset, DataLoader
# 自定义数据集
X = np.random.randn(1000, 2).astype(np.float32)
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 创建数据集和数据加载器
dataset = TensorDataset([X, y])
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 定义损失函数和优化器
criterion = nn.BCELoss()
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
# 创建 paddle.Model 实例
paddle_model = paddle.Model(model)
paddle_model.prepare(optimizer, criterion)
# 训练模型
paddle_model.fit(dataloader, epochs=100)
# 保存模型
paddle_model.save('./paddle_Model保存模型/final_model')
TensorDataset
并使用 DataLoader
加载。paddle.Model
实例:使用 paddle.Model(model)
创建实例,并使用 prepare
方法配置优化器和损失函数。fit
方法进行训练,训练完成后使用 paddle_model.save
保存模型。通过以上三种方式,可以根据实际的需求选择合适的方法来保存 PaddlePaddle 模型。
以下为PaddlePaddle 中使用基础 API 和高级 API 加载模型的具体方法,将结合前面保存模型的示例,给出完整的代码实现和解释。
当使用基础 API 保存模型参数和检查点信息后,可按如下步骤加载:
import paddle
import paddle.nn as nn
import numpy as np
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 定义优化器
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
# 加载模型参数
model_state_dict = paddle.load('./基础API/model.pdparams')
# 加载优化器状态(如果之前保存了)
# 这里假设之前保存了优化器状态到 optimizer.pdopt 文件
optimizer_state_dict = paddle.load('./基础API/optimizer.pdopt')
# 加载检查点信息
final_checkpoint_state_dict = paddle.load('./基础API/final_checkpoint.pkl')
print(final_checkpoint_state_dict)
# 将模型和参数联系起来
model.set_state_dict(model_state_dict)
# 恢复优化器状态(如果需要)
optimizer.set_state_dict(optimizer_state_dict)
# 生成新数据进行预测
new_X = np.random.randn(100, 2).astype(np.float32)
new_X = paddle.to_tensor(new_X)
# 使用加载的模型进行预测
model.eval()
with paddle.no_grad():
predictions = model(new_X)
predicted_labels = (predictions >= 0.5).astype(paddle.float32).numpy()
print("预测标签:", predicted_labels)
paddle.load('./基础API/model.pdparams')
:加载模型的参数。paddle.load('./基础API/optimizer.pdopt')
:加载优化器的状态(如果之前保存了)。paddle.load('./基础API/final_checkpoint.pkl')
:加载检查点信息。model.set_state_dict(model_state_dict)
:将加载的模型参数应用到模型上。optimizer.set_state_dict(optimizer_state_dict)
:恢复优化器的状态(如果需要继续训练)。使用 paddle.Model
封装模型并保存后,可按如下步骤加载:
import paddle
import paddle.nn as nn
import numpy as np
from paddle.io import TensorDataset, DataLoader
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 使用 paddle.Model 进行封装
paddle_model = paddle.Model(model)
# 准备模型
paddle_model.prepare(optimizer=paddle.optimizer.SGD(learning_rate=0.01, parameters=model.parameters()),
loss=nn.BCELoss(),
metrics=paddle.metric.Accuracy())
# 高级 API 模型的加载
paddle_model.load("./高层API1/final")
# 生成新数据进行预测
new_X = np.random.randn(100, 2).astype(np.float32)
new_y = (2 * new_X[:, 0] + 3 * new_X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
new_X = paddle.to_tensor(new_X)
new_y = paddle.to_tensor(new_y)
# 创建数据集和数据加载器
new_dataset = TensorDataset([new_X, new_y])
new_dataloader = DataLoader(new_dataset, batch_size=32, shuffle=False)
# 评估模型
result = paddle_model.evaluate(new_dataloader, verbose=1)
print("评估结果:", result)
paddle.Model(model)
进行封装。prepare
方法配置优化器、损失函数和评估指标。paddle_model.load("./高层API1/final")
加载之前保存的模型。TensorDataset
并使用 DataLoader
加载。paddle_model.evaluate
对加载的模型进行评估,并输出评估结果。通过以上两种方式,可以根据之前保存模型的方式,选择合适的方法加载 PaddlePaddle 模型。
class nn.Layer
组网,且仅使用基础 API 保存与加载)生成符合特定分布的特征矩阵和对应的标签向量。
定义一个简单的逻辑回归模型,这里使用类的方式 class nn.Layer
组网。
使用生成的数据集对模型进行训练。
将训练好的模型保存到本地文件。
从本地文件中加载保存的模型。
使用加载的模型对新数据进行预测。
import paddle
import paddle.nn as nn
import numpy as np
from sklearn.metrics import accuracy_score
# 自定义数据集
# 生成 1000 个样本,每个样本有 2 个特征
X = np.random.randn(1000, 2).astype(np.float32)
# 根据特征生成标签
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
# 将 numpy 数组转换为 PaddlePaddle 张量
X = paddle.to_tensor(X)
y = paddle.to_tensor(y)
# 定义逻辑回归模型
class LogisticRegression(nn.Layer):
def __init__(self, input_size):
super(LogisticRegression, self).__init__()
self.linear = nn.Linear(input_size, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
out = self.linear(x)
out = self.sigmoid(out)
return out
# 初始化模型
input_size = 2
model = LogisticRegression(input_size)
# 定义损失函数和优化器
criterion = nn.BCELoss() # 二元交叉熵损失函数
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
# 前向传播
outputs = model(X)
loss = criterion(outputs, y)
# 反向传播和优化
optimizer.clear_grad()
loss.backward()
optimizer.step()
if (epoch + 1) % 10 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy()[0]:.4f}')
# 保存模型
paddle.save(model.state_dict(), 'logistic_regression_model.pdparams')
# 加载模型
loaded_model = LogisticRegression(input_size)
loaded_model.set_state_dict(paddle.load('logistic_regression_model.pdparams'))
loaded_model.eval()
# 生成新数据进行预测
new_X = np.random.randn(100, 2).astype(np.float32)
new_X = paddle.to_tensor(new_X)
# 使用加载的模型进行预测
with paddle.no_grad():
predictions = loaded_model(new_X)
predicted_labels = (predictions >= 0.5).astype(paddle.float32).numpy()
# 生成新数据对应的真实标签
true_labels = (2 * new_X.numpy()[:, 0] + 3 * new_X.numpy()[:, 1] > 0).astype(np.float32).reshape(-1, 1)
# 计算准确率
accuracy = accuracy_score(true_labels, predicted_labels)
print(f"预测准确率: {accuracy}")
X = np.random.randn(1000, 2).astype(np.float32)
:生成 1000 个样本,每个样本有 2 个特征。y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.float32).reshape(-1, 1)
:根据特征的线性组合生成标签,大于 0 标记为 1,否则标记为 0。X = paddle.to_tensor(X)
和 y = paddle.to_tensor(y)
:将 numpy
数组转换为 PaddlePaddle 张量。LogisticRegression
类继承自 nn.Layer
,包含一个线性层 nn.Linear
和一个 Sigmoid 激活函数 nn.Sigmoid
。forward
方法定义了前向传播的逻辑。criterion = nn.BCELoss()
:使用二元交叉熵损失函数,适用于二分类问题。optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.01)
:使用 Adam 优化器,学习率为 0.01。paddle.save(model.state_dict(), 'logistic_regression_model.pdparams')
:保存模型的参数到本地文件 logistic_regression_model.pdparams
。loaded_model = LogisticRegression(input_size)
:创建一个新的模型实例。loaded_model.set_state_dict(paddle.load('logistic_regression_model.pdparams'))
:加载保存的模型参数。loaded_model.eval()
:将模型设置为评估模式。new_X
并转换为张量。loaded_model
进行预测,通过 (predictions >= 0.5).astype(paddle.float32).numpy()
将预测概率转换为标签。true_labels
。accuracy_score
计算预测准确率。