动手学深度学习(十二)——心跳信号分类预测(天池学习赛)简略


天池比赛: 零基础入门数据挖掘-心跳信号分类预测
主要介绍建模的步骤和思路(借鉴了B榜第一、第七以及各位大佬的部分内容,关于模型融合的部分将在之后的博客继续推出),采用CNN卷积神经网络对提供的一维数据进行训练。

一、认识数据

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
1.1 加载原始数据

原始数据下载:https://tianchi.aliyun.com/competition/entrance/531883/information

# 加载原始数据
df_train = pd.read_csv('./initial_data/train.csv')
df_testA = pd.read_csv('./initial_data/testA.csv')
1.2 查看原始数据相关信息
# 查看训练和测试数据的前五条
print(df_train.head())
print('\n')
print(df_testA.head())
# 检查数据是否有NAN数据
print(df_train.isna().sum(),df_testA.isna().sum())
# 确认标签的类别及数量
print(df_train['label'].value_counts())
# 查看训练数据集特征
print(df_train.describe())
# 查看数据集信息
print(df_train.info())

数据信息
在这里插入图片描述

1.3 查看心跳信号波形
# 绘制每种类别的折线图
ids = []
for id, row in df_train.groupby('label').apply(lambda x: x.iloc[2]).iterrows():
    ids.append(int(id))
    signals = list(map(float, row['heartbeat_signals'].split(',')))
    sns.lineplot(data=signals)

plt.legend(ids)
plt.show()

心跳信号波形

原始数据信息整理
  1. 主要特征数据为1维信号振幅,总长度为205。(已经归一化到0~1了)
  2. 除波形数据外无其他辅助和先验信息
  3. 波形数据为float64格式
  4. 没有缺失值,无需填充。(未采集到的数据默认为0,故无缺失数据)
  5. 非表格数据更适合用神经网络处理

二、构建pytorch数据集

import pandas as pd 
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import torch.nn as nn
import torch.utils.data as Data
import torch.optim as optim
import torch

说明:关于数据加载我的思路是:(1)原始数据->(2)提取原始数据中的训练数据和标签数据-> (3)将训练数据和对应标签放入到pytorch的Dataset重构的类中构建新的pytorch数据集->(4)最后使用pytorch的DataLoaser打乱数据集构建批次数据集方便后面训练

# 加载原始数据
class MyData(Data.Dataset):
    def __init__(self, feature, label):
        self.feature = feature # 特征
        self.label = label # 标签

    def __len__(self):
        return len(self.feature)

    def __getitem__(self, idx):
        return self.feature[idx], self.label[idx]

def load_data(batch_size):
    # 加载原始数据
    df_train = pd.read_csv('./initial_data/train.csv')
    # 拆解heartbeat_signals
    train_signals = np.array(df_train['heartbeat_signals'].apply(lambda x: np.array(list(map(float, x.split(','))),dtype=np.float32)))
    train_labels = np.array(df_train['label'].apply(lambda x:float(x)),dtype=np.float32)  
    # 构建pytorch数据类
    train_data = MyData(train_signals,train_labels)
    # 构建pytorch数据集Dataloader
    train_loader = Data.DataLoader(dataset = train_data,batch_size=batch_size,shuffle=True)
    return train_loader

三、构建神经网络

说明:
网络主要包括了两个大的部分:(1)一维卷积神经网络(2)线性全连接层。

对于一维卷积神经网络其中的一些参数我作以下说明,pytorch不太方便的一点在于你需要自己计算一下其输出的结果大小,从而设置合适的padding进行填充(网上随便就可以找到计算方法):

nn.Conv1D(in_channels=1,out_channels=32,kernel_size=11,stride=1,padding=5)
   in_channels:输入通道数,对于本波形数据就是1,对于彩色图片就是RGB这三个通道3;
   out_channels:输出通道数,根据卷积核计算得到的输出结果的特征图的数量;
   kernel_size: 一维卷积核的数量,对于conv1D卷积而言,沿着横向进行一维单方向卷积,所以卷积核的大小为(kernel_size,in_channels):
   stride:卷积步长;
   padding: 对输入的每一条边的填充。   
