当前位置: 首页 > news >正文

深度学习每周学习总结R5(LSTM-实现糖尿病探索与预测-模型优化)

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客R7中的内容,为了便于自己整理总结起名为R5
  • 🍖 原作者:K同学啊 | 接辅导、项目定制

目录

      • 0. 总结
        • 优化细节(目前只采用了1、2两种方式)
          • 1. L2 正则化(权重衰减)
          • 2. Dropout
          • 3. Early Stopping(早停)
          • 4. Batch Normalization
          • 总结
          • 其他可行的方法(待测试)
      • 1. LSTM介绍
        • LSTM的基本组成部分
        • 如何理解与应用LSTM
      • 2. 数据预处理
      • 3. 数据集构建
      • 4. 定义模型
      • 5. 初始化模型及优化器
      • 6. 训练函数
      • 7. 测试函数
      • 8. 训练过程
      • 9. 模型评估

0. 总结

数据导入及处理部分:在 PyTorch 中,我们通常先将 NumPy 数组转换为 torch.Tensor,再封装到 TensorDataset 或自定义的 Dataset 里,然后用 DataLoader 按批次加载。

模型构建部分:LSTM

设置超参数:在这之前需要定义损失函数,学习率(动态学习率),以及根据学习率定义优化器(例如SGD随机梯度下降),用来在训练中更新参数,最小化损失函数。

定义训练函数:函数的传入的参数有四个,分别是设置好的DataLoader(),定义好的模型,损失函数,优化器。函数内部初始化损失准确率为0,接着开始循环,使用DataLoader()获取一个批次的数据,对这个批次的数据带入模型得到预测值,然后使用损失函数计算得到损失值。接下来就是进行反向传播以及使用优化器优化参数,梯度清零放在反向传播之前或者是使用优化器优化之后都是可以的,一般是默认放在反向传播之前。

定义测试函数:函数传入的参数相比训练函数少了优化器,只需传入设置好的DataLoader(),定义好的模型,损失函数。此外除了处理批次数据时无需再设置梯度清零、返向传播以及优化器优化参数,其余部分均和训练函数保持一致。

训练过程:定义训练次数,有几次就使用整个数据集进行几次训练,初始化四个空list分别存储每次训练及测试的准确率及损失。使用model.train()开启训练模式,调用训练函数得到准确率及损失。使用model.eval()将模型设置为评估模式,调用测试函数得到准确率及损失。接着就是将得到的训练及测试的准确率及损失存储到相应list中并合并打印出来,得到每一次整体训练后的准确率及损失。

结果可视化

模型的保存,调取及使用。在PyTorch中,通常使用 torch.save(model.state_dict(), ‘model.pth’) 保存模型的参数,使用 model.load_state_dict(torch.load(‘model.pth’)) 加载参数。

需要改进优化的地方:确保模型和数据的一致性,都存到GPU或者CPU;注意numclasses不要直接用默认的1000,需要根据实际数据集改进;实例化模型也要注意numclasses这个参数;此外注意测试模型需要用(3,224,224)3表示通道数,这和tensorflow定义的顺序是不用的(224,224,3),做代码转换时需要注意。

关于优化:

目前的尝试: 采用了L2正则化及dropout 测试集准确率目前可以达到 78%

优化细节(目前只采用了1、2两种方式)
1. L2 正则化(权重衰减)

Adam 优化器中添加 weight_decay 参数,这相当于在损失函数中添加了L2正则化项。L2正则化有助于限制模型的权重过大,从而减少过拟合。

你只需要在优化器的定义中添加 weight_decay 参数:

optimizer = torch.optim.Adam(model.parameters(), lr=learn_rate, weight_decay=1e-4)

其中 1e-4 是L2正则化的强度,你可以根据需要调整这个值。一般来说,较小的值(如1e-5到1e-4)就可以起到一定的正则化作用。

2. Dropout

Dropout 是一种非常有效的正则化技术,通过随机丢弃神经网络中的一部分神经元,减少模型的复杂度。你可以在LSTM层和全连接层之间加入 Dropout 层。

在你的 model_lstm 类中,可以在每个LSTM层后加入 Dropout 层。例如,在forward函数中插入Dropout操作:

class model_lstm(nn.Module):def __init__(self):super(model_lstm, self).__init__()self.lstm0 = nn.LSTM(input_size=13, hidden_size=200, num_layers=1, batch_first=True)self.lstm1 = nn.LSTM(input_size=200, hidden_size=200, num_layers=1, batch_first=True)self.dropout = nn.Dropout(0.5)  # 设置Dropout比率为0.5self.fc0 = nn.Linear(200, 2)def forward(self, x):out, hidden1 = self.lstm0(x)out, _ = self.lstm1(out, hidden1)out = self.dropout(out)  # 在LSTM后加Dropoutout = self.fc0(out)return out

这里,0.5 表示每次训练时会随机丢弃50%的神经元。你可以调整这个比例,通常0.3到0.5是常见的选择。

3. Early Stopping(早停)

你可以在训练过程中监控验证集准确率,若验证集的准确率在若干个epoch内没有提升,可以提前停止训练。这可以避免模型在训练集上过拟合,减少不必要的训练。

