4.1 机器学习的四个分支

4.1.1 监督学习

含义:给定一组样本,它可以学会将输入数据映射到已知目标。

常见监督学习有:分类、回归、序列生成、语法树预测、目标检测、图像分割。

 

4.1.2 无监督学习

含义:是指在没有i目标的情况下寻找输入数据的有趣变换,其目的在于数据可视化、数据压缩、数据去噪或更好地理解数据中的相关性。

常见无监督学习有:降维、聚类。

 

4.1.3 自监督学习

含义:是没有人工标注的标签的监督学习,可以看作没有人参与的监督学习。

常见自监督学习有:自编码器、时序监督学习。

 

4.1.4 强化学习

含义:在强化学习中,智能体接收有关其环境的信息,并学会选择使某种奖励最大化的行动。

主要应用于游戏领域。

 

4.2 评估机器学习模型

4.2.1 训练集、验证集和测试集

(1)简单的留出验证:留出一定比例的数据作为测试集。在剩余的数据上训练模型,然后再测试机上评估模型。

 1 from keras import models
 2 from keras import layers
 3 import numpy as np
 4 
 5 data = list(range(60000)) #模拟全部样本
 6 num_validation_samples = 10000 #验证集个数
 7 num_test_samples = 10000 #测试集个数
 8 np.random.shuffle(data) #随机打乱data
 9 
10 validation_data = data[:num_validation_samples]#验证集 10000个样本
11 training_data = data[num_validation_samples:-num_test_samples]#训练集 40000个样本
12 test_data = data[num_test_samples:]#测试集 10000个样本
13 
14 #这里是示例,可以用keras建立更复杂的网络结构
15 def get_model():
16     model = models.Sequential()
17     model.add(layers.Dense(1,activation='relu',input_shape=(1,)))
18     model.compile(optimizer='rmsprop',loss='mse',metrics=['mae'])
19     return model
20 
21 model = get_model()
22 
23 validation_score = model.evaluate(validation_data)
24 
25 #调节模型、重新训练、评估等过程之后
26 
27 model = get_model()
28 model.fit(np.concatenate([training_data,validation_data]))
29 
30 test_score = model.evaluate(test_data)

 

(2)K折验证:将数据划分为大小相同的K个分区,对于每个分区i,再剩余的K-1个分区上训练模型,然后在分区i上评估模型。

 1 from keras import models
 2 from keras import layers
 3 import numpy as np
 4 
 5 data = list(range(60000)) #模拟全部样本
 6 num_test_samples = 10000 #测试集个数
 7 data = data[:-num_test_samples]
 8 test_data = data[num_test_samples:]#测试集 10000个样本
 9 k = 4
10 num_validation_samples = len(data) // k
11 np.random.shuffle(data)
12 
13 validation_scores = []
14 
15 #这里是示例,可以用keras建立更复杂的网络结构
16 def get_model():
17     model = models.Sequential()
18     model.add(layers.Dense(1,activation='relu',input_shape=(1,)))
19     model.compile(optimizer='rmsprop',loss='mse',metrics=['mae'])
20     return model
21 
22 for fold in range(k):
23     validation_data = data[num_validation_samples * fold:num_validation_samples * (fold + 1)]
24     training_data = data[:num_validation_samples * fold] + data[num_validation_samples * (fold + 1):]
25     model = get_model()
26     model.fit(training_data)
27     validation_score = model.evaluate(validation_data)
28     validation_scores.append(validation_score)
29 
30 validation_score = np.average(validation_scores)
31 
32 model = get_model()
33 model.fit(np.concatenate([training_data,validation_data]))
34 test_score = model.evaluate(test_data)

 

(3)带有打乱数据的重复K折验证:如果可用的数据相对较少,而你又需要尽可能精确地评估模型,那么可以选择带有打乱数据的重复K折验证。

具体做法是多次使用K折验证,在每次将数据划分为K个分区之前都先将数据打乱。最终分数是每次K折验证分数的平均值。

 1 from keras import models
 2 from keras import layers
 3 import numpy as np
 4 
 5 data = list(range(60000)) #模拟全部样本
 6 num_test_samples = 10000 #测试集个数
 7 data = data[:-num_test_samples]
 8 test_data = data[num_test_samples:]#测试集 10000个样本
 9 epoch = 3
