一、机器学习工作流程
· 通过线性回归模型回顾机器学习模型的一般工作流程:
(1) 获取数据;
(2) 数据基本处理;
(3) 特征工程;
(4) 机器学习(模型训练);
(5) 模型评估;
· 在线性回归模型中的具体表现:
1. 针对某个实际问题,构想解决该问题的机器模型,并根据需求获取输入值,建立输入的数据集。
2. 对数据进行预处理,将数据统一化为机器可学习的数据类型。
(1) 利用张量来对不同类型的数据进行不同维度的存储。
(2) 创建人工数据集并存储在csv等类型文件中。
(3) 生成小批量数据集,以对模型进行多次小批量训练。
3. 特征工程,确定好合适的特征值,确定好合适的数据拟合曲线。
(1) 尽量选取影响因素较大、更关键的输入属性作为特征值。
(2) 进行特征缩放操作。将取值范围较大的特征值进行特征缩放,提高梯度下降的执行速度。
(3) 利用多项式回归等算法,找到更好地拟合数据的曲线,以优化模型。
4. 机器学习(模型训练),最关键的部分,利用已建立好的数据集构建机器学习模型。
4.1 预先设置参数 以及学习率
,对数据初步进行预测。
4.2 构建损失函数 用来评估评测值与实际值的差异,以方便后续优化参数。
4.3 通过梯度下降优化算法不断优化参数 :
在这个过程中, 会被不断地向使
值更小方向更新,直到使其达到最小值。
※ 注意,要对梯度下降进行收敛判断,一般通过学习曲线或自动收敛测试进行。
4.4 预设好这些函数之后,不断执行for循环对模型重复训练,通过损失函数评判模型精度。
二、张量、广播机制、数据预处理等知识
· 张量:表示一个多维数组,常用 numpy 实现;
· 广播机制:对不同 shape 值的张量进行加减操作,会自动填充缺失的行列值。
· 数据预处理:对于数字数据,将NA数据补充为mean();对于字符数据,将数据化为多种类别并赋值表示每一类。以此将所有数据化为数值类型,再转换为张量格式。
· 线性回归模型的代码实现:
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
# 初始化w, b的真实值,定义特征值与标签数
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
# 获取数据迭代器
def load_array(data_arrays, batch_size, is_train=True):
# 构造一个pytorch数据迭代器
# 已知features和labels,可以直接调用TensorDataset函数来将特征数据与标签数据直接生成数据集
dataset = data.TensorDataset(*data_arrays)
# 拿到数据集之后,可以调用DataLoader每次从中拿出小批量数据,并打乱标签
# 最后返回一个数据迭代器对象
return data.DataLoader(dataset, batch_size, shuffle=True)
batch_size = 10
# 调用load_array函数将特征数据与标签数据传入,得到一个数据迭代器对象
data_iter = load_array((features, labels), batch_size)
# 使用next可以获取数据迭代器的下一个批量数据
next(iter(data_iter))
# 使用框架预定义的线性层
# nn是神经网络的缩写
from torch import nn
# 指定输入维度和输出维度
net = nn.Sequential(nn.Linear(2, 1))
# 初始化模型参数
# net[0]访问Linear,weight访问w,data访问w的值,normal_可以将w设置均值为0,方差0.01正态分布
net[0].weight.data.normal_(0, 0.01)
# 同样地将方差设置为0
net[0].bias.data.fill_(0)
# 直接调用平方损失和梯度算法
loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
# 训练模型
num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:
# 首先计算模型的预测值net(X),并将其与真实标签y传入损失函数loss中计算损失l
# net里面自带了模型参数,因此不再需要将w和b的值传入了
l = loss(net(X), y)
# 调用trainer.zero_grad()将模型参数的梯度清零,以便进行下一次迭代时重新计算梯度
trainer.zero_grad()
# 调用l.backward()进行反向传播,计算损失对模型参数的梯度
l.backward()
# 调用trainer.step()根据梯度更新模型参数
trainer.step()
# 使用loss(net(features), labels)计算整个数据集上的损失l
l = loss(net(features), labels)
print(f'epoch {epoch+1}, loss {l:f}')