【机器学习模型评估:8种算法对比实战】
将得到的训练数据集和测试数据集通过8种算法来进行模型评估,对比结果得到最优的模型评估
1.LR逻辑回归算法
数据提取(本文以平均填充值为例子)
import pandas as pd from sklearn import metrics train_data=pd.read_excel(r'训练数据集[平均填充].xlsx]') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_daata.iloc[:,0]#训练数据集的测试标签label test_data=pd.read_excel(r'测试数据集[平均值填充].xlsx') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={} 逻辑回归LR算法实现代码
from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV#网络搜索 param_grid={ 'C':[0.01], 'penalty':['l2'], 'solver':['lbfgs'], 'max_iter':[3000], 'class_weight':['balanced'] } logreg = LogisticRegression() grid_search = GridSearchCV(logreg,param_grid,cv=5)#创建GridSearchCV对象 grid_search.fit(train_data_x,train_data_y)#在训练集上执行网格搜索 print("best parameters set found debelopment set:")#输出最佳参数 pritn(grid_search.best_params_) 建立最优模型
LR_result={}#用来保存训练之后的结果 lr = LogistRegression(C=0.01,max_iter=1000,penalty=None,solver='lbfgs') lr=.fit(train_data_x,train_data_y)测试结果[含训练数据集的测试+测试数据集的测试]
train_predicted=lr.predict(train_data_x)#训练数据集的预测结果 print('LR的train:\n',metric.classification_report(train_data_y,train_predicted) test_predicted=lr.predict(test_data_x)#测试数据集的预测结果 print('LR的test:\n',metrics.classification_report(test_data_y,test_predicted) a=metrics.classification_report(test_data_y,test_predicted,digits=6)#digits表示保留有效位小数 b=a.split() LR_result['recall_0']=float(b[8])#添加类别为0的召回率 LR_result['recall_1']=float(b[11])#添加类别为1的召回率 LR_result['recall_2']=float(b[16])#添加类别为2的召回半 LR_result['recall_3']=float(b[21])#添加类别为3的什问率 LR_result['acc']=float(b[25])#添加accuracy的结果 result_data['acc']=LR_result#result_data是总体的结果 print('lr结束') 运行结果:

训练集准确率:0.87
测试集准确率:0.87
训练集和测试集准确率几乎一致,说明模型没有过拟合 / 欠拟合,泛化能力稳定。
2.随机森林算法
数据提取
import pandas as pd from sklearn import metrics '''数据提取''' train_data=pd.read_excel(r'训练数据集[平均值填充].xlsx') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_data.iloc[:,0]#训练数据集的测试标签label test_data = pd.read_excel(r'测试数据集[平均值填充].xlsx') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={}#用来保存后面6种算法的结果。随机森林RF算法实现代码
'''----------------------RF算法实现代码------------------------------''' from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV#网络搜索 param_grid ={ 'n_estimators':[50,100,200],# 树的数量 'max_depth':[None,10,20,30],#树的深度 'min_samples_split':[2,5,10], #节点分裂所需的最小样本数 'min_samples_leaf':[1,2,5], # 叶子节点所需的最小样本数 'max_features':['auto','sqrt','log2'],#最大特征数 'bootstrap':[True,False] #是否使用自举样本 } rf = RandomForestClassifier() grid_search = GridSearchCV(rf,param_grid,cv=5)# 创建GridSearchCV对象 grid_search.fit(train_data_x,train_data_y)# 在训练集上执行网格搜索 print("Best parameters set found on development set:")#输出最佳参数 print(grid_search.best_params_)建立模型
# """建立最优模型""" RF_result={}#用来保存训练之后的结果 rf = RandomForestClassifier( bootstrap=False, max_depth=20, max_features='log2', min_samples_leaf=1, n_estimators=50, random_state=487) rf.fit(train_data_x, train_data_y)测试结果[含训练数据集的测试+测试数据集的测试]
# '''测试结果[含训练数据集的测试+测试数据集的测试]''' train_predicted=rf.predict(train_data_x)#训练数据集的预测结果 print('RF的train:\n',metrics.classification_report(train_data_y,train_predicted)) test_predicted=rf.predict(test_data_x)#训练数据集的预测结果 print('RF的test:\n',metrics.classification_report(test_data_y,test_predicted)) a=metrics.classification_report(test_data_y,test_predicted,digits=6)#digits表示保倒有效位数 b=a.split() RF_result['recall_0']=float(b[8])#添加类别为0的召回率 RF_result['recall_1']=float(b[11])#添加类别2的付四率 RF_result['recall_2']=float(b[16])#添加类别为2的召回半 RF_result['recall_3']=float(b[21])#添加类别为3的什问率 RF_result['acc']=float(b[25])#添加accuracy的结果 result_data['acc']=RF_result#result datg是总体的结果, print('rf结束') 
训练集准确率:1
测试集准确率:0.96
随机森林准确率更高,泛化能力极强,几乎没有过拟合。
3.支持向量机算法
数据提取
import pandas as pd from sklearn import metrics '''数据提取''' train_data=pd.read_excel(r'训练数据集[平均值填充].xlsx') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_data.iloc[:,0]#训练数据集的测试标签label test_data = pd.read_excel(r'测试数据集[平均值填充].xlsx') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={}#用来保存后面6种算法的结果。支持向量积SVM代码实现
#‘‘‘--------------------支持向量机----------------------------------’’’ from sklearn.svm import SVC from sklearn.model_selection import GridSearchCV #定义参数网络 param_grid = { 'C':[0.01,0.1,1,2], 'kernel':['linear','poly','rbf','sigmoid'],#核函数类型 'degree':[2,3,4,5],#多项式核函数的阶数,仅在‘ploy’核函数下有效 'gamma':['scale','auto']+[1],#RBF,poly和sigmoid的核函数参数 'coef0':[0.1],#和函数中的独立项,仅在‘poly’和'sigmoid'核函数下有效 } svc = SVC()#创建SVC分类器实例 #创建GridSearchCV对象 grid_search=GridSearchCV(svc,param_grid,cv=5)#五折交叉验证 #在训练集上执行网络搜索 grid_search.fit(train_data_x,train_data_y) #输出最佳参数 print("Best parameters set found on development set:") print() print(grid_search.best_params_)建立模型,测试结果
#下面的参数均已通过网格搜索算法调优 SVM_result ={} svm = SVC (C=1,coef0=0.1,degree=4,gamma=1,kernel='poly',probability=True,random_state=100) svm.fit(train_data_x,train_data_y) test_predicted=svm.predict(test_data_x)#训练数据集的预测结果 print('SVM的test:\n',metrics.classification_report(test_data_y,test_predicted)) a=metrics.classification_report(test_data_y,test_predicted,digits=6) b=a.split() print(a) SVM_result['recall_0']=float(b[6])#添加类别为0的召回率 SVM_result['recall_1']=float(b[11])#添加类别为1的召回率 SVM_result['recall_2']=float(b[16])#添加类别为2的召回率 SVM_result['recall_3']=float(b[25])#添加类别为3的召回率 SVM_result['acc']=float(b[25])#添加accutancy的结果 result_data['SVM']=SVM_result 运行结果:

4.AdaBoost算法:
AdaBoost算法是集成学习算法中的stacking方法

