加入收藏 | 设为首页 | 会员中心 | 我要投稿 威海站长网 (https://www.0631zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 经验 > 正文

你用什么方法调试深度神经网络?这里有四种简单的方式哦

发布时间:2019-04-02 00:17:30 所属栏目:经验 来源:机器之心编译
导读:当你花了几个星期构建一个数据集、编码一个神经网络并训练好了模型,然后发现结果并不理想,接下来你会怎么做? 深度学习通常被视为一个黑盒子,我并不反对这种观点但是你能讲清楚学到的上万参数的意义吗? 但是黑盒子的观点为机器学习从业者指出了一个明显
副标题[/!--empirenews.page--]

当你花了几个星期构建一个数据集、编码一个神经网络并训练好了模型,然后发现结果并不理想,接下来你会怎么做?

深度学习通常被视为一个黑盒子,我并不反对这种观点——但是你能讲清楚学到的上万参数的意义吗?

但是黑盒子的观点为机器学习从业者指出了一个明显的问题:你如何调试模型?

在这篇文章中,我将会介绍一些我们在 Cardiogram 中调试 DeepHeart 时用到的技术,DeepHeart 是使用来自 Apple Watch、 Garmin、和 WearOS 的数据预测疾病的深度神经网络。

在 Cardiogram 中,我们认为构建 DNN 并不是炼金术,而是工程学。

调试深度神经网络

你的心脏暴露了很多你的信息。DeepHeart 使用来自 Apple Watch、 Garmin、和 WearOS 的心率数据来预测你患糖尿病、高血压以及睡眠窒息症(sleep apnea)的风险。

一、预测合成输出

通过预测根据输入数据构建的合成输出任务来测试模型能力。

我们在构建检测睡眠窒息症的模型时使用了这个技术。现有关于睡眠窒息症筛查的文献使用日间和夜间心率标准差的差异作为筛查机制。因此我们为每周的输入数据创建了合成输出任务:

标准差 (日间心率)—标准差 (夜间心率)

为了学习这个函数,模型要能够:

  • 区分白天和黑夜
  • 记住过去几天的数据

这两个都是预测睡眠窒息症的先决条件,所以我们使用新架构进行实验的第一步就是检查它是否能学习这个合成任务。

你也可以通过在合成任务上预训练网络,以半监督的形式来使用类似这样的合成任务。当标记数据很稀缺,而你手头有大量未标记数据时,这种方法很有用。

二、可视化激活值

理解一个训练好的模型的内部机制是很难的。你如何理解成千上万的矩阵乘法呢?

在这篇优秀的 Distill 文章《Four Experiments in Handwriting with a Neural Network》中,作者通过在热图中绘制单元激活值,分析了手写模型。我们发现这是一个「打开 DNN 引擎盖」的好方法。

我们检查了网络中几个层的激活值,希望能够发现一些语义属性,例如,当用户在睡觉、工作或者焦虑时,激活的单元是怎样的?

用 Keras 写的从模型中提取激活值的代码很简单。下面的代码片段创建了一个 Keras 函数 last_output_fn,该函数在给定一些输入数据的情况下,能够获得一层的输出(即它的激活值)。

  1. from keras import backend as K 
  2.  
  3. def extract_layer_output(model, layer_name, input_data): 
  4.   layer_output_fn = K.function([model.layers[0].input], 
  5.                                [model.get_layer(layer_name).output]) 
  6.  
  7.   layer_output = layer_output_fn([input_data]) 
  8.  
  9.   # layer_output.shape is (num_units, num_timesteps) 
  10.   return layer_output[0] 

我们可视化了网络好几层的激活值。在检查第二个卷积层(一个宽为 128 的时间卷积层)的激活值时,我们注意到了一些奇怪的事:

卷积层的每个单元在每个时间步长上的激活值。蓝色的阴影代表的是激活值。

激活值竟然不是随着时间变化的!它们不受输入值影响,被称为「死神经元」。

ReLU 激活函数,f(x) = max(0, x)

这个架构使用了 ReLU 激活函数,当输入是负数的时候它输出的是 0。尽管它是这个神经网络中比较浅的层,但是这确实是实际发生的事情。

在训练的某些时候,较大的梯度会把某一层的所有偏置项都变成负数,使得 ReLU 函数的输入是很小的负数。因此这层的输出就会全部为 0,因为对小于 0 的输入来说,ReLU 的梯度为零,这个问题无法通过梯度下降来解决。

当一个卷积层的输出全部为零时,后续层的单元就会输出其偏置项的值。这就是这个层每个单元输出一个不同值的原因——因为它们的偏置项不同。

我们通过用 Leaky ReLU 替换 ReLU 解决了这个问题,前者允许梯度传播,即使输入为负时。

我们没想到会在此次分析中发现「死神经元」,但最难找到的错误是你没打算找的。

三、梯度分析

梯度的作用当然不止是优化损失函数。在梯度下降中,我们计算与Δparameter 对应的Δloss。尽管通常意义上梯度计算的是改变一个变量对另一个变量的影响。由于梯度计算在梯度下降方法中是必需的,所以像 TensorFlow 这样的框架都提供了计算梯度的函数。

我们使用梯度分析来确定我们的深度神经网络能否捕捉数据中的长期依赖。DNN 的输入数据特别长:4096 个时间步长的心率或者计步数据。我们的模型架构能否捕捉数据中的长期依赖非常重要。例如,心率的恢复时间可以预测糖尿病。这就是锻炼后恢复至休息时的心率所耗的时间。为了计算它,深度神经网络必须能够计算出你休息时的心率,并记住你结束锻炼的时间。

衡量模型能否追踪长期依赖的一种简单方法是去检查输入数据的每个时间步长对输出预测的影响。如果后面的时间步长具有特别大的影响,则说明模型没有有效地利用早期数据。

(编辑:威海站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读