《人工智能概论》实验4 知识点复习提纲
一、实验任务与数据简介
-
任务:根据房屋的79个特征(如面积、地段、建筑年份等)预测房价(SalePrice)。
-
数据集:来自Kaggle的房价预测竞赛,包含训练集(train.csv)和测试集(test.csv)。
-
评价指标:通常使用均方根对数误差(RMSLE),但实验中我们使用均方误差(MSE)作为损失函数。
二、数据预处理流程(核心)
1. 标签预处理:取对数
-
对目标变量
SalePrice取对数:y_train = np.log(train_data['SalePrice']) -
原因:房价分布通常右偏(长尾),取对数使其接近正态分布,利于模型训练;且对数误差与相对误差相关,更合理。
2. 合并训练集和测试集
-
为统一进行特征工程,将训练集(不含标签)和测试集按行合并。
-
好处:对缺失值填充、编码等操作一致,避免测试集单独处理时出错。
3. 处理缺失值
-
数值型特征:用中位数填充(
median()),因为中位数对异常值更稳健。 -
类别型特征:用字符串
'None'填充,表示缺失为一类。
4. 处理类别特征:独热编码(One-Hot Encoding)
-
使用
pd.get_dummies(data, dummy_na=True) -
作用:将类别变量转换为0/1数值,使模型能使用。
-
dummy_na=True:为缺失值也创建一个虚拟列,避免信息丢失。
5. 标准化(Z-score标准化)
-
公式:
X_std = (X - mean) / std -
注意:用训练集的均值与标准差标准化训练集、验证集和测试集(不能重新计算测试集的统计量,否则分布不一致)。
-
标准化让所有特征在同一量级,加快梯度下降收敛。
三、数据集划分
-
训练集:用于训练模型参数。
-
验证集:从训练集中划分出一部分(如20%),用于调参和早停,不用于训练。
-
测试集:原始提供的 test.csv,用于最终提交(无标签)。
-
区别:验证集有标签,可计算损失评估模型;测试集无标签,仅供预测。
四、模型设计(MLP)
-
使用
nn.Module自定义模型,结构可配置:input_dim→ 多个隐藏层(如256→128→64)→ 输出层(1个神经元)。 -
每个隐藏层后跟:
-
激活函数(如
ReLU) -
Dropout层(随机丢弃一部分神经元,防止过拟合)
-
-
Dropout:
dropout_rate表示神经元被丢弃的概率。训练时启用,验证/测试时自动关闭(需model.eval())。
五、损失函数与优化器
-
损失函数:回归任务用均方误差
nn.MSELoss()。 -
优化器:Adam(自适应学习率),常用参数
lr(学习率)和weight_decay(L2正则化系数)。 -
weight_decay:对参数施加L2惩罚,使权重趋向小值,防止过拟合。
六、训练技巧
1. 学习率调度器 ReduceLROnPlateau
-
当验证损失连续
patience轮不再下降时,将学习率乘以factor。 -
作用:自动降低学习率,帮助模型跳出局部最优或平稳期。
2. 早停(Early Stopping)
-
当验证损失连续
patience轮没有下降时,停止训练,防止过拟合。 -
同时保存最佳模型(
best_val_loss对应的权重)。
3. 设备管理(device)
-
将模型和数据移动到 GPU(
cuda)或 CPU。 -
预测时,结果需用
.cpu()移回CPU才能转为NumPy。
七、模型评估与可视化
-
损失曲线:训练损失和验证损失随epoch变化。若验证损失上升而训练损失下降 → 过拟合;两者都高且不降 → 欠拟合。
-
真实值vs预测值散点图:点应大致落在
y=x对角线附近,偏离说明预测偏差大。
八、预测与提交
-
加载最佳模型,对测试集进行预测,注意:
-
模型输出的是对数价格,需用
np.exp()转换回原始价格。
-
-
生成提交文件:
Id和SalePrice两列。
附加
正则化手段:权重衰减(L2正则化)与暂退法(Dropout)—— 解决过拟合
一、过拟合与欠拟合
1.1 概念定义
| 现象 | 定义 | 训练误差 | 验证/测试误差 |
|---|---|---|---|
| 欠拟合 | 模型过于简单,未能捕捉数据中的规律 | 高 | 高 |
| 过拟合 | 模型过于复杂,死记硬背训练数据,泛化能力差 | 很低 | 高 |
| 正常拟合 | 模型复杂度适中,既能学习规律又能泛化 | 较低 | 较低 |
1.2 图像呈现状态
假设我们用一个多项式拟合一些散点:
-
欠拟合(例如用一次函数拟合抛物线分布):
-
图像:一条直线穿不过大部分点,预测曲线平滑但偏离真实趋势。
-
特点:模型太简单,偏差高。
-
-
过拟合(例如用高次多项式拟合少量点):
-
图像:曲线剧烈震荡,精确穿过每一个训练点,但形状极不规则。
-
特点:模型太复杂,方差高,对噪声也学习了。
-
-
正常拟合(例如用二次函数拟合抛物线分布):
-
图像:平滑曲线,基本贴合点分布趋势,且没有剧烈波动。
-
手绘图描述(考试时可用文字说明):
-
欠拟合:直线穿过散点,大部分点远离直线。
-
过拟合:锯齿状曲线,每个点都被准确经过,但预测新点时会偏离很远。
二、两种正则化手段详解
2.1 权重衰减(Weight Decay,即 L2 正则化)
原理
在损失函数中添加一个惩罚项:

作用:惩罚大的权重,迫使权重尽量小,从而降低模型复杂度,防止过拟合。
用法(PyTorch)
optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=0.001)
# 或 Adam
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=0.001)
参数 weight_decay 的含义
-
即公式中的 λ(lambda),控制正则化强度。
-
越大,对权重的惩罚越重,模型越简单(可能欠拟合)。
-
越小,正则化作用越弱,接近无正则化。
-
常用值:
1e-4,1e-5,0.001等。
为什么叫“权重衰减”?
因为梯度下降更新时,相当于先把权重乘以 (1 - ηλ) 再减去梯度项,即权重被衰减了。
2.2 暂退法(Dropout)
原理
训练时,以概率 p 随机将某些神经元的输出置为0(“丢弃”或“暂退”),并且为了保持期望不变,保留的神经元输出除以 (1-p)。
作用:强制网络学习冗余表示,避免神经元之间过强的协同适应(co-adaptation),提高泛化能力。
用法(PyTorch)
import torch.nn as nn
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 256)
self.dropout1 = nn.Dropout(p=0.5) # 暂退概率 0.5
self.fc2 = nn.Linear(256, 128)
self.dropout2 = nn.Dropout(p=0.5)
self.fc3 = nn.Linear(128, 10)
def forward(self, x):
x = x.view(x.size(0), -1)
x = torch.relu(self.fc1(x))
x = self.dropout1(x) # 训练时随机丢弃,测试时自动关闭
x = torch.relu(self.fc2(x))
x = self.dropout2(x)
x = self.fc3(x)
return x
参数 p 的含义(Dropout rate)
-
每个神经元被丢弃的概率(即输出置0的概率)。
-
p=0.5:一半神经元随机失活(常用值)。
-
p=0.2:20%失活,正则化较弱。
-
p=0.9:90%失活,模型可能欠拟合。
-
注意:测试时 Dropout 层会自动关闭(不丢弃神经元),且不需要缩放。
三、对比总结
| 方法 | 核心思想 | 参数 | 参数越大 → | 训练/测试行为 |
|---|---|---|---|---|
| 权重衰减 | 限制权重大小 | weight_decay (λ) |
模型越简单 | 训练和测试时都生效 |
| Dropout | 随机丢弃神经元 | p |
丢弃越多 → 正则化越强 | 训练时随机丢弃,测试时不丢弃 |
四、例题
例题1(概念判断)
题目:判断下列现象属于欠拟合还是过拟合。
(1) 训练损失 0.01,验证损失 0.85。
(2) 训练损失 0.45,验证损失 0.46。
(3) 训练损失 0.80,验证损失 0.81。
答案:
(1) 过拟合(训练很好,验证很差)
(2) 正常拟合(两者相近且较低)
(3) 欠拟合(两者都高)
例题2(原理简述)
题目:简述权重衰减为什么能防止过拟合。
参考答案:
权重衰减在损失函数中加入权重的平方和,使模型在优化时不仅最小化原始损失,还要尽量保持权重较小。小权重意味着模型对输入变化不敏感,决策边界更平滑,从而降低了过拟合风险。
例题3(Dropout 参数设置)
题目:在训练一个深度网络时,发现验证集准确率远低于训练集,你怀疑是过拟合。你想在模型中增加 Dropout 层,现有两个候选参数 p=0.2 和 p=0.8。应该选哪个?为什么?
答案:
应选 p=0.8(丢弃80%的神经元)。因为过拟合严重时,需要更强的正则化,更大的 p 意味着更多神经元被随机丢弃,模型被迫学习更鲁棒的特征。当然 p 过大可能导致欠拟合,需要调参。
例题4(代码填空)
题目:补全以下代码,添加 Dropout 层和权重衰减。
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 256)
self.dropout = nn.______(p=0.5) # 填空1
self.fc2 = nn.Linear(256, 10)
def forward(self, x):
x = x.view(x.size(0), -1)
x = torch.relu(self.fc1(x))
x = self.______(x) # 填空2
x = self.fc2(x)
return x
model = MLP()
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=______) # 填空3
答案:
填空1:Dropout
填空2:dropout(实例名)
填空3:0.001(或其他数值,如 1e-4)
例题5(数值理解)

