机器学习与深度学习常见问题解答

内容分享6小时前发布
0 0 0

37、硬投票分类器和软投票分类器有什么区别?

投票分类器

硬投票分类器 :通过聚合每个分类器的预测结果,选择获得最多票数的类别作为最终预测结果。

软投票分类器 :在所有分类器都能估计类别概率(即具备
predict_proba()
方法)的前提下,计算所有单个分类器对各类别的平均概率,并选择平均概率最高的类别作为最终预测结果。

说明 :软投票通常比硬投票性能更高,因为它会给高置信度的投票更多权重。

38、是否可以通过将装袋集成(bagging ensemble)分布到多个服务器上来加快训练速度?粘贴集成(pasting ensembles)、提升集成(boosting ensembles)、随机森林(random forests)或堆叠集成(stacking ensembles)呢?

可以通过将装袋集成分布到多个服务器上来加快训练速度,因为集成中的每个预测器相互独立。出于同样的原因,粘贴集成和随机森林也可以。

然而,提升集成中的每个预测器是基于前一个预测器构建的,训练必须按顺序进行,将训练分布到多个服务器上不会有任何帮助。

对于堆叠集成,给定层中的所有预测器相互独立,因此可以在多个服务器上并行训练,但一层中的预测器只能在前一层的所有预测器训练完成后才能训练。

39、包外评估的好处是什么?

由于预测器在训练期间看不到包外(OOB)实例,因此可以在这些实例上对其进行评估,而无需单独的验证集或交叉验证。还可以通过对每个预测器的 OOB 评估求平均值来评估集成模型本身。

40、是什么让极度随机树(Extra – Trees)比普通随机森林更随机?这种额外的随机性有什么帮助?极度随机树比普通随机森林训练速度慢还是快?

极度随机树除了像随机森林在每个节点考虑特征的随机子集进行分裂外,还为每个特征使用随机阈值,而不是像普通决策树那样搜索最佳可能的阈值,这使其更随机。 这种额外的随机性用更高的偏差换取了更低的方差,通常能产生更好的整体模型。 极度随机树比普通随机森林训练速度快得多,因为在每个节点为每个特征找到最佳可能的阈值是生成树最耗时的任务之一,而极度随机树无需进行此操作。

41、如果你的梯度提升集成模型对训练集过拟合,你应该提高还是降低学习率?

应该降低学习率。将学习率设置为较低值(如
0.1
),需要更多树来拟合训练集,但预测通常能更好地泛化,这是一种称为 收缩 的正则化技术。

42、降低数据集维度的主要动机是什么?主要缺点是什么?

主要动机

加快后续训练算法的速度(在某些情况下,甚至可以去除噪声和冗余特征,使训练算法表现更好) 可视化数据并深入了解最重要的特征 节省空间(压缩)

主要缺点

会丢失一些信息,可能会降低后续训练算法的性能 计算量可能很大 会增加机器学习流程的复杂性 转换后的特征通常难以解释

43、什么是维度灾难?

维度灾难

许多机器学习问题中,每个训练实例有数千甚至数百万个特征。这不仅使训练极其缓慢,还让找到好的解决方案变得更难,此问题常被称为 维度灾难

此外,高维空间中很多情况与低维不同:

如高维超立方体中,大多数点靠近边界; 高维数据集中,训练实例可能彼此距离远、数据稀疏; 新实例可能远离训练实例,导致预测不可靠; 且训练集维度越多,过拟合风险越大。

理论上可通过增加训练集大小来解决,但实际上,达到给定密度所需的训练实例数量随维度数呈指数增长。

44、一旦数据集的维度被降低,是否可以逆转这个操作?如果可以,如何进行?如果不可以,原因是什么?

使用讨论过的算法降低数据集维度后,几乎不可能完美逆转操作,因为降维过程中会丢失一些信息。不过,有些算法(如 PCA)有简单的逆变换程序,可以重建出与原始数据集相对相似的数据;而其他算法(如 t-SNE)则没有。

45、在哪些情况下你会使用普通PCA、增量PCA、随机PCA或核PCA?

普通PCA
默认选择,适用于数据集能放入内存的情况。

增量PCA
适用于数据集无法放入内存的大型数据集,也适用于需要实时处理新实例的在线任务。

随机PCA
适用于希望大幅降低维度且数据集能放入内存的情况。

核PCA
适用于处理非线性数据集。

46、创建计算图而不是直接执行计算的主要好处和缺点分别是什么?

