All pastes #5exuaaxywU Raw Edit

text paste

public text v1 · immutable
·published 2026-11-06 07:30 UTC
rendered paste body
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport torchimport torch.nn as nnimport torch.optim as optimfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler# ========== 全局配置 中文+随机种子 ==========plt.rcParams['font.sans-serif'] = ['SimHei']plt.rcParams['axes.unicode_minus'] = Falsetorch.manual_seed(42)np.random.seed(42)# ========== 1.读取并预处理数据 ==========df = pd.read_csv("pima-diabetes.csv")X = df.drop("Outcome", axis=1).valuesy = df["Outcome"].values.reshape(-1, 1)# 划分训练集、测试集,分层抽样保证正负样本比例X_train, X_test, y_train, y_test = train_test_split(    X, y, test_size=0.2, random_state=42, stratify=y)scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)# 转为torch张量X_train = torch.tensor(X_train, dtype=torch.float32)y_train = torch.tensor(y_train, dtype=torch.float32)X_test = torch.tensor(X_test, dtype=torch.float32)y_test = torch.tensor(y_test, dtype=torch.float32)# ========== 2.定义网络 ==========class DiabetesNet(nn.Module):    def __init__(self):        super().__init__()        self.net = nn.Sequential(            nn.Linear(8, 64),            nn.ReLU(),            nn.Linear(64, 32),            nn.ReLU(),            nn.Linear(32, 1),            nn.Sigmoid()        )    def forward(self, x):        return self.net(x)loss_fn = nn.BCELoss()lr = 0.001max_epoch = 150# ===================== 第一部分:无早停,完整训练(观察过拟合) =====================print("===== 开始无早停训练 =====")model1 = DiabetesNet()opt1 = optim.Adam(model1.parameters(), lr=lr)train_loss_no_early = []test_loss_no_early = []for epoch in range(max_epoch):    model1.train()    opt1.zero_grad()    pred_train = model1(X_train)    tr_loss = loss_fn(pred_train, y_train)    tr_loss.backward()    opt1.step()    model1.eval()    with torch.no_grad():        pred_test = model1(X_test)        te_loss = loss_fn(pred_test, y_test)    train_loss_no_early.append(tr_loss.item())    test_loss_no_early.append(te_loss.item())    if (epoch+1) % 20 == 0:        print(f"Epoch {epoch+1:3d} | Train:{tr_loss:.4f} | Test:{te_loss:.4f}")# 绘图:无早停loss曲线plt.figure(figsize=(8, 5))plt.plot(train_loss_no_early, label="Train Loss")plt.plot(test_loss_no_early, label="Test Loss")plt.xlabel("Epoch")plt.ylabel("Loss")plt.title("Training and Testing Loss Curves(无早停,出现过拟合)")plt.legend()plt.grid(alpha=0.3)plt.tight_layout()plt.savefig("loss_no_earlystop.jpg", dpi=300)plt.show()# ===================== 第二部分:带早停法训练 =====================print("\n===== 开始带早停训练 =====")model2 = DiabetesNet()opt2 = optim.Adam(model2.parameters(), lr=lr)train_loss_early = []test_loss_early = []patience = 15          # 连续15轮测试loss不下降就停止best_test_loss = float("inf")wait = 0stop_epoch = max_epoch # 记录停止轮次for epoch in range(max_epoch):    model2.train()    opt2.zero_grad()    pred_train = model2(X_train)    tr_loss = loss_fn(pred_train, y_train)    tr_loss.backward()    opt2.step()    model2.eval()    with torch.no_grad():        pred_test = model2(X_test)        te_loss = loss_fn(pred_test, y_test)    train_loss_early.append(tr_loss.item())    test_loss_early.append(te_loss.item())    # 早停判断逻辑    if te_loss < best_test_loss:        best_test_loss = te_loss        wait = 0    else:        wait += 1        if wait >= patience:            stop_epoch = epoch + 1            print(f"✅ 触发早停,Epoch={stop_epoch},最佳测试损失:{best_test_loss:.4f}")            break    if (epoch+1) % 20 == 0:        print(f"Epoch {epoch+1:3d} | Train:{tr_loss:.4f} | Test:{te_loss:.4f}")# 绘图:带早停loss曲线,标记停止点plt.figure(figsize=(8, 5))plt.plot(train_loss_early, label="Train Loss")plt.plot(test_loss_early, label="Test Loss")plt.axvline(x=stop_epoch-1, color="red", linestyle="--", label=f"早停点 Epoch={stop_epoch}")plt.xlabel("Epoch")plt.ylabel("Loss")plt.title("Training and Testing Loss Curves(加入早停法 Early Stopping)")plt.legend()plt.grid(alpha=0.3)plt.tight_layout()plt.savefig("loss_with_earlystop.jpg", dpi=300)plt.show()print("\n✅ 全部训练完成,两张图片已保存:")print("loss_no_earlystop.jpg    无早停(过拟合对照)")print("loss_with_earlystop.jpg  带早停法")