专栏首页拇指笔记【动手学深度学习笔记】之线性回归实现

【动手学深度学习笔记】之线性回归实现

实现线性回归

这一节不牵扯深度学习框架,仅使用Tensor和autograd库来训练线性回归模型。

#需要导入的库import torch	#张量计算from IPython import display		#嵌入显示图像from matplotlib import pyplot as plt	#绘制图像import numpy as np		#矩阵运算import random	#生成随机数

创建一个数据集

要训练一个模型,首先需要训练数据集和数据对应的标签。

先随机生成一个样本数为1000的「随机样本特征」

然后使用真实模型 y = 2x1-3.4x2+4.2+随机噪声项,生成1000个「标签」

其中随机噪声项服从均值为0、标准差为0.01的正态分布,代表列无意义的干扰

程序实现

#生成数据集num_inputs = 2	#特征数,数据集的列数num_examples = 1000	#样本数,数据集的行数true_w = [2,-3.4]	#线性模型的真实权重true_b = 4.2		#线性模型的真实偏差
featrues = torch.randn(num_examples,num_inputs,dtype = torch.float32)#使用随机张量函数,生成一个1000行2列的随机张量labels = true_w[0]*featrues[:,0]+true_w[1]*featrues[:,1]+true_b#使用随机张量作为输入生成一组标签labels += torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)#为标签加随机噪声,生成随机噪声方法:使用numpy库的random.normal生成一个均值为0,标准拆为0.0.1的正态分布,其大小为1行2000个的行向量。#在这一部分,使用了两种随机矩阵生成的方法,主要区别是第二个为正态分布。且第二种生成的行向量。

数据可视化:绘制散点图象

def use_deg_display():    display.set_matplotlib_formats('svg')    #绘制矢量图,不同散点有深浅。    def set_figsize(figsize=(3.5,2.5)):    use_deg_display()    plt.rcParams['figure.figsize'] = figsize    #设置散点图和图像大小    set_figsize()
%matplotlib inline#使用juterpy notebook要注意,需要使用这行代码,才能显示图像
plt.scatter(featrues[:,1].numpy(),labels.numpy(),c='b');#关于散点图绘制函数的参数,见这个:https://www.imooc.com/article/29522

绘制出的散点图

读取数据

#读取数据def data_iter(batch_size,features,labels):    num_examples = len(features)    indices = list(range(num_examples))    #从0到num_examples生成一个列表indices    random.shuffle(indices)                #打乱indices这个列表(随机)        #这个for循环也叫做迭代器    for i in range(0,num_examples,batch_size):	#找到每一个小批量起始的索引(如:0 10 20...)        j = torch.LongTensor(indices[i:min(i+batch_size,num_examples)])        #将小批量对应的所有索引转换为张量j        yield features.index_select(0,j),labels.index_select(0,j)        #定义了一个生成器,节省了内存       #输出batch_size =10for X,y in data_iter(batch_size,featrues,labels):    print(X,y)    break	#只输出一次    #使用for循环来读取生成器data_iter中的数据

2020\2\21\1:48

2020\2\22\8:57

初始化模型参数

模型参数指:权重w1,w2;偏差b。

首先将权重初始化成均值为0,标准差为0.01的正态随机数。偏差初始化为0。

w = torch.tensor(np.randm.normal(0,0.01,(num_inputs,1)),dtype = torch.float32)#使用numpy生成大小为2*1的一个均值为0,标准差为0.01正态分布b = torch.zeros(1,dtypr = float32)#生成一个大小为1的全0矩阵

定义模型

将前文所述的矩阵形式模型

转换为程序形式

def linreg(X,w,b):	return torch.mm(X,w)+b	#torch.mm(X,b)函数,对X和b进行矩阵乘法运算。

定义损失函数

也是将之前的函数

转换为程序形式

def squared_loss(y_hat,y):	return (y_hat - y.view(y_hat_size()))**2/2	#**是平方

定义优化算法

实现上一节中的小批量随机下降算法,通过不断迭代模型参数来优化损失函数。

def sgd(params,lr,batch_size):    for param in aprams:        param.data -= lr*param.grad/batch_size        #不理解.data什么意思。好像是对数据本身进行操作

训练模型

在训练中,多次迭代模型参数。在每次迭代中:

  1. 读取小批量随机样本
  2. 调用反向函数.backward计算样本的梯度(小批量随机梯度)
  3. 调用sgd函数迭代模型参数,然后将参数的梯度清零
#当前程序迭代周期数设置为3;学习率设置为0.03lr = 0.03num_epochs = 3net = linreg 		#换名loss = squared_loss	#换名,不知道为什么
for epoch in range(num_epochs):    #一共需要num_epochs个迭代周期    #每一个迭代周期都需要遍历所有样本    for X,y in data_iter(batch_size,features,labels):        #一次接收一组读取数据得到的小批量特征与标签        l = loss(net(X,w,b),y).sum()        #首先计算模型得到的值,再计算损失函数值,由于直接计算得到的是向量的形式,无法直接求梯度,因此对他进行加和运算。        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()))    #对损失值求均值。输出每一个学习周期得到的损失值。