主要好处:

TensorFlow 可以自动为你计算梯度(使用反向模式自动微分) TensorFlow 可以处理在不同线程中并行运行操作 便于在不同设备上运行相同的模型 简化内省,例如在 TensorBoard 中查看模型

主要缺点:

使学习曲线更陡峭 使逐步调试更困难

47、语句 a_val = a.eval(session=sess) 是否等同于 a_val = sess.run(a)?

是的,语句
a_val = a.eval(session=sess)
确实等同于
a_val = sess.run(a)

48、语句 a_val, b_val = a.eval(session=sess), b.eval(session=sess) 是否等同于 a_val, b_val = sess.run([a, b])?

否。在
a_val, b_val = a.eval(session=sess), b.eval(session=sess)
中,
a.eval(session=sess)

b.eval(session=sess)
会分别进行图的运行,可能会重复计算依赖节点的值;而
a_val, b_val = sess.run([a, b])
会在一次图运行中同时计算
a

b
的值,避免重复计算依赖节点的值。

49、如果你创建一个包含变量 w 的图 g,然后启动两个线程,并在每个线程中打开一个会话,两个会话都使用同一个图 g,那么每个会话会有变量 w 的独立副本,还是会共享该变量?

在本地 TensorFlow 中,会话管理变量值,每个会话会有变量
w
的独立副本。但在分布式 TensorFlow 中,如果两个会话连接到同一个集群并使用同一个容器,它们将共享变量
w
的值。

50、占位符和变量有什么区别?

变量 是有状态的,在图的连续运行中保持相同的值,通常用于保存模型参数或其他用途。 占位符 本身不执行计算,仅保存所代表张量的类型和形状信息,没有实际值。 若尝试评估依赖占位符的操作,必须为其提供值,否则会引发异常。 占位符常用于在执行阶段向 TensorFlow 提供训练或测试数据,也可用于向赋值节点传递值以改变变量的值。

51、当你运行计算图来评估一个依赖于占位符的操作,但没有提供占位符的值时会发生什么?如果操作不依赖于占位符又会怎样?

如果运行计算图来评估一个依赖于占位符的操作,但不提供其值,会抛出异常;
如果操作不依赖于占位符,则不会抛出异常。

52、当你运行一个图时,你可以馈送任何操作的输出值,还是只能馈送占位符的值?

当你运行一个图时,你可以馈送任何操作的输出值,而不只是占位符的值。不过在实践中,这种情况相当少见。

53、为什么通常更倾向于使用逻辑回归分类器而不是经典感知机(即使用感知机训练算法训练的单层线性阈值单元)?如何调整感知机使其等同于逻辑回归分类器?

通常更倾向于使用逻辑回归分类器而非经典感知机,原因在于:

经典感知机只有在数据集线性可分时才会收敛; 且无法估计类别概率。

而逻辑回归分类器:

即使数据集不是线性可分也能收敛到一个较好的解; 并且会输出类别概率。

要使感知机等同于逻辑回归分类器:

将感知机的激活函数改为逻辑激活函数(若有多个神经元则改为softmax激活函数); 并使用梯度下降(或其他最小化成本函数的优化算法,通常为交叉熵)进行训练。

54、为什么逻辑激活函数是训练第一代多层感知机(MLP)的关键要素?

因为阶跃函数只有平坦段,没有可用于梯度下降的梯度(梯度下降无法在平坦表面上移动),而逻辑函数处处有定义明确的非零导数,能让梯度下降在每一步取得进展。

55、如果你想将电子邮件分类为垃圾邮件或正常邮件,输出层需要多少个神经元?输出层应使用什么激活函数?如果要处理MNIST数据集,输出层需要多少个神经元,使用什么激活函数?对于预测房价的问题,输出层需要多少个神经元,使用什么激活函数?

将电子邮件分类为垃圾邮件或正常邮件,输出层需要1个神经元,通常使用逻辑激活函数。

处理MNIST数据集,输出层需要10个神经元,使用softmax激活函数。

预测房价,输出层需要1个神经元,输出层不使用任何激活函数。

56、什么是反向传播,它是如何工作的?反向传播和反向模式自动微分有什么区别?

反向传播简介

反向传播是一种用于训练人工神经网络的技术。它的工作方式为:

对于每个训练实例,先将其输入网络并计算每一层每个神经元的输出(前向传播)。 接着测量网络的输出误差。 计算最后一个隐藏层的每个神经元对每个输出神经元误差的贡献。 依次向前计算前一个隐藏层的每个神经元的误差贡献,直到输入层(反向传播)。
– 此过程通过在网络中反向传播误差梯度来高效测量网络中所有连接权重的误差梯度。 最后,使用之前测量的误差梯度对网络中所有连接权重进行梯度下降步骤。

反向传播与反向模式自动微分的区别

反向传播 :指的是使用多个反向传播步骤训练人工神经网络的整个过程,每个步骤计算梯度并使用它们执行梯度下降步骤。 反向模式自动微分 :是一种有效计算梯度的技术,恰好被反向传播所使用。

57、只要使用何氏初始化(He initialization)随机选择权重值,是否可以将所有权重初始化为相同的值?

不行,所有权重应独立采样,不应都具有相同的初始值。 随机采样权重的一个重要目标是 打破对称性 。 如果所有权重具有相同的初始值,即使该值不为零,对称性也不会被打破。 反向传播 将无法打破这种对称性。 实际上,这种配置几乎不可能收敛到一个好的解决方案。

58、将偏置项初始化为0是否可行?

将偏置项初始化为
0
是完全可行的。有些人喜欢像初始化权重一样初始化它们,那也没问题;这没什么太大区别。

59、列举 ELU 激活函数相对于 ReLU 的三个优点。

当 $ z < 0 $ 时取负值,使单元平均输出更接近 0,有助于缓解梯度消失问题; 当 $ z < 0 $ 时具有非零梯度,避免了神经元死亡问题; 函数在各处都平滑,包括 $ z = 0 $ 附近,有助于加速梯度下降。

60、在哪些情况下你会想要使用以下激活函数:ELU、Leaky ReLU(及其变体)、ReLU、tanh、Logistic和Softmax?


对于隐藏层,一般而言 ELU 效果较好;若注重运行时性能,可选择 Leaky ReLU;若不想调整超参数,可使用默认 α 值的 Leaky ReLU 或 ELU;若有时间和计算资源,可通过交叉验证评估其他激活函数,如网络过拟合时用 RReLU,训练集很大时用 PReLU。ReLU 在大多数情况下可用于隐藏层,其计算稍快,梯度下降在高原区域不易卡住。

输出层用于分类任务(类别互斥)时,Softmax 激活函数通常是不错的选择;用于回归任务时,可不用激活函数。

tanh 和 logistic 函数在大输入值时会饱和,不如 ReLU 和 ELU 等。

61、Dropout会减慢训练速度吗?它会减慢推理速度(即对新实例进行预测)吗?

Dropout 会减慢训练速度,通常大约会使训练速度减慢一半。但它对推理没有影响,因为它只在训练期间开启。

62、创建一个新的深度神经网络(DNN),复用前一个模型的所有预训练隐藏层,冻结这些层,并将softmax输出层替换为一个新的输出层。

可以按照以下步骤实现:

冻结隐藏层:可以通过给优化器指定要训练的变量列表,排除下层隐藏层的变量来冻结它们。示例代码如下:


import tensorflow as tf

# 获取要训练的变量列表,排除下层隐藏层的变量
train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope="hidden[34]|outputs")

# 定义优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

# 定义损失函数
loss = ...

# 创建训练操作
training_op = optimizer.minimize(loss, var_list=train_vars)

上述代码中,
train_vars
包含了隐藏层3、4和输出层的可训练变量,排除了隐藏层1和2的变量,从而实现了对隐藏层1和2的冻结。

另一种方法是在图中添加
stop_gradient()
层,其下方的任何层都将被冻结。示例代码如下:


with tf.name_scope("dnn"):
    hidden1 = tf.layers.dense(X, n_hidden1, activation=tf.nn.relu, name="hidden1") # 复用并冻结
    hidden2 = tf.layers.dense(hidden1, n_hidden2, activation=tf.nn.relu, name="hidden2") # 复用并冻结
    hidden2_stop = tf.stop_gradient(hidden2)
    hidden3 = tf.layers.dense(hidden2_stop, n_hidden3, activation=tf.nn.relu, name="hidden3") # 复用,不冻结
    hidden4 = tf.layers.dense(hidden3, n_hidden4, activation=tf.nn.relu, name="hidden4") # 新的层
    logits = tf.layers.dense(hidden4, n_outputs, name="outputs") # 新的层

替换输出层:由于原模型的输出层通常对新任务无用,且输出数量可能不适合新任务,所以需要替换输出层。在上述代码中,
logits
就是新的输出层。