随机森林和XGBoost使用的基学习器都是决策树,而AdaBoost可以使用其他各种弱学习器,集成学习。
数据提取
import pandas as pd from sklearn import metrics import warnings warnings.filterwarnings('ignore', category=FutureWarning) # 屏蔽FutureWarning '''数据提取''' train_data=pd.read_excel(r'训练数据集[平均值填充].xlsx').dropna(how='any') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_data.iloc[:,0]#训练数据集的测试标签label test_data = pd.read_excel(r'测试数据集[平均值填充].xlsx').dropna(how='any') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={}#用来保存后面6种算法的结果。 AdaBoost算法代码实现:
#--------------------AdaBoost算法------------------------- from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import GridSearchCV ada = AdaBoostClassifier(algorithm='SAMME',random_state=0) param_grid={ 'n_estimators':[50,100,200],#弱分类器的数量 'learning_rate':[0.01,0.1,0.5,1.0],#学习率 'algorithm':['SAMME','SAMME.R'],#提升算法的类型 'estimator':[DecisionTreeClassifier(max_depth=1),DecisionTreeClassifier(max_depth=2)] } abf = AdaBoostClassifier(n_estimators=100,random_state=0)#创建AdaBoost分类器 grid_search = GridSearchCV(abf,param_grid,cv=5)#创建GridSearchCV对象 #在训练集上执行网格搜索 grid_search.fit(train_data_x,train_data_y) #输出最佳参数 print("Best parameters set found on development set :\n ") print(grid_search.best_params_) AdaBoostClassifier_result={} abf = AdaBoostClassifier(algorithm='SAMME', estimator=DecisionTreeClassifier(max_depth=2), n_estimators=200, learning_rate=1.0, random_state=0)#创建AdaBoost分类器 abf.fit(train_data_x,train_data_y) train_predicted=abf.predict(train_data_x)#训练数据集的预测结果 print("AdaBoost的train:\n",metrics.classification_report(train_data_y,train_predicted)) test_predicted = abf.predict(test_data_x)#训练数据集的预测结果 print("AdaBoost的test:\n",metrics.classification_report(test_data_y,test_predicted)) a=metrics.classification_report(test_data_y,test_predicted,digits=6) b=a.split() AdaBoostClassifier_result['recall_0']=float(b[6]) AdaBoostClassifier_result['recall_1']=float(b[11]) AdaBoostClassifier_result['recall_2']=float(b[16]) AdaBoostClassifier_result['recall_3']=float(b[21]) AdaBoostClassifier_result['acc']=float(b[25]) result_data['AdaBoost']=AdaBoostClassifier_result 运行结果:

训练集准确率:1
测试集准确率:0.96
5.高斯贝叶斯(GNB)算法:要求是连续性的变量
本项目矿物数据文件中的数据矿物的含量就是连续的变量
代码显示:
from sklearn import metrics import warnings warnings.filterwarnings('ignore', category=FutureWarning) # 屏蔽FutureWarning '''数据提取''' train_data=pd.read_excel(r'训练数据集[平均值填充].xlsx').dropna(how='any') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_data.iloc[:,0]#训练数据集的测试标签label test_data = pd.read_excel(r'测试数据集[平均值填充].xlsx').dropna(how='any') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={}#用来保存后面6种算法的结果。 #---------------------GNB高斯贝叶斯算法------------------------------ from sklearn.naive_bayes import GaussianNB GNB_result={} gnb = GaussianNB()#创建高斯朴素贝叶斯分类器 gnb.fit(train_data_x,train_data_y) train_predicted=gnb.predict(train_data_x)#训练数据的预测结果 print('GNB的train:\n',metrics.classification_report(train_data_y,train_predicted)) test_predicted = gnb.predict(test_data_x)#训练数据集的预测结果 print('GNB的test:\n',metrics.classification_report(test_data_y,test_predicted)) a=metrics.classification_report(test_data_y,test_predicted,digits=6) b=a.split() 运行结果:

高斯贝叶斯算法准确率太低,已经过时。
6.XGBoost算法
Xgboost算法也是集成算法之一

