除模型评估之外,在深入研究模型开发之前,我们还必须解决另一个重要问题:将数据输入神经网络之前,如何准备输入数据和目标?

一、神经网络的数据预处理

数据预处理的目的是使原始数据更适于用神经网络处理,包括向量化、标准化、处理缺失值和特征提取。

1. 向量化

神经网络的所有输入和目标都必须是浮点数张量(在特定情况下可以是整数张量)。 无论处理什么数据(声音、图像还是文本),都必须首先将其转换为张量,这一步叫作数据向量化( data vectorization)

2. 值标准化

在手写数字分类的例子中,开始时图像数据被编码为 0~255 范围内的整数,表示灰度值。将这一数据输入网络之前,你需要将其转换为 float32 格式并除以 255,这样就得到 0~1 范围内的浮点数。同样,预测房价时,开始时特征有各种不同的取值范围,有些特征是较小的浮点数,有些特征是相对较大的整数。将这一数据输入网络之前,你需要对每个特征分别做标准化,使其均值为 0、标准差为 1。

一般来说,将取值相对较大的数据(比如多位整数,比网络权重的初始值大很多)或异质数据( heterogeneous data,比如数据的一个特征在 0~1 范围内,另一个特征在 100~200 范围内)输入到神经网络中是不安全的。这么做可能导致较大的梯度更新,进而导致网络无法收敛。
为了让网络的学习变得更容易,输入数据应该具有以下特征:

  • 取值较小:大部分值都应该在 0~1 范围内。
  • 同质性( homogenous):所有特征的取值都应该在大致相同的范围内。

此外,下面这种更严格的标准化方法也很常见,而且很有用,虽然不一定总是必需的(例如,对于数字分类问题就不需要这么做)。

  • 将每个特征分别标准化,使其平均值为 0。
  • 将每个特征分别标准化,使其标准差为 1。

这对于 Numpy 数组很容易实现:

  1. # 假设 x 是一个形状为(sammples, features)的二维矩阵
  2. x -= x.mean(axis=0)
  3. x /= x.std(axis=0)

3. 处理缺失值

你的数据中有时可能会有缺失值。 一般来说,对于神经网络,将缺失值设置为 0 是安全的,只要 0 不是一个有意义的值。网络能够从数据中学到 0 意味着缺失数据,并且会忽略这个值。

注意,如果测试数据中可能有缺失值,而网络是在没有缺失值的数据上训练的,那么网络不可能学会忽略缺失值。在这种情况下,你应该人为生成一些有缺失项的训练样本:多次复制一些训练样本,然后删除测试数据中可能缺失的某些特征。

二、特征工程

特征工程( feature engineering)是指将数据输入模型之前,利用你自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。多数情况下,一个机器学习模型无法从完全任意的数据中进行学习。呈现给模型的数据应该便于模型进行学习。

比如我们为了识别钟表当前时间,把指针的极坐标传给神经网络学习比传时钟图片要好得多。

特征工程的本质:用更简单的方式表述问题,从而使问题变得更容易。它通常需要深入理解问题。
幸运的是,对于现代深度学习,大部分特征工程都是不需要的,因为神经网络能够从原始数据中自动提取有用的特征。

  • 良好的特征仍然可以让你用更少的资源更优雅地解决问题。例如,使用卷积神经网络来读取钟面上的时间是非常可笑的。
  • 良好的特征可以让你用更少的数据解决问题。深度学习模型自主学习特征的能力依赖于大量的训练数据。如果只有很少的样本,那么特征的信息价值就变得非常重要。