# 假设best_acc为最优验证集准确率,patience为耐心值,即允许多少个epoch验证集准确率不提升
patience = 5
trigger_times = 0
best_acc = 0.0for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)# 如果验证集准确率没有提升,增加trigger_timesif epoch_test_acc > best_acc:best_acc = epoch_test_acctrigger_times = 0else:trigger_times += 1if trigger_times >= patience:print(f"Early stopping at epoch {epoch + 1}")break
4. Batch Normalization

BatchNormalization 是另一种正则化技术,通过对每一层的输出进行标准化来加速训练并减少过拟合。对于LSTM等循环神经网络模型,BatchNormalization的使用可能不是很直接,通常建议在全连接层或卷积层后使用。如果要在LSTM中使用,可以尝试在LSTM之后添加BatchNormalization层:

class model_lstm(nn.Module):def __init__(self):super(model_lstm, self).__init__()self.lstm0 = nn.LSTM(input_size=13, hidden_size=200, num_layers=1, batch_first=True)self.lstm1 = nn.LSTM(input_size=200, hidden_size=200, num_layers=1, batch_first=True)self.bn = nn.BatchNorm1d(200)  # BatchNorm层self.fc0 = nn.Linear(200, 2)def forward(self, x):out, hidden1 = self.lstm0(x)out, _ = self.lstm1(out, hidden1)out = self.bn(out[:, -1, :])  # 对LSTM的输出进行Batch Normalizationout = self.fc0(out)return out
总结

你可以根据需求选择一种或多种正则化方法:

  • 在优化器中添加L2正则化(weight_decay)。
  • 在LSTM后加入Dropout层。
  • 采用Early Stopping技术来避免过拟合。
  • 如果适用的话,考虑Batch Normalization。

你可以根据实验结果逐步调整这些方法,看看哪种最适合你的数据和任务。

其他可行的方法(待测试)

进一步调整学习率
网络机构调整
增加训练集数据等

1. LSTM介绍

LSTM(Long Short-Term Memory)是一种特殊类型的循环神经网络(RNN),主要用于处理和预测基于时间序列的数据。它解决了传统RNN在处理长时间依赖问题时的局限性,比如“梯度消失”问题。

LSTM的基本组成部分

LSTM通过“记忆单元”来决定哪些信息需要记住,哪些需要遗忘。它的核心是一个“门控”机制,主要有三个“门”:

  1. 遗忘门(Forget Gate):决定上一时刻的状态需要遗忘多少。
  2. 输入门(Input Gate):决定当前输入信息中有多少被存储到“记忆单元”。
  3. 输出门(Output Gate):决定“记忆单元”中的信息有多少会传递到下一时刻的状态。
如何理解与应用LSTM
  1. 理解LSTM的优势:LSTM能捕捉长时间序列中的依赖关系,适合处理那些长序列的数据,如文本、语音、金融数据等。相比于传统的RNN,LSTM能够有效解决“梯度消失”问题,使得模型能够学习长期的依赖关系。

  2. 应用场景:LSTM广泛应用于自然语言处理(如文本生成、机器翻译、情感分析)、语音识别、时间序列预测(如股市预测)等领域。

  3. 如何使用LSTM:在初学者阶段,可以从以下几个步骤入手:

    • 数据预处理:将数据转换成适合时间序列建模的格式,比如文本序列或连续的时间戳数据。
    • 选择框架:使用像TensorFlow或PyTorch这样的深度学习框架来实现LSTM。你可以从简单的LSTM网络开始,逐渐增加网络复杂性。
    • 调试与优化:调整LSTM的超参数(如隐藏单元数、学习率、批量大小等)来提升模型性能。

你可以从一个简单的文本生成模型或者时间序列预测模型开始,逐步理解LSTM的细节和优势。

import torch.nn as nn
import torch.nn.functional as F
import torchvision,torchimport numpy             as np
import pandas            as pd
import seaborn           as sns
from sklearn.model_selection   import train_test_split
import matplotlib.pyplot as pltplt.rcParams['savefig.dpi'] = 500 #图片像素
plt.rcParams['figure.dpi']  = 500 #分辨率plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签import warnings 
warnings.filterwarnings("ignore")# 设置硬件设备,如果有GPU则使用,没有则使用cpu
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
device(type='cuda')

2. 数据预处理

