对于所有时间步长 t,我们想要计算的梯度是与Δinput_t 对应的Δoutput。下面是用 Keras 和 TensorFlow 计算这个梯度的代码示例:
- def gradient_output_wrt_input(model, data):
- # [:, 2048, 0] means all users in batch, midpoint timestep, 0th task (diabetes)
- output_tensor = model.model.get_layer('raw_output').output[:, 2048, 0]
- # output_tensor.shape == (num_users)
-
- # Average output over all users. Result is a scalar.
- output_tensor_sum = tf.reduce_mean(output_tensor)
-
- inputs = model.model.inputs # (num_users x num_timesteps x num_input_channels)
- gradient_tensors = tf.gradients(output_tensor_sum, inputs)
- # gradient_tensors.shape == (num_users x num_timesteps x num_input_channels)
-
- # Average over users
- gradient_tensors = tf.reduce_mean(gradient_tensors, axis=0)
- # gradient_tensors.shape == (num_timesteps x num_input_channels)
- # eg gradient_tensor[10, 0] is deriv of last output wrt 10th input heart rate
-
- # Convert to Keras function
- k_gradients = K.function(inputsinputs=inputs, outputs=gradient_tensors)
-
- # Apply function to dataset
- return k_gradients([data.X])
在上面的代码中,我们在平均池化之前,在中点时间步长 2048 处计算了输出。我们之所以使用中点而不是最后的时间步长的原因是,我们的 LSTM 单元是双向的,这意味着对一半的单元来说,4095 实际上是第一个时间步长。我们将得到的梯度进行了可视化:
Δoutput_2048 / Δinput_t
请注意我们的 y 轴是 log 尺度的。在时间步长 2048 处,与输入对应的输出梯度是 0.001。但是在时间步长 2500 处,对应的梯度小了一百万倍!通过梯度分析,我们发现这个架构无法捕捉长期依赖。
四、分析模型预测
你可能已经通过观察像 AUROC 和平均绝对误差这样的指标分析了模型预测。你还可以用更多的分析来理解模型的行为。
例如,我们好奇 DNN 是否真的用心率输入来生成预测,或者说它的学习是不是严重依赖于所提供的元数据——我们用性别、年龄这样的用户元数据来初始化 LSTM 的状态。为了理解这个,我们将模型与在元数据上训练的 logistic 回归模型做了对比。
DNN 模型接收了一周的用户数据,所以在下面的散点图中,每个点代表的是一个用户周。
这幅图验证了我们的猜想,因为预测结果并不是高度相关的。
除了进行汇总分析,查看最好和最坏的样本也是很有启发性的。对一个二分类任务而言,你需要查看最令人震惊的假阳性和假阴性(也就是预测距离标签最远的情况)。尝试鉴别损失模式,然后过滤掉在你的真阳性和真阴性中出现的这种模式。 (编辑:西安站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|