简介:这是一份面向深度学习初学者与备考人群的专项练习资料,以100道选择题的形式覆盖机器学习与深度学习的核心知识点,帮助学习者在刷题中检验理论掌握程度、查漏补缺。题目涉及监督与无监督学习、梯度下降、交叉验证、准确率与F1分数等评估指标、L1正则化与PCA降维、类别不平衡处理、过拟合、CNN与全连接层、词嵌入、SVM支持向量、YOLO目标检测、学习率以及主流深度学习框架等内容,并延伸至人工智能、机器学习与深度学习三者关系的辨析。资源包共1个docx文档,约76KB,结构紧凑,便于打印或在线练习。目前已有142人学习浏览。每道题均配有选项,可自测对概念细节的掌握,适合课程复习、面试准备与知识点梳理,是巩固深度学习基础、快速定位薄弱环节的实用工具。
1. 深度学习100道选择题:从题库到能力评估的落地路径
很多人第一次看到“深度学习100道选择题”这个标题,会下意识觉得这就是一份刷题资料。但如果你带过团队、做过技术面试、或者给新人做过培训,就会意识到:一套高质量的100道选择题,本质上是一套能力评估工具。它要解决的不是“有没有题做”,而是“怎么用最低成本判断一个人对深度学习核心概念的掌握程度”。
我在某公司内部做算法岗转正考核时,就吃过没有标准化题库的亏。当时靠几位老员工各自出题,结果同一批新人拿到的卷子难度方差极大,有人抽到全是卷积公式推导,有人抽到全是框架API调用,最后分数根本没法横向比较。后来我们花了三周时间,把深度学习知识体系拆成六个模块,每个模块出15到20道选择题,最终收敛到100道,才让考核有了可复现的基准线。
这套东西适合三类人:需要做技术面试的团队负责人、想系统自检知识盲区的算法工程师、以及给课程设计阶段测验的讲师。接下来的内容,我会把题库设计、难度分层、干扰项构造、自动评分脚本和避坑经验全部拆开讲清楚。
2. 把100道题拆成六个知识模块:权重分配与难度分层
2.1 模块划分与题量分配逻辑
100道题不能平均撒胡椒面。深度学习这个领域,有些概念是地基,有些是上层建筑。我一般按下面的比例来分配题量,这个比例是经过多轮实际考核验证后收敛出来的:
| 知识模块 | 题量 | 占比 | 核心考查点 |
|---|---|---|---|
| 数学基础 | 12 | 12% | 矩阵运算、梯度、概率分布、信息论 |
| 神经网络基础 | 20 | 20% | 反向传播、激活函数、损失函数、初始化 |
| 卷积网络 | 18 | 18% | 卷积计算、池化、感受野、经典结构 |
| 序列模型 | 15 | 15% | RNN、LSTM、注意力机制、Transformer |
| 训练与优化 | 20 | 20% | 优化器、正则化、学习率策略、批归一化 |
| 工程实践 | 15 | 15% | 框架使用、数据处理、模型部署、调试 |
数学基础只占12%,是因为选择题这种形式很难考查深层推导能力,能覆盖到“这个公式在说什么”的层面就够了。神经网络基础和训练优化各占20%,因为这两块是实际工作中翻车最多的地方。工程实践占15%,用来筛掉那些只会背公式但没动过手的人。
难度分层上,我按3:5:2的比例分配简单、中等、困难题。简单题考查定义和基本事实,中等题考查理解和简单计算,困难题考查多概念综合和边界情况判断。这个比例不是拍脑袋定的——如果简单题低于30%,区分度会集中在低分段;如果困难题超过25%,大部分人分数会挤在及格线附近,失去区分意义。
2.2 用Python脚本管理题库与自动组卷
题库不建议用Excel维护,字段一多就容易乱。我一般用JSON来存,结构清晰,也方便程序读取。下面是一个题目条目的标准结构:
# question_bank.py # 题库条目结构定义与示例 import json import random from typing import List, Dict # 单道题目的标准结构 SAMPLE_QUESTION = { "id": "NN-001", # 模块前缀 + 序号 "module": "神经网络基础", # 所属知识模块 "difficulty": "medium", # easy / medium / hard "stem": "在反向传播中,损失函数对某一层权重的梯度主要依赖于什么?", "options": { "A": "该层的输入和从后一层传回的误差梯度", "B": "该层的输出和损失函数的绝对值", "C": "该层权重的初始值和学习率", "D": "该层的偏置项和激活函数的导数" }, "answer": "A", "explanation": "根据链式法则,权重梯度等于该层输入与从后一层传回的误差梯度的乘积。", "tags": ["反向传播", "链式法则", "梯度计算"] } def load_bank(path: str) -> List[Dict]: """从JSON文件加载题库""" with open(path, "r", encoding="utf-8") as f: return json.load(f) def sample_paper(bank: List[Dict], n: int = 100) -> List[Dict]: """按模块和难度分层抽样组卷""" # 按模块分组 by_module = {} for q in bank: by_module.setdefault(q["module"], []).append(q) # 各模块目标题量(按前述比例) module_quota = { "数学基础": 12, "神经网络基础": 20, "卷积网络": 18, "序列模型": 15, "训练与优化": 20, "工程实践": 15 } paper = [] for module, quota in module_quota.items(): pool = by_module.get(module, []) # 按难度分层抽样:easy 30%, medium 50%, hard 20% easy = [q for q in pool if q["difficulty"] == "easy"] medium = [q for q in pool if q["difficulty"] == "medium"] hard = [q for q in pool if q["difficulty"] == "hard"] n_easy = round(quota * 0.3) n_medium = round(quota * 0.5) n_hard = quota - n_easy - n_medium selected = (random.sample(easy, min(n_easy, len(easy))) + random.sample(medium, min(n_medium, len(medium))) + random.sample(hard, min(n_hard, len(hard)))) paper.extend(selected) random.shuffle(paper) return paper[:n]这段代码的核心逻辑是分层抽样。module_quota字典控制每个模块出多少题,n_easy、n_medium、n_hard控制难度分布。random.sample保证同一模块内不重复抽题。最后random.shuffle打乱顺序,避免同一模块的题连续出现。
参数调整上,如果发现某次考试整体偏难,可以把n_easy的系数从0.3调到0.35,同时降低n_hard。如果某个模块的题目池不够,min()函数会兜底,但最好保证每个模块的题目池至少是需求量的1.5倍,否则每次组卷重复率会很高。
2.3 干扰项设计的四个原则
选择题的质量,八成看干扰项。我见过太多题库,正确答案一眼就能看出来,因为干扰项要么明显荒谬,要么和题干毫无关系。好的干扰项要满足四个条件:
第一,语法结构一致。如果正确答案是“该层的输入与从后一层传回的误差梯度的乘积”,干扰项就不能写成“输入乘以误差”这种长度和结构完全不同的表述,否则考生靠语感就能排除。
第二,对应常见误解。比如考查Batch Normalization,正确答案是“在训练时对每个mini-batch做归一化”,干扰项应该包含“对整个数据集做归一化”“只在测试时做归一化”这类真实存在的错误理解,而不是“对标签做归一化”这种没人会犯的错。
第三,难度对等。如果正确答案涉及两个概念的组合,干扰项也应该涉及两个概念的组合,不能一个是复合概念、另一个是单一概念。
第四,避免绝对化词汇。“总是”“从不”“一定”这类词会让干扰项变得容易排除。除非你故意设置一个绝对化但正确的选项来考查考生的审题能力,否则干扰项里尽量用“通常”“在大多数情况下”这类限定词。
3. 从题干到解析:让每道题都能反向定位知识盲区
3.1 题干编写的三个反模式
题干不是越短越好,也不是越长越好。我总结了三类需要避免的写法:
反模式一:题干里藏着答案线索。比如“以下关于ReLU激活函数的说法,正确的是”,然后选项里有一个是“ReLU在负半轴梯度为零,可能导致神经元死亡”。这个选项本身是对的,但题干里的“ReLU”已经提示了考生往激活函数特性上想,如果换成“以下关于常见激活函数的说法”,难度会更高。
反模式二:题干包含多个独立问题。比如“关于卷积核大小和步长,以下说法正确的是”,然后选项里有的在说卷积核、有的在说步长、有的在说填充。这种题考生做对了也不知道自己到底掌握了哪个点。一道题只考查一个核心概念,这是铁律。
反模式三:否定式题干滥用。“以下说法不正确的是”这种题干,考生需要先判断每个选项是否正确,再反向选择,认知负荷是正向题的两倍。除非你专门想考查审题能力,否则否定式题干占比不要超过10%。
3.2 解析字段的写法:从“为什么对”到“为什么错”
解析不能只写“正确答案是A,因为……”。好的解析要覆盖三层:正确答案为什么对、每个干扰项为什么错、这个知识点在实际中怎么用。下面是一个解析的完整示例:
# 解析字段的完整写法示例 EXPLANATION_SAMPLE = { "id": "OPT-007", "stem": "在使用Adam优化器时,如果发现训练损失剧烈震荡,以下哪种调整最可能有效?", "options": { "A": "增大beta1参数,使一阶矩估计更平滑", "B": "减小学习率,降低单步更新幅度", "C": "增大epsilon参数,增加数值稳定性", "D": "关闭偏置修正,使用原始矩估计" }, "answer": "B", "explanation": ( "正确答案是B。Adam的更新步长与学习率成正比," "损失剧烈震荡通常意味着单步更新幅度过大,减小学习率是最直接有效的措施。\n\n" "A错误:增大beta1会让一阶矩估计更依赖历史梯度," "虽然能平滑方向,但无法解决步长过大的问题。\n" "C错误:epsilon主要防止除零,对更新幅度的影响极小。\n" "D错误:关闭偏置修正会导致早期更新偏差更大,可能加剧震荡。\n\n" "实际工作中,遇到Adam震荡,先降学习率到原来的1/3到1/5," "如果还不行再考虑换优化器或检查数据分布。" ), "tags": ["Adam", "学习率", "训练稳定性"] }解析里用\n\n分段,是为了在导出PDF或网页展示时保持可读性。每个干扰项单独一段,用“A错误:”“B错误:”开头,方便考生快速定位。最后一段“实际工作中”是加分项,让题目不止于考试,还能指导实践。
3.3 用知识点标签做能力雷达图
每道题的tags字段不是装饰,它是做能力诊断的基础。当考生做完100道题,你可以按标签聚合正确率,生成一张雷达图。下面是用matplotlib生成雷达图的代码:
# radar_chart.py # 根据答题结果生成知识点能力雷达图 import numpy as np import matplotlib.pyplot as plt def plot_radar(tag_scores: dict, save_path: str = "radar.png"): """ tag_scores: {标签名: 正确率(0-1)} 例如 {"反向传播": 0.85, "优化器": 0.6, ...} """ labels = list(tag_scores.keys()) values = list(tag_scores.values()) n = len(labels) # 计算角度 angles = np.linspace(0, 2 * np.pi, n, endpoint=False).tolist() values += values[:1] # 闭合 angles += angles[:1] fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True)) ax.plot(angles, values, "o-", linewidth=2, color="#2E86AB") ax.fill(angles, values, alpha=0.25, color="#2E86AB") ax.set_xticks(angles[:-1]) ax.set_xticklabels(labels, fontsize=10) ax.set_ylim(0, 1) ax.set_yticks([0.2, 0.4, 0.6, 0.8, 1.0]) ax.set_yticklabels(["20%", "40%", "60%", "80%", "100%"], fontsize=8) ax.set_title("知识点掌握度雷达图", fontsize=14, pad=20) plt.tight_layout() plt.savefig(save_path, dpi=150) plt.close() # 使用示例 scores = { "反向传播": 0.85, "激活函数": 0.9, "初始化": 0.7, "优化器": 0.6, "正则化": 0.55, "批归一化": 0.75, "卷积计算": 0.8, "注意力机制": 0.5 } plot_radar(scores)这段代码的关键参数是tag_scores字典,键是标签名,值是正确率。ax.set_ylim(0, 1)固定量程,保证不同人之间的图可以横向对比。ax.fill填充颜色让图形更直观。生成的雷达图能一眼看出哪些标签的正确率明显低于平均线,那些就是需要重点复习的模块。
标签的粒度要控制好。太粗(比如只分“CNN”“RNN”)看不出具体问题,太细(比如“卷积核大小为3的卷积计算”)会导致每个标签只有一两道题,统计意义不足。我一般控制在15到25个标签之间,每个标签对应3到8道题。
4. 避坑:题库建设中最容易翻车的五个地方
4.1 题目难度主观标注导致组卷失衡
现象:同一道题,出题人标为“简单”,但实际考核中正确率只有40%。
原因:出题人自己觉得简单,是因为他已经掌握了这个知识点,产生了“知识诅咒”。他无法站在初学者的角度判断难度。
解决:难度标注不能靠感觉,要靠数据。新题入库时先标一个初始难度,然后在实际使用中记录正确率。正确率高于80%的降为简单,60%到80%的保持中等,低于60%的升为困难。每季度根据累积数据重新校准一次。
4.2 选项顺序固定被考生摸出规律
现象:有考生发现正确答案集中在B和C,A和D很少是正确答案。
原因:出题人潜意识里会把正确答案放在中间位置,或者习惯性地把某个选项设为正确答案后就不再调整。
解决:入库时记录正确答案的原始位置,组卷时用程序随机打乱选项顺序,同时更新answer字段。下面是一个打乱选项的代码片段:
import random def shuffle_options(question: dict) -> dict: """打乱选项顺序并更新正确答案""" options = list(question["options"].items()) correct_text = question["options"][question["answer"]] random.shuffle(options) new_options = {} new_answer = None for idx, (_, text) in enumerate(options): key = chr(65 + idx) # A, B, C, D new_options[key] = text if text == correct_text: new_answer = key question["options"] = new_options question["answer"] = new_answer return question这个函数在每次组卷时调用,保证同一道题在不同试卷中正确答案的位置不同。注意correct_text要在打乱前保存,否则打乱后找不到正确答案对应的文本。
4.3 解析写得太简略,考生看完还是不懂
现象:解析只写“A正确,因为链式法则”,考生看完不知道链式法则具体怎么用。
原因:出题人默认考生具备前置知识,但选择题的考生可能来自不同背景,前置知识参差不齐。
解决:解析要写到“一个没学过这门课但学过微积分的人能看懂”的程度。具体标准是:解析里出现的每个专业术语,要么在前文中解释过,要么在解析中给出定义或公式。如果解析超过200字还说不清,说明这道题考查的知识点太复杂,应该拆成两道题。
4.4 题目更新滞后于技术发展
现象:题库里还在考“Sigmoid作为激活函数的优势”,但实际工作中Sigmoid在隐藏层已经很少用了。
原因:题库建好后没有定期审查机制,出题人也没有持续跟踪领域进展。
解决:每半年做一次题目审查,标记出“当前最佳实践已变化”的题目。比如Sigmoid的题目可以保留,但要把考查重点从“优势”改为“局限性”和“适用场景”。同时每年补充10%到15%的新题,覆盖新出现的概念和技术。
4.5 自动评分脚本没有处理边界情况
现象:考生答案里有多余空格或大小写不一致时,评分脚本判为错误。
原因:脚本直接用==比较字符串,没有做标准化处理。
解决:评分前先对答案做标准化,去掉首尾空格、统一大写、过滤不可见字符。下面是一个健壮的评分函数:
def grade(answer_key: str, user_answer: str) -> bool: """标准化后比较答案""" if not user_answer: return False # 去空格、转大写、只保留字母 normalized = "".join( c for c in user_answer.strip().upper() if c.isalpha() ) return normalized == answer_key.strip().upper()这个函数能处理“ a ”、“A”、“a”等各种输入形式。如果考试系统支持多选,还需要把answer_key和user_answer都拆成集合再比较。
5. 用100道题做能力诊断:从分数到行动清单
5.1 总分之外,你还需要三个指标
100道题做完,如果只给一个总分,那这套题库的价值就浪费了。我一般会计算三个额外指标:
模块均衡度:各模块正确率的标准差。标准差越大,说明偏科越严重。比如数学基础90%、工程实践40%,标准差就很高,需要优先补工程实践。
难度通过率:简单题、中等题、困难题各自的正确率。如果简单题正确率低于70%,说明基础不牢;如果简单题90%但中等题只有50%,说明理解停留在表面;如果中等题80%但困难题只有20%,说明缺乏综合应用能力。
标签薄弱项:正确率低于60%的标签列表。这些标签对应的题目就是需要重点复习的内容。
5.2 从诊断结果生成复习路径
拿到三个指标后,可以按下面的优先级生成行动清单:
| 优先级 | 条件 | 行动 |
|---|---|---|
| P0 | 简单题正确率 < 70% | 回归教材,重读基础章节 |
| P1 | 某模块正确率 < 50% | 该模块专项练习,每天20题 |
| P2 | 标签正确率 < 60% | 针对该标签找3篇技术文章精读 |
| P3 | 困难题正确率 < 30% | 做综合项目,把多个概念串起来 |
这个优先级的意思是:先保证基础题不丢分,再补薄弱模块,然后针对具体标签查漏补缺,最后才去攻难题。很多人的误区是一上来就刷难题,结果基础题该拿的分没拿到。
5.3 一个我踩过的坑:别把题库当唯一标准
最后说一个血泪经验。我曾经用这套题库做转正考核,有个新人考了92分,但实际动手写代码时连数据加载管道都搭不起来。后来我反思,选择题能考查的是“知不知道”,但“会不会做”是另一回事。
所以现在我的做法是:选择题占考核权重的40%,动手任务占60%。选择题用来快速筛掉基础太差的人,动手任务用来判断实际能力。两者结合,才能既保证效率又不漏掉真正能干活的人。
如果你也在做类似的事情,建议先把题库建起来,用起来,根据数据迭代。不要追求一次做到完美,先有60分的版本,再慢慢优化到90分。希望帮到你。
本文还有配套的精品资源,点击获取