深度学习笔记004LinearRegression&005LinearRegressionBuildingUpByPytorch线性回归/基础优化算法
今天,跟着李沐老师学习了单层的神经网络,也就是机器学习里面的线性回归,分为三个阶段——理论知识学习;手搓线性回归;调库写线性回归,笔记如下:
1 # https://blog.csdn.net/w5688414/article/details/103058802 评论区解决No module named 'torchvision.models.detection的问题 2 3 # 线性回归 4 ''' 5 假设1: 影响房价的关键因素是卧室个数,卫生间个数,居住面积(x1,x2,x3) 6 假设2:成交价是关键因素的加权和 y=w1x1+w2y2+w3y3+b 7 可以将x看作一个输入向量,w看作权重向量,b是标准偏差 8 y=<x,w>+b 9 这种简单的线性模型可以看做一个单层的神经网络 10 11 评估一个模型的平方损失: 12 假设y是真实值,Y是估计值,(y-Y)²/2即为平方损失 13 可见,平方损失越小,模型越好 14 训练损失: 15 X,训练集样本 16 y,训练集加权和 17 w,目标权重 18 b,目标标准偏差 19 f(X,y,w,b)=(1/2n)||y-Xw-b||² 20 最小化损失来学习参数:w*,b* = arg min(f(X,y,w,b)) 21 22 线性回归是对N维输入的加权,外加偏差; 23 常用平方损失来衡量预测值和真实值的差异; 24 线性回归有显示解;(有显示解的,一般都是简单模型,大部分常用模型是没有显示解的。 显示解,即可以用数学方式求出来的解) 25 线性回归可以看做单层神经网络。 26 27 深度学习常用的是小批量梯度下降(梯度下降一般不使用,太贵了) 28 梯度下降:不断沿着反梯度方向更新参数求解 29 深度学习默认的求解算法:小批量随即梯度下降 30 两个重要的超参数:批量大小,学习率 31 32 ''' 33 34 # 线性回归从零开始实现 35 # %matplotlib inline 36 import random 37 import torch 38 from d2l import torch as d2l 39 import os 40 41 42 # 根据带有噪声的线性模型构造一个人造数据集,w=【2,-3.4】;b=4.2,外加一个噪声 43 def synthetic_data(w, b, num_example): 44 # 生成 y=Xw+b 45 X = torch.normal(0, 1, (num_example, len(w))) 46 y = torch.matmul(X, w) + b 47 y += torch.normal(0, 0.01, y.shape) 48 return X, y.reshape((-1, 1)) 49 50 51 true_w = torch.tensor([2, -3.4]) 52 true_b = 4.2 53 features, labels = synthetic_data(true_w, true_b, 1000) 54 print(features[0], labels[0]) 55 56 d2l.set_figsize() 57 d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1); 58 #这里的detach就是将features从计算图里拿出来放到numpy中去 59 60 61 # d2l.plt.show() 62 63 # 随机选取批量的函数 64 def data_iter(batch_size, features, labels): 65 num_examples = len(features) 66 indices = list(range(num_examples)) 67 random.shuffle(indices) 68 for i in range(0, num_examples, batch_size): 69 batch_indices = indices[i:min(i + batch_size, num_examples)] 70 yield features[batch_indices], labels[batch_indices] # 相当于return,或者迭代器,但是节省内存,不需要一次性计算出来 71 72 73 74 batch_size = 10 75 for X, y in data_iter(batch_size, features, labels): 76 print(X, '\n', y) 77 break 78 79 # 定义模型 80 w = torch.normal(0, 0.01, size=(2, 1), requires_grad=True) 81 b = torch.zeros(1, requires_grad=True) 82 83 84 def linreg(X, w, b): 85 return torch.matmul(X, w) + b 86 87 88 # 损失函数 89 def squared_loss(y_hat, y): 90 return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2 91 92 93 def sgd(params, lr, batch_Size): 94 # 小批量随即梯度下降 95 with torch.no_grad(): 96 for param in params: 97 param -= lr * param.grad / batch_Size # 这里的batch_Size是求均值,在损失函数求也行在这里也行 98 param.grad.zero_() 99 100 101 # 指定超参数:学习率、循环次数、模型、损失函数 102 lr = 0.03 103 num_epochs = 3 104 net = linreg 105 loss = squared_loss 106 107 for epoch in range(num_epochs): 108 for X, y in data_iter(batch_size, features, labels): 109 l = loss(net(X, w, b), y) # x和y的小批量损失 110 l.sum().backward() # 对损失进行求和之后求梯度,这里可以理解为把所有的l求和求梯度,所以必须除以batch_size在sgd里面 111 # 换句话说,这里的l是一个(batch_size,1),而不是一个标量 112 sgd([w, b], lr, batch_size) # 这里使用参数的梯度更新里面batch_size有问题,可能不能整除则就会在最后一个batch里面过大 113 with torch.no_grad(): 114 train_l = loss(net(features, w, b), labels) 115 print(f'epoch {epoch + 1},loss{float(train_l.mean()):f}') 116 117 print(f'w的估算误差:{true_w-w.reshape(true_w.shape)}') 118 print(f'b的估算误差:{true_b-b}')
1 #关于星号和双星号的用法(多非关键字变量、关键字变量的关系,参考这篇非常清晰的博客:https://www.cnblogs.com/empty16/p/6229538.html 2 3 import numpy as np 4 import torch 5 from torch.utils import data 6 from d2l import torch as d2l 7 8 true_w=torch.tensor([2,-3.4]) 9 true_b=4.2 10 11 features,labels=d2l.synthetic_data(true_w,true_b,1000) 12 13 # 构造一个pytorch的数据迭代器 14 def load_array(data_arrays,batch_size,is_train=True): 15 dataset=data.TensorDataset(*data_arrays) #一个星号代表这里可以传入多个非关键字变量,在*data_arrays位置会被处理成为元组 16 return data.DataLoader(dataset,batch_size,shuffle=is_train) 17 18 batch_size=10 19 data_iter=load_array((features,labels),batch_size,True) 20 21 print(next(iter(data_iter))) 22 23 from torch import nn 24 net = nn.Sequential(nn.Linear(2,1)) #这里2代表输入层维度,1代表输出层维度 25 # Sequential可以理解为把神经网络放在一个层的容器里,即list of layers 26 net[0].weight.data.normal_(0,0.01) #替换之前的w 27 net[0].bias.data.fill_(0) #替换之前的b 28 loss =nn.MSELoss() #均方误差:MSE 29 trainer=torch.optim.SGD(net.parameters(),lr=0.03) #之前实例化好的SGD 30 31 # 开始训练!!! 32 num_epochs=3 33 for epoch in range(num_epochs): 34 for X,y in data_iter: 35 l=loss(net(X),y) #net内本身有w和b,接口实现了,不用传参 36 trainer.zero_grad() 37 l.backward() #接口已经帮你实现了sum(),不用额外求sum() 38 trainer.step() #进行模型更新 39 l=loss(net(features),labels) 40 print(f'epoch{epoch+1},loss {l:f}')

浙公网安备 33010602011771号