一、线性回归
线性模型:给定由d个属性描述的示例,其中
是x在第i个属性上的取值,线性模型试图学习一个通过属性的线性组合来进行预测的函数,即:
其中w和b通过学习得到后,模型就确定。
线性回归:给定数据集,其中,
,线性回归试图学习一个线性模型以尽可能的准确预测实值输出标记y。
二、线性回归的简单基础实现
从零实现代码如下:
import torch
import numpy as np
import matplotlib.pyplot as plt
# 生成样本数据
np.random.seed(0)
x = np.random.rand(100, 1) # 输入特征
y = 3 * x + 2 + np.random.randn(100, 1) * 0.2 # 线性关系 y = 3x + 2 加上一些噪声
# 转换为PyTorch的张量
x_tensor = torch.from_numpy(x).float()
y_tensor = torch.from_numpy(y).float()
# 初始化模型参数:权重 w 和偏置 b
w = torch.randn(1, requires_grad=True) # 权重初始化为随机值
b = torch.randn(1, requires_grad=True) # 偏置初始化为随机值
# requires_grad=True 表示这些变量需要计算梯度,这是神经网络训练过程中必需的操作,以便我们能够通过反向传播算法更新它们的值。
# 学习率
lr = 0.01
# 手动定义均方误差损失函数(MSELoss)
def mse_loss(predictions, targets):
# 均方误差(MSE)是回归问题中常用的损失函数,它量化了模型预测值与真实值之间的差异。
return torch.mean((predictions - targets) ** 2)
# 手动定义梯度下降优化器
def sgd_step(params, lr):
with torch.no_grad(): # 在不计算梯度的情况下更新参数,确保不会影响后续的反向传播
for param in params:
param -= lr * param.grad # 更新参数
param.grad = None # 更新完参数后,清除梯度,因为 PyTorch 会自动累积梯度,所以需要在每次更新后手动清除。
# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
# 前向传播:计算预测值 y_pred = wx + b
y_pred = w * x_tensor + b
# 计算损失
loss = mse_loss(y_pred, y_tensor)
# 计算梯度
loss.backward()
# 更新参数(手动梯度下降)
sgd_step([w, b], lr)
# 每100次迭代输出一次损失
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
# 打印最终学习到的权重和偏置
print(f'Learned Weight: {w.item()}, Bias: {b.item()}')
# 可视化
predicted = w * x_tensor + b
plt.scatter(x, y, label='Original Data')
plt.plot(x, predicted.detach().numpy(), label='Fitted Line', color='r')
plt.legend()
plt.show()
上述代码实现效果图:
使用pytorch框架实现代码如下:
import torch
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
# 生成样本数据
np.random.seed(0)
x = np.random.rand(100, 1) # 输入特征
y = 3 * x + 2 + np.random.randn(100, 1) * 0.2 # 线性关系 y = 3x + 2 加上一些噪声
# 转换为PyTorch的张量
x_tensor = torch.from_numpy(x).float()
y_tensor = torch.from_numpy(y).float()
# 初始化模型参数:权重 w 和偏置 b
w = torch.randn(1, requires_grad=True) # 权重初始化为随机值
b = torch.randn(1, requires_grad=True) # 偏置初始化为随机值
# 定义学习率和优化器
lr = 0.01
optimizer = optim.SGD([w, b], lr=lr) # 只优化权重和偏置
# 定义损失函数
criterion = torch.nn.MSELoss() # 均方误差损失
# 训练模型
num_epochs = 1000
for epoch in range(num_epochs):
# 前向传播:计算预测值 y_pred = wx + b
y_pred = w * x_tensor + b
# 计算损失
loss = criterion(y_pred, y_tensor)
# 反向传播和优化
optimizer.zero_grad() # 清除之前的梯度
loss.backward() # 计算梯度
optimizer.step() # 更新权重和偏置
# 每100次迭代输出一次损失
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
# 打印最终学习到的权重和偏置
print(f'Learned Weight: {w.item()}, Bias: {b.item()}')
# 可视化
predicted = w * x_tensor + b
plt.scatter(x, y, label='Original Data')
plt.plot(x, predicted.detach().numpy(), label='Fitted Line', color='r')
plt.legend()
plt.show()
最终代码运行效果图:
三、总结
简单来说,线性回归是对n为输入的加权,外加偏差
线性回归可以看作是单层神经网络