程序

import torchfrom IPython import displayfrom matplotlib import pyplot as pltimport numpy as npimport random
#生成数据集num_inputs = 2num_examples = 1000true_w = [2,-3.4]true_b = 4.2features = torch.randn(num_examples,num_inputs,dtype = torch.float32)#1000行2列labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_blabels += torch.tensor(np.random.normal(0,0.01,size = labels.size()),dtype = torch.float32)
#绘制图像def use_deg_display():    display.set_matplotlib_formats('svg')    def set_figsize(figsize=(3.5,2.5)):    use_deg_display()    plt.rcParams['figure.figsize'] = figsize    # set_figsize()# %matplotlib inline# plt.scatter(featrues[:,1].numpy(),labels.numpy(),c='b');
#读取数据def data_iter(batch_size,features,labels):    num_examples = len(features)    indices = list(range(num_examples))    #从0到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)])        yield features.index_select(0,j),labels.index_select(0,j)
w = torch.tensor(np.random.normal(0,0.01,(num_inputs,1)),dtype = torch.float32)#使用numpy生成大小为2*1的一个均值为0,标准差为0.01正态分布b = torch.zeros(1,dtype = torch.float32)#生成一个大小为1的全0矩阵
w.requires_grad_(requires_grad=True)b.requires_grad_(requires_grad=True)#开始追踪其上的所有操作
def linreg(X,w,b):    return torch.mm(X,w)+b    #torch.mm(X,b)函数,对X和b进行矩阵乘法运算。    def squared_loss(y_hat,y):    return (y_hat - y.view(y_hat.size()))**2/2    #view:将y转换为与y_hat同形的    def sgd(params,lr,batch_size):    for param in params:        param.data -= lr*param.grad/batch_size        #不理解.data什么意思。好像是对数据本身进行操作
#当前程序迭代周期数设置为3;学习率设置为0.03lr = 0.03num_epochs = 3net = linreg 		#换名loss = squared_loss	#换名,不知道为什么batch_size = 10
for epoch in range(num_epochs):    #一共需要num_epochs个迭代周期    #每一个迭代周期都需要遍历所有样本    for X,y in data_iter(batch_size,features,labels):        #一次接收一组读取数据得到的小批量特征与标签        l = loss(net(X,w,b),y).sum()        #首先计算模型得到的值,再计算损失函数值,由于直接计算得到的是向量的形式,无法直接求梯度,因此对他进行加和运算。        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)

本文分享自微信公众号 - 拇指笔记(shuzhi990),作者:拇指笔记

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从0到1,实现你的第一个多层神经网络

    多层感知机在单层神经网络的基础上引入了一到多个隐藏层(hidden layer)。如图所示的隐藏层一共有5个隐藏单元。由于输入层不涉及计算,因此这个多层感知机的...

    树枝990
  • 【动手学深度学习笔记】之多层感知机实现

    Fashion-MNIST数据集中的图像为28*28像素,也就是由784个特征值。Fashion-MNIST数据集一共有十个类别。因此模型需要784个输入,10...

    树枝990
  • 【动手学深度学习笔记】之过拟合与欠拟合实例

    每个小批量设置为10,使用TensorDataset转换为张量,使用DataLoader生成迭代器。

    树枝990
  • ios 笔试题3

         *(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5,&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小...

    py3study
  • 【LeetCode】830. 较大分组的位置

    例如,在字符串 s = “abbxxxxzyy” 中,就含有 “a”, “bb”, “xxxx”, “z” 和 “yy” 这样的一些分组。

    韩旭051
  • Windows开机过程和测试方法探索

    用户会经常抱怨自从安装自己的应用后,电脑开机变慢,到底是系统的原因还是应用的原因,为了了解这里的问题,探秘了下windows的开机过程和测试方法。 一、开机过...

    腾讯移动品质中心TMQ
  • android view实现横向滑动选择

    本文实例为大家分享了android view实现横向滑动选择的具体代码,供大家参考,具体内容如下

    砸漏
  • 剑指offer 第十天

    37.数字在排序数组中出现的次数 统计一个数字在排序数组中出现的次数。 采用二分查找法 /* 方法一:时间复杂度O(n),不可选 */ public cla...

    郭耀华
  • 手把手教你 SpringBoot 分布式锁的实现

    前段时间面试了一个高级程序员,问他了一些分布式锁的知识,回答的还不错。后来进了我们的团队,刚好让他接手一个新项目,需要用到分布式锁,我说这是你的强项,你来实现。

    业余草
  • 关于指针的详细讲解

    一旦指针变量指向对象,就可以使用*运算符访问存储在对象中的内容。例如p指向i,那么可以写出显示i的值:

    心跳包

扫码关注云+社区

领取腾讯云代金券