🖋️【深度学习原理与PyTorch实战】实验二:使用神经网络预测共享单车的使用量
00 分钟
2023-5-13
2023-9-1
type
status
date
slug
summary
tags
category
icon
password
Last edited time
Sep 1, 2023 04:40 AM
Created time
May 24, 2023 07:13 AM
本文介绍了使用神经网络预测共享单车使用量的实验,包括手动编写用Tensor运算的人工神经网络和调用PyTorch现成的函数构建序列化的神经网络,以及数据的分批次处理和测试网络。通过数据的可视化,我们可以观察到两个曲线基本是吻合的,但是在 12 月 25 日附近几天实际值和预测值偏差较大,可能是因为圣诞节前后人们的出行习惯与往日有很大的不同,而训练样本中包含圣诞节前后的样本仅仅有一次,导致没办法对这一特殊假期的模式进行很好地预测。

实验介绍

实验内容

本次实验中,我们将设计我们的第一个有实用价值的人工神经网络,并用它来预测未来某地区的租赁单车的使用情况。

实验知识点

  • 数据归一化、类型变量的转换
  • 搭建基本神经网络的方法
  • 数据分批次训练原则
  • 测试及简单分析神经网络的方法

实验环境

  • Jupyter Notebook
  • Python 3.7
  • PyTorch 1.4.0

预处理实验数据

读取数据

共享单车公司,根据过去两年的单车使用数据训练一个模型,用于预测单车在未来的使用量。
先观察一下这两年间共享单车使用情况的数据。
示例代码:
记录共享单车使用情况的数据都在文件“hour.csv”中,该文件大小为 1.2M,完全可以直接读取到内存中。
下面读取这个文件,并运用 pandas 模块的 head 方法,将数据的数据表头和部分数据项打印出来。
示例代码:
可以观察到,数据文件记录了每小时(hr)共享单车的使用数量(cnt),
除了这两个数据项外,还包括当天的日期(dteday),季节(season),星期几(weekday),是否是假期(holiday),
当天的温度、湿度、风速、用户是否注册等等,我们就是要使用这些数据训练神经网络模型。

对于类型变量的处理

数据文件中的数据往往不能直接用来训练神经网络模型。
因为这些数据具有不同的数据类型,不同的取值范围。
数据用于神经网络模型中之前,需要对这些数据进行一系列的预处理。
首先是类型变量。类型变量是指这个变量的不同值仅仅表达不同的类型,值的大小不同但没有高低之分。
有很多变量都属于类型变量,例如season=1,2,3,4代表四季。不能将season变量直接输入到神经网络,这是因为season数值越高并不表示相应的信号强度越大。
解决方案是将类型变量用一个“一位热码”(one-hot)来编码,也就是:
  • season=1 ⇒(1,0,0,0)
  • season=2 ⇒(0,1,0,0)
  • season=3 ⇒(0,0,1,0)
  • season=4 ⇒(0,0,0,1)
因此,如果一个类型变量有n个不同取值,那么one-hot所对应的向量长度就为n。
示例代码:

对于数值类型变量进行标准化

由于每个数值型变量都是相互独立的,所以它们的数值绝对大小与问题本身没有关系。
为了消除数值大小的差异,我们对每个数值型变量进行标准化处理,也就是让其数值都围绕着0左右波动。
比如,对于温度temp这个变量来说,它在整个数据库的平均值为mean(temp),方差为std(temp),所以,归一化的温度计算为:
这样做的好处就是可以将不同的取值范围的变量设置为让它们处于一个平等的地位。
示例代码:

将数据集进行分割

