深度学习基础之目标及评估

明确任务目标和评价准则对于模型的设计及优化至关重要,本文将总结常用的相关方法和模型性能评价准则。为了简化,本文将主要针对回归问题和分类问题分别予以归纳,其它问题可采取类似的方法及手段。


深度学习基础之数据准备与预处理

由于人工智能面向的应用和场景的多样性,导致需要分析的数据无论是从维度还是格式上都存在巨大差异,数据准备阶段需要解决数据的数值化、归一化、特征工程等共性的问题。

深度学习基础篇将从几个不同的层面来总结在过去一段时间对于深度学习关键技术的理解,通过知识体系的归纳了解知识体系的不足,提升对核心技术点的认识。所有系列文章将在未来一段时间内容随着掌握了解的深入迭代更新。目前主要希望对如下几个领域进行归纳汇总:

  1. 问题定义
  2. 目标及评估
  3. 数据准备与预处理
  4. 激活函数的归纳及总结
  5. 优化算法的归纳及总结
  6. 正则化与泛化性能
  7. 模型压缩
  8. 数据扩充

由于人工智能面向的应用和场景的多样性,导致需要分析的数据无论是从维度还是格式上都存在巨大差异,数据准备阶段需要解决数据的数值化、归一化、特征工程等共性的问题。

深度学习的端到端学习能力并不意味着在实际的业务处理中把原始数据直接丢进网络模型,与传统的机器学习技术类似必要的数据预处理工作无论是对于提升模型的收敛效率还是提升模型的训练质量都具备十分重要的意义。

数值化

由于神经网络的输入限定为数值数据,所以对于字符串数据、文本数据、类别数据,在导入网络模型之前需要进行数值化处理,转换为数值数据。其中类别数据可以采用one-hot编码等方式进行编码。

数据归一化

数据归一化是属于预处理阶段经常采用的一种手段。虽然这里有一系列可行的方法,但是这一步通常是根据数据的具体情况而明确选择的。特征归一化常用的方法包含如下几种:

  • 简单缩放
  • 逐样本均值消减(也称为移除直流分量)
  • 特征标准化(使数据集中所有特征都具有零均值和单位方差)

简单缩放

在简单缩放中,我们的目的是通过对数据的每一个维度的值进行重新调节(这些维度可能是相互独立的),使得最终的数据向量落在 [0,1]或[ − 1,1] 的区间内(根据数据情况而定)。这对后续的处理十分重要,因为很多默认参数(如 PCA-白化中的 epsilon)都假定数据已被缩放到合理区间。

例子:在处理自然图像时,我们获得的像素值在 [0,255] 区间中,常用的处理是将这些像素值除以 255,使它们缩放到 [0,1] 中.

逐样本均值消减

如果你的数据是平稳的(即数据每一个维度的统计都服从相同分布),那么你可以考虑在每个样本上减去数据的统计平均值(逐样本计算)。

例子:对于图像,这种归一化可以移除图像的平均亮度值 (intensity)。很多情况下我们对图像的照度并不感兴趣,而更多地关注其内容,这时对每个数据点移除像素的均值是有意义的。注意:虽然该方法广泛地应用于图像,但在处理彩色图像时需要格外小心,具体来说,是因为不同色彩通道中的像素并不都存在平稳特性。

特征标准化

特征标准化指的是(独立地)使得数据的每一个维度具有零均值和单位方差。这是归一化中最常见的方法并被广泛地使用(例如,在使用支持向量机(SVM)时,特征标准化常被建议用作预处理的一部分)。在实际应用中,特征标准化的具体做法是:首先计算每一个维度上数据的均值(使用全体数据计算),之后在每一个维度上都减去该均值。下一步便是在数据的每一维度上除以该维度上数据的标准差。

例子:处理音频数据时,常用 Mel 倒频系数 MFCCs 来表征数据。然而MFCC特征的第一个分量(表示直流分量)数值太大,常常会掩盖其他分量。这种情况下,为了平衡各个分量的影响,通常对特征的每个分量独立地使用标准化处理。

原理: 在每个样本中减去数据的统计平均值,可以移除数据的共同部分,凸显个体差异。

注意:

数据归一化中采取的统计平均值和均方差值都来源于训练数据,由于理论上不应该从验证集和测试集中获取信息,所以对于验证集和测试集的处理也使用训练集的结果。

标准流程

在这一部分中,我们将介绍几种在一些数据集上有良好表现的预处理标准流程.

自然灰度图像

灰度图像具有平稳特性,我们通常在第一步对每个数据样本分别做均值消减(即减去直流分量),然后采用 PCA/ZCA 白化处理,其中的 epsilon 要足够大以达到低通滤波的效果。

彩色图像

对于彩色图像,色彩通道间并不存在平稳特性。因此我们通常首先对数据进行特征缩放(使像素值位于 [0,1] 区间),然后使用足够大的 epsilon 来做 PCA/ZCA。注意在进行 PCA 变换前需要对特征进行分量均值归零化。

音频 (MFCC/频谱图)

对于音频数据 (MFCC 和频谱图),每一维度的取值范围(方差)不同。例如 MFCC 的第一分量是直流分量,通常其幅度远大于其他分量,尤其当特征中包含时域导数 (temporal derivatives) 时(这是音频处理中的常用方法)更是如此。因此,对这类数据的预处理通常从简单的数据标准化开始(即使得数据的每一维度均值为零、方差为 1),然后进行 PCA/ZCA 白化(使用合适的 epsilon)。

MNIST 手写数字

MNIST 数据集的像素值在 [0,255] 区间中。我们首先将其缩放到 [0,1] 区间。实际上,进行逐样本均值消去也有助于特征学习。注:也可选择以对 MNIST 进行 PCA/ZCA 白化,但这在实践中不常用。

图像预处理

Mean Subtraction

data normalization

目的:减少不同图片受光照变化的影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import cv2

class MeanPreprocessor:
def __init__(self, rMean, gMean, bMean):
# store the Red, Green, and Blue channel averages across a
# training set
self.rMean = rMean
self.gMean = gMean
self.bMean = bMean

def preprocess(self, image):
# split the image into its respective Red, Green, and Blue
# channels
(B, G, R) = cv2.split(image.astype("float32"))

# subtract the means for each channel
R -= self.rMean
G -= self.gMean
B -= self.bMean

# merge the channels back together and return the image
return cv2.merge([B, G, R])

Patch Extraction

从原始图像中随机采样MxN的区域,当原始图像的稀疏度较高时可以采用该方法。

降低过拟合的概率

256x256 ===> 227x227

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.feature_extraction.image import extract_patches_2d

class PatchPreprocessor:
def __init__(self, width, height):
# store the target width and height of the image
self.width = width
self.height = height

def preprocess(self, image):
# extract a random crop from the image with the target width
# and height
return extract_patches_2d(image, (self.height, self.width),
max_patches=1)[0]

Cropping(Over-Sampling)

使用扣取方法可以从原始图像的四个角+中心位置进行扣取,实验证明该方法可以提升1-2个百分比的分类精度;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import numpy as np
import cv2

class CropPreprocessor:
def __init__(self, width, height, horiz=True, inter=cv2.INTER_AREA):
# store the target image width, height, whether or not
# horizontal flips should be included, along with the
# interpolation method used when resizing
self.width = width
self.height = height
self.horiz = horiz
self.inter = inter

def preprocess(self, image):
# initialize the list of crops
crops = []

# grab the width and height of the image then use these
# dimensions to define the corners of the image based
(h, w) = image.shape[:2]
coords = [
[0, 0, self.width, self.height],
[w - self.width, 0, w, self.height],
[w - self.width, h - self.height, w, h],
[0, h - self.height, self.width, h]]

# compute the center crop of the image as well
dW = int(0.5 * (w - self.width))
dH = int(0.5 * (h - self.height))
coords.append([dW, dH, w - dW, h - dH])

# loop over the coordinates, extract each of the crops,
# and resize each of them to a fixed size
for (startX, startY, endX, endY) in coords:
crop = image[startY:endY, startX:endX]
crop = cv2.resize(crop, (self.width, self.height),
interpolation=self.inter)
crops.append(crop)

# check to see if the horizontal flips should be taken
if self.horiz:
# compute the horizontal mirror flips for each crop
mirrors = [cv2.flip(c, 1) for c in crops]
crops.extend(mirrors)

# return the set of crops
return np.array(crops)

Keras中的数据预处理功能

http://keras-cn.readthedocs.io/en/latest/preprocessing/sequence/

A. 设置随机种子

1
np.random.seed(1337)  # for reproducibility

B. 输入数据维度规格化,这里每个样本只是size为784的一维数组。

1
X_train = X_train.reshape(60000, 784)

将类别标签转换为one-hot encoding, 这一步对多分类是必须的

1
one_hot_labels  = keras.utils.np_utils.to_categorical(labels, num_classes=10)

C. 输入数据类型转换,数值归一化

1
2
X_train = X_train.astype('float32')
X_train /= 255

序列预处理

文本预处理

图片预处理

样本数据序列化为HDF5文件

目的:减少多次IO读取的延时

参考

  1. 《解析卷积神经网络—深度学习实践手册》
  2. Keras文档
  3. http://deeplearning.stanford.edu/wiki/index.php/%E6%95%B0%E6%8D%AE%E9%A2%84%E5%A4%84%E7%90%86
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×