示例代码如下:读取数据
import pandas as pd from sklearn import metrics import warnings warnings.filterwarnings('ignore', category=FutureWarning) # 屏蔽FutureWarning '''数据提取''' train_data=pd.read_excel(r'训练数据集[平均值填充].xlsx').dropna(how='any') train_data_x=train_data.iloc[:,1:]#训练数据集的特征 train_data_y=train_data.iloc[:,0]#训练数据集的测试标签label test_data = pd.read_excel(r'测试数据集[平均值填充].xlsx').dropna(how='any') test_data_x=test_data.iloc[:,1:]#测试数据集的特征 test_data_y=test_data.iloc[:,0]#测试数据集的测试标簽label result_data={}#用来保存后面6种算法的结果。 建立模型,测试结果
import xgboost as xgb # #---------------------------XGBoost算法---------------- XGBoost_result={} xgb_model = xgb.XGBClassifier(learning_rate=0.05,#学习率(越小越稳定) n_estimators=200,#树的数量 num_class=5, max_depth=7, min_child_weight=1, gamma=0, subsample=0.6, colsample_bytree=0.8, objective='multi:softmax', seed=0)#学习率 xgb_model.fit(train_data_x,train_data_y) train_predicted=xgb_model.predict(train_data_x)#训练数据集的预测结果 print("XGBoost的train:\n",metrics.classification_report(train_data_y,train_predicted)) test_predicted = xgb_model.predict(test_data_x)#训练数据集的预测结果 print("XGBoost的test:\n",metrics.classification_report(test_data_y,test_predicted)) a=metrics.classification_report(test_data_y,test_predicted,digits=6) b=a.split() XGBoost_result['recall_0']=float(b[6]) XGBoost_result['recall_1']=float(b[11]) XGBoost_result['recall_2']=float(b[16]) XGBoost_result['recall_3']=float(b[21]) XGBoost_result['acc']=float(b[25]) 运行结果:

XGBoost 是你目前所有模型中效果最好的:
1. 测试集准确率 97%,比 RF 高 1%,比 LR 高 10%;
2. 类别 2 召回率 100%,对小样本类别的识别能力极强;
3. 训练集全对、测试集 97% 准确率,几乎无过拟合,泛化能力拉满。
XGBoost 模型在你的矿物分类数据集上表现极佳,训练集完全拟合,测试集准确率高达 97%,是目前最优的分类模型
7.神经网络算法
深度学习介绍:

深度学习-神经网络的构造

公式:

深度学习-感知器
有两层神经元组成的神经网络-感知器,感知器只能划分数据


将输入信息与ω1,ω2...相乘,输出的结果代入非线性激活函数sigmod得到输出结果
多层感知器:增加一个中间层,隐含层,神经网络可以做非线性分类的关键-隐藏层,即神经网络构造包括:输入层,隐藏层,输出层


深度学习—偏置
在神经网络的每个层次中,除了输出层以外,都会有一个偏置单元,本质上是一个只含有存储功能,且存储值为1的单元。

中间层如何确定:
输入层的节点数:与特征的维度匹配
输出层的节点数:与目标的维度匹配。
中间层的节点数:目前业界没有完善的理论来指导这个决策。一般是根据经验来设置。较好的方法就是预先设定几个可选值,通过切换这几个值来看整个模型的预测效果,选择效果最好的值作为最终选择。
神经网络训练方法——损失函数
模型训练的目的:使得参数尽可能的与真实的模型逼近。
具体做法:
1、首先给所有参数赋上随机值。我们使用这些随机生成的参数值,来预测训练数据中的样本。 2、计算预测值为yi,真实值为y。那么,定义一个损失值loss,损失值用于判断预测的结果和真实值的误差,误差越小越好。
常用的损失函数: 0-1损失函数 均方差损失 平均绝对差损失 交叉熵损失 合页损失
回归用均方损失函数,二分类多分类用交叉熵损失函数
均方差损失函数【Mean Squared Error Loss,MSE】:
多分类情况下,如何计算损失值:用Softmax + 交叉熵损失实现多分类,其作用是衡量模型预测概率与真实标签的差距

