(pytorch-深度学习系列)pytorch实现线性回归

pytorch实现线性回归

1. 实现线性回归前的准备

线性回归输出是一个连续值,因此适用于回归问题。回归问题在实际中很常见,如预测房屋价格、气温、销售额等连续值的问题。
与回归问题不同,分类问题中模型的最终输出是一个离散值。我们所说的图像分类、垃圾邮件识别、疾病检测等输出为离散值的问题都属于分类问题的范畴。softmax回归则适用于分类问题。

定义两个1000维的向量

import torch
from time import timea = torch.ones(1000)
b = torch.ones(1000)

向量相加的一种方法是,将这两个向量按元素逐一做标量加法。如下:

start = time()
c = torch.zeros(1000)
for i in range(1000):c[i] = a[i] + b[i]
print(time() - start)

输出:

0.02039504051208496

向量相加的另一种方法是,将这两个向量直接做矢量加法。

start = time()
d = a + b
print(time() - start) # 0.0008330345153808594

结果很明显,后者比前者更省时。因此,我们应该尽可能采用矢量计算,以提升计算效率。

定义一个房价预测问题,实例化应用场景:

在这里插入图片描述
我们通常收集一系列的真实数据,例如多栋房屋的真实售出价格和它们对应的面积和房龄。我们希望在这个数据上面寻找模型参数来使模型的预测价格与真实价格的误差最小。在机器学习术语里,该数据集被称为训练数据集(training data set)或训练集(training set),一栋房屋被称为一个样本(sample),其真实售出价格叫作标签(label),用来预测标签的两个因素叫作特征(feature)。特征用来表征样本的特点。
在这里插入图片描述
在模型训练中,我们需要衡量价格预测值与真实值之间的误差。通常我们会选取一个非负数作为误差,且数值越小表示误差越小。一个常用的选择是平方函数。它在评估索引为 i 的样本误差的表达式为:
在这里插入图片描述
误差越小表示预测价格与真实价格越相近,且当二者相等时误差为0
我们用训练数据集中所有样本误差的平均来衡量模型预测的质量:
在这里插入图片描述
在这里插入图片描述

2. 线性回归的pytorch实现

导入所需的包或模块,其中的matplotlib包可用于作图,且设置成嵌入显示。

%matplotlib inline
import torch
from IPython import display
from matplotlib import pyplot as plt # matplotlib包可用于作图,且设置成嵌入显示
import numpy as np
import random

生成一个数据集:

num_inputs = 2 #特征数量
num_examples = 1000 # 数据数量,即样本数量
true_w = [2, -3.4] # 线性回归模型真实权重
true_b = 4.2 # 偏差
features = torch.randn(num_examples, num_inputs,dtype=torch.float32)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b 
# y=k*x+b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()),dtype=torch.float32) # 噪声项,服从均值为0、标准差为0.01的正态分布。噪声代表了数据集中无意义的干扰

features的每一行是一个长度为2的向量,而labels的每一行是一个长度为1的向量(标量)

通过生成第二个特征features[:, 1]和标签 labels 的散点图,可以更直观地观察两者间的线性关系。

def use_svg_display():# 用矢量图显示display.set_matplotlib_formats('svg') # 设置图类型为svg图def set_figsize(figsize=(3.5, 2.5)):use_svg_display()# 设置图的尺寸plt.rcParams['figure.figsize'] = figsizeset_figsize()
plt.scatter(features[:, 1].numpy(), labels.numpy(), 1) # 注意这里将tensor转化为numpy

在这里插入图片描述
在训练模型的时候,我们需要遍历数据集并不断读取小批量数据样本。这里我们定义一个函数:它每次返回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):j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) # 最后一次可能不足一个batchyield  features.index_select(0, j), labels.index_select(0, j)

读取第一个小批量数据样本并打印。每个批量的特征形状为(10, 2),分别对应批量大小和输入个数;标签形状为批量大小。

batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, y)break # 读取一个batch

输出:

tensor([[-1.4239, -1.3788],[ 0.0275,  1.3550],[ 0.7616, -1.1384],[ 0.2967, -0.1162],[ 0.0822,  2.0826],[-0.6343, -0.7222],[ 0.4282,  0.0235],[ 1.4056,  0.3506],[-0.6496, -0.5202],[-0.3969, -0.9951]]) tensor([ 6.0394, -0.3365,  9.5882,  5.1810, -2.7355,  5.3873,  4.9827,  5.7962,4.6727,  6.7921])