class model_CNN_1(nn.Module):
    def __init__(self):
        super(model_CNN_1,self).__init__()
        self.conv_unit = nn.Sequential(
            nn.BatchNorm1d(1),
            nn.Conv1d(in_channels=1,out_channels=32,kernel_size=11,stride=1,padding=5),
            nn.LeakyReLU(),
            nn.BatchNorm1d(32),
            nn.Conv1d(in_channels=32,out_channels=64,kernel_size=11,stride=1,padding=5),
            nn.LeakyReLU(),
            nn.BatchNorm1d(64),
            nn.MaxPool1d(4),
            nn.Conv1d(in_channels=64,out_channels=128,kernel_size=3,stride=1,padding=1),
            nn.LeakyReLU(),
            nn.BatchNorm1d(128),
            nn.Conv1d(in_channels=128,out_channels=256,kernel_size=3,stride=1,padding=1),
            nn.LeakyReLU(),
            nn.MaxPool1d(4),
            nn.Dropout(0.1),
        )
        self.dense_unit = nn.Sequential(
            nn.Linear(3072,1024),
            nn.LeakyReLU(),
            nn.Linear(1024,128),
            nn.LeakyReLU(),
            nn.Linear(128,4),
            nn.Softmax(dim=1)
        )
        
        
    def forward(self,inputs):
        inputs = inputs.view(inputs.size()[0],1,inputs.size()[1])
        inputs = self.conv_unit(inputs)
        inputs = inputs.view(inputs.size()[0],-1)
        inputs = self.dense_unit(inputs)
        return inputs

四、训练模型

def train_model(model,train_loader):
    model.train()
    running_loss = 0.0
    running_acc = 0.0
    for i,data in enumerate(train_loader):
        inputs,labels = data
        predictions = model(inputs)
        loss = criterion(predictions,labels.long())
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        running_loss += loss.item()*labels.size()[0]
        _,pred = torch.max(predictions,1)
        num_correct = (pred==labels).sum()
        running_acc += num_correct.item()
    return running_loss,running_acc

def loss_curve(list_loss,list_acc):
    epochs = np.arange(1,len(list_loss)+1) 
    fig,ax = plt.subplots()
    ax.plot(epochs,list_loss,label='loss')
    ax.plot(epochs,list_acc,label='accuracy')
    ax.set_xlabel('epoch')
    ax.set_ylabel('%')
    ax.set_title('loss & accuray ')
    ax.legend()
# 调用定义的加载函数进行数据加载
batch_size = 64
train_data,train_loader = load_data(batch_size)

# 定义模型、loss function 
model = model_CNN_1()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(),lr=0.0001)

# 循环20个epoch进行数据训练
list_loss,list_acc = [],[] 
for epoch in range(20):
    running_loss,running_acc=train_model(model,train_loader)
    list_loss.append(running_loss/train_data.__len__())
    list_acc.append(running_acc/train_data.__len__())
    print('Train {} epoch, Loss: {:.6f}, Acc:{:.6f}'.format(epoch+1,running_loss/train_data.__len__(),running_acc/train_data.__len__()))

# 绘图查看loss 和 accuracy曲线
loss_curve(list_loss,list_acc)

训练精度及误差:
训练精度及误差
figure of loss and accuray

五、模型测试:

由于模型测试其实是需要将结果放入到天池比赛官方才能看到的,所以我只能知道自己最后的一个分数。这个模型是为了练习CNN做的,单模型的分数也不高,有很多地方也需要优化。所以模型测试和修改部分将在后面更改完善后上传。

六、后期优化方向

  1. CNN网络优化:包括网络的层数、输出的通道数量、池化层的位置和方法等等
  2. 多模型优化和模型融合:建立多个模型进行加权投票,这样可以在一定程度上提高模型的泛化性和精度,同时降低了loss。这里模型的选择不仅仅包括CNN,LSTM等。
  3. 模型更新参数调整方法:可以采用自动学习率降低方法来动态调整学习率,减小模型过拟合的风险,同时加快训练的效率。
  • 26
    点赞
  • 209
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
天池心跳信号分类预测是基于卷积神经网络(Convolutional Neural Network,CNN)的一个任务。CNN是一种专门用于处理具有网格状拓扑结构数据的深度学习算法,常用于图像识别和处理方面。 对于天池心跳信号分类预测任务,首先需要准备好心跳信号的数据集,包括心电图信号的采集数据以及对应的标签。然后,可以使用CNN模型对这些心跳信号进行分类预测CNN模型的主要思想是通过多层卷积和池化操作来提取信号的特征,并利用这些特征进行分类预测。具体而言,CNN模型由输入层、卷积层、池化层、全连接层和输出层组成。首先,输入层接收心跳信号数据,然后通过卷积层提取信号的局部特征,并通过池化层对特征进行降维。接下来,通过全连接层将数据进行分类,最后在输出层得到分类预测结果。 在训练CNN模型时,通常采用反向传播算法来更新模型的参数,通过最小化损失函数来优化模型的分类效果。训练过程中,可以采用一部分数据用于训练,另一部分数据用于验证模型的泛化能力。 总之,天池心跳信号分类预测使用CNN模型进行信号特征提取和分类预测,通过卷积、池化和全连接等操作,充分利用心跳信号的局部特征进行分类判断,从而实现对心跳信号的准确分类预测。这有助于医领域对心脏疾病等相关问题的研究和诊断。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

留小星

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

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

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

打赏作者

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

抵扣说明:

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

余额充值