10 k = 4
11 num_validation_samples = len(data) // k
12 np.random.shuffle(data)
13 
14 validation_scores = []
15 
16 #这里是示例,可以用keras建立更复杂的网络结构
17 def get_model():
18     model = models.Sequential()
19     model.add(layers.Dense(1,activation='relu',input_shape=(1,)))
20     model.compile(optimizer='rmsprop',loss='mse',metrics=['mae'])
21     return model
22 for e in range(epoch):
23     for fold in range(k):
24         np.random.shuffle(data)
25         validation_data = data[num_validation_samples * fold:num_validation_samples * (fold + 1)]
26         training_data = data[:num_validation_samples * fold] + data[num_validation_samples * (fold + 1):]
27         model = get_model()
28         model.fit(training_data)
29         validation_score = model.evaluate(validation_data)
30         validation_scores.append(validation_score)
31 
32 validation_score = np.average(validation_scores)
33 
34 model = get_model()
35 model.fit(np.concatenate([training_data,validation_data]))
36 test_score = model.evaluate(test_data)

如代码所示:循环变成了两层循环,在24行每次都要随机打乱训练集data中的数据。

 

4.2.2 评估模型的注意事项

(1)数据代表性:如果数据本身是按类别连续分布的,需要随机打乱数据。

(2)时间箭头:如果要根据过去预测未来,不应该随机打乱数据,要保证测试集中所有数据都i晚于训练集数据。

(3)数据冗余:保证训练集和验证集之间没有交集。

 

4.3 数据预处理、特征工程和特征学习 

4.3.1 神经网络的数据预处理

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

(1)向量化:神经网络所有输入和目标都必须是浮点数/整数的张量,无论处理什么数据,都必须将其转换为张量。

(2)值标准化:输入数据赢具有以下特征(取值较小,同质性)。

(3)处理缺失值:如果测试数据中有缺失值,而训练数据没有缺失值,需要人为在训练数据制造缺失值。

 

4.3.2 特征工程

含义:是指将数据输入模型之前,利用自己关于数据和机器学习算法的知识对数据进行硬编码的转换,以改善模型的效果。

本质:用更简单的方式表述问题,从而使问题变得更容易。

现代深度学习,大部分特侦工程都是不需要的,因为神经网络能从原始数据中自动提取有用特征,

但仍然需要特征工程,原因是:

(1)良好的特征仍然可以让你用更少的资源更优雅的解决问题。

(2)良好的特征可以让你用更少的数据解决问题。

 

4.4 过拟合与欠拟合

机器学习的根本问题是优化和泛化之间的对立。优化是指调节模型以在训练数据上得到最佳的性能,而泛化是指训练好的模型在前所未见的数据上的性能好坏。

解决过拟合的常用方式:

(1)获取更多的训练数据。

(2)正则化

 

4.4.1 减小网络大小

减小模型的大小(减少模型中可学习参数的个数)

但网络规模太小又会导致欠拟合,因此需要找到网络模型的一个适中的规模。

一般的工作流程是开始时选择相对较少的层和参数,然后逐渐增加层的大小或增加新层,知道这种增加对验证损失的影响变得很小。

 

4.4.2 添加权重正则化

奥卡姆剃刀原理:如果一件事情有两种解释,那么可能正确的解释就是最简单的哪个,即假设更少的哪个。

权重正则化:强制让模型权重只能取较小的值,从而限制模型的复杂度,使这种权重的分布更加规则。

(1)L1正则化:添加的成本与权重系数的绝对值成正比

(2)L2正则化:添加的成本与权重系数的平方成正比。

 1 from keras import regularizers
 2 from keras import models
 3 from keras import layers
 4 import matplotlib.pyplot as plt
 5 from keras.datasets import imdb
 6 import numpy as np
 7 
 8 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
 9 
10 def vectorize_sequences(sequences, dimension=10000):
11     # Create an all-zero matrix of shape (len(sequences), dimension)
12     results = np.zeros((len(sequences), dimension))
13     for i, sequence in enumerate(sequences):
14         results[i, sequence] = 1.  # set specific indices of results[i] to 1s
15     return results
16 
17 # Our vectorized training data
18 x_train = vectorize_sequences(train_data)
19 # Our vectorized test data
20 x_test = vectorize_sequences(test_data)
21 # Our vectorized labels
22 y_train = np.asarray(train_labels).astype('float32')
23 y_test = np.asarray(test_labels).astype('float32')
24 
25 original_model = models.Sequential()
26 original_model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
27 original_model.add(layers.Dense(16, activation='relu'))
28 original_model.add(layers.Dense(1, activation='sigmoid'))
29 
30 original_model.compile(optimizer='rmsprop',
31                        loss='binary_crossentropy',
32                        metrics=['acc'])
33 
34 original_hist = original_model.fit(x_train, y_train,
35                                    epochs=20,
36                                    batch_size=512,
37                                    validation_data=(x_test, y_test))
38 
39 epochs = range(1, 21)
40 original_val_loss = original_hist.history['val_loss']                     
41 
42 
43 l2_model = models.Sequential()
44 l2_model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
45                           activation='relu', input_shape=(10000,)))
46 l2_model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
47                           activation='relu'))
48 l2_model.add(layers.Dense(1, activation='sigmoid'))
49 
50 l2_model.compile(optimizer='rmsprop',
51                  loss='binary_crossentropy',
52                  metrics=['acc'])
53 
54 l2_model_hist = l2_model.fit(x_train, y_train,
55                              epochs=20,
56                              batch_size=512,
57                              validation_data=(x_test, y_test))
58 
59 
60 l2_model_val_loss = l2_model_hist.history['val_loss']
61 
62 plt.plot(epochs, original_val_loss, 'b+', label='Original model')
63 plt.plot(epochs, l2_model_val_loss, 'bo', label='L2-regularized model')
64 plt.xlabel('Epochs')
65 plt.ylabel('Validation loss')
66 plt.legend()
67 
68 plt.show()
69 
70 
71 from keras import regularizers
72 
73 # L1 regularization
74 regularizers.l1(0.001)
75 
76 # L1 and L2 regularization at the same time
77 regularizers.l1_l2(l1=0.001, l2=0.001)

 