我们将模型参数权重初始化成均值为0、标准差为0.01的正态随机数,偏差则初始化成0。

w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32)
b = torch.zeros(1, dtype=torch.float32)

之后的模型训练中,需要对这些参数求梯度来迭代参数的值,因此我们要让它们的requires_grad=True:

w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True) 

定义模型:

def linreg(X, w, b):  # 矢量表达式return torch.mm(X, w) + bdef squared_loss(y_hat, y):  # 损失函数# 注意这里返回的是向量, 另外, pytorch里的MSELoss并没有除以 2return (y_hat - y.view(y_hat.size())) ** 2 / 2def sgd(params, lr, batch_size):  # 优化算法:小批量随机梯度下降算法for param in params:param.data -= lr * param.grad / batch_size # 注意这里更改param时用的是param.data

在求数值解的优化算法中,小批量随机梯度下降(mini-batch stochastic gradient descent)在深度学习中被广泛使用。它的算法很简单:先选取一组模型参数的初始值,如随机选取;接下来对参数进行多次迭代,使每次迭代都可能降低损失函数的值。在每次迭代中,先随机均匀采样一个由固定数目训练数据样本所组成的小批量(mini-batch),然后求小批量中数据样本的平均损失有关模型参数的导数(梯度),最后用此结果与预先设定的一个正数的乘积作为模型参数在本次迭代的减小量。

训练模型:

lr = 0.03 # 学习率
num_epochs = 3
net = linreg
loss = squared_lossfor epoch in range(num_epochs):  # 训练模型一共需要num_epochs个迭代周期# 在每一个迭代周期中,会使用训练数据集中所有样本一次(假设样本数能够被批量大小整除)。X# 和y分别是小批量样本的特征和标签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()))
epoch 1, loss 0.021578
epoch 2, loss 0.000096
epoch 3, loss 0.000050

输出学到的参数和用来生成训练集的真实参数:

print(true_w, '\n', w)
print(true_b, '\n', b)
[2, -3.4] tensor([[ 1.9998],[-3.3998]], requires_grad=True)
4.2 tensor([4.2001], requires_grad=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(pytorch-深度学习系列)pytorch实现多层感知机(手动定义模型)对Fashion-MNIST数据集进行分类-学习笔记

pytorch实现多层感知机对Fashion-MNIST数据集进行分类(手动定义模型) 多层感知机: 多层感知机在单层神经网络的基础上引入了一到多个隐藏层(hidden layer)。隐藏层位于输入层和输出层之间。 输入和输出个数分别为4和…

(pytorch-深度学习系列)ResNet残差网络的理解-学习笔记

ResNet残差网络的理解 ResNet伴随文章 Deep Residual Learning for Image Recognition 诞生,该文章是MSRA何凯明团队在2015年ImageNet上使用的网络,在当年的classification、detection等比赛中,ResNet均获了第一名,这也导致了Res…

(pytorch-深度学习系列)卷积神经网络LeNet-学习笔记

卷积神经网络LeNet 先上图:LeNet的网络结构 卷积(6个5∗5的核)→降采样(池化)(2∗2的核,步长2)→卷积(16个5∗5的核)→降采样(池化)(2∗2的核,步长2)→全连接16∗5∗5→120→全连接120→84→全连接84→10\begin{matrix}卷积 \\ (6个5*5的核…

(pytorch-深度学习系列)深度卷积神经网络AlexNet

深度卷积神经网络AlexNet 文字过多,但是重点已经标出来了 背景 在LeNet提出后的将近20年里,神经网络一度被其他机器学习方法超越,如支持向量机。虽然LeNet可以在早期的小数据集上取得好的成绩,但是在更大的真实数据集上的表现并…

(pytorch-深度学习)包含并行连结的网络(GoogLeNet)

包含并行连结的网络(GoogLeNet) 在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet的网络结构大放异彩。它虽然在名字上向LeNet致敬,但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想&#…

(pytorch-深度学习)实现稠密连接网络(DenseNet)

稠密连接网络(DenseNet) ResNet中的跨层连接设计引申出了数个后续工作。稠密连接网络(DenseNet)与ResNet的主要区别在于在跨层连接上的主要区别: ResNet使用相加DenseNet使用连结 ResNet(左)…

(pytorch-深度学习)循环神经网络

循环神经网络 在nnn元语法中,时间步ttt的词wtw_twt​基于前面所有词的条件概率只考虑了最近时间步的n−1n-1n−1个词。如果要考虑比t−(n−1)t-(n-1)t−(n−1)更早时间步的词对wtw_twt​的可能影响,需要增大nnn。 这样模型参数的数量将随之呈指数级增长…

(pytorch-深度学习)使用pytorch框架nn.RNN实现循环神经网络

使用pytorch框架nn.RNN实现循环神经网络 首先,读取周杰伦专辑歌词数据集。 import time import math import numpy as np import torch from torch import nn, optim import torch.nn.functional as Fimport sys sys.path.append("..") device torch.d…

(pytorch-深度学习)通过时间反向传播

通过时间反向传播 介绍循环神经网络中梯度的计算和存储方法,即通过时间反向传播(back-propagation through time)。 正向传播和反向传播相互依赖。正向传播在循环神经网络中比较直观,而通过时间反向传播其实是反向传播在循环神经…

(pytorch-深度学习)门控循环单元(GRU)

门控循环单元(GRU) 循环神经网络中的梯度计算 当时间步数较大或者时间步较小时,循环神经网络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸,但无法解决梯度衰减的问题。通常由于这个原因,循环神经网络在…

(pytorch-深度学习)长短期记忆(LSTM)

长短期记忆(LSTM) LSTM 中引入了3个门,即 输入门(input gate)遗忘门(forget gate)输出门(output gate)以及与隐藏状态形状相同的记忆细胞(某些文献把记忆细…

(pytorch-深度学习)深度循环神经网络

深度循环神经网络 循环神经网络只有一个单向的隐藏层,在深度学习应用里,我们通常会用到含有多个隐藏层的循环神经网络,也称作深度循环神经网络。 下图演示了一个有LLL个隐藏层的深度循环神经网络,每个隐藏状态不断传递至当前层的…

(pytorch-深度学习)双向循环神经网络

双向循环神经网络 一般,我们认为循环神经网络模型都是假设当前时间步是由前面的较早时间步的序列决定的,因此它们都将信息通过隐藏状态从前往后传递。 有时候,当前时间步也可能由后面时间步决定。 例如,当我们写下一个句子时&…

pytorch实现梯度下降、随机梯度下降-图像直观展示

深度学习与优化算法原理 优化函数与深度学习 在一个深度学习问题中,通常需要预先定义一个损失函数。有了损失函数以后,使用优化算法试图将其最小化。 在优化中,这样的损失函数通常被称作优化问题的目标函数(objective function…

小批量随机梯度下降

小批量随机梯度下降 在每一次迭代中,梯度下降使用整个训练数据集来计算梯度,因此它有时也被称为批量梯度下降(batch gradient descent)。 随机梯度下降在每次迭代中只随机采样一个样本来计算梯度。可以在每轮迭代中随机均匀采样…

动量法解决梯度下降的一些问题

动量法 目标函数有关自变量的梯度代表了目标函数在自变量当前位置下降最快的方向,因此,梯度下降也叫作最陡下降(steepest descent)。在每次迭代中,梯度下降根据自变量当前位置,沿着当前位置的梯度更新自变…

深度学习AdaGrad算法

AdaGrad算法 在一般的优化算法中,目标函数自变量的每一个元素在相同时间步都使用同一个学习率来自我迭代。 例如,假设目标函数为fff,自变量为一个二维向量[x1,x2]⊤[x_1, x_2]^\top[x1​,x2​]⊤,该向量中每一个元素在迭代时都使…

深度学习优化算法:RMSProp算法

RMSProp算法 在AdaGrad算法中,因为调整学习率时分母上的变量st\boldsymbol{s}_tst​一直在累加按元素平方的小批量随机梯度,所以目标函数自变量每个元素的学习率在迭代过程中一直在降低(或不变)。因此,当学习率在迭代…

深度学习优化算法-AdaDelta算法

AdaDelta算法 除了RMSProp算法以外,另一个常用优化算法AdaDelta算法也针对AdaGrad算法在迭代后期可能较难找到有用解的问题做了改进 [1]。 不一样的是,AdaDelta算法没有学习率这个超参数。 它通过使用有关自变量更新量平方的指数加权移动平均的项来替代…

深度学习优化算法-Adam算法

Adam算法 Adam算法在RMSProp算法基础上对小批量随机梯度也做了指数加权移动平均。Adam算法可以看做是RMSProp算法与动量法的结合。 算法内容 Adam算法使用了动量变量vt\boldsymbol{v}_tvt​和RMSProp算法中小批量随机梯度按元素平方的指数加权移动平均变量st\boldsymbol{s}_…