动手学AI——线性回归
AI 回归 线性 动手
2023-09-14 09:14:57 时间
文章目录
%matplotlib inline
import random
import torch
from d2l import torch as d2l
线性回归的从零实现
torch.cuda.is_available(),torch.__version__
(True, '1.10.0')
1.构造数据集
def synthetic_data(w, b, num_examples):
"""生成 y = Xw + b + 噪声。"""
X = torch.normal(0, 1, (num_examples, len(w)))
# y = torch.matmul(X, w) + b # 区别就是torch.matmul自带形状转化
y = torch.mv(X,w) + b
y += torch.normal(0, 0.01, y.shape)
return X, y.reshape((-1, 1))
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
print('features:', features[0], '\nlabel:', labels[0])
features: tensor([0.3420, 0.0065])
label: tensor([4.8720])
d2l.set_figsize()
d2l.plt.scatter(features[:,1].numpy(),labels.numpy(), 1)
<matplotlib.collections.PathCollection at 0x1b64f008208>
2.定义数据读取函数
# 定义一个data_iter 函数, 该函数接收批量大小、特征矩阵和标签向量作为输入,生成大小为batch_size的小批量
def data_iter(batch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices)
for i in range(0, num_examples, batch_size):
batch_indices = indices[i:min(i+batch_size,num_examples)]
yield features[batch_indices], labels[batch_indices]
batch_size = 10
for X,y in data_iter(batch_size, features, labels):
print(X,y)
break
tensor([[-1.0328, -1.6753],
[ 0.0146, -0.1582],
[ 1.3496, -0.2746],
[ 0.7416, 1.1490],
[-0.6307, -1.3160],
[-0.4223, 0.2959],
[ 0.1045, 0.0867],
[-0.2621, 1.2941],
[-0.1359, 0.5364],
[-0.9781, -0.6348]]) tensor([[ 7.8388],
[ 4.7718],
[ 7.8217],
[ 1.7736],
[ 7.4124],
[ 2.3772],
[ 4.1344],
[-0.7325],
[ 2.0993],
[ 4.3911]])
3.定义初始化模型参数
w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
4.定义模型
def linreg(X,w,b):
''' 线性回归模型 '''
return torch.matmul(X,w) + b
5.定义损失函数和优化算法
def squared_loss(y_hat,y,batch_size):
'''
y_hat:预测值
'''
return (y_hat - y.reshape(y_hat.shape))**2 / 2 / batch_size
def sgd(params,lr):
''' 小批量梯度下降算法 '''
with torch.no_grad():
for param in params:
param -= lr * param.grad
param.grad.zero_()
6.开始训练
lr = 0.03
num_epochs = 3
net = linreg
loss = squared_loss
for epoch in range(num_epochs):
for X,y in data_iter(batch_size, features,labels):
l = loss(net(X,w,b),y,batch_size)
l.sum().backward() # 求和目的:在神经网络中我们往往对标量进行求导,而不是对向量/矩阵,防止数据扩大
sgd([w,b],lr)
with torch.no_grad():
train_l = loss(net(features,w,b),labels,batch_size)
print(f'epoch {epoch+1},loss{float(train_l.mean()):f}')
epoch 1,loss0.000022
epoch 2,loss0.000005
epoch 3,loss0.000005
7.模型评估
print(f"w的估计误差:{true_w - w.reshape(true_w.shape)}")
w的估计误差:tensor([-0.0001, 0.0005], grad_fn=<SubBackward0>)
print(f'b的估计误差: {true_b - float(b)}')
b的估计误差: -0.0005381584167478692
线性回归的简洁实现
import numpy as np
import torch
from torch.utils import data
from d2l import torch as d2l
1.构造数据
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)
2.读取数据
def load_array(data_arrays, batch_size, is_train=True):
''' 构造一个数据迭代器 '''
dataset = data.TensorDataset(*data_arrays)
return data.DataLoader(dataset, batch_size, shuffle = is_train)
batch_size = 10
data_iter = load_array((features,labels), batch_size)
next(iter(data_iter))
[tensor([[-0.5843, 0.8177],
[ 2.0447, 0.0471],
[-0.4842, 0.4462],
[-0.7347, -0.1442],
[-0.1306, -1.0834],
[-0.9230, -0.5122],
[ 0.5734, 0.4148],
[-0.8744, -0.8803],
[ 0.2996, -1.8365],
[-1.7872, -0.6060]]),
tensor([[ 0.2532],
[ 8.1311],
[ 1.7064],
[ 3.2185],
[ 7.6259],
[ 4.0917],
[ 3.9358],
[ 5.4591],
[11.0403],
[ 2.6870]])]
3.定义模型
from torch import nn
net = nn.Linear(2,1)
4.初始化模型参数(可以省略,因为pytorch自带参数初始化)
net.weight
Parameter containing:
tensor([[-0.0771, 0.0570]], requires_grad=True)
net.bias
Parameter containing:
tensor([-0.3867], requires_grad=True)
net.weight.data.normal_(0,0.01)
net.bias.data.fill_(0)
tensor([0.])
5.损失函数和优化算法
list(net.parameters())
[Parameter containing:
tensor([[-0.0771, 0.0570]], requires_grad=True),
Parameter containing:
tensor([-0.3867], requires_grad=True)]
loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
6.开始训练
num_epochs = 3
for epoch in range(num_epochs):
for X,y in data_iter:
l = loss(net(X), y)
trainer.zero_grad()
l.backward()
trainer.step()
l = loss(net(features), labels)
print(f"epoch {epoch + 1}, loss{l:.6f}")
epoch 1, loss0.000093
epoch 2, loss0.000093
epoch 3, loss0.000094
7.评估模型
w = net.weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net.bias.data
print('b的估计误差:', true_b - b)
w的估计误差: tensor([ 0.0001, -0.0009])
b的估计误差: tensor([1.0014e-05])
相关文章
- 【华为云技术分享】华为专家亲述:如何转型搞 AI?
- 大数据和AI怎么与现代教育相结合?
- AI面试-算法结构基础
- AI - TensorFlow - 分类与回归(Classification vs Regression)
- XMOS发布集单片机,AI,FPGA,DSP于一身的跨界处理器完全体xcore.ai,致力于AIOT,售价1美元起步
- AI:人工智能领域算法思维导图集合之有监督学习/无监督学习/强化学习类型的具体算法简介(预测函数/优化目标/求解算法)、分类/回归/聚类/降维算法模型选择思路、11类机器学习算法详细分类之详细攻略
- CSDN:博主为粉丝真心送福利——对比三大云产品窥探未来AI+云(云服务器、AI产品、云数据库、网站等)
- 【华为云技术分享】从软件开发到 AI 领域工程师:模型训练篇
- 沈抚示范区·“华为云杯”2021全国AI大赛圆满落幕
- 带你读AI论文丨LaneNet基于实体分割的端到端车道线检测
- 【ChatGPT】AI 人工智能——100年都不可能否取代程序员的:因为这么多人工智能机器人都这么认为——文心一言,ChatGLM, ChatGPT,Claude,Sage/By禅与计算机程序设计艺术
- 【人工智能AI】三、NoSQL 实战《NoSQL 企业级基础入门与进阶实战》
- 冰河指南AI技术社区基于ChatGPT正式启动运营
- AI学习之路(3): 牛刀小试之线性回归