kernel_regularizer=regularizers.l2(0.001)的意思时该层权重矩阵的每个系数都会使网络总损失增加0.001 * weight_coefficient_value。
注意这个惩罚只在训练时添加,所以这个网络的训练损失会比测试损失大很多。
 

4.4.3 添加dropout正则化

dropout时神经网络最有效也最常用的正则化方法之一,就是在训练过程中随机将该层的一些输出特征舍弃。

dropout比率是被设为0的特征所占的比例,通常在0.2~0.5范围内。

测试时没有单元被舍弃,而该层的输出值需要按dropout比例缩小。

 1 from keras import regularizers
 2 from keras import models
 3 from keras import layers
 4 import matplotlib.pyplot as plt
 5 from keras.datasets import imdb
 6 import numpy as np
 7 
 8 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
 9 
10 def vectorize_sequences(sequences, dimension=10000):
11     # Create an all-zero matrix of shape (len(sequences), dimension)
12     results = np.zeros((len(sequences), dimension))
13     for i, sequence in enumerate(sequences):
14         results[i, sequence] = 1.  # set specific indices of results[i] to 1s
15     return results
16 
17 # Our vectorized training data
18 x_train = vectorize_sequences(train_data)
19 # Our vectorized test data
20 x_test = vectorize_sequences(test_data)
21 # Our vectorized labels
22 y_train = np.asarray(train_labels).astype('float32')
23 y_test = np.asarray(test_labels).astype('float32')
24 
25 
26 original_model = models.Sequential()
27 original_model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
28 original_model.add(layers.Dense(16, activation='relu'))
29 original_model.add(layers.Dense(1, activation='sigmoid'))
30 
31 original_model.compile(optimizer='rmsprop',
32                        loss='binary_crossentropy',
33                        metrics=['acc'])
34 
35 original_hist = original_model.fit(x_train, y_train,
36                                    epochs=20,
37                                    batch_size=512,
38                                    validation_data=(x_test, y_test))
39 
40 epochs = range(1, 21)
41 original_val_loss = original_hist.history['val_loss']      
42 
43 dpt_model = models.Sequential()
44 dpt_model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
45 dpt_model.add(layers.Dropout(0.5))
46 dpt_model.add(layers.Dense(16, activation='relu'))
47 dpt_model.add(layers.Dropout(0.5))
48 dpt_model.add(layers.Dense(1, activation='sigmoid'))
49 
50 
51 
52 dpt_model.compile(optimizer='rmsprop',
53                   loss='binary_crossentropy',
54                   metrics=['acc'])
55 
56 dpt_model_hist = dpt_model.fit(x_train, y_train,
57                                epochs=20,
58                                batch_size=512,
59                                validation_data=(x_test, y_test))                  
60 
61 
62 dpt_model_val_loss = dpt_model_hist.history['val_loss']
63 
64 plt.plot(epochs, original_val_loss, 'b+', label='Original model')
65 plt.plot(epochs, dpt_model_val_loss, 'bo', label='Dropout-regularized model')
66 plt.xlabel('Epochs')
67 plt.ylabel('Validation loss')
68 plt.legend()
69 
70 plt.show()      

 

4.5 机器学习的通用工作流程

4.5.1 定义问题,收集数据集

4.5.2 选择衡量成功的指标

4.5.3 确定评估方法

4.5.4 准备数据

4.5.5 开发比基准更好的模型

4.5.6 扩大模型规模:开发过拟合的模型

4.5.7 模型正则化与调节超参数

 

posted on 2021-01-24 09:28  Sempron2800+  阅读(156)  评论(0编辑  收藏  举报