持续创造,加快成长!这是我参与「日新计划 10 月更文应战」的第11天,点击检查活动概况
1.线性回归的基本要素
1.1 模型界说
以简单的房子价格猜测来作为线性回归的基本要素,目标是售出价格(元)。设房子的面积为x1,房龄为x2,售出价格为y。咱们需要建立基于输入x1和x2来计算输出y的表达式,也就是模型。
其间,w1和w2是权重,b是偏差,且均为标量。它们是线性回归模型的参数。模型输出的结果是线性回归对实在价格y的猜测和估量。一般会允许存在必定的差错。
1.2 模型练习
然后咱们就需要数据来寻觅特定的模型参数值,使模型在数据上的差错尽可能小。这个过程叫做模型练习。其间包括三个要素:
(1)练习数据
练习的数据应该用实在数据,这些数据一般就被称为练习数据集,这儿咱们将一栋房子作为一个样本(sample),实在价格叫标签(label),用来猜测标签的两个要素叫特征(feature)。
(2)丢失函数
在模型练习中,咱们需要衡量价格猜测值与实在值之间的差错。一般咱们会选取一个非负数作为差错,且数值越小表明差错越小。一个常用的选择是平方函数。它在评估索引为i的样本差错的表达式为:
能够看出,差错越小表明猜测价格与实在价格越相近。这儿运用的平方差错函数也称为平方丢失。
(3)优化算法
在求数值解的优化算法中,咱们一般运用小批量随机梯度下降。它的算法思路:先选取一组模型参数的初始值,如随机选取;接下来对参数进行屡次迭代,使每次迭代都可能降低丢失函数的值。在每次迭代中,先随机均匀采样一个由固定数目练习数据样本所组成的小批量(mini-batch),然后求小批量中数据样本的均匀丢失有关模型参数的导数(梯度),最后用此结果与预先设定的一个正数的乘积作为模型参数在本次迭代的减小量。
2.代码完成线性回归
2.1 环境装备要求
Pytorch1.12.1
Python3.8
Numpy 1.21库
Cuda11.3
2.2环境导入
import matplotlib_inline#用于作图
import torch#导入pytorch
from IPython import display
from matplotlib import pyplot as plt
import numpy as np
import random
2.3生成数据集
num_inputs=2 #输入特征数为2,
num_examples=1000 #设置练习样本数为1000
true_w=[2,-3.4] #设置模型的实在权重别离为2和-3.4
true_b=4.2 #设置偏差值为4.2
features=torch.from_numpy(np.random.normal(0,1,(num_examples,num_inputs)))#就是torch.from_numpy()办法把数组转换成张量,且二者共享内存.
labels=true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b#代码完成公式
labels+=torch.from_numpy(np.random.normal(0,0.01,size=labels.size()))
print(features[0],labels[0])
留意,features的每一行是一个长度为2的向量,而labels的每一行是一个长度为1的向量(标量)。
这儿代码进行了改进,改进之后不再报红了。
def use_svg_display():
#用矢量图进行显示
matplotlib_inline.backend_inline.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5,2.5)):
use_svg_display()
#设置图的尺寸
plt.rcParams['figure.figsize']=figsize
set_figsize()
plt.scatter(features[:,1].numpy(),labels.numpy(),1);
经过生成第二个特征features[;,1]和标签labels的散点图,能够更直观地调查两者间的线性关系。
2.4读取数据
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):
j=torch.LongTensor(indices[i:min(i+batch_size,num_examples)])#最后一次可能不足一个batch
yield features.index_select(0,j),labels.index_select(0,j)
batch_size=10
for X,y in data_iter(batch_size,features,labels):
print(X,y)
break
咱们读取第一个小批量数据样本并打印。每个批量的特征形状为(10,2),别离对应批量巨细和输入个数;标签形状为批量巨细。
2.5初始化模型参数
w=torch.tensor(np.random.normal(0,0.01,(num_inputs,1)),dtype=torch.float64)
b=torch.zeros(1,dtype=torch.float64)
w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)
这儿会在最后有一个报错,所以float32改成了float64。
2.6界说模型
运用mm函数做矩阵乘法
def linreg(X, w,b):
return torch.mm(X,w) + b
2.7界说丢失函数
def squared_loss(y_hat, y):
# 留意这⾥回来的是向量, 另外, pytorch⾥的MSELoss并没有除以 2
return (y_hat - y.view(y_hat.size())) ** 2 / 2
这儿运用平方丢失来界说线性回归的丢失函数,把实在值y变为y_hat的形状。
2.8界说优化算法
def sgd(params, lr, batch_size):
for param in params:
param.data -= lr * param.grad / batch_size # 留意这⾥更改param时⽤的param.data
这儿运用小批量随机梯度算法进行优化
2.9练习模型
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).sum() # l是有关⼩批量X和y的丢失
l.backward() # ⼩批量的丢失对模型参数求梯度
sgd([w, b],lr, batch_size) # 使⽤⼩批量随机梯度下降迭代模型参数
# 不要忘了梯度清零
w.grad.data.zero_()
b.grad.data.zero_()
train_l = loss(net(features, w, b), labels)
print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item()))
练习后检查生成的参数
print(true_w, '\n', w)
print(true_b, '\n', b)
2.10可能呈现的bug
呈现:RuntimeError:expectedscalartypeDoublebutfoundFloat报错
这是因为double类型和float类型发生了冲突,将dtype的32改成64问题就能够解除。