DataFrame=pd.read_excel('./data/dia.xlsx')
DataFrame.head()
卡号性别年龄高密度脂蛋白胆固醇低密度脂蛋白胆固醇极低密度脂蛋白胆固醇甘油三酯总胆固醇脉搏舒张压高血压史尿素氮尿酸肌酐体重检查结果是否糖尿病
0180544210381.252.991.070.645.31838304.99243.35010
1180544220311.151.990.840.503.98856304.72391.04710
2180544230271.292.210.690.604.19736105.87325.75110
3180544240330.932.010.660.843.60836002.40203.24020
4180544250361.172.830.830.734.83856704.09236.84300
# 查看数据是否有缺失值
print('数据缺失值---------------------------------')
print(DataFrame.isnull().sum())
数据缺失值---------------------------------
卡号            0
性别            0
年龄            0
高密度脂蛋白胆固醇     0
低密度脂蛋白胆固醇     0
极低密度脂蛋白胆固醇    0
甘油三酯          0
总胆固醇          0
脉搏            0
舒张压           0
高血压史          0
尿素氮           0
尿酸            0
肌酐            0
体重检查结果        0
是否糖尿病         0
dtype: int64
# 数据分布分析
feature_map = {'年龄': '年龄','高密度脂蛋白胆固醇': '高密度脂蛋白胆固醇','低密度脂蛋白胆固醇': '低密度脂蛋白胆固醇','极低密度脂蛋白胆固醇': '极低密度脂蛋白胆固醇','甘油三酯': '甘油三酯','总胆固醇': '总胆固醇','脉搏': '脉搏','舒张压':'舒张压','高血压史':'高血压史','尿素氮':'尿素氮','尿酸':'尿酸','肌酐':'肌酐','体重检查结果':'体重检查结果'
}
plt.figure(figsize=(15, 10))for i, (col, col_name) in enumerate(feature_map.items(), 1):plt.subplot(3, 5, i)sns.boxplot(x=DataFrame['是否糖尿病'], y=DataFrame[col])plt.title(f'{col_name}的箱线图', fontsize=14)plt.ylabel('数值', fontsize=12)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.tight_layout()
plt.show()

​ 在这里插入图片描述

# # 相关性分析  
# import plotly
# import plotly.express as px# # 删除列 '卡号'
# DataFrame.drop(columns=['卡号'], inplace=True)
# # 计算各列之间的相关系数
# df_corr = DataFrame.corr()# # 相关矩阵生成函数
# def corr_generate(df):
#     fig = px.imshow(df,text_auto=True,aspect="auto",color_continuous_scale='RdBu_r')
#     fig.show()# # 生成相关矩阵
# corr_generate(df_corr)

3. 数据集构建

from sklearn.preprocessing import StandardScaler# '高密度脂蛋白胆固醇'字段与糖尿病负相关,故而在 X 中去掉该字段
X = DataFrame.drop(['是否糖尿病','高密度脂蛋白胆固醇'],axis=1)
y = DataFrame['是否糖尿病']sc_X    = StandardScaler()
X = sc_X.fit_transform(X)X = torch.tensor(np.array(X), dtype=torch.float32)
y = torch.tensor(np.array(y), dtype=torch.int64)train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.2,random_state=1)
train_X.shape, train_y.shape
(torch.Size([804, 13]), torch.Size([804]))
from torch.utils.data import TensorDataset, DataLoadertrain_dl = DataLoader(TensorDataset(train_X, train_y),batch_size=64, shuffle=False)test_dl  = DataLoader(TensorDataset(test_X, test_y),batch_size=64, shuffle=False)

4. 定义模型

class model_lstm(nn.Module):def __init__(self):super(model_lstm, self).__init__()self.lstm0 = nn.LSTM(input_size=13 ,hidden_size=200, num_layers=1, batch_first=True)self.lstm1 = nn.LSTM(input_size=200 ,hidden_size=200, num_layers=1, batch_first=True)self.dropout = nn.Dropout(0.5)  # 尝试设置Dropout比率为0.5;0.5 表示每次训练时会随机丢弃50%的神经元。你可以调整这个比例,通常0.3到0.5是常见的选择。self.fc0   = nn.Linear(200, 2)def forward(self, x):out, hidden1 = self.lstm0(x) out, _ = self.lstm1(out, hidden1)out    = self.dropout(out)  # 尝试在LSTM后加Dropoutout    = self.fc0(out) return out   

5. 初始化模型及优化器