预处理做完以后,我们的数据集包含17379条记录,59个变量。
首先,在变量集合上,我们分为特征和目标两个集合。
其中,特征变量集包括:年份(yr),是否节假日(holiday),温度(temp),湿度(hum),风速(windspeed),季节1~4(season),天气1~4(weathersit,不同天气类型),月份1~12(mnth),小时0~23(hr),星期0~6(weekday),它们是输入给神经网络的变量;
目标变量包括:用户数(cnt),临时用户数(casual),以及注册用户数(registered),其中我们仅仅将cnt作为我们的目标变量,另外两个暂时不做任何处理。
这样我们就将利用56个特征变量作为神经网络的输入,来预测1个变量作为神经网络的输出。
接下来,我们再将17379条记录划分为两个集合,分别为前16875条记录作为训练集训练我们的神经网络;后21天的数据,也就是21x24=504条记录作为测试集来检验我们的模型的预测效果。
示例代码:

构建神经网络模型

手动编写用Tensor运算的人工神经网络

构建神经网络,这里的网络有三层:输入、隐含和输出层。每层的尺寸(神经元个数)分别是56、10和1。其中,输入输出层的神经元个数分别有数据决定,隐含神经元个数则是根据我们对数据复杂度的预估决定的
通常,数据越复杂、数据量越大,我们就需要越多的神经元。但是神经元过多很容易造成过拟合。
示例代码:

调用PyTorch现成的函数,构建序列化的神经网络

示例代码:
在这段代码里,我调用torch.nn.Sequential来构造神经网络,并将构造好的神经网络存放到neu中。
torch.nn.Sequential这个函数的作用是将一系列的运算模块按照顺序搭建成一个多层的神经网络。
这个例子中,这些模块包括输入到隐含层的线性映射Linear(input_size,hidden_size),隐含层的非线性Sigmoid函数torch.nn.Sigmoid(),以及从隐含到输出的线性映射torch.nn.Linear(hidden_size,output_size)。
值得注意的是,Sequential里面的层次并不与神经网络的层次严格对应,而是指多步的运算,它与动态计算图的层次相对应。
这里torch.nn.MSELoss()是PyTorch自带的一个封装好的计算均方差的损失函数,它是一个函数指针,赋予变量cost。在计算的时候我们只需要调用cost(x,y)就可以计算预测向量x和目标向量y之间的均方误差。
PyTorch也自带优化器来自动实现优化算法:optimizer=torch.optim.SGD(neu.parameters(),lr=0.01),这里torch.nn.SGD调用PyTorch自带随机梯度下降算法(Stochastic Gradien Descent,SGD)作为优化器。
在初设化optimizer的时候,我们需要将待优化的所有参数(在本例中就是传入的参数包括神经网络neu包含的所有权重和偏度(即neu.parameters()),以及执行梯度下降算法的学习率lr=0.01。

数据的分批次处理

在大数据量的情况下如果还是在每个训练周期处理所有的数据,那么可能会出现,运算速度过慢,迭代可能不收敛的问题。
人们通常采用的解决方法是批处理(batch processing)的模式,也就是将所有的数据记录划分成一个批次大学(batch size)的小数据集,然后每个训练周期喂给神经网络一批数据。
示例代码:
示例代码:
在上段代码绘制出的图中,横坐标表示训练周期,纵坐标表示平均误差。
可以看到,平均误差快速地随训练周期而下降。

测试网络

使用测试数据集测试网络

示例代码:

预测结果分析

在上一步的代码绘制的图中,横坐标是不同的日期,纵坐标是预测或真实数据的值。
通过数据的可视化,我们可以观察到两个曲线基本是吻合的,但是在 12 月 25 日附近几天实际值和预测值偏差较大。为什么这段时间表现这么差呢?
仔细观察数据,我们知道 12 月 25 日正好是圣诞节。对于欧美国家来说,圣诞节就相当于是我们的春节,而从圣诞节之后的一周直到元旦都是假期。因此,在圣诞节的前后人们的出行习惯肯定会与往日有很大的不同。但是,在我们的训练样本中,因为整个数据仅仅有两年的长度,所以包含圣诞节前后的样本仅仅有一次,这就导致我们没办法对这一特殊假期的模式进行很好地预测。
👌🏼
若您有更好的见解,请您在评论区评论!

评论