-log的原因 —— 概率越接近 1(预测越准),损失越小;概率越接近 0(预测错误),损失越大,实现对错误预测的强惩罚。
正则化:解决过拟合问题
L1 正则化:

让权重稀疏化;
L2正则化:

让权重平滑,是实战中最常用的方式。
梯度下降与反向传播
梯度下降:沿损失函数梯度的反方向更新参数,逐步找到损失最小值,学习率(lr)决定更新幅度;
反向传播(BP):通过链式法则将损失误差从输出层反向传递到输入层,计算各层权重的梯度,是神经网络端到端训练的核心。

神经网络训练三部分:神经网络本身,梯度下降,损失函数
MLP(全连接神经网络) 由全连接层(nn.Linear)堆叠而成,通过激活函数引入非线性,突破线性模型的表达限制:
从数据中学习特征并完成分类 / 回归任务,且遵循统一的训练范式:
- 前向传播:输入数据通过网络层计算得到预测输出;
- 损失计算:用损失函数(如交叉熵)衡量预测值与真实值的差距;
- 反向传播:通过梯度下降优化算法,更新网络参数以最小化损失;
- 评估迭代:重复上述过程,直到模型收敛或达到预设训练轮数。
import torch import torch.nn as nn import torch.optim as optim import numpy as np from sklearn.model_selection import train_test_split #定义神经网络结构 ''' 1.网络结构定义:包括输入层、隐含层和输出层的神经元数量。 2.初始化方法:通过继承nn.Module类,初始化父类并进行自定义层的创建。 3.权重初始化:全连接层的权重参数通过随机初始化进行赋值 ''' class Net(nn.Module): def __init__(self): super(Net,self).__init__() # 输入层(13维特征)→ 隐藏层1(32神经元) self.fc1 = nn.Linear(13, 32) # 隐藏层1 → 隐藏层2(64神经元) self.fc2 = nn.Linear(32, 64) # 隐藏层2 → 输出层(4分类) self.fc3 = nn.Linear(64, 4) def forward(self,x):#覆盖父类的方法 # 前向传播,ReLU激活函数,防止梯度爆炸 x=torch.relu(self.fc1.forward(x))# 隐藏层1激活 x=torch.relu(self.fc2(x)) # 隐藏层2激活 x=self.fc3(x)# 输出层不激活(CrossEntropyLoss内置Softmax) return(x) 
#数据预处理:转换为 PyTorch 张量 #Pandas 数据框需转换为张量(Tensor)才能输入 PyTorch 模型: X_train = torch.tensor(train_data_x.values,dtype=torch.float32)#精度 Y_train = torch.tensor(train_data_y.values) X_test = torch.tensor(test_data_x.values,dtype=torch.float32) Y_test = torch.tensor(test_data_y.values)#values将表格类型的数据转化为矩阵数据 #实例化网络,损失函数和优化器 model = Net() # 多分类损失函数:CrossEntropyLoss(Softmax+交叉熵) criterion = nn.CrossEntropyLoss()#损失函数-交叉熵损失函数,煤矿数据为多分类 # 优化器:Adam(自适应学习率,优于基础梯度下降) optimizer = torch.optim.Adam(model.parameters(),lr=0.001)#用Adam优化器 def evaluate_model(model, X_data, Y_data, train_or_test): size = len(X_data) model.eval() # 模型切换为评估模式(禁用Dropout/BN等) with torch.no_grad(): # 禁用梯度计算,提升速度并节省显存 predictions = model(X_data) # 计算准确率:argmax(1)取概率最大的类别,与真实标签对比 correct = (predictions.argmax(1) == Y_data).type(torch.float).sum().item() correct /= size # 准确率=正确数/总数 loss = criterion(predictions, Y_data).item() # 计算损失 print(f"{train_or_test}:\t 准确率:{(100*correct):.2f}%,损失:{loss:.4f}") model.train() # 切回训练模式 return correct epochs =15000# 训练轮数 accs =[]# 记录测试集准确率 for epoch in range(epochs):#训练网络 # 前向传播 outputs=model(X_train)#model前向传播 loss = criterion(outputs,Y_train) # 反向传播与参数更新 optimizer.zero_grad() # 梯度的初始化,梯度清零 loss.backward() # 反向传播计算梯度 optimizer.step() # 更新模型参数 # 每100轮打印一次结果,评估模型 if (epoch +1)%100==0: print(f'Epoch[{epoch + 1}/{epochs},Loss:{loss.item():.4f}') train_acc =evaluate_model(model,X_train,Y_train,'train') test_acc = evaluate_model(model,X_test,Y_test,'test') accs.append(test_acc*100) # 记录最优结果 net_result={} net_result['acc']=max(accs) result_data['net']=net_result运行结果:


训练数据集准确率:1
测试数据集准确率:0.94888
全连接神经网络
优势:结构简单、训练速度快,适配无局部关联的表格数据(如年龄、性别、收入等)
劣势:无参数共享,参数数量随特征数指数增长,易过拟合;忽略特征的局部 / 序列关联,不适配序列 / 图像数据。
8.卷积神经网络算法
卷积神经网络是神经网络的子集,继承了 神经网络 的核心训练逻辑,核心结构:卷积层+池化层+少量全连接,通过「局部感受野 + 参数共享」优化,专门处理有局部关联的结构化数据(序列、图像、3D 数据)。
import torch import torch.nn as nn import torch.optim as optim import numpy as np定义卷积神经网络模型
class ConvNet(nn.Module): def __init__(self, num_features, hidden_size, num_classes): super(ConvNet, self).__init__() # 1D卷积层:输入通道1,输出通道16,卷积核长度3,padding=1(保持序列长度) self.conv1 = nn.Conv1d(in_channels=1, out_channels=16, kernel_size=3, padding=1) self.conv2 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3, padding=1) self.conv3 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3, padding=1) self.relu = nn.ReLU() self.fc = nn.Linear(64, num_classes) def forward(self, x):#x[1472*1*13] # 由于Conv1d期望的输入维度是(batch_size, channels, length),我们需要增加一个维度 x = x.unsqueeze(1) # 增加channels维度 # 卷积+激活:提取局部序列特征 x = self.conv1(x) x = self.relu(x) x = self.conv2(x) x = self.relu(x) x = self.conv3(x) #全局平均池化:压缩维度➡️[batch,64] x = self.relu(x) x = x.mean(dim=2) # 这里使用平均池化作为简化操作 x = self.fc(x) return x # Conv1d输入格式:[batch, in_channels, seq_len],需通过unsqueeze(1)为扁平特征增加通道维度;
CNN 的不同维度实现仅适配不同数据形态,核心逻辑完全一致:
| 卷积类型 | 输入维度 | 卷积核形态 | 滑动维度 | 核心应用场景 |
|---|---|---|---|---|
| Conv1d | [batch, C, L](序列) | [out_C, in_C, kL] | 沿长度 L 滑动 | 时间序列、语音、文本 |
| Conv2d | [batch, C, H, W](图像) | [out_C, in_C, kH, kW] | 沿 H/W 滑动 | RGB 图片、灰度图、二维特征图 |
| Conv3d | [batch, C, D, H, W](3D) | [out_C, in_C, kD, kH, kW] | 沿 D/H/W 滑动 | 3D 医学影像、视频、点云数据 |
卷积核kernel_size=3:每次捕捉 3 个连续特征的局部关联(如传感器读数的短期趋势);
参数共享:卷积核权重在整个序列上复用,大幅减少参数数量。
数据预处理:Pandas转PyTorch张量
# 1. 将Pandas DataFrame格式的训练特征数据转换为PyTorch张量 # - train_data_x.values:把表格数据转为numpy矩阵(Pandas表格无法直接输入神经网络) # - dtype=torch.float32:特征数据必须是浮点型(神经网络的权重是浮点型,输入需匹配) X_train = torch.tensor(train_data_x.values, dtype=torch.float32) # 2. 训练标签数据转张量(分类任务标签默认转为long型,适配CrossEntropyLoss) Y_train = torch.tensor(train_data_y.values) # 3. 测试特征数据转张量(同训练集格式) X_test = torch.tensor(test_data_x.values, dtype=torch.float32) # 4. 测试标签数据转张量 Y_test = torch.tensor(test_data_y.values) 模型初始化:
# 冗余参数 hidden_size = 10 # 分类任务的类别数:4分类 num_classes = 4 # 实例化一维卷积神经网络模型 # 参数说明:13=输入特征长度(序列长度),hidden_size=冗余参数,num_classes=4分类 model = ConvNet(13, hidden_size, num_classes) # 定义损失函数:交叉熵损失(多分类任务的标配损失函数) # 作用:衡量模型预测结果与真实标签的差距,值越小预测越准 criterion = nn.CrossEntropyLoss() # 定义优化器:Adam自适应优化器(比SGD收敛更快) # 参数说明:model.parameters()=优化模型所有参数,lr=0.001=学习率(参数更新步长) optimizer = optim.Adam(model.parameters(), lr=0.001)模型训练主逻辑
# 训练模型 # 训练轮数:遍历全部训练数据的次数 num_epochs = 15000 # 用于保存每100轮的训练精度,后续取最大值 accs=[] # 遍历每一轮训练 for epoch in range(num_epochs): # 1. 前向传播:将训练数据输入模型,得到预测输出 # outputs.shape = [batch_size, 4](每个样本输出4个类别的预测值) outputs = model(X_train)#向前传播 # 2. 计算损失:对比预测输出和真实标签的差 loss = criterion(outputs,Y_train) # 3. 反向传播 + 参数优化: # - optimizer.zero_grad():清空上一轮的梯度(避免梯度累加) # - loss.backward():自动计算所有参数的梯度(损失对参数的偏导数) # - optimizer.step():根据梯度更新模型参数(最小化损失) optimizer.zero_grad()#反向传播和优化 loss.backward() optimizer.step() # 每训练100轮,打印训练结果并评估精度 if (epoch + 1)%100==0: # 打印当前轮数和损失值(loss.item()取出张量的数值) print(f'Epoch[{epoch + 1}/{num_epochs},Loss:{loss.item():.4f}') #测试模型 # with torch.no_grad():关闭梯度计算 with torch.no_grad(): # 用训练集数据预测 predictions = model(X_train) # 取预测值中概率最大的维度作为预测类别(argmax(dim=1):按行取最大值索引) # 例如:predictions=[[0.1,0.8,0.05,0.05]] → predicted_classes=1(第2类) predicted_classes = predictions.argmax(dim=1) accuracy = (predicted_classes==Y_train).float().mean() print(f'Train Accuracy:{accuracy.item()*100:.2f}%') accs.append(accuracy*100) # 创建字典保存CNN模型的最优结果 cnn_result={} # 取accs列表中的最大值(训练过程中的最高准确率),.item()转为Python数值 cnn_result['acc']=max(accs).item() result_data['cnn']=cnn_result # 打印最终结果字典(包含CNN的最高准确率) print(result_data) #导入json库:用于将字典数据保存为JSON文件 import json#数据格式,网络传输。保存提取json类型的数据。 csv:表格类型的数据 # 使用 'w' 模式打开文件,确保如果文件已存在则会被覆盖, result = {} result['mean fill'] = result_data with open(r'temp_data/平均值填充result.json', 'w', encoding='utf-8') as file: # 使用 json.dump() 方法将字典转换为 JSON 格式并写入文件,JSON一般来是字典 json.dump(result, file, ensure_ascii=False, indent=4) 运行结果:

卷积神经网络的准确率为100%很高,说明与全连接神经网络相比,卷积神经网络泛化能力更强,不容易过拟合