《人工智能概论》实验4 考试题
(总分100分,建议完成时间80分钟)
一、单选题(每题3分,共15分)
-
对房价标签
SalePrice取对数的原因是( )
A. 使标签变为整数
B. 让标签分布更接近正态分布,利于模型训练
C. 减少特征数量
D. 方便可视化 -
填充数值特征的缺失值时,实验中使用的是( )
A. 均值
B. 众数
C. 中位数
D. 直接删除 -
以下哪个操作可以防止模型过拟合?( )
A. 增加学习率
B. 使用 Dropout
C. 减少训练数据
D. 不使用激活函数 -
标准化测试集时,应该使用( )
A. 测试集的均值和标准差
B. 训练集的均值和标准差
C. 验证集的均值和标准差
D. 全数据集的均值和标准差 -
在早停机制中,
patience参数的含义是( )
A. 训练的总轮数
B. 学习率下降的等待轮数
C. 验证损失连续不下降的最大轮数,超过则停止训练
D. 每轮训练的批次数量
二、填空题(每空2分,共20分)
-
对类别特征进行独热编码应使用 pandas 的
pd.______()函数,参数dummy_na=True的作用是 ______。 -
模型定义中,Dropout层的参数
dropout_rate=0.2表示 ______。训练时 Dropout 生效,验证时需调用model.______()来禁用 Dropout。 -
学习率调度器
ReduceLROnPlateau中,mode='min'表示监控指标 ______ 时降低学习率,factor=0.5表示学习率 ______。 -
在训练循环中,梯度清零使用
optimizer.______(),参数更新使用optimizer.______()。 -
模型预测后,输出的
SalePrice是 ______(填“原始价格”或“对数价格”),需要用np.______()转换回原始价格。
三、判断题(正确打“√”,错误打“×”,每题2分,共10分)
-
( )训练集和测试集应该分别进行标准化,各自计算均值和标准差。
-
( )Dropout层在验证阶段也会随机丢弃神经元,以保持一致性。
-
( )早停机制中,当验证损失连续10轮不下降时,应停止训练并保存最佳模型。
-
( )独热编码会增加特征的维度。
-
( )均方误差(MSE)是分类问题的常用损失函数。
四、简答题(将原实验中的思考题整合,共35分)
简答题1(4分,来自实验一)
device 变量的作用是什么?如果电脑有GPU,device 会是什么?
简答题2(4分,来自实验二)
训练集和测试集分别有多少个样本?目标变量(预测值)是哪一列?
简答题3(4分,来自实验3.1)
为什么要对 SalePrice 取对数?如果不取对数会怎样?
简答题4(4分,来自实验3.3)
为什么需要对类别特征进行独热编码?dummy_na=True 的作用是什么?
简答题5(4分,来自实验3.5)
为什么要用训练集的均值和标准差来标准化测试集,而不是重新计算?
简答题6(4分,来自实验四)
验证集和测试集的区别是什么?为什么需要验证集?
简答题7(4分,来自实验四)
模型训练时,代码中计算的 train_loss 和 val_loss 分别是哪个集的结果?它们各自的作用是什么?
简答题8(4分,来自实验五)
Dropout层放在什么位置?它的参数 dropout_rate 代表什么?如果将 dropout_rate 从 0.2 改为 0.5,会发生什么?
简答题9(3分,来自实验五)
模型定义中,self.net = nn.Sequential(*layers) 的作用是什么?
五、代码填空题(每空2分,共20分)
请根据上下文填写正确的代码。
# 处理缺失值
numeric_cols = all_data.select_dtypes(include=[np.number]).columns
for col in numeric_cols:
if all_data[col].isnull().any():
median_val = all_data[col].______() # 空1
all_data[col].fillna(median_val, inplace=True)
# 独热编码
all_data = pd.______(all_data, dummy_na=True) # 空2
# 标准化
train_means = X_train.______() # 空3
train_stds = X_train.______() # 空4
# 创建 DataLoader
train_dataset = TensorDataset(______, ______) # 空5, 空6
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=______) # 空7
# 模型定义中的激活函数和 Dropout
layers.append(nn.______()) # 空8
layers.append(nn.______(dropout_rate)) # 空9
# 损失函数
criterion = nn.______() # 空10
参考答案与超详细解析
一、单选题
-
B
解析:房价分布通常右偏(长尾),取对数后接近正态分布,利于模型学习;同时预测对数价格再指数还原,得到的误差更接近相对误差,符合竞赛评价指标RMSLE。 -
C
解析:实验中使用中位数填充。中位数对异常值不敏感,比均值更稳健;尤其房价数据中可能存在极端值(豪宅),中位数更合适。 -
B
解析:Dropout随机丢弃神经元,迫使网络学习冗余表示,防止过拟合。增加学习率可能使训练不稳定;减少数据反而容易过拟合;无激活函数无法学习非线性。 -
B
解析:标准化必须使用训练集的统计量,因为测试集是模拟“未见数据”,我们不知道其分布。若使用测试集的均值和标准差,相当于“偷看”了测试集,会破坏评估的公正性。 -
C
解析:patience表示验证损失连续不下降的轮数上限。当连续patience轮验证损失都没有改善时,停止训练,防止过拟合。
二、填空题
-
答案:
get_dummies;为缺失值单独创建一个虚拟列
解析:pd.get_dummies将类别转换为0/1列。dummy_na=True会对原本缺失的值生成一列,例如col_NaN标记为1,保留缺失信息。 -
答案:每个神经元有20%的概率被丢弃(或随机失活概率0.2);
eval()
解析:dropout_rate是神经元被暂时移除的概率。训练时启用,验证时需用model.eval()关闭Dropout,让所有神经元参与计算。 -
答案:不再下降(或达到最小值);乘以0.5(即缩小一半)
解析:mode='min'表示监控指标(如验证损失)达到最小值时触发;factor=0.5表示将学习率乘以0.5,降低一半。 -
答案:
zero_grad();step()
解析:标准三步:清零梯度(zero_grad)→ 反向传播(backward)→ 更新参数(step)。 -
答案:对数价格;
exp
解析:模型训练时对SalePrice取了对数,所以输出的是对数价格。提交时需要还原为原始价格,用np.exp()。
三、判断题
-
×
解析:测试集必须使用训练集的均值和标准差,不能独立计算,否则导致分布不一致。 -
×
解析:Dropout仅在训练阶段启用,验证和测试阶段自动关闭(需调用model.eval()),否则会导致预测结果随机。 -
√
解析:早停机制正是这样:连续patience轮验证损失未改善则停止,并回滚到最佳模型。 -
√
解析:每个类别值会生成一个新列,因此特征维度增加(如性别有男、女,则变成两列)。 -
×
解析:MSE 是回归任务的损失函数,分类任务通常用交叉熵。
四、简答题(详细解析)
简答题1
作用:device 变量指定模型和数据运行的硬件(CPU或GPU)。
有GPU时:device = torch.device('cuda')。
解析:GPU并行计算可大幅加速训练。代码中通过 torch.cuda.is_available() 自动判断,避免手动修改。
简答题2
训练集样本数:根据 train_data.shape,一般为1460(Kaggle房价数据集)。
测试集样本数:1459。
目标变量列:'SalePrice'。
简答题3
取对数原因:
-
房价分布右偏,对数变换后接近正态分布,满足线性回归假设。
-
使用对数损失(RMSLE)对异常值不敏感,且预测误差与相对误差相关。
不取对数的后果: -
模型可能受高价房影响大,低价房预测不准;
-
损失值巨大,训练不稳定;
-
提交的RMSLE得分会较差。
简答题4
独热编码原因:机器学习模型只能处理数值,类别特征(如地段、材质)需要转换为0/1特征。dummy_na=True:为缺失值单独生成一列(如 col_NaN),保留缺失信息,避免简单删除导致信息丢失。
简答题5
标准化测试集使用训练集统计量:
-
测试集模拟真实未见数据,我们不知道其均值和标准差。
-
若使用测试集自己的统计量,相当于引入了未来信息,评估结果不可靠。
-
保证训练和测试数据处于同一量纲,模型才能正确预测。
简答题6
验证集:从训练集中划分,有标签,用于调参、早停、选择最佳模型。
测试集:无标签(竞赛提供),用于最终评估或提交。
为什么需要验证集:防止模型在测试集上过拟合(不能反复使用测试集调参),验证集作为“模拟考试”来调整超参数。
简答题7
-
train_loss:训练集上的平均损失,反映模型拟合训练数据的能力。 -
val_loss:验证集上的平均损失,反映模型泛化能力。
作用:比较两者可判断欠拟合(两者都高)、过拟合(train_loss低,val_loss高)或正常。
简答题8
Dropout位置:通常放在每个隐藏层之后、激活函数之后(或之前均可,但常见于激活后)。dropout_rate:每个神经元被随机丢弃的概率,0.2表示20%的神经元在每次前向传播时临时移除。
改为0.5:更强的正则化,可能提升泛化能力,但若模型容量不足,可能导致欠拟合;训练速度变慢(因为有效参数减少)。
改为0:关闭Dropout,容易过拟合。
简答题9
nn.Sequential(*layers) 将 layers 列表中的所有层(Linear、ReLU、Dropout等)按顺序封装成一个序列网络。调用 forward 时自动依次执行。这样代码简洁,不需要手动写每层的前向传播。
五、代码填空题答案
空1:median
空2:get_dummies
空3:mean
空4:std
空5:X_train_tensor
空6:y_train_tensor
空7:True
空8:ReLU(或其他激活函数如 LeakyReLU,但实验使用ReLU)
空9:Dropout
空10:MSELoss
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)