利用简单的全连接神经网络来预测1月28日的武汉新型冠状病毒累计确诊病例数

代码背景

这几天,由于新型冠状病毒的爆发,每天的新确诊人数都让早上起床的我感到吃惊!大家为了给社会贡献一份力量,即使在春节期间,都可以待在家里少外出。各大IT企业纷纷捐钱捐物资,为抗战一线出力!而此时待在家里的我们能做些什么呢?
由于我是学计算机科学与技术的大三学生,想在待在家的时间,利用专业知识,预测一下下一天的确诊人数。因此,就简单地写了一个基础代码,跑了一下,得到了一个结果,准确率不敢保证,毕竟数据有限hhh~

环境

Windows10
python3.7.4
pytorch1.2.0
matplotlib(忘了版本号)

建模

在这里,因变量的我选的是每天的累计确诊人数,而自变量即特征其实有很多,但是我只能获取时间特征,因此只能简单地预测一下下一天的累计确诊人数。
通过观察每天的数据,我们可以很轻松地得出这是一个非线性回归问题,而对于处理非线性问题,用神经网络再合适不过了。因为神经网络每层都可以拥有非线性的激活函数,因此可以较好地拟合非线性数据。(数据量少我就不考虑过拟合问题了)
我选取了从1月20到27号的数据作为训练集,明天的结果自动的成为测试集。建立了一个输入层,两个隐藏层,一个输出层的全连接神经网络。数据集长度为BatchSize进行训练。
全连接神经网络
在激活函数上用来tanh和relu,tanh具有较好的非线性,relu具有较稳定的梯度。

Tanh

tanh是双曲函数中的一个,tanh()为双曲正切。在数学中,双曲正切“tanh”是由双曲正弦和双曲余弦这两种基本双曲函数推导而来。
在这里插入图片描述

公式:
在这里插入图片描述

relu

线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元,是一种人工神经网络中常用的激活函数(activation function),通常指代以斜坡函数及其变种为代表的非线性函数。
在这里插入图片描述
公式:
在这里插入图片描述

损失函数

在这里,损失函数用的是L1loss,L1loss为目标值与预测值的差的绝对值的平均值,然后梯度下降反馈回去。如果不是对平均值的反馈,那效果就和batchsize==1一样,对每个x进行y的单独靠近而无法兼顾所有地x同时靠近所有的y,使得结果不稳定产生震荡而且无法有效地拟合。
在这里插入图片描述

优化器

下面是Adam优化器的伪代码:
在这里插入图片描述
关于adam优化器的详细介绍,可以参考链接:
简单认识Adam优化器

代码

import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torch.nn.functional as F
learning_rate=0.006
class virus(nn.Module):
    def __init__(self):
        super(virus,self).__init__()
        self.fc1 = nn.Sequential(nn.Linear(1,10),nn.Tanh()) 
        self.fc2 = nn.Sequential(nn.Linear(10,20),nn.ReLU()) 
        self.fc3 = nn.Sequential(nn.Linear(20,10),nn.ReLU())
        self.fc4 = nn.Sequential(nn.Linear(10,1))
    def forward(self,x):
        out = self.fc1(x)
        out = self.fc2(out)
        out = self.fc3(out)
       
        out = self.fc4(out)
        return out

if __name__=='__main__':
    plt.ion()
    plt.show()

    x=torch.tensor([[20],[21],[22],[23],[24],[25],[26],[27]]).float()
    y=torch.tensor([[217],[291],[440],[571],[830],[1287],[1975],[2744]]).float()
    
    model=virus()
    
    loss=nn.MSELoss()
    
    optimizer=torch.optim.Adam(model.parameters(),lr = learning_rate)
    num_epoch=50000
    for epoch in range(num_epoch):
        
        
        model.train()
        optimizer.zero_grad()
        result=model.forward(x)
        
        loss_value=loss(result,y)
        loss_value.backward()
        print(loss_value)
        print(loss_value.item())
        optimizer.step()
        print("epoch:{} loss:{}".format(epoch,loss_value.item()))
        if epoch % 10 == 0:
            plt.cla()
            plt.scatter(x.data.numpy(), y.data.numpy())
            # r- 是红色 lw 是线宽
          
            plt.plot(x.data.numpy(), result.data.numpy(), 'r-', lw=5)
           
            plt.text(0.5, 0, 'Loss=%.4f'%loss_value.data.numpy(), fontdict={'size':20, 'color': 'red'})
            # 间隔多久再次进行绘图
            plt.pause(0.1)

    torch.save(model.state_dict(),'epoch{}-loss{}weight.pth'.format(epoch,loss_value.item()))
    r=model.forward(torch.tensor([[28]]).float())
    print(r.item())

拟合效果

在这里插入图片描述

预测的1月28号的累计确诊病例结果

在这里插入图片描述
四舍五入后就是3447人。希望明天的确诊累积结果可以比这个值要低很多很多!

TYP
发布了7 篇原创文章 · 获赞 0 · 访问量 538

猜你喜欢

转载自blog.csdn.net/weixin_44000193/article/details/104091767
今日推荐