library(torch)
library(luz)
# input dimensionality (number of input features)
# 定义输入的特征维度为 3
d_in <- 3
# 定义训练数据的样本数量为 1000
# number of observations in training set
n <- 1000
# 生成一个形状为 (1000, 3) 的随机张量,作为输入特征
x <- torch_randn(n, d_in)
# 定义一个系数向量,用于线性映射
coefs <- c(0.2, -1.3, -0.5)
# 是生成的目标标签(模拟真实结果)
# 通过将 x 和 coefs 进行矩阵乘法后
# 加上形状为 (1000, 1) 的随机噪声生成
y <- x$matmul(coefs)$unsqueeze(2) + torch_randn(n, 1)
# 将张量 x 和 y 封装成一个数据集对象
ds <- tensor_dataset(x, y)
# 创建用于训练的批量加载器
# 表示每次从数据集中加载 100 个样本
# 在加载数据时数据会被打乱
dl <- dataloader(ds, batch_size = 100, shuffle = TRUE)
# dimensionality of hidden layer
d_hidden <- 32 # 隐藏层的维度
# output dimensionality (number of predicted features)
d_out <- 1 # 输出层的维度
# 定义神经网络模块
net <- nn_module(
initialize = function(d_in, d_hidden, d_out) {
# 三个层组成的序列
self$net <- nn_sequential(
nn_linear(d_in, d_hidden), # 线性全连接层
nn_relu(), # 激活函数
nn_linear(d_hidden, d_out) # 线性全连接层
)
},
# 向前传播方法
forward = function(x) {
self$net(x)
}
)
# 结果赋值给fitted
fitted <- net %>%
# 设置损失函数和优化器
setup(loss = nn_mse_loss(), optimizer = optim_adam) %>%
# 设置超参数
set_hparams(
d_in = d_in, # 输入层维度
d_hidden = d_hidden, d_out = d_out # 隐藏层神经元数量和输出层维度
) %>%
fit(dl, epochs = 200) # 使用数据加载器,200个epoch
# 从数据集的完整索引中随机抽取60%的索引作为训练集的索引
train_ids <- sample(1:length(ds), size = 0.6 * length(ds))
# 从剩余的索引中(即非训练集的部分)随机抽取20%的索引作为验证集的索引
valid_ids <- sample(
setdiff(1:length(ds), train_ids),
size = 0.2 * length(ds)
)
# 将训练集和验证集的索引从完整索引中排除,剩下的索引作为测试集的索引
test_ids <- setdiff(
1:length(ds),
union(train_ids, valid_ids)
)
# 创建基于训练集索引的子数据集
train_ds <- dataset_subset(ds, indices = train_ids)
# 基于验证集索引的数据集
valid_ds <- dataset_subset(ds, indices = valid_ids)
# 测试集索引的子数据集
test_ds <- dataset_subset(ds, indices = test_ids)
# 为训练集创建数据加载器,指定批量大小为100,并启用数据打乱(shuffle)
train_dl <- dataloader(train_ds,
batch_size = 100, shuffle = TRUE
)
# 为验证集创建数据加载器,指定批量大小为100
valid_dl <- dataloader(valid_ds, batch_size = 100)
# 为测试集创建数据加载器,指定批量大小为100
test_dl <- dataloader(test_ds, batch_size = 100)
fitted <- net %>%
# 函数用于设置模型的基本配置
setup(
loss = nn_mse_loss(), # 指定使用均方误差 (MSE) 作为损失函数
optimizer = optim_adam, # 选择使用 Adam 优化器
metrics = list(luz_metric_mae()) # 评估指标使用平均绝对误差 (MAE)
) %>%
set_hparams( # 设置模型的超参数
d_in = d_in, # 输入维度
d_hidden = d_hidden, d_out = d_out # 隐藏层维度和输出维度
) %>%
# 训练模型,训练加载,200个周期,验证集
fit(train_dl, epochs = 200, valid_data = valid_dl)
# fitted 在测试数据集 test_dl 上进行评估
fitted %>% evaluate(test_dl)
# 另一个训练
fitted <- net %>%
setup(
loss = nn_mse_loss(),
optimizer = optim_adam,
metrics = list(luz_metric_mae())
) %>%
set_hparams(d_in = d_in,
d_hidden = d_hidden,
d_out = d_out) %>%
fit(
train_dl,
epochs = 200,
valid_data = valid_dl,
callbacks = list( # 回调函数提供训练过程中的特殊功能
# 模型检查点功能,自动保存性能最佳的模型,保存在./modoels/
luz_callback_model_checkpoint(path = "./models/",
# 只保存最佳模型
save_best_only = TRUE),
# 提前停止功能,当验证集性能在 10 轮内没有改善时停止训练,避免过拟合
luz_callback_early_stopping(patience = 10)
)
)
# 使用训练好的模型(fitted)对测试数据集 (test_dl) 进行预测
fitted %>% predict(test_dl)
发表评论