2021研究生数学建模D题,BP神经网络和卷积神经网络解题代码(基于pytorch)

本文介绍了使用PyTorch实现BP神经网络和卷积神经网络解决实际问题。对于第一题,通过BP神经网络预测二十个自变量的结果,选取前1800行数据训练,剩余数据作为测试集,展示训练过程及预测效果。第二题是分类问题,采用卷积神经网络处理729个变量,训练五个模型进行五种性质的分类,验证集测试显示分类精度较高。
摘要由CSDN通过智能技术生成

2021研究生数学建模D题,BP神经网络和卷积神经网络解题代码(基于pytorch)

(需要数据或者有关于代码问题请留言)

第二题

本题是利用二十个自变量对最后的结果(因变量)做预测,本题我使用BP神经网络解题。先将数据整理好,把二十个变量选出来放入新的excel表,把因变量放在最后一列。下面进行代码解析(代码博主已经跑通)

导入包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.nn as nn

读取excel数据

# ------------------1. 数据读取------------------

# 读取数据
data = pd.read_excel("a.xlsx")
# 看看数据长什么样子
print(data.head())
# 查看数据维度
print("数据维度:", data.shape
# 查看数据类型
print("数据类型:", type(data))

本文读取的使excel数据,其余类型数据也可以使用pandas库里的对应函数进行读取,读取后的数据都是dataframe类型

数据处理

# ------------------2. 数据预处理------------------

# 标签,即因变量,因变量名字是pIC50
labelss = np.array(data["pIC50"])
# 取前1800行因变量作为训练数据标签
labels=labelss[:1800,]
print('----------------lable.shape-----------')
print(labels.shape)
# 取消标签,即将标签列(因变量)删除
data = data.drop(["pIC50"], axis= 1)
# 取前1800行自变量数据作为训练数据
data_news = np.array(data)
data_new=data_news[:1800,:]
print('-----------------data.shape------------')
print(data_new.shape)

在本题中选择前1800行数据作为训练集,后174行数据作为测试集,用来测试网络实际预测效果。

定义网络

#------------------3. 定义网络------------------
input_size = data_new.shape[1]
hidden_size = 128
output_size = 1
batch_size = 16
my_nn = nn.Sequential(
    nn.Linear(input_size,hidden_size),
    nn.ReLU(),
    nn.Linear(hidden_size,hidden_size),
    nn.ReLU(),
    nn.Linear(hidden_size,hidden_size),
    nn.ReLU(),
    nn.Linear(hidden_size, hidden_size),
    nn.ReLU(),
    nn.Linear(hidden_size, hidden_size),
    nn.ReLU(),
    nn.Linear(hidden_size,output_size)
)
cost = torch.nn.MSELoss(reduction = 'mean') #损失函数
optimizer = torch.optim.Adam(my_nn.parameters(),lr=0.001) #优化器 Adam/SGD

训练网络

#------------------4. 训练集训练网络------------------
losses = []
for i in range(1000):
    batch_loss = []
    #MINI-Batch方法来进行训练 每次取16个数据
    for start in range(0,len(data_new),batch_size):
        end = start + batch_size if start + batch_size < len(data_new) else len(data_new)
        xx = torch.tensor(data_new[start:end],dtype=torch.float,requires_grad = True)
        yy = torch.tensor(labels[start:end],dtype=torch.float,requires_grad = True)
        prediction = my_nn(xx)
        prediction=prediction.squeeze(1)
        loss = cost(prediction,yy)
        optimizer.zero_grad() #每次梯度清零
        loss.backward(retain_graph=True)
        optimizer.step()#实时更新
        batch_loss.append(loss.data.numpy())
    #打印损失
    if i%100==0:
        losses.append(np.mean(batch_loss))
        print(i,np.mean(batch_loss))
torch.save(my_nn,'my_nn_3.pth')

验证集预测结果,画出预测图与实际值图

#------------------5. 验证集预测结果------------------
test_x=data_news[1801:,:]
test_x=torch.tensor(test_x,dtype=torch.float)
predx=my_nn(test_x).data.numpy()
predx=np.squeeze(predx,1)
test_y=labelss[1801:,]
loss=[]
for i in range(len(test_y)):
    lo=abs(predx[i]-test_y[i])/test_y[i]
    loss.append(lo)
print(sum(loss))
#------------------6. 画图观察预测拟合情况------------------
#画损失函数曲线
# 真实值
plt.plot(test_y,'b', label ='pIC50')
# 预测值
plt.plot(predx, 'r', label ='prediction')
plt.xticks(rotation = '60')
plt.legend()
# 图名
plt.title('Actual and Predicted Values')
plt.show()

结果预测

#-----------测试集测试结果
testdata = pd.read_excel("test.xlsx")
testdata=np.array(testdata)
testdata_x=torch.tensor(testdata,dtype=torch.float)
predx=my_nn(testdata_x).data.numpy()
print(predx.shape)
print(predx)

训练损失(我训练1000次,每过100次就输出一个损失值):

0 11.978955
100 0.7511373
200 0.35879636
300 0.2481647
400 0.22193664
500 0.16860785
600 0.16576535
700 0.13864414
800 0.17848253
900 0.14543799

可以看出训练损失较低,说明模型拟合效果不错,下面看一下实际预测效果如何。

输出图片如下,因为最后174个结果上下起伏较大,所以实际预测效果不好。预测值和实际值之间偏差较大,但是总体预测趋势是有的,预测误差为19%.ps:换一组测试集可能会实际预测效果好一点。
在这里插入图片描述

第三题

第三题是0、1分类问题,要建立五个0,1分类模型,因为要对五种性质进行分类。本题想利用尽可能多的变量对结果进行预测,本题共有729个变量,且变量直接并没有时序关系,所以我们把729个变量进行排列,既有27* 27=729 ,把729个变量变成二维数据。这样我们就可以使用卷积神经网络,用尽量少的参数提取更加多的特征。代码如下(代码博主已经跑通)

读取数据

本题的数据读取不用对原数据进行处理,因为我们选择全部变量作为网络的输入。

# ------------------1. 数据读取------------------
#下面三行是测试数据的读取
testdata=pd.read_excel('D:\\SZ\\jianmo\\1\Molecular_Descriptor.xlsx',sheet_name='test')
testdata=testdata.drop(['SMILES'],1)
testdata=np.array(testdata)
# 读取训练数据
data = pd.read_excel("D:\\SZ\\jianmo\\1\\Molecular_Descriptor.xlsx")
#读取标签数据
labelss=pd.read_excel('D:\\SZ\\jianmo\\1\\ADMET.xlsx')
# 看看数据长什么样子
print(labelss.head())
labelss=labelss.drop(['SMILES'], axis= 1)
# 查看数据维度
print("数据维度:", data.shape)
# 查看数据类型
print("数据类型:", type(data))

数据预处理

同样取前1800行数据作为训练集,后174行数据作为验证集

# ------------------2. 数据预处理------------------
# 标签
labelss=np.array(labelss)
labela=labelss[:1800,:1]
labelb=labelss[:1800,1:2]
labelc=labelss[:1800,2:3]
labeld=labelss[:1800,3:4]
labele=labelss[:1800,4:]
print('----------------lable.shape-----------')
print(labela.shape)
print(labelb.shape)
print(labelc.shape)
# 取消标签
data = data.drop(["pIC50",'SMILES'], axis= 1)
data_news = np.array(data)
data_new=data_news[:1800,:].reshape(1800,27,27)
print('-----------------data.shape------------')
print(data_new.shape)

定义网络

#------------------3. 定义网络------------------
input_size = 1
hidden_size = 16
output_size = 1
batch_size = 16
class ABC(nn.Module):
    def __init__(self):
         super(ABC, self).__init__()
         self.a=nn.Sequential(
             nn.Conv2d(1, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 1, 3),
             nn.Sigmoid()
         )
         self.b=nn.Sequential(
             nn.Conv2d(1, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 1, 3),
             nn.Sigmoid()
         )
         self.c=nn.Sequential(
             nn.Conv2d(1, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 1, 3),
             nn.Sigmoid()
         )
         self.d=nn.Sequential(
             nn.Conv2d(1, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 1, 3),
             nn.Sigmoid()
         )
         self.e=nn.Sequential(
             nn.Conv2d(1,8,3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 8, 3),
             nn.ReLU(),
             nn.Conv2d(8, 1, 3),
             nn.Sigmoid()
         )
    def forward(self, x):
        a=self.a(x)
        b = self.b(x)
        c = self.c(x)
        d = self.d(x)
        e = self.e(x)
        return a,b,c,d,e
my_nn=ABC()
my_nn.to('cuda')
cost = nn.BCELoss() #损失函数
optimizer = torch.optim.Adam(my_nn.parameters(),lr=0.001) #优化器 Adam/SGD

训练网络

#------------------4. 训练集训练网络------------------
losses = []
for i in range(50):
    batch_loss = []
    #MINI-Batch方法来进行训练 每次取16个数据
    for start in range(0,len(data_new),batch_size):
        end = start + batch_size if start + batch_size < len(data_new) else len(data_new)
        xx = torch.tensor(data_new[start:end],dtype=torch.float,requires_grad = True,device='cuda').unsqueeze(1)
        a = torch.tensor(labela[start:end],dtype=torch.float,device='cuda')
        b=torch.tensor(labelb[start:end],dtype=torch.float,device='cuda')
        c=torch.tensor(labelc[start:end],dtype=torch.float,device='cuda')
        d=torch.tensor(labeld[start:end],dtype=torch.float,device='cuda')
        e=torch.tensor(labele[start:end],dtype=torch.float,device='cuda')
        prediction =my_nn(xx)
        pa=prediction[0]
        pb=prediction[1]
        pc=prediction[2]
        pd=prediction[3]
        pe=prediction[4]
        loss = cost(pa,a)+cost(pb,b)+cost(pc,c)+cost(pd,d)+cost(pe,e)
        optimizer.zero_grad() #每次梯度清零
        loss.backward(retain_graph=True)
        optimizer.step()#实时更新
        batch_loss.append(loss.clone().detach().requires_grad_(False).cpu().numpy())
        # torch.save(my_nn,'my_nn_1.pkl')
    #打印损失
    if i%10==0:
        losses.append(np.mean(batch_loss))
        print(i,np.mean(batch_loss))
torch.save(my_nn,'test2.pth')

验证集测试

#------------------5. 验证集预测结果------------------
lo=nn.L1Loss()
lossa=[]
lossb=[]
lossc=[]
lossd=[]
losse=[]
my_nn.to('cpu')
test_xx=data_news[1801:,:]
for i in range(173):
    test_x=test_xx[i:i+1,:].reshape(1,27,27)
    # print('a',test_x.shape)
    test_x = torch.tensor(test_x, dtype=torch.float,device='cpu').unsqueeze(0)#1,1,20
    # print('b',test_x.shape)
    predx = my_nn(test_x)
    predx=torch.tensor(predx).squeeze(0).squeeze(0).squeeze(0)
    # print(predx.dtype)#5
    # print(predx)
    preda=predx[0]
    predb=predx[1]
    predc=predx[2]
    predd=predx[3]
    prede=predx[4]
    test_y = labelss[1801:, ]
    test_y=test_y[i:i+1,:]
    test_y=torch.tensor(test_y, dtype=torch.float,device='cpu').squeeze(0)
    test_ya = test_y[0]
    test_yb = test_y[1]
    test_yc = test_y[2]
    test_yd = test_y[3]
    test_ye = test_y[4]
    # print(test_ya)
    # print(preda)
    la=lo(preda,test_ya).cpu().numpy()
    lb = lo(predb, test_yb).cpu().numpy()
    lc = lo(predc, test_yc).cpu().numpy()
    ld = lo(predd, test_yd).cpu().numpy()
    le = lo(prede, test_ye).cpu().numpy()
    lossa.append(la)
    lossb.append(lb)
    lossc.append(lc)
    lossd.append(ld)
    losse.append(le)
aa=1-sum(lossa)/174
bb = 1 - sum(lossb) / 174
cc = 1 - sum(lossc) / 174
dd = 1 - sum(lossd) / 174
ee = 1 - sum(losse) / 174
print(aa,bb,cc,dd,ee)

plt.plot(lossa,'r')
# plt.plot(lossb,'g')
# plt.plot(lossc,'b')
# plt.plot(lossd,'w')
# plt.plot(losse,'y')
plt.show()

结果预测

#-------------实际预测值------------
for i in range(50):
    test_data=testdata[i:i+1,:].reshape(1,27,27)
    # print('c',test_data.shape)
    test_data = torch.tensor(test_data, dtype=torch.float,device='cpu').unsqueeze(1)#1,1,20
    # print('d',test_data.shape)
    predx = my_nn(test_data)
    predx=torch.tensor(predx).squeeze(0).squeeze(0).squeeze(0)
    print(predx.dtype)#5
    print(predx)

输出图片如下,在验证集上测试分类精度还不错,分别是87.35%,91.37%,86.78%,86.78%,82.18%
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

种树家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值