day37打卡

news2025/5/30 16:22:07

知识点回顾:@浙大疏锦行

  1. 过拟合的判断:测试集和训练集同步打印指标
  2. 模型的保存和加载
    1. 仅保存权重
    2. 保存权重和模型
    3. 保存全部信息checkpoint,还包含训练状态
  3. 早停策略

作业:对信贷数据集训练后保存权重,加载权重后继续训练50轮,并采取早停策略

import numpy as np
import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from tqdm import tqdm
import matplotlib.pyplot as plt
import warnings
from sklearn.metrics import classification_report

warnings.filterwarnings("ignore")

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 设置GPU设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"使用设备: {device}")

# 数据预处理
data = pd.read_csv(r'data.csv')
data = data.drop(['Id'], axis=1)

# 标签编码
home_ownership_mapping = {
    'Own Home': 1,
    'Rent': 2,
    'Have Mortgage': 3,
    'Home Mortgage': 4
}
data['Home Ownership'] = data['Home Ownership'].map(home_ownership_mapping)

years_in_job_mapping = {
    '< 1 year': 1,
    '1 year': 2,
    '2 years': 3,
    '3 years': 4,
    '4 years': 5,
    '5 years': 6,
    '6 years': 7,
    '7 years': 8,
    '8 years': 9,
    '9 years': 10,
    '10+ years': 11
}
data['Years in current job'] = data['Years in current job'].map(years_in_job_mapping)

# 独热编码
data = pd.get_dummies(data, columns=['Purpose'])

# Term列映射与重命名
term_mapping = {
    'Short Term': 0,
    'Long Term': 1
}
data['Term'] = data['Term'].map(term_mapping)

# 列名验证
original_columns = data.columns.tolist()
data.rename(columns={'Term': 'Long Term'}, inplace=True)
new_columns = data.columns.tolist()

if 'Long Term' not in new_columns:
    print(f"警告:列名重命名失败!原始列名: {original_columns}")
    if 'Term' in new_columns:
        print("使用原始列名'Term'继续处理...")
    else:
        raise KeyError("无法找到'Term'或'Long Term'列!")

# 重新生成连续特征列表并验证
continuous_features = data.select_dtypes(include=['int64', 'float64']).columns.tolist()
print(f"连续特征列表: {continuous_features}")

# 缺失值处理
for feature in continuous_features:
    if feature not in data.columns:
        print(f"警告:列 '{feature}' 不存在,跳过该列!")
        continue
        
    if data[feature].isnull().sum() > 0:
        if data[feature].dtype in [np.float64, np.int64]:
            fill_value = data[feature].median()
        else:
            fill_value = data[feature].mode()[0]
            
        data[feature].fillna(fill_value, inplace=True)
        print(f"已填充 {feature} 列的 {data[feature].isnull().sum()} 个缺失值,填充值: {fill_value}")

# 划分训练集和测试集
X = data.drop(['Credit Default'], axis=1)
y = data['Credit Default']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 归一化数据
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 转换为PyTorch张量并移至GPU
X_train = torch.FloatTensor(X_train).to(device)
y_train = torch.LongTensor(y_train.values).to(device)
X_test = torch.FloatTensor(X_test).to(device)
y_test = torch.LongTensor(y_test.values).to(device)

# 定义MLP模型
class MLP(nn.Module):
    def __init__(self, input_size):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(input_size, 10)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(10, 2)

    def forward(self, x):
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        return out

