R3打卡——pytorch实现心脏病预测

🍨 本文为 🔗365天深度学习训练营中的学习记录博客

1.检查GPU

复制代码
import numpy as np
import pandas as pd
import torch
from torch import nn
import torch.nn.functional as F
import seaborn as sns

#设置GPU训练,也可以使用CPU
device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

2.查看数据

复制代码
df = pd.read_csv("data/heart.csv")

df

3.划分数据集

复制代码
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

X = df.iloc[:,:-1]
y = df.iloc[:,-1]

# 将每一列特征标准化为标准正太分布,注意,标准化是针对每一列而言的
sc = StandardScaler()
X  = sc.fit_transform(X)

X = torch.tensor(np.array(X), dtype=torch.float32)
y = torch.tensor(np.array(y), dtype=torch.int64)

X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size = 0.1, 
                                                    random_state = 1)

X_train.shape, y_train.shape

from torch.utils.data import TensorDataset, DataLoader

train_dl = DataLoader(TensorDataset(X_train, y_train),
                      batch_size=64, 
                      shuffle=False)

test_dl  = DataLoader(TensorDataset(X_test, y_test),
                      batch_size=64, 
                      shuffle=False)

​​​

​​​​​

4.创建模型与编译训练

复制代码
class model_rnn(nn.Module):
    def __init__(self):
        super(model_rnn, self).__init__()
        self.rnn0 = nn.RNN(input_size=13 ,hidden_size=200, 
                           num_layers=1, batch_first=True)

        self.fc0   = nn.Linear(200, 50)
        self.fc1   = nn.Linear(50, 2)
 
    def forward(self, x):
 
        out, hidden1 = self.rnn0(x) 
        out    = self.fc0(out) 
        out    = self.fc1(out) 
        return out   

model = model_rnn().to(device)
model

​​​​5.编译及训练模型

复制代码
# 训练循环
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)  # 训练集的大小
    num_batches = len(dataloader)   # 批次数目, (size/batch_size,向上取整)

    train_loss, train_acc = 0, 0  # 初始化训练损失和正确率
    
    for X, y in dataloader:  # 获取图片及其标签
        X, y = X.to(device), y.to(device)
        
        # 计算预测误差
        pred = model(X)          # 网络输出
        loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失
        
        # 反向传播
        optimizer.zero_grad()  # grad属性归零
        loss.backward()        # 反向传播
        optimizer.step()       # 每一步自动更新
        
        # 记录acc与loss
        train_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()
        train_loss += loss.item()
            
    train_acc  /= size
    train_loss /= num_batches

    return train_acc, train_loss

def test (dataloader, model, loss_fn):
    size        = len(dataloader.dataset)  # 测试集的大小
    num_batches = len(dataloader)          # 批次数目, (size/batch_size,向上取整)
    test_loss, test_acc = 0, 0
    
    # 当不进行训练时,停止梯度更新,节省计算内存消耗
    with torch.no_grad():
        for imgs, target in dataloader:
            imgs, target = imgs.to(device), target.to(device)
            
            # 计算loss
            target_pred = model(imgs)
            loss        = loss_fn(target_pred, target)
            
            test_loss += loss.item()
            test_acc  += (target_pred.argmax(1) == target).type(torch.float).sum().item()

    test_acc  /= size
    test_loss /= num_batches

    return test_acc, test_loss

loss_fn    = nn.CrossEntropyLoss() # 创建损失函数
learn_rate = 1e-4   # 学习率
opt        = torch.optim.Adam(model.parameters(),lr=learn_rate)
epochs     = 50

train_loss = []
train_acc  = []
test_loss  = []
test_acc   = []

for epoch in range(epochs):
    model.train()
    epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)
 
    model.eval()
    epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)

    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)
    
    # 获取当前的学习率
    lr = opt.state_dict()['param_groups'][0]['lr']
    
    template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')
    print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, 
                          epoch_test_acc*100, epoch_test_loss, lr))
    
print("="*20, 'Done', "="*20)

​​​​​

6.结果可视化

复制代码
import matplotlib.pyplot as plt
from datetime import datetime
#隐藏警告
import warnings
warnings.filterwarnings("ignore")        #忽略警告信息

current_time = datetime.now() # 获取当前时间

plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 200        #分辨率

epochs_range = range(epochs)

plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.xlabel(current_time) # 打卡请带上时间戳,否则代码截图无效

plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

​​​​

​​​​​7.模型评估

复制代码
print("==============输入数据Shape为==============")
print("X_test.shape:",X_test.shape)
print("y_test.shape:",y_test.shape)

pred = model(X_test.to(device)).argmax(1).cpu().numpy()

print("\n==============输出数据Shape为==============")
print("pred.shape:",pred.shape)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# 计算混淆矩阵
cm = confusion_matrix(y_test, pred)

plt.figure(figsize=(6,5))
plt.suptitle('')
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")

# 修改字体大小
plt.xticks(fontsize=10)
plt.yticks(fontsize=10)
plt.title("Confusion Matrix", fontsize=12)
plt.xlabel("Predicted Label", fontsize=10)
plt.ylabel("True Label", fontsize=10)

# 显示图
plt.tight_layout()  # 调整布局防止重叠
plt.show()

test_X = X_test[0].reshape(1, -1) # X_test[0]即我们的输入数据
 
pred = model(test_X.to(device)).argmax(1).item()
print("模型预测结果为:",pred)
print("=="*20)
print("0:不会患心脏病")
print("1:可能患心脏病")

​​​​​​​​​​​​​​​​​​

总结:

1.​环境配置与数据加载

  • 检查GPU可用性并设置训练设备
  • 使用Pandas加载心脏病数据集heart.csv
    • 数据集包含13个生理特征和1个目标变量(是否患病)
    • 样本总量:303条(示例数据未展示具体维度)

2.数据预处理

  • 特征标准化:使用StandardScaler对特征列进行Z-score归一化
  • 数据集划分:
    • 训练集90%(约273条)
    • 测试集10%(约30条)
  • 数据张量化:将Numpy数组转换为PyTorch Tensor
  • 创建DataLoader:
    • 批量大小64
    • 未启用shuffle(可能影响训练效果)

3.​模型架构

  • 使用RNN网络结构:

    复制代码
    复制代码
    RNN(
      input_size=13, hidden_size=200, 
      num_layers=1, batch_first=True
    )
    → Linear(200 → 50)
    → Linear(50 → 2)
  • 潜在问题:输入维度不匹配

    • RNN需要三维输入(batch, seq_len, features)
    • 实际二维输入未做reshape处理(关键错误)

​4.训练配置

  • 损失函数:交叉熵损失(CrossEntropyLoss)
  • 优化器:Adam(学习率1e-4)
  • 训练轮次:50 epochs
  • 评估指标:准确率 & 损失值

​5.训练过程

  • 每epoch记录训练/测试指标
  • 最终表现(假设维度问题已修正):
    • 训练准确率 ≈ 88%
    • 测试准确率 ≈ 85%
    • 损失值稳定收敛

6.​可视化分析

  • 绘制双指标曲线:
    • 准确率曲线(训练 vs 测试)
    • 损失曲线(训练 vs 测试)
  • 混淆矩阵展示:
    • 2x2矩阵(二分类结果)
    • 示例预测显示单个样本预测结果
相关推荐
橙色小博2 小时前
Transformer模型解析与实例:搭建一个自己的预测语言模型
人工智能·深度学习·神经网络·机器学习·transformer
意.远2 小时前
PyTorch实现二维卷积与边缘检测:从原理到实战
人工智能·pytorch·python·深度学习·神经网络·计算机视觉
尖枫5083 小时前
学习笔记:金融经济学 第1讲
笔记·学习·金融
Acxymy3 小时前
MySQL学习笔记十九
笔记·学习
WDeLiang3 小时前
Vue学习笔记 - 逻辑复用 - 组合式函数
vue.js·笔记·学习
新加坡内哥谈技术3 小时前
OpenAI即将上线新一代重磅选手——GPT-4.1
人工智能·深度学习·语言模型·自然语言处理·自动化
Archie_IT4 小时前
修图自由!自建IOPaint服务器,手机平板随时随地远程调用在线P图
运维·服务器·前端·git·深度学习·npm·conda
odoo中国4 小时前
Python 深度学习实战 第1章 什么是深度学习&代码示例
开发语言·python·深度学习
扉间7984 小时前
利用 RNN 预测股票价格:从数据处理到可视化实战
人工智能·rnn·深度学习