63、在本练习中,你将构建一个深度神经网络(DNN),用于比较两张MNIST数字图像,并预测它们是否代表同一个数字。然后,你将复用该网络的较低层,使用极少的训练数据来训练一个MNIST分类器。首先,构建两个DNN(我们称之为DNN A和DNN B),它们都与你之前构建的网络类似,但没有输出层:每个DNN应包含五个隐藏层,每层有100个神经元,采用He初始化和ELU激活函数。接下来,在两个DNN的顶部添加一个包含10个单元的隐藏层。为此,你应该使用TensorFlow的concat()函数,将每个实例的两个DNN的输出沿轴1进行拼接,然后将结果输入到该隐藏层。最后,添加一个使用逻辑激活函数的单神经元输出层。

该步骤详细说明了构建用于比较两张MNIST数字图像并预测是否为同一数字的DNN的具体方法,以及后续复用其低层训练MNIST分类器的思路。具体构建步骤为:

构建两个无输出层的DNN(DNN A和DNN B),每个DNN有五个隐藏层,每层100个神经元,采用He初始化和ELU激活函数; 用
concat()
函数沿轴1拼接两个DNN输出,输入到一个有10个单元的隐藏层; 添加一个使用逻辑激活函数的单神经元输出层。

64、在给定的训练集上训练深度神经网络(DNN),对于每一对图像,将第一张图像输入到 DNN A 中,将第二张图像输入到 DNN B 中,整个网络会逐渐学习判断两张图像是否属于同一类别。请问这种训练方式的目的是什么?

让网络学习判断图像对是否属于同一类别

65、如果在启动TensorFlow程序时遇到CUDA_ERROR_OUT_OF_MEMORY错误,可能是什么情况?该如何解决?

可能是其他进程(很可能是另一个 TensorFlow 进程)正在运行,已经占用了至少一个可见 GPU 设备上的所有内存。解决方法有:

停止其他进程并重新尝试; 若需所有进程同时运行,可通过为每个设备适当设置
CUDA_VISIBLE_DEVICES
环境变量,为每个进程分配不同的设备; 创建
ConfigProto
,将其
gpu_options.per_process_gpu_memory_fraction
设置为应占用的总内存比例(如
0.4
),并在打开会话时使用该
ConfigProto
,使 TensorFlow 只占用部分 GPU 内存; 将
gpu_options.allow_growth
设置为
True
,让 TensorFlow 仅在需要时占用内存,但此方法通常不推荐,因为 TensorFlow 占用的内存不会释放,且难以保证可重复的行为。

66、将操作固定到设备上和将操作放置到设备上有什么区别?


将操作固定到设备上是指通过指定作业名称、任务索引、设备类型和设备索引等信息,使用 `device()` 函数创建设备块,明确地把操作固定在特定设备上。例如,使用 `with tf.device("/job:ps/task:0/cpu:0")` 将操作固定在指定 CPU 上。

而将操作放置到设备上,在 TensorFlow 中有不同的方式。开源版本中没有动态放置算法,主要依靠简单放置器。简单放置器会遵循一定规则:

- 若节点在之前运行已被放置在设备上则保持不变;
- 若用户固定了节点则放置到指定设备;
- 否则默认放置到 GPU #0,没有 GPU 时则放置到 CPU。

若用户不做任何操作,整个图将被放置在默认设备上。

67、如果你在支持 GPU 的 TensorFlow 安装环境中运行,并且仅使用默认放置方式,所有操作都会被放置在第一个 GPU 上吗?

如果所有操作都有 GPU 内核(即 GPU 实现),那么是的,它们都会被放置在第一个 GPU 上。然而,如果有一个或多个操作没有 GPU 内核,那么默认情况下 TensorFlow 会抛出异常。如果将 TensorFlow 配置为回退到 CPU(软放置),那么除了没有 GPU 内核的操作以及所有必须与它们并置的操作外,所有操作都将被放置在第一个 GPU 上。

68、如果你将一个变量固定到“/gpu:0”,它能否被放置在/gpu:1上的操作使用?能否被放置在“/cpu:0”上的操作使用?能否被固定到其他服务器上设备的操作使用?

可以。TensorFlow会自动添加适当的操作来跨设备传输变量的值,对于位于不同服务器上的设备(只要它们属于同一个集群)也是如此。

69、什么是控制依赖,何时需要使用它?