model = model_lstm().to(device)
print(model)loss_fn    = nn.CrossEntropyLoss() # 创建损失函数
weight_decay = 1e-4 # 尝试加入权重衰减;一般来说,较小的值(如1e-5到1e-4)就可以起到一定的正则化作用。
# weight_decay = 1e-3
learn_rate = 1e-3   # 学习率
# learn_rate = 3e-4   # 学习率
lambda1 = lambda epoch:(0.92**(epoch//2))optimizer = torch.optim.Adam(model.parameters(),lr = learn_rate, weight_decay = 1e-4)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer,lr_lambda=lambda1) # 选定调整方法
epochs     = 50
model_lstm((lstm0): LSTM(13, 200, batch_first=True)(lstm1): LSTM(200, 200, batch_first=True)(dropout): Dropout(p=0.5, inplace=False)(fc0): Linear(in_features=200, out_features=2, bias=True)
)

6. 训练函数

# 训练循环
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与losstrain_acc  += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc  /= sizetrain_loss /= num_batchesreturn train_acc, train_loss

7. 测试函数

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 X, y in dataloader:X, y = X.to(device), y.to(device)# 计算losstarget_pred = model(X)loss        = loss_fn(target_pred, y)test_loss += loss.item()test_acc  += (target_pred.argmax(1) == y).type(torch.float).sum().item()test_acc  /= sizetest_loss /= num_batchesreturn test_acc, test_loss

8. 训练过程

import copytrain_loss = []
train_acc  = []
test_loss  = []
test_acc   = []best_acc = 0.0for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)# 更新学习率scheduler.step() # 更新学习率——调用官方动态学习率时使用model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)# 保存最佳模型if epoch_test_acc > best_acc:best_acc = epoch_test_accbest_model = copy.deepcopy(model)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 = optimizer.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('Done. Best test acc: ', best_acc)
Epoch: 1, Train_acc:53.5%, Train_loss:0.683, Test_acc:55.9%, Test_loss:0.681, Lr:1.00E-03
Epoch: 2, Train_acc:65.0%, Train_loss:0.636, Test_acc:68.8%, Test_loss:0.623, Lr:9.20E-04
Epoch: 3, Train_acc:73.0%, Train_loss:0.536, Test_acc:75.2%, Test_loss:0.542, Lr:9.20E-04
Epoch: 4, Train_acc:76.7%, Train_loss:0.473, Test_acc:78.2%, Test_loss:0.510, Lr:8.46E-04
Epoch: 5, Train_acc:78.7%, Train_loss:0.444, Test_acc:75.7%, Test_loss:0.498, Lr:8.46E-04
Epoch: 6, Train_acc:79.0%, Train_loss:0.425, Test_acc:77.2%, Test_loss:0.485, Lr:7.79E-04
Epoch: 7, Train_acc:80.5%, Train_loss:0.408, Test_acc:76.2%, Test_loss:0.482, Lr:7.79E-04
Epoch: 8, Train_acc:80.8%, Train_loss:0.407, Test_acc:77.7%, Test_loss:0.476, Lr:7.16E-04
Epoch: 9, Train_acc:81.0%, Train_loss:0.392, Test_acc:76.7%, Test_loss:0.483, Lr:7.16E-04
Epoch:10, Train_acc:82.5%, Train_loss:0.391, Test_acc:76.2%, Test_loss:0.481, Lr:6.59E-04
Epoch:11, Train_acc:81.1%, Train_loss:0.380, Test_acc:77.2%, Test_loss:0.481, Lr:6.59E-04
Epoch:12, Train_acc:82.2%, Train_loss:0.361, Test_acc:77.7%, Test_loss:0.494, Lr:6.06E-04
Epoch:13, Train_acc:82.5%, Train_loss:0.355, Test_acc:75.2%, Test_loss:0.500, Lr:6.06E-04
Epoch:14, Train_acc:83.3%, Train_loss:0.341, Test_acc:74.3%, Test_loss:0.507, Lr:5.58E-04
Epoch:15, Train_acc:83.6%, Train_loss:0.333, Test_acc:74.3%, Test_loss:0.514, Lr:5.58E-04
Epoch:16, Train_acc:85.0%, Train_loss:0.321, Test_acc:74.8%, Test_loss:0.527, Lr:5.13E-04
Epoch:17, Train_acc:84.8%, Train_loss:0.303, Test_acc:73.8%, Test_loss:0.542, Lr:5.13E-04
Epoch:18, Train_acc:86.6%, Train_loss:0.289, Test_acc:73.8%, Test_loss:0.554, Lr:4.72E-04
Epoch:19, Train_acc:85.8%, Train_loss:0.300, Test_acc:73.8%, Test_loss:0.499, Lr:4.72E-04
Epoch:20, Train_acc:87.1%, Train_loss:0.282, Test_acc:74.3%, Test_loss:0.525, Lr:4.34E-04
Epoch:21, Train_acc:88.2%, Train_loss:0.255, Test_acc:73.8%, Test_loss:0.610, Lr:4.34E-04
Epoch:22, Train_acc:89.2%, Train_loss:0.239, Test_acc:72.3%, Test_loss:0.604, Lr:4.00E-04
Epoch:23, Train_acc:88.4%, Train_loss:0.231, Test_acc:70.3%, Test_loss:0.601, Lr:4.00E-04
Epoch:24, Train_acc:89.7%, Train_loss:0.218, Test_acc:72.3%, Test_loss:0.632, Lr:3.68E-04
Epoch:25, Train_acc:90.3%, Train_loss:0.214, Test_acc:73.3%, Test_loss:0.682, Lr:3.68E-04
Epoch:26, Train_acc:91.5%, Train_loss:0.200, Test_acc:72.8%, Test_loss:0.712, Lr:3.38E-04
Epoch:27, Train_acc:92.3%, Train_loss:0.176, Test_acc:72.3%, Test_loss:0.743, Lr:3.38E-04
Epoch:28, Train_acc:92.5%, Train_loss:0.166, Test_acc:71.8%, Test_loss:0.771, Lr:3.11E-04
Epoch:29, Train_acc:92.4%, Train_loss:0.164, Test_acc:71.3%, Test_loss:0.778, Lr:3.11E-04
Epoch:30, Train_acc:92.9%, Train_loss:0.162, Test_acc:71.8%, Test_loss:0.832, Lr:2.86E-04
Epoch:31, Train_acc:93.3%, Train_loss:0.143, Test_acc:71.3%, Test_loss:0.906, Lr:2.86E-04
Epoch:32, Train_acc:94.3%, Train_loss:0.131, Test_acc:71.8%, Test_loss:0.976, Lr:2.63E-04
Epoch:33, Train_acc:95.1%, Train_loss:0.122, Test_acc:74.3%, Test_loss:0.955, Lr:2.63E-04
Epoch:34, Train_acc:94.4%, Train_loss:0.119, Test_acc:71.3%, Test_loss:0.927, Lr:2.42E-04
Epoch:35, Train_acc:94.3%, Train_loss:0.126, Test_acc:71.8%, Test_loss:0.896, Lr:2.42E-04
Epoch:36, Train_acc:95.5%, Train_loss:0.115, Test_acc:70.8%, Test_loss:1.024, Lr:2.23E-04
Epoch:37, Train_acc:95.1%, Train_loss:0.108, Test_acc:70.8%, Test_loss:1.005, Lr:2.23E-04
Epoch:38, Train_acc:96.3%, Train_loss:0.092, Test_acc:71.3%, Test_loss:1.140, Lr:2.05E-04
Epoch:39, Train_acc:96.5%, Train_loss:0.085, Test_acc:70.3%, Test_loss:1.137, Lr:2.05E-04
Epoch:40, Train_acc:97.0%, Train_loss:0.079, Test_acc:71.8%, Test_loss:1.148, Lr:1.89E-04
Epoch:41, Train_acc:96.4%, Train_loss:0.081, Test_acc:71.8%, Test_loss:1.153, Lr:1.89E-04
Epoch:42, Train_acc:97.0%, Train_loss:0.079, Test_acc:69.3%, Test_loss:1.119, Lr:1.74E-04
Epoch:43, Train_acc:96.0%, Train_loss:0.082, Test_acc:71.8%, Test_loss:1.161, Lr:1.74E-04
Epoch:44, Train_acc:96.8%, Train_loss:0.080, Test_acc:72.3%, Test_loss:1.126, Lr:1.60E-04
Epoch:45, Train_acc:97.9%, Train_loss:0.068, Test_acc:70.8%, Test_loss:1.235, Lr:1.60E-04
Epoch:46, Train_acc:98.0%, Train_loss:0.058, Test_acc:71.8%, Test_loss:1.281, Lr:1.47E-04
Epoch:47, Train_acc:97.6%, Train_loss:0.057, Test_acc:70.3%, Test_loss:1.271, Lr:1.47E-04
Epoch:48, Train_acc:98.5%, Train_loss:0.052, Test_acc:71.3%, Test_loss:1.259, Lr:1.35E-04
Epoch:49, Train_acc:98.6%, Train_loss:0.054, Test_acc:70.3%, Test_loss:1.405, Lr:1.35E-04
Epoch:50, Train_acc:98.1%, Train_loss:0.046, Test_acc:71.3%, Test_loss:1.315, Lr:1.24E-04
Done. Best test acc:  0.7821782178217822

9. 模型评估

import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率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.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()

在这里插入图片描述



相关文章:

深度学习每周学习总结R5(LSTM-实现糖尿病探索与预测-模型优化)

🍨 本文为🔗365天深度学习训练营 中的学习记录博客R7中的内容,为了便于自己整理总结起名为R5🍖 原作者:K同学啊 | 接辅导、项目定制 目录 0. 总结优化细节(目前只采用了1、2两种方式)1. L2 正则…...

单元测试在复杂业务逻辑开发中的重要性与实践

背景 以前编写程序时,我并没有养成大量撰写单元测试的习惯,尤其是在写偏向业务代码的情况下,写的单元测试很少,只有在封装一些公共方法的时候才会写一些测试用例。 然而,最近我在开发的一个业务时,深刻地…...

Kubernetes 环境中的自动化运维实战指南

Kubernetes 作为容器编排领域的领导者,已经成为云原生应用的核心基础设施。然而,随着集群规模的扩大和应用的复杂化,手动运维 Kubernetes 集群变得愈发困难。自动化运维成为提升效率、保障系统稳定性的关键。本文将详细介绍如何在 Kubernetes 环境中实施自动化运维,涵盖工具…...

Linux 如何使用fdisk进行磁盘相关的操作

简介 fdisk 命令是 Linux 中用于管理磁盘分区的强大文本实用程序。它可以创建、删除、调整大小和修改硬盘上的分区。 基本语法 fdisk [options] <device> <device>&#xff1a;要管理的磁盘&#xff0c;例如 /dev/sda、/dev/nvme0n1 或 /dev/vda 示例用法 列…...

嵌入式Linux:如何监视子进程

目录 1、wait()函数 2、waitpid()函数 3、SIGCHLD信号 在嵌入式Linux系统中&#xff0c;父进程通常需要创建子进程来执行特定任务&#xff0c;例如处理网络请求、执行计算任务等。监视子进程的状态不仅可以确保资源的合理利用&#xff0c;还能防止僵尸进程的产生&#xff0c…...

【信息系统项目管理师-选择真题】2010上半年综合知识答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 【第1~2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20题】【第21题】…...

工作总结:压测篇

前言 压测是测试需要会的一项技能&#xff0c;作为开发&#xff0c;有点时候也要会一点压测。也是被逼着现学现卖的。 一、压测是什么&#xff0c;以及压测工具的选择 压测&#xff0c;即压力测试&#xff0c;是一种性能测试手段&#xff0c;通过模拟大量用户同时访问系统&am…...

doris:STRUCT

STRUCT<field_name:field_type [COMMENT comment_string], ... > 表示由多个 Field 组成的结构体&#xff0c;也可被理解为多个列的集合。 不能作为 Key 使用&#xff0c;目前 STRUCT 仅支持在 Duplicate 模型的表中使用。一个 Struct 中的 Field 的名字和数量固定&…...

二叉树介绍

一.树的概念 树的图&#xff1a; 1.结点的度&#xff1a;一个结点含有子树的个数称为该结点的度&#xff1b; 如上图&#xff1a;A的度为6 2.树的度&#xff1a;一棵树中&#xff0c;所有结点度的最大值称为树的度&#xff1b; 如上图&#xff1a;树的度为6 3.叶子结点或终…...

通过Ngrok实现内网穿透助力远程开发

在现代软件开发和网络应用的环境下&#xff0c;开发人员常常需要在本地搭建服务器进行调试、测试或演示。然而&#xff0c;传统的端口映射&#xff08;如使用 NAT 或 SSH 隧道&#xff09;配置繁琐&#xff0c;且并非所有环境都允许直接暴露本地服务。ngrok 作为一款强大的隧道…...

DeepSeek-R1:通过强化学习激励大型语言模型(LLMs)的推理能力

摘要 我们推出了第一代推理模型&#xff1a;DeepSeek-R1-Zero和DeepSeek-R1。DeepSeek-R1-Zero是一个未经监督微调&#xff08;SFT&#xff09;作为初步步骤&#xff0c;而是通过大规模强化学习&#xff08;RL&#xff09;训练的模型&#xff0c;展现出卓越的推理能力。通过强…...

Node.js基础

浏览器知识 浏览器 个浏览器都内置了DOM、BOM等API函数&#xff0c;供浏览器中的Javascript调用。 每个浏览器都有对应的JavaScript解析引擎。 浏览器中的JavaScript环境 V8引擎负责解析和执行JavaScript代码 内置API是由运行环境提供的特殊接口&#xff0c;只能在所属的运…...

DeepSeek R1:中国AI黑马的崛起与挑战

在人工智能&#xff08;AI&#xff09;领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;正以迅猛之势重塑世界&#xff0c;其发展速度和影响力令人瞩目。近期&#xff0c;中国DeepSeek公司发布的DeepSeek R1模型&#xff0c;宛如一颗璀璨新星&#xff0c;凭借卓越的推…...

【JavaEE】_MVC架构与三层架构

目录 1. MVC架构 2. 三层架构 3. MVC架构与三层架构的对比 3.1 MVC与三层架构的对比 3.2 MVC与三层架构的共性 1. MVC架构 在前文已介绍关于SpringMAC的设计模式&#xff0c;详见下文&#xff1a; 【JavaEE】_Spring Web MVC简介-CSDN博客文章浏览阅读967次&#xff0c;点…...

对比DeepSeek、ChatGPT和Kimi的学术写作摘要能力

摘要 摘要是文章的精华&#xff0c;通常在200-250词左右。要包括研究的目的、方法、结果和结论。让AI工具作为某领域内资深的研究专家&#xff0c;编写摘要需要言简意赅&#xff0c;直接概括论文的核心&#xff0c;为读者提供快速了解的窗口。 下面我们使用DeepSeek、ChatGPT…...

ts 进阶

吴悠讲编程 : 20分钟TypeScript进阶&#xff01;无废话快速提升水平 前端速看 https://www.bilibili.com/video/BV1q64y1j7aH...

Kubernetes(一)

Kubernetes&#xff08;简称K8s&#xff09;是一个开源的容器编排平台&#xff0c;已经成为现代云原生应用的核心技术&#xff0c;主要应用于对容器化应用程序的自动化部署、扩展以及管理。k8s配备了一组核心组件以及一系列功能&#xff0c;这些组件能够实现容器的调度、负载均…...

Python里的小整数问题挺有意思的

简单来说&#xff0c;Python为了优化性能&#xff0c;会把一些常用的整数&#xff08;通常是-5到256&#xff09;提前创建好&#xff0c;放到一个“缓存池”里。这样&#xff0c;当你用到这些小整数时&#xff0c;Python就不用每次都重新创建对象了&#xff0c;直接从缓存池里拿…...

基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结

title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付&#xff08;CI/CD&#xff09;流程里&#xff0c;及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...

java.util.Random类(详细案例拆解)(已完结)

前言&#xff1a; 小编打算近期更俩三期类的专栏&#xff0c;一些常用的专集类&#xff0c;给大家分好类别总结和详细的代码举例解释。 今天是除夕&#xff0c;小编先祝贺大家除夕快乐啦&#xff01;&#xff01; 今天是第六个 java.lang.Math 包中的 java.util.Random类 我…...

CMake常用命令指南(CMakeList.txt)

CMakeList从入门到精通的文章有很多不再赘述&#xff08; 此处附带一篇优秀的博文链接&#xff1a;一个简单例子&#xff0c;完全入门CMake语法与CMakeList编写 &#xff09;。 本文主要列举 CMake 中常用命令的详细说明、优缺点分析以及推荐做法&#xff0c;以更好地理解和灵…...

Mybatis是如何进行分页的?

大家好&#xff0c;我是锋哥。今天分享关于【Mybatis是如何进行分页的&#xff1f;】面试题。希望对大家有帮助&#xff1b; Mybatis是如何进行分页的&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MyBatis 实现分页的方式有很多种&#xff0c;最常见…...

推动知识共享的在线知识库实施与优化指南

内容概要 在当今迅速发展的数字化时代&#xff0c;在线知识库的实施显得尤为重要。它不仅为企业提供了高效的信息存储与共享平台&#xff0c;还能够有效促进团队成员之间的协作与知识传递。通过集中管理企业内的各类知识资源&#xff0c;在线知识库帮助员工快速查找所需信息&a…...

【最后203篇系列】007 使用APS搭建本地定时任务

说明 最大的好处是方便。 其实所有任务的源头&#xff0c;应该都是通过定时的方式&#xff0c;在每个时隙发起轮询。当然在任务的后续传递中&#xff0c;可以通过CallBack或者WebHook的方式&#xff0c;以事件的形态进行。这样可以避免长任务执行的过程中进行等待和轮询。 总结…...

为AI聊天工具添加一个知识系统 之78 详细设计之19 正则表达式 之6

本文要点 要点 本项目设计的正则表达式 是一个 动态正则匹配框架。它是一个谓词系统&#xff1a;谓词 是运动&#xff0c;主语是“维度”&#xff0c;表语是 语言处理。主语的一个 双动结构。 Reg三大功能 语法验证、语义检查和 语用检验&#xff0c;三者 &#xff1a;语义约…...

三天急速通关JavaWeb基础知识:Day 1 后端基础知识

三天急速通关JavaWeb基础知识&#xff1a;Day 1 后端基础知识 0 文章说明1 Http1.1 介绍1.2 通信过程1.3 报文 Message1.3.1 请求报文 Request Message1.3.2 响应报文 Response Message 2 XML2.1 介绍2.2 利用Java解析XML 3 Tomcat3.1 介绍3.2 Tomcat的安装与配置3.3 Tomcat的项…...

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…...

前端-Rollup

Rollup 是一个用于 JavaScript 的模块打包工具&#xff0c;它将小的代码片段编译成更大、更复杂的代码&#xff0c;例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式&#xff0c;而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…...

EtherCAT主站IGH-- 21 -- IGH之fsm_reboot.h/c文件解析

EtherCAT主站IGH-- 21 -- IGH之fsm_reboot.h/c文件解析 0 预览一 该文件功能`fsm_reboot.c` 文件功能函数预览二 函数功能介绍`fsm_reboot.c` 中主要函数的作用1. `ec_fsm_reboot_init`2. `ec_fsm_reboot_clear`3. `ec_fsm_reboot_single`4. `ec_fsm_reboot_all`5. `ec_fsm_reb…...

【NLP251】NLP RNN 系列网络

NLP251 系列主要记录从NLP基础网络结构到知识图谱的学习 &#xff11;.原理及网络结构 &#xff11;.&#xff11;&#xff32;&#xff2e;&#xff2e; 在Yoshua Bengio论文中( http://proceedings.mlr.press/v28/pascanu13.pdf )证明了梯度求导的一部分环节是一个指数模型…...

数据分析系列--④RapidMiner进行关联分析(案例)

一、核心概念 1.1项集&#xff08;Itemset&#xff09; 1.2规则&#xff08;Rule&#xff09; 1.3支持度&#xff08;Support&#xff09; 1.3.1 支持度的定义 1.3.2 支持度的意义 1.3.3 支持度的应用 1.3.4 支持度的示例 1.3.5 支持度的调整 1.3.6 支持度与其他指标的…...

深度学习:基于MindNLP的RAG应用开发

什么是RAG&#xff1f; RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09; 是一种结合检索&#xff08;Retrieval&#xff09;和生成&#xff08;Generation&#xff09;的技术&#xff0c;旨在提升大语言模型&#xff08;LLM&#xff09;生…...

Hive安装教程

Hive安装教程 文章目录 Hive安装教程写在前面安装下载安装部署安装Hive启动并使用Hive MySQL安装检查当前系统是否安装过MySQL安装初始化数据库 Hive元数据配置到MySQL拷贝驱动配置Metastore到MySQL再次启动Hive 写在前面 Linux版本&#xff1a;CentOS7.5Hive版本&#xff1a;…...

安卓逆向之脱壳-认识一下动态加载 双亲委派(二)

一&#xff1a;动态加载与双亲委派模型 在 Java 和 Android 中&#xff0c;ClassLoader 是一个非常重要的组件&#xff0c;负责将 .class 文件或 .dex 文件的字节码加载到内存中&#xff0c;供程序使用。在这其中&#xff0c;有两种关键的概念需要深入理解&#xff1a;动态加载…...

全程Kali linux---CTFshow misc入门(14-24)

第十四题&#xff1a; dd命令&#xff1a;dd是一个用于复制和转换数据的命令&#xff0c;它可以对文件、设备等进行操作&#xff0c;在数据备份、转换格式等场景经常使用。 ifmisc14.jpg&#xff1a;if表示 “input file”&#xff08;输入文件&#xff09;&#xff0c;这里指…...

学习数据结构(3)顺序表

1.动态顺序表的实现 &#xff08;1&#xff09;初始化 &#xff08;2&#xff09;扩容 &#xff08;3&#xff09;头部插入 &#xff08;4&#xff09;尾部插入 &#xff08;5&#xff09;头部删除 &#xff08;这里注意要保证有效数据个数不为0&#xff09; &#xff08;6&a…...

知识体系、知识管理角度的赚钱思考

从知识管理和知识体系的角度出发&#xff0c;赚钱的问题思考清单可以帮助你系统地梳理和优化自己在财富创造方面的策略。 以下是一个详细的清单&#xff0c;涵盖从知识获取、技能提升到实际应用的各个环节&#xff0c;帮助你在赚钱的道路上更加高效和有条理。 一、赚钱的目标与…...

(done) ABI 相关知识补充:内核线程切换、用户线程切换、用户内核切换需要保存哪些寄存器?

由于操作系统和编译器约定了 ABI&#xff0c;如下&#xff1a; 编译器在对 C 语言编译时&#xff0c;会自动 caller 标注的寄存器进行保存恢复。保存的步骤通常发生在进入函数的时候&#xff0c;恢复的步骤通常发生在从函数返回的时候。 内核线程切换需要保存的寄存器&#…...

QT6 + CMAKE编译OPENCV3.9

参考文档 [1] https://blog.csdn.net/rjkf_css/article/details/135676077 前提条件 配置好相关运行环境&#xff1a;QT6、OPENCV3.9的sources文件 OPENCV下载网页&#xff1a;https://opencv.org/releases/ QT6下载教程&#xff1a;https://blog.csdn.net/caoshangpa/article…...

Linux 常用命令——系统设置篇(保姆级说明)

系统设置类 显示当前运行的进程&#xff08;ps&#xff09; ps [options] [--help]# 查找指定进程格式&#xff1a; ps -ef | grep 进程关键字# 显示进程信息 ps -A 参数&#xff1a; -A 列出所有的进程 -w 显示加宽可以显示较多的资讯 -au 显示较详细的资讯 -aux 显示所有包…...

完美世界前端面试题及参考答案

如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...

Vue3笔记——(三)hooks、路由

015 hooks 作用&#xff1a;使得代码更加模块化和可维护 Person.vue <template><div><h2>当前求和{{ sum }}</h2><button click"addFn">点我sum1</button></div> </template> <script setup lang"ts"…...

网络安全大模型和人工智能场景及应用理解

本文通过通俗易懂的方式的进行阐述&#xff0c;大家读完觉得有帮助记得及时关注和点赞&#xff01;&#xff01;&#xff01; 一、网络安全大模型的概述 网络安全大模型是一种用于识别和应对各种网络安全威胁的模型。它通过分析网络数据包、网络行为等信息&#xff0c;识别潜在…...

python-leetcode-从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树 - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right r…...

NLP模型大对比:Transformer > RNN > n-gram

结论 Transformer 大于 RNN 大于 传统的n-gram n-gram VS Transformer 我们可以用一个 图书馆查询 的类比来解释它们的差异&#xff1a; 一、核心差异对比 维度n-gram 模型Transformer工作方式固定窗口的"近视观察员"全局关联的"侦探"依赖距离只能看前…...

MySQL查询优化(三):深度解读 MySQL客户端和服务端协议

如果需要从 MySQL 服务端获得很高的性能&#xff0c;最佳的方式就是花时间研究 MySQL 优化和执行查询的机制。一旦理解了这些&#xff0c;大部分的查询优化是有据可循的&#xff0c;从而使得整个查询优化的过程更有逻辑性。下图展示了 MySQL 执行查询的过程&#xff1a; 客户端…...

[STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器

一、高级定时器简介 高级定时器的简介在前面一章已经介绍过&#xff0c;可以点击下面链接了解&#xff0c;在这里进行一些补充。 [STM32 - 野火] - - - 固件库学习笔记 - - -十二.基本定时器 1.1 功能简介 1、高级定时器可以向上/向下/两边计数&#xff0c;还独有一个重复计…...

Antd React Form使用Radio嵌套多个Select和Input的处理

使用Antd React Form使用Radio会遇到嵌套多个Select和Input的处理&#xff0c;需要多层嵌套和处理默认事件和冒泡&#xff0c;具体实现过程直接上代码。 实现效果布局如下图 代码 <Formname"basic"form{form}labelWrap{...formItemLayoutSpan(5, 19)}onFinish{on…...

固有频率与模态分析

目录 引言 1. 固有频率&#xff1a;物体的“天生节奏” 1.1 定义 1.2 关键特点 1.3 实际意义 2. 有限元中的模态分析&#xff1a;给结构“体检振动” 2.1 模态分析的意义 2.2 实际案例 2.2.1 桥梁模态分析 2.2.2 飞机机翼模态分析 2.2.3 具体事例 3. 模态分析的工具…...

视频多模态模型——视频版ViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文《ViViT: A Video Vision Transformer》&#xff0c;2021由google 提出用于视频处理的视觉 Transformer 模型&#xff0c;在视频多模态领域有…...