# 实例化模型
input_size = X_train.shape[1]
model = MLP(input_size).to(device)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
def train_model(model, optimizer, num_epochs, save_path, is_continue=False):
    best_test_loss = float('inf')
    best_epoch = 0
    patience = 50
    counter = 0
    early_stopped = False
    train_losses = []
    test_losses = []
    epochs = []
    
    start_time = time.time()
    
    if is_continue:
        total_epochs = num_epochs
        print(f"继续训练 {num_epochs} 轮")
    else:
        total_epochs = num_epochs
        print(f"开始初始训练 {num_epochs} 轮")
    
    with tqdm(total=total_epochs, desc="训练进度", unit="epoch") as pbar:
        for epoch in range(total_epochs):
            # 前向传播
            model.train()
            outputs = model(X_train)
            loss = criterion(outputs, y_train)
            
            # 反向传播和优化
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            
            # 记录损失值并更新进度条
            if (epoch + 1) % 200 == 0:
                model.eval()
                with torch.no_grad():
                    test_outputs = model(X_test)
                    test_loss = criterion(test_outputs, y_test)
                model.train()
                
                train_losses.append(loss.item())
                test_losses.append(test_loss.item())
                epochs.append(epoch + 1)
                
                # 调试输出:打印当前损失值
                print(f"Epoch {epoch+1}, Train Loss: {loss.item():.4f}, Test Loss: {test_loss.item():.4f}")
                
                pbar.set_postfix({'Loss': f'{loss.item():.4f}'})
                
                # 早停逻辑
                if test_loss.item() < best_test_loss:
                    best_test_loss = test_loss.item()
                    best_epoch = epoch + 1
                    counter = 0
                    torch.save(model.state_dict(), save_path)
                else:
                    counter += 1
                    if counter >= patience:
                        print(f"早停触发!在第{epoch+1}轮,测试集损失已有{patience}轮未改善。")
                        print(f"最佳测试集损失出现在第{best_epoch}轮,损失值为{best_test_loss:.4f}")
                        early_stopped = True
                        break
            
            # 更新进度条
            pbar.update(1)
    
    time_all = time.time() - start_time
    print(f'Training time: {time_all:.2f} seconds')
    
    # 调试输出:打印损失列表
    print(f"训练完成后,记录了 {len(epochs)} 个损失值")
    if epochs:
        print(f"Epochs范围: {min(epochs)} 到 {max(epochs)}")
        print(f"训练损失范围: {min(train_losses):.4f} 到 {max(train_losses):.4f}")
        print(f"测试损失范围: {min(test_losses):.4f} 到 {max(test_losses):.4f}")
    
    return model, best_test_loss, best_epoch, early_stopped, train_losses, test_losses, epochs

# 第一阶段训练
initial_save_path = 'initial_model.pth'
model, best_test_loss, best_epoch, early_stopped, train_losses1, test_losses1, epochs1 = train_model(
    model, optimizer, num_epochs=20000, save_path=initial_save_path
)

# 可视化第一阶段损失曲线
plt.figure(figsize=(10, 6))
plt.plot(epochs1, train_losses1, label='初始训练 - 训练损失')
plt.plot(epochs1, test_losses1, label='初始训练 - 测试损失')

# 设置坐标轴范围
if epochs1:  # 确保有数据
    plt.xlim(min(epochs1), max(epochs1))
    all_losses = train_losses1 + test_losses1
    plt.ylim(min(all_losses) * 0.9, max(all_losses) * 1.1)

plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('初始训练阶段的损失曲线')
plt.legend()
plt.grid(True)
plt.show()

# 评估初始训练模型
model.eval()
with torch.no_grad():
    outputs = model(X_test)
    _, predicted = torch.max(outputs, 1)
    correct = (predicted == y_test).sum().item()
    accuracy = correct / y_test.size(0)
    print(f'初始训练后的测试集准确率: {accuracy * 100:.2f}%')
    print(classification_report(y_test.cpu().numpy(), predicted.cpu().numpy(), target_names=['未违约', '违约']))

# 第二阶段训练:加载权重并继续训练50轮
print("\n===== 开始第二阶段训练:加载权重并继续训练50轮 =====")

# 重新实例化模型
continued_model = MLP(input_size).to(device)
continued_model.load_state_dict(torch.load(initial_save_path))

# 定义新的优化器
continued_optimizer = optim.SGD(continued_model.parameters(), lr=0.001)

# 继续训练50轮
continued_save_path = 'continued_model.pth'
continued_model, best_test_loss2, best_epoch2, early_stopped2, train_losses2, test_losses2, epochs2 = train_model(
    continued_model, continued_optimizer, num_epochs=50, save_path=continued_save_path, is_continue=True
)

# 可视化第二阶段损失曲线
plt.figure(figsize=(10, 6))
plt.plot(epochs2, train_losses2, label='继续训练 - 训练损失')
plt.plot(epochs2, test_losses2, label='继续训练 - 测试损失')

# 设置坐标轴范围
if epochs2:  # 确保有数据
    plt.xlim(min(epochs2), max(epochs2))
    all_losses2 = train_losses2 + test_losses2
    plt.ylim(min(all_losses2) * 0.9, max(all_losses2) * 1.1)

# 添加调试输出
print(f"绘图数据 - Epochs: {epochs2}")
print(f"绘图数据 - 训练损失: {[round(loss, 4) for loss in train_losses2]}")
print(f"绘图数据 - 测试损失: {[round(loss, 4) for loss in test_losses2]}")

plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('继续训练阶段的损失曲线')
plt.legend()
plt.grid(True)
plt.show()

# 评估继续训练后的模型
continued_model.eval()
with torch.no_grad():
    outputs = continued_model(X_test)
    _, predicted = torch.max(outputs, 1)
    correct = (predicted == y_test).sum().item()
    accuracy = correct / y_test.size(0)
    print(f'继续训练后的测试集准确率: {accuracy * 100:.2f}%')
    print(classification_report(y_test.cpu().numpy(), predicted.cpu().numpy(), target_names=['未违约', '违约']))


Training time: 0.19 seconds
训练完成后,记录了 0 个损失值
绘图数据 - Epochs: []
绘图数据 - 训练损失: []
绘图数据 - 测试损失: []

继续训练后的测试集准确率: 76.73%
              precision    recall  f1-score   support

         未违约       0.75      0.99      0.86      1059
          违约       0.93      0.22      0.36       441

    accuracy                           0.77      1500
   macro avg       0.84      0.61      0.61      1500
weighted avg       0.81      0.77      0.71      1500

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2386696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式缓存:证明分布式系统的 CAP 理论

文章目录 Pre一、分布式系统背景与特点二、CAP 三要素详解三、CAP 定理的反证证明四、CP 架构与 AP 架构对比典型场景 五、CAP 理论在系统设计中的应用六、总结 Pre 分布式缓存&#xff1a;CAP 理论在实践中的误区与思考 分布式缓存&#xff1a;BASE理论实践指南 分布式 - 从…

软件设计师“面向对象设计”真题考点分析——求三连

一、考点分值占比与趋势分析 综合知识历年考察统计 年份考题数分值占比考察重点2018334%继承类型、设计原则2019445.3%多态实现、类关系2020556.7%设计模式应用、接口隔离2021334%消息通信、封装特性2022668%开闭原则、组合模式2023556.7%模板方法、适配器模式2024445.3%单一…

AI大模型学习二十八、ACE-Step:生成式AI音乐大模型简介与安装(一)

一、说明 先来一首创作的歌&#xff1a; 在大模型和生成式AI模型大规模发达的今天&#xff0c;利用大模型生成音乐也是其中一个重要的发展方向。今天我们就介绍一个这样的音乐生成模型ACE-Step&#xff0c;可基于关键字和歌词生成歌曲&#xff1b;基于歌曲生成伴奏等等功能。 …

接口性能测试-工具JMeter的学习

接口登录链接http://111.230.19.204:8080/blog_login.html 一、JMeter基本使用流程 1、启动Jmeter 2、在“测试计划”下添加线程组 3、在“线程组”下添加“HTTP”取样器 4、填写“HTTP请求”的相关请求数据 5、在“线程组”下添加“查看结果树”监听器 6、点击“启动”按钮…

python如何离线安装pandas,numpy

1.首先在有网的电脑上正常安装python&#xff08;和离线环境一样的版本&#xff09; 然后 pip install pandas &#xff08;不嫌麻烦的话也可以自己手动去pandas PyPI​​​​​​​ 一个个下载&#xff09; 安装好后导出相关包&#xff0c;使用如下指令 2.然后相关依赖包就…

Java Swing 自定义JOptionPane

运行后的样式 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class demoB {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame jf new JFrameDemo();jf.se…

【图像大模型】Stable Diffusion XL:下一代文本到图像生成模型的技术突破与实践指南

Stable Diffusion XL&#xff1a;下一代文本到图像生成模型的技术突破与实践指南 一、架构设计与技术演进1.1 核心架构革新1.2 关键技术突破1.2.1 双文本编码器融合1.2.2 动态扩散调度 二、系统架构解析2.1 完整生成流程2.2 性能指标对比 三、实战部署指南3.1 环境配置3.2 基础…

C 语言指针之手写内存深度剖析与手写库函数:带你从0开始手撸库 附录1.5 万字实战笔记

一、指针入门&#xff1a;从野指针到空指针 1.1 野指针的第一次暴击&#xff1a;沃日 哪里来的Segmentation Fault &#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 刚学指针时写过一段让我及其楠甭的代码,我x了xx的&#xff0c;最后才发现是为…

C#高级:Winform桌面开发中CheckedListBox的详解

一、基础设置 单击触发选择效果&#xff1a;需要选择下面这个为True 二、代码实现 1.设置数据源 /// <summary> /// 为CheckBoxList设置数据源 /// </summary> /// <param name"checkedListBox1"></param> /// <param name"data&…

AI学习笔记二十八:使用ESP32 CAM和YOLOV5实现目标检测

若该文为原创文章&#xff0c;转载请注明原文出处。 最近在研究使用APP如何显示ESP32 CAM的摄像头数据&#xff0c;看到有人实现把ESP32 CAM的数据流上传&#xff0c;通过YOLOV5来检测&#xff0c;实现拉流推理&#xff0c;这里复现一下。 一、环境 arduino配置esp32-cam开发环…

免费分享50本web全栈学习电子书

最近搞到一套非常不错的 Web 全栈电子书合集&#xff0c;整整 50 本&#xff0c;都是epub电子书格式&#xff0c;相当赞&#xff01;作为一个被期末大作业和项目 ddl 追着跑的大学生&#xff0c;这套书真的救我狗命&#xff01; 刚接触 Web 开发的时候&#xff0c;我天天对着空…

【prometheus+Grafana篇】基于Prometheus+Grafana实现MySQL数据库的监控与可视化

&#x1f4ab;《博主主页》&#xff1a; &#x1f50e; CSDN主页 &#x1f50e; IF Club社区主页 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(MongoDB)有了…

全链路解析:影刀RPA+Coze API自动化工作流实战指南

在数字化转型加速的今天&#xff0c;如何通过RPA与API的深度融合实现业务自动化提效&#xff0c;已成为企业降本增效的核心命题。本文以「影刀RPA」与「Coze API」的深度协作为例&#xff0c;系统性拆解从授权配置、数据交互到批量执行的完整技术链路&#xff0c;助你快速掌握跨…

高阶数据结构——哈希表的实现

目录 1.概念引入 2.哈希的概念&#xff1a; 2.1 什么叫映射&#xff1f; 2.2 直接定址法 2.3 哈希冲突&#xff08;哈希碰撞&#xff09; 2.4 负载因子 2.5 哈希函数 2.5.1 除法散列法&#xff08;除留余数法&#xff09; 2.5.2 乘法散列法&#xff08;了解&#xff09…

2025 年网络安全趋势报告

一、引言 自欧洲信息安全协会&#xff08;Infosecurity Europe&#xff09;首次举办活动的 30 年来&#xff0c;网络安全格局发生了翻天覆地的变化。如今&#xff0c;网络安全领导者必须应对众多威胁&#xff0c;维持法规合规性&#xff0c;并与董事会成员合作推进组织的网络安…

uniapp 条件筛选

v3 版本 <template><view class"store flex "><view class"store_view"><view class"store_view_search flex jsb ac"><!-- <view class"store_view_search_select">全部</view> --><v…

pytorch问题汇总

conda环境下 通过torch官网首页 pip安装 成功运行 后面通过conda安装了别的包 似乎因为什么版本问题 就不能用了 packages\torch_init_.py", line 245, in _load_dll_libraries raise err OSError: [WinError 127] 找不到指定的程序。 Error loading ackages\torch\lib\c…

开发过的一个Coding项目

一、文档资料、人员培训&#xff1a; 1、文档资料管理&#xff1a;这个可以使用OnLineHelpDesk。 2、人员培训&#xff1a;可以参考Is an Online Medical Billing and Coding Program Right for You - MedicalBillingandCoding.org。 3、人员招聘、考核&#xff1a;可以在Onli…

数据仓库维度建模详细过程

数据仓库的维度建模&#xff08;Dimensional Modeling&#xff09;是一种以业务用户理解为核心的设计方法&#xff0c;通过维度表和事实表组织数据&#xff0c;支持高效查询和分析。其核心目标是简化复杂业务逻辑&#xff0c;提升查询性能。以下是维度建模的详细过程&#xff1…

python打卡day37

早停策略和模型权重保存 知识点回顾&#xff1a; 过拟合的判断&#xff1a;测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint&#xff0c;还包含训练状态 早停策略 是否过拟合&#xff0c;可以通过同步打印训练集和测试集的loss曲线…