控制依赖用于在其他一些操作运行之后再推迟操作 X 的评估,即便这些操作并非计算 X 所必需。当操作 X 会占用大量内存且在计算图中较晚才需要其结果,或者操作 X 消耗大量 I/O(例如需要位于不同设备或服务器上的大变量值),且不想让它与其他大量消耗 I/O 的操作同时运行以避免带宽饱和时,使用控制依赖是有用的。

可以通过添加控制依赖来推迟某些节点的评估,例如使用 `tf.control_dependencies()` 函数指定操作的执行顺序。

70、假设你在TensorFlow集群上花了几天时间训练一个深度神经网络(DNN),训练程序结束后你立刻意识到忘记使用Saver保存模型了。你训练好的模型是不是就丢失了?

是的,若没有使用Saver保存模型,训练好的模型参数未存储到磁盘,模型就丢失了。

71、在TensorFlow集群上使用不同的超参数值并行训练多个深度神经网络(DNN)。这些DNN可以用于MNIST分类或任何你感兴趣的其他任务。最简单的方法是编写一个只训练一个DNN的单个客户端程序,然后并行运行多个该程序的进程,每个客户端使用不同的超参数值。该程序应具有命令行选项,以控制DNN应放置在哪个服务器和设备上,以及使用什么资源容器和超参数值(确保每个DNN使用不同的资源容器)。使用验证集或交叉验证来选择前三个模型。

可按以下步骤操作:

编写一个仅训练一个DNN的客户端程序; 并行运行多个该程序的进程,为每个进程设置不同的超参数值; 程序设置命令行选项,用于指定DNN所在的服务器和设备、资源容器及超参数值,且每个DNN使用不同资源容器; 用验证集或交叉验证选出前三个模型。

72、在图像分类任务中,卷积神经网络(CNN)相较于全连接深度神经网络(DNN)有哪些优势?

参数更少 :由于连续层仅部分连接且大量复用权重,CNN比全连接DNN的参数少得多,这使得训练速度更快,降低了过拟合风险,并且所需的训练数据也少得多。

特征检测能力更强 :当CNN学习到一个能检测特定特征的内核时,它可以在图像的任何位置检测该特征;而DNN在一个位置学习到一个特征后,只能在该特定位置检测它。由于图像通常具有非常重复的特征,因此CNN在图像处理任务(如分类)中能够使用更少的训练示例进行更好的泛化。

具备先验知识 :DNN对像素的组织方式没有先验知识,不知道相邻像素是接近的;而CNN的架构嵌入了这种先验知识,其较低层通常识别图像小区域中的特征,较高层将低层特征组合成更大的特征,这与大多数自然图像配合良好,使CNN相较于DNN有决定性的先发优势。

73、如果在训练卷积神经网络(CNN)时,你的GPU内存不足,你可以尝试哪五件事来解决这个问题?

以下是调整为 Markdown 格式的文本内容:

减小小批量大小; 在一个或多个层中使用更大的步幅来降低维度; 移除一个或多个层; 使用16位浮点数代替32位浮点数; 将CNN分布到多个设备上。

74、为什么你想添加最大池化层而不是具有相同步幅的卷积层?

添加最大池化层而非具有相同步幅的卷积层,是因为最大池化层可对输入图像进行下采样,减少计算量、内存使用和参数数量,降低过拟合风险,还能使神经网络对图像的位置偏移有一定容忍度。并且池化层无权重,只是使用聚合函数(如最大值或均值)聚合输入,而卷积层有可学习的权重。

75、什么时候需要添加局部响应归一化层?

添加局部响应归一化层可确保前层学习到多种特征、捕捉多种模式,如在GoogLeNet中,在两个卷积层之后添加该层确保前层学习到多种特征,在另外两个卷积层之后添加该层确保前层捕捉多种模式;在AlexNet中,在C1和C3层的ReLU步骤之后使用该层,鼓励不同特征图专业化,探索更广泛的特征,提高泛化能力。

76、如何下载最新的预训练 Inception v3 模型?

下载最新的预训练 Inception v3 模型,检查点可在 https://goo.gl/nxSQvl 获取。

77、打开一个会话,并使用Saver恢复你之前下载的预训练模型检查点。


import tensorflow as tf

# 创建Saver对象
saver = tf.train.Saver()

# 打开会话
with tf.Session() as sess:
    # 恢复预训练模型检查点
    saver.restore(sess, "/tmp/my_model_final.ckpt")
    # 后续操作 ...
© 版权声明

相关文章

暂无评论

none
暂无评论...