4.1 机器学习的四个分支
二分类问题、多分类问题和标量回归问题,都是监督学习(supervised learning),目标是学习训练输入与训练目标之间的关系。
4.1.1 监督学习
给定一组样本(通常由人工标注),他可以学会将输入数据映射到已知目标【也叫标注(annotation)】。
- 序列生成(sequence generation)。给定一张图,预测描述图像的文字,序列生成有时可以被重新表示为一系列分类问题,比如反复预测序列中的单词或标记。
- 语法树预测(syntax tree prediction),给定一个句子,预测其分解生成的语法树。
- 目标检测(object detection),给定一张图,在图像中特定目标的周围画一个边框。这个问题也可以表示为分类问题(给定多个候选边界框,对每个框内的目标进行分类)或分类与回归联合问题(用向量回归来预测边界框的坐标)。
- 图像分割(image segmentation)。给定一张图像,在特定图物体上画一个像素的掩码(mask)
4.1.2 无监督学习
无监督学习是指没有目标的情况下寻找输入数据的有趣变换,降维(dimensionality reduction)和聚类(clustering)。
4.1.3 自监督学习
自编码器(autoendcoder),时序监督学习(temporally supervised learning)用输入作为监督。
4.1.4 强化学习
智能体(agent)接收有关其环境的信息,并学会选择使某种奖励最大化的行动。
分类和回归语表
- 样本(sample)或输入(input):进入模型出来的数据点
- 预测(prediction)或者输出(output):从模型出来的结果
- 目标(target):真实值。模型应该能够预测出目标。
- 预测误差(predication error)或损失值(loss value):模型预测与目标之间距离
- 类别(class):分类问题中选择的一组标签。
- 标签(label):分类问题中类别标注的具体例子
- 真值(ground-truth)或标注(annotation):数据集的所有目标,通常人工收集。
- 二分类(binary classification):每个输入样本都应该划分到两个互斥的类别中。
- 多分类(multiclass classification):每个输入样本都可以分配多个标签。
- 多标签分类(multilabel classification):每个输入样本可以分配多个标签。
- 标量回归(scalar regression):目标是连续标量值的任务
- 向量回归(vector regression):目标是一组连续值的任务
- 小批量(mini-batch)或批量(batch):模型同时处理一小部分样本。
4.2 评估机器学习模型
过拟合:在训练数据少表现越来越好,在预测数据上表现越来越差
可泛化(generalize)的模型,在前所未见的数据上表现很好的模型。
4.2.1 训练集、验证集和测试集
训练集训练模型,验证集评估模型,测试集上测试。
调节模型配置,【模型的超参数(hyperparameter),为了便于和模型参数(权重)区分开】。
如果一直根据模型在验证集上的表现来调整模型配准,很快就会导致模型在验证集上过拟合。
这一现象的关键在于信息泄露(information leak),每次基于模型在验证集上性能来调整模型参数,都会有一些关于验证数据的信息泄漏到模型中。
验证集上性能很好(认为造成的),这正是你优化的目的。测试集就是为了评估模型的 。
模型不能读取与测试集有关的任何信息。
1、简单的留出验证
留出验证(hold-out validation)留出一定比例的数据作为测试集。在剩下的数据上训练模型,然后在测试集上评估模型。
#4-1 留出验证
import numpy as np
data=np.zeros((20000,10000))
num_validation_samples =10000
np.random.shuffle(data) #通常要打乱数据
validation_data =data[:num_validation_samples]#定义验证集
data = data[num_validation_samples:]
traing_data=data[:]#定义训练集
model =get_model()
model.train(training_data)#在训练数据上训练模型
validatiob_score = model.evaluate(validation_data)#并在验证数据上评估模型
# 现在你可以调节模型、重新训练、评估,然后再次调节
model =get_model()#调整好超参
model.train(np.concatenate([training_data,validation_data]))#在所有非测试数据上从头开始训练最终模型
test_score = model.evaluate(test_data)
如果可用数据很少,随机打乱后模型性能差别很大。
2、K折验证
K折验证(K-fold validation)将数据划分为大小相同的K个分区,每个分区i,在剩余的K-1个分区上进行训练,然后在分区i上评估模型,最终得到k个分数的平均值
k = 4
num_validation_samples = len(data) // k
np.random.shuffle(data)
validation_scores=[]
for fold in range(k):
validation_data = data[num_validation_samples * fold:#选择验证数据分区
num_validation_samples * (fold+1)]
training_data=data[:num_validation_samples * fold]+data[num_validation_samples * (fold+1):]#将剩余数据作为训练数据。注意+运算是列表合并,不是求和
model = get_model()#创建一个全新的模型实例(未训练)
model.train(training_data)
validation_score = model.evaluate(validation_data)
validation_score.append(validation_score)
validation_score = np.average(validation_scores)#最终验证分数:K折验证分数的平均值
model = get_model()
model.train(data)#在所有非测试数据上训练最终的模型
test_score = model.evaluate(test_data)
3、带有打乱数据的重复K折验证
带有打乱数据的重复K折验证(iterated K-fold validation with shuffling)
多次使用K折验证,在每次将数据划分为K个分区之前都现将数据打乱,最终分数是每次K折验证分数的平均值。一共要训练和评估P*K个模型
4.2.2 评估模型的注意事项
- 数据代表性(data representativeness):将数据划分为训练集和测试集之前,通常应该随机打乱数据。
- 时间箭头(the arrow of time):有时间顺序,不应该随机打乱数据,造成时间泄露(temporal leak)
- 数据冗余(redundancy in your data):确保训练集和验证集之间没有交集。
4.3 数据预处理、特征工程和特征学习。
4.3.1 神经网络的数据预处理
使原始数据更适于神经网络处理。
1、向量化
神经网络所有输入和目标都必须是浮点数张量(特定情况下是整数张量)。
将数据转换成张量,这一步叫做数据向量化(data vectorization)
文本表示为整数列表(单词序列),用one-hot编码将其转换为float32格式的张量。
2、值标准化
0~255范围内的整数,表示灰度值。
将其转换为float32格式并除以255,这样就得到0~1范围内的浮点数。
将取值相对较大的数据或者异质数据(heterogeneous data),导致较大的梯度更新,进而导致网络无法收敛。
- 取值较小:大部分值都应该在0~1
- 同质性(homogeneous)
平均值为0,标准差为1
x -= x.mean(axis=0)#假设x是一个形状为(samples,features)的二维矩阵
x /= x.std(axis=0)
3、处理缺失值
将缺失值设置为0是安全的,只要0不是一个有意义的值,网络能从数据中学到0意味着缺失数据,并且会忽略这个值。
测试数据中有缺失值,但是网络没有在缺失值的数据上训练,那么网络不可能学会忽略之,应当认为生成一些缺失项样本:多次复制一些训练样本,然后删除测试数据中可能确实的某些特征。
4.3.2 特征工程
特征工程(feature engineering)是指将数据输入模型之前,利用自己关于数据和机器学习算法(这里指神经网络)的知识对数据进行因编码的变换(不是模型学习到的),已改善模型效果。
特征工程的本质:用更简单的方式表述问题,从而使问题变得更容易。
神的学习之前特征工程很重要,因为经典的浅层算法没有足够大的假设空间来自己学习有用的表示。
- 好的特征可以减少资源的消耗
- 好的特征可以减少训练数据。
4.4 过拟合和欠拟合
优化(optimization)是指调节模型以在训练数据上得到最佳性能(即机器学习中的学习)。
泛化(generalization)是指训练好的模型在前所未见数据上的性能好坏。
一开始是欠拟合的(underfit),训练数据上损失越小,测试数据上的损失也越小,仍然有改进空间,网络还没有对训练数据中所有相关模式建模。
在训练数据上迭代一定数据后,泛化不在提高,验证指标先是不变,而后开始变差,就是过拟合。
为了防止学习到错误或无关紧要的模型,最优解决方案就是获取更多的训练数据。
没有办法获得更多数据,次优解解决方法是调节模型允许存储信息量,或对模型允许存储的信息加以约束。
降低过拟合的方法叫做正则化(regularization)
4.4.1 减小网络大小
防止过拟合最简单的方法就是减少模型大小,也就是减少模型中可学习参数的个数(这由层数和每层的单元个数决定)。
模型中科学学习参数个数通常被称为模型的容量(capacity)。
参数更多的模型拥有更大的记忆容量(memorization capacity),因此能够在训练样本和目标之间轻松的学完完美的字典映射,这样的映射没有泛化能力。
深度学习真正的挑战是在泛化而不是在拟合。
参数多了过拟合,参数少了欠拟合,在容量过大和容量不足之间找到一个折中。
#4-3 原始模型
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(1000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
#4-4 容量更小的网络
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(4, activation='relu', input_shape=(1000,)))
model.add(layers.Dense(4, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
防止神经网络过拟合:
- 增加更多的数据
- 减少网络容量
- 增加权重正则化
- 添加dropout
4.5 机器学习通用工作流程
4.5.1 定义问题,收集数据
- 输入的数据?预测的数据?拥有的数据。
- 什么类型的问题(分类。。。)
问题明确了
- 假设输出可以通过输入预测
- 可用数据足够多,足够学习输入输出之间的关系。
非平稳问题(nonstationary problem)输入和输出数据所处的差异很大
机器学习只能用来记忆训练数据中存在的模型,预测也只是假设未来的规律与过去相同。
4.5.2 选择衡量成功的指标
衡量是否成功,给出成功的蒂尼:精度?准确率(precision)和召回率(recall)?客户保留率?。
损失函数,即模型要优化什么。
平衡分类问题(每个类别可能性相同),精度和接受者操作特征曲线下面积(area under the receiver operating characteristic curve,ROC AUC)。
对于类别不平衡问题,准确率和召回率。
对于排序问题或多标签分类问题,平均准确率均值(mean average precision)
4.5.3 确定评估方法
- 留出验证集,数据量很大时
- K折交叉验证,样本量少,无法保证可靠性
- 重复K折验证,样本少,模型需要评估准确。
4.5.4 准备数据
- 数据格式化为张量
- 张量取值缩放较小值[-1,1]或[0,1]
- 不同特征具有不同取值范围(异质数据),那么应该做数据标准化。
- 特征工程对于小数据问题。
4.5.5 开发比基准更好的模型
目标是获得统计功效(statistical power),开发一个小模型,它能够打败纯随机的基准(dumb baseline)。
- 假设输出是可以根据输入进行预测的。
- 假设可用的数据包含更多的信息,足以学习输入和输出之间的关系。
三个关键参数构建第一个模型
- 最后一层的激活,它对网络输出进行有效的限制。
- 损失函数,要解决的问题
- 优化配置,要使用那种优化器,学习率是多少?
4.5.6 扩大模型规模:开发过拟合的模型
开发过拟合模型:
- 添加更多的层
- 让每一层变得更大
- 训练更多轮次
验证集合上性能下降,就是过拟合了。
4.5.7 模型正则化与调节超参数
调节模型、训练、在验证数据集上评估:
- 添加dropout
- 尝试不同架构:增加或者减少层数。
- 添加L1或/和L2正则化
- 尝试用不同的超参数(比如每层的单元个数或优化器的学习率),已找到最佳配置。
- 反复做特征工程:添加新特性或删除没有信息量的特征。
本章小结
- 定义问题与要训练的数据,收集这些数据有必要的话增加标注
- 选择衡量问题成功的指标。
- 确定评估方法
- 开发第一个比基准好的模型
- 开发一个过拟合模型
- 基于模型在验证数据上的性能来进行模型正则化与调节参数。