python 深度学习-第3章 神经网络入门

from keras import layers
layer = layers.Dense(32,input_shape=(784,)) # 32个输出单元的密集层,只接受第一个维度大小为784的2D张量的输入,第0轴是批量的维度,其大小没有指定,因此可以使用任意取值,
                                            #第一个维度的大小变成32.因此这个层后面只能接受一个接受32维向量作为输入的层。在Keras中,向模型中添加的层都会自动匹配输入层的形状
from keras import models
from keras import layers

model = models.Sequential()
model.add(layers.Dense(32, input_shape=(784,)))
model.add(layers.Dense(32))#没有指定输入层的形状(input_shape),实际上他可以自动导出输入形状等于上一层的输出形状

3.1.2 模型:层构成的网络

深度学习模型是层构成的有向无环图。

网络拓扑结构:

  • 双分支(two-branch)网络
  • 多头(multihead)网络
  • inception模块

网络拓扑结构定义了一个假设空间(hypothesis space)。

机器学习,在预先定义好的可能性空间中,利用反馈信号的指引来寻找输入数据的有用表示。

选定了网络拓扑结构,意味着将可能性空间(假设空间)限定为一系列特定的张量运算,将输入数据映射为输出数据,然后须要为这些张量运算找到一组合适的值。

3.1.3 损失函数与优化器:配置学习过程的关键

  • 损失函数(目标函数)--在训练过程中需要将其最小化。特能够衡量当前任务是否已成功完成。
  • 优化器--决定如何基于损失函数对网络进行更新,它执行的是随机梯度下降(SGD)的某个变体。

多个输出的神经网络可能具有多个损失函数(每个输出对应一个损失函数)。但是梯度下降过程必须基于单个标量损失值,因此基于多个损失函数的网络,需要将所有损失函数取平均值,变成一个标量。

二分类问题:二元交叉熵(binary crossentropy)损失函数

多分类问题:分类交叉熵(categorical crossentropy)损失函数。

回归类问题:均方误差(mean-squared error)损失函数

序列学习问题:联结主义时序分类(CTC, connectionist temporal classfication)损失函数。

3.2 Keras简介

3.2.1 Keras、TensorFlow、Theano、CNTK

keras是一个模型级(model-level)库,提供高层次构建模块,不处理张量操作、求微分等低层次的运算。依赖于一个专门的、高度优化 的张量库来完成这些运算,该张量库就是Keras后端引擎(backend engine),没有选择单个张量库并将Keras实现与这个库进行绑定,而是以模块化的方式处理这个问题,因此不同后端引擎都可以无缝嵌入到Keras中。

Keras三个后端实现:TensorFlow后端、theano后端(蒙特利尔大学的MILA实验室开发)和微软认知工具包(CNTK, Microsoft cognitive toolkit)后端

python 深度学习-第3章 神经网络入门_第1张图片

TensorFlow在CPU上运行的低层次张量运算库eigen,在GPU上运行,就是高度优化深度学习运算库,NIVIDA CUDA深度神经网络库cuDNN

3.2.2 使用Keras开发:概述

  1. 定义训练数据:输入张量和目标张量。
  2. 定义层组成的网络(或者模型),将输入映射到目标。
  3. 配置学习过程,选择损失函数、优化器和需要监控的指标。
  4. 调用模型的fit方法在训练数据上进行迭代

定义模型:一种是使用sequential类(仅用于层的线性堆叠),另一种是函数式API(function API, 用于层组成的有向无环图,让你可以构建任意形式的架构)。

from keras import models
from keras import layers

model = models.Sequential()#利用sequential定义了两层线性堆叠模型
model.add(layers.Dense(32, activation='relu', input_shape=(784,)))#传入了输入数据的预期形状
model.add(layers.Dense(10, activation='softmax'))
from keras import models
from keras import layers
#函数式API定义
input_tensor = layers.Input(shape=(784,))#操纵模型处理数据张量
x = layers.Dense(32, activation='relu')(input_tensor)#将层应用于这个张量
output_tensor = layers.Dense(10, activation = 'softmax')(x)

model = models.Model(inputs=input_tensor,outputs= output_tensor)
from keras import optimizers
#指定模型使用的优化器和损失函数以及训练过程中想要监控的指标
model.compile(optimizer=optimizers.RMSprop(lr=0.001),
             loss='mse',
             metrics=['accuracy'])
#学习过程就是通过fit()方法将输入数据的Numpy数组(和对应的目标数组)传入模型
from keras.datasets import mnist
(input_tensor, target_tensor),(test_images, test_labels)=mnist.load_data()
input_tensor = input_tensor.reshape((60000,28*28))
input_tensor = input_tensor.astype('float32')/255

from keras.utils import to_categorical
target_tensor = to_categorical(target_tensor)
model.fit(input_tensor, target_tensor, batch_size=128, epochs=10)

3.3 建立深度学习工作站

NVIDIA GPU+UNIX+Keras + TensorFlow

3.3.1 Jupyter笔记本:运行深度学习实验的首选方法

3.3.2 运行Keras:两种选择

3.3.3 在云端运行深度学习任务:优点和缺点

3.3.4 深度学习的最佳GPU

NVIDIA GPU

3.4 电影评论分类:二分类问题

将电影评论文字内容划分成正面或者负面

3.4.1 IMDA数据集

import numpy as np
old = np.load
np.load = lambda *a,**k: old(*a,**k,allow_pickle=True)
#加载IMDB数据集
from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)#仅保留训练数据中前10000个最常出现的单词,低频词汇被舍弃
np.load = old
del(old)
train_data[0]#每条评论组成的列表,每条评论又是单词索引组成的列表(表示一系列单词)
train_labels[0]#0,1组成的列表,其中0代表负面(negative)1代表正面(positive)
max([max(sequence) for sequence in train_data])#单词索引不会超过10000
word_index = imdb.get_word_index()#word_index是一个将单词映射为整数索引的字典
reverse_word_index = dict([(value , key) for (key, value) in word_index.items()])#键值颠倒,将整数索引映射为单词
decoded_review=''.join([reverse_word_index.get(i - 3 ,'?') for i in train_data[0]])#将评论解码。注意,索引减去了3,因为0,1,2是为“padding”(填充)、“start of sequence”(序列开始)、“unknown”(未知词)分别保留的索引

3.4.2 准备数据

不能将整数序列直接输入到神经网络,需要将列表转换为张量。

  • 填充列表,使其具有相同的长度,再将列表转换成形状为(samples word_indices)的整数张量,然后网络第一层使用能处理这种整数张量的层(Embedding层)
  • 对列表进行one-hot编码,将其转换成为0和1组成的向量,[3,5]只有索引在3~5之间的元素是1,其他的元素都是0,凑够10000维度,然后网络第一层可以使用Dense层,它能够处理浮点数向量数据。
import numpy as np
def vectorize_sequences(sequences, dimension = 10000):
  results = np.zeros((len(sequences),dimension))#创建一个形状为(len(sequences),dimension)的零矩阵
  for i, sequence in enumerate(sequences):
    results[i,sequence]=1.#将results[i]的指定索引设为1
  return results
x_train = vectorize_sequences(train_data) #将训练数据向量化
x_test = vectorize_sequences(test_data)#将测试数据向量化
x_train[0]
y_train = np.asarray(train_labels).astype('float32')#将标签向量化
y_test = np.asarray(test_labels).astype('float32')

3.4.3 构建网络

输入数据是向量,而标签是标量(1,0)。带有relu激活的全连接层(Dense)的简单堆叠Dense(16,activation='relu')

传入Dense层的参数16是该层 的隐藏单元个数,一个隐藏单元(hidden unit)是该层表示空间的一个维度。每一个带有relu激活 的Dense层都实现了下面张量运算

output = relu(dot(W,input)+b)

16个隐藏单元对应的权重矩阵W的形状为(input_dimension,16),与W做点积相当于将输入数据投影到16维表示空间中(然后加上偏置向量b并运用relu运算)。表示空间的维度直观的理解为“网络学习内部表示时所拥有的自由度”。隐藏单元越多(即更高维的表示空间),网络越能学习到更加复杂的表示,但是网络计算代价也变得很大,而且可能导致学习到不好的模式(这种模式会提高训练数据的性能,但不会提高测试数据上的性能)。

  • 网络有多上层
  • 每层有多少隐藏单元

两个中间层,每层都有16个隐藏单元,第三层输出一个标量,预测当前评论的情感。

中间层使用relu作为激活函数,最后一层使用sigmoid激活以输出一个0~1范围内的概率值(表示样本的目标值等于1的可能性,评论为正面的可能性)。

relu(rectified linear unit,整流线性单元)函数将所有负值都归0

sigmoid函数将任意值“压缩”到[0,1]区间内,输出值可以看做概率值。

python 深度学习-第3章 神经网络入门_第2张图片python 深度学习-第3章 神经网络入门_第3张图片

 

python 深度学习-第3章 神经网络入门_第4张图片

如果没有激活函数(非线性),Dense层将只包含两个线性运算-点积和加法

output = dot(W ,input) + b

这样Dense层就只能学习输入数据的线性变换(仿射变换),该层的假设空间是从输入数据到16维空间所有可能的线性变换集合。这种假设空间非常有限,无法利用多个表示层的优势,因为多个现行层堆叠实现的仍是线性运算,添加层数并不会扩展假设空间。

为了得到更丰富的假设空间,从而充分利用多层表示的优势,才需要加入非线性或者激励函数。

输出是概率模型,交叉熵(crossentropy)是常用选择,来自于信息论领域,用于衡量概率分部之间的距离。

from keras import models
from keras import layers
#3-3 模型定义
model =models.Sequential()
model.add(layers.Dense(16, activation = 'relu', input_shape=(10000,)))#relu用于将负值归0,主要是非线性或激励函数以得到丰富的假设空间,充分利用多层优势
model.add(layers.Dense(16, activation = 'relu'))
model.add(layers.Dense(1, activation = 'sigmoid'))#sigmoid将任意值压缩至[0,1]空间,输出的是一个概率值,仅包含一个单元
#3-4 编译模型
model.compile(optimizer ='rmsprop',#用rmsprop作为优化器
             loss='binary_crossentropy',#bina因为输出的是一个概率值,因此使用二元交叉熵,衡量概率分布之间的距离
             metrics=['accuracy'])#指标
#3-5 配置优化器
from keras import optimizers

model.compile(optimizer=optimizers.RMSprop(lr=0.001),#配置优化器
             loss='binary_crossentropy',
             metrics=['accuracy'])
#3-6 使用自定义的损失和指标
from keras import losses
from keras import metrics

model.compile(optimizer=optimizers.RMSprop(lr=0.001),#配置优化器
             loss=losses.binary_crossentropy,#使用自定义的损失
             metrics=[metrics.binary_accuracy])#使用自定义的指标

3.4.4 验证你的方法

#3-7 留出验证集
x_val = x_train[:10000] #10000个样本作为验证集
partial_x_train = x_train[10000:]

y_val = y_train[:10000]#10000个样本作为验证集
partial_y_train = y_train[10000:]
#3-8 训练模型
model.compile(optimizer ='rmsprop',
             loss = 'binary_crossentropy',
             metrics = ['acc'])
#model.fit()反回了一个History对象,这个对象有一个成员history,是一个字典,包含训练过程中的所有数据
history = model.fit(partial_x_train,
                   partial_y_train,
                   epochs=20,#将模型训练
                   batch_size=512,#512个样本组成一个小批量
                   validation_data = (x_val, y_val))#监控在流出的10000个样本上的损失和精度
history_dict = history.history
history_dict.keys()
#3-9 绘制训练损失和验证损失
import matplotlib.pyplot as plt

history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']

epochs = range(1, len(loss_values)+1)

plt.plot(epochs, loss_values, 'bo',label='Traing loss')#'bo'表示蓝色的原点
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')#'b'表示蓝色实现
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend

plt.show()
#3-10 绘制训练精度和验证精度
plt.clf() #清空图像
acc = history_dict['acc']
val_acc = history_dict['val_acc']

plt.plot(epochs, acc, 'bo', label = 'Training acc')
plt.plot(epochs, val_acc, 'b', label = 'Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuray')
plt.legend()

plt.show()

模型在训练数据上表现越好,但是在所未见的数据上不一定表现得越来越好,这就是过拟合overfit。

#3-11 从头开始重新训练一个模型
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(optimizer='rmsprop',
             loss ='binary_crossentropy',
             metrics=['accuracy'])

model.fit(x_train, y_train, epochs =4, batch_size=512)
results = model.evaluate(x_test, y_test)
results

3.4.5 使用训练好的网络在新的数据上生成预测结果

model.predict(x_test)

3.4.7 小结

  • 通常需要对原始数据进行大量预处理,以便将其转换为张量输入到神经网络中,单词序列可以编码为二进制向量,但也有其他编码方式。
  • 带有relu激活的Dense层堆叠,可以解决很多问题(包括情感分类)。
  • 对于二分类问题(网络输出类别),网络最后一层应该是只有一个单元并使用sigmoid激活的Dense层,网络输出应该是0~1范围内的标量,表示概率值。
  • 对于二分类问题的sigmoid标量输出,应该使用binary_crossentropy损失函数。
  • rmsprop优化器通常都是足够好的选择。
  • 随着训练数据上的表现越好最终会过拟合,并且前所未见的数据上得到越来越差的结果,一定要一直监控模型在训练集之外的数据上的性能。

3.5 新闻分类:多分类问题

多分类(multiclass classification),单标签、多分类(single-label, multiclass classification)。

每个数据点只能划分到一个类别,单标签、多分类(single-label,multiclass classification)

每个数据点可以划分到多个类别,多标签、多分类(multilabel, multiclass classification)

3.5.1 路透社数据集

#3-12 加载路透社数据集
import numpy as np
old = np.load
np.load = lambda *a,**k: old(*a,**k,allow_pickle=True)
from keras.datasets import reuters
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)#仅保留训练数据中前10000个最常出现的单词,低频词汇被舍弃
np.load = old
del(old)
len(train_data)#8982个训练样本
len(test_data)#2246个测试样本
train_data[10]
#3-13 将索引解码为新闻文本
word_index =  reuters.get_word_index()
reverse_word_index = dict([(value,key) for (key, value) in word_index.items()])
decoded_newswire = ''.join([reverse_word_index.get(i - 3,'?') for i in train_data[0]])#注意,索引减去3,因为0,1,2是为"padding"(填充)、"start of sequence"(序列开始)、"unknown"(未知词)分别保留索引
train_labels[10]

3.5.2 准备数据

将数据向量化。

将标签列表转化为整数张量,或者使用one-hot编码。

one-hot编码是分类数据广泛使用的一种格式,也叫分类编码(categorical encoding)。只有有标签索引对应的元素为1.

#3-14 编码数据
import numpy as np
def vectorize_sequences(sequences, dimension=10000):
  results = np.zeros((len(sequences),dimension))
  for i , sequence in enumerate(sequences):
    results[i,sequence] = 1.
  return results

x_train = vectorize_sequences(train_data)#将训练数据向量化
y_train = vectorize_sequences(test_data)#将测试数据向量化

def to_one_hot(labels, dimension=46):
  results = np.zeros((len(labels),dimension))
  for i, label in enumerate(labels):
    results[i,label]=1
  return results

one_hot_train_labels = to_one_hot(train_labels)#将训练标签向量化
one_hot_test_labels = to_one_hot(test_labels)#将测试标签向量化

from keras.utils.np_utils import to_categorical

one_hot_train_labels = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)

3.5.3 构建网络

维度较小的层可能成为信息瓶颈,永远地丢失相关信息。

#3-15 模型定义
from keras import models
from keras import layers

model = models.Sequential()
model.add(layers.Dense(64,activation='relu',input_shape=(10000,)))
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dense(46,activation='softmax'))#对于每个输入样本,网络都会输出一个46维向量,输出46个不同输出类别上的概率分布,output[i]样本属于第i各类别的概率,46个概率的总和为1

#3-16 编译模型
model.compile(optimizer = 'rmsprop',
             loss = 'categorical_crossentropy',#分类交叉信息熵,衡量两个概率分布之间的距离,即网络输出的概率分布和标签的真是分布
             metrics=['accuracy'])

3.5.4 验证你的方法

#3-17 留出验证集
x_val = x_train[:1000]
partial_x_train = x_train[1000:]

y_val = one_hot_train_labels[:1000]
partial_y_train = one_hot_train_labels[1000:]

#3-18 训练模型
history = model.fit(partial_x_train,
                   partial_y_train,
                   epochs=20,
                   batch_size=512,
                   validation_data = (x_val,y_val))
#3-19 绘制训练损失和验证损失
import matplotlib.pyplot as plt

loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(1,len(loss)+1)

plt.plot(epochs, loss,'bo',label='Training loss')
plt.plot(epochs, val_loss,'b',label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()

plt.show()
#3-20 绘制训练精度和验证精度
plt.clf()#清空图像
acc = history.history['acc']
val_acc = history.history['val_acc']

plt.plot(epochs, acc, 'bo', label ='Training acc')
plt.plot(epochs, val_acc, 'b',label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()

plt.show()
#3-21 从头开始重新训练一个模型
model = models.Sequential()
model.add(layers.Dense(64,activation='relu',input_shape=(10000,)))
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dense(46,activation='softmax'))

model.compile(optimizer='rmsprop',
             loss='categorical_crossentropy',
             metrics=['accuracy'])

model.fit(partial_x_train,
         partial_y_train,
         epochs=9,
         batch_size=512,
         validation_data=(x_val,y_val))
results = model.evaluate(x_test,one_hot_test_labels)
results
import copy
test_labels_copy = copy.copy(test_labels)
np.random.shuffle(test_labels_copy)
hits_array = np.array(test_labels) == np.array(test_labels_copy)
float(np.sum(hits_array))/len(test_labels)

3.5.5 在新数据上生成预测结果

#3-22 在新数据上生成预测结果
predictions = model.predict(x_test)
predictions[0].shape#每个元素的长度是46
np.sum(predictions[0])#这个向量的所有元素总和是1
np.argmax(predictions[0])#概率最大的类别就是预测类别

3.5.6 处理标签和损失的另一种方法

x_train = np.array(train_labels)#将其转换为整数张量
y_test = np.array(test_labels)
model.compile(optimizer='rmsprop',
             loss='sparse_categorical_crossentropy',#整数标签的损失函数
             metrics=['acc'])

3.5.7 中间层维度足够大的重要性

#3-23 具有信息瓶颈的模型
model = models.Sequential()
model.add(layers.Dense(64, activation='relu',input_shape=(10000,)))
model.add(layers.Dense(4,activation='relu'))
model.add(layers.Dense(46,activation='softmax'))
model.compile(optimizer='rmsprop',
             loss='categorical_crossentropy',
             metrics=['accuracy'])
model.fit(partial_x_train,
         partial_y_train,
         epochs=20,
         batch_size=128,
         validation_data=(x_val,y_val))#验证结果下降8%主要在于第二层四维表示中数据被压缩了

3.5.9 小结

  • N个类别分类,最后一层大小应该是N的Dense层
  • 单分类或者多分类,最后一层应该使用softmax作为激活函数,因为可以输出N个输出类别上的概率
  • 损失函数几乎总是要是用分类交叉熵,将网络输出的概率分布与目标真实值分布之间的距离最小化
  • 处理分类问题标签方法:
  •         分类编码(one-hot编码)对标签进行编码。然后使用categorical_crossentropy作为损失函数
  •         标签编码为整数,使用sparse_categorical_crossentropy损失函数
  • 多分类问题,避免使用太小的中间层,避免在网络中造成信息瓶颈。

3.6 预测房价:回归问题

预测一个连续值而不是离散的标签

3.6.1 波士顿房价数据集

#3-24 加载波士顿房价数据
import numpy as np
old = np.load
np.load = lambda *a,**k: old(*a,**k,allow_pickle=True)
from keras.datasets import boston_housing
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()
np.load = old
del(old)
train_data.shape#404个训练样本
test_data.shape#102个测试样本,13个特征
train_targets

3.6.2 准备数据

#3-25 数据标准化
mean_train_data.mean(axis=0)
train_data -=mean#减去均值
std = train_data.std(axis=0)#
train_data/=std#除以标准差,得到特征平均是0,标准差为1

test_data -= mean
test_data /= std

3.6.3 构建网络

#3-26 模型定义
from keras import models
from keras import layers

def build_model():#因为需要将同一个模型多次实例化所以用一个函数来构建模型
  model = models.Sequential()
  model.add(layers.Dense(64, activation='relu',input_shape=(train_data.shape[1],)))
  model.add(layers.Dense(64, activation='relu'))
  model.add(layers.Dense(1))#最后一层只有一个单元,没有激活,是一个线性层,这是标量回归(预测单一连续值),添加激活函数将会限制输出范围,如果有sigmoid激活函数,那么网络只能学会预测0~1,最后一层是纯线性的,所以网络可以学会预测任意范围内的值。
  model.compile(optimizer='rmsprop',loss='mse',metrics=['mae'])#mse是损失函数,均方误差(MSE, mean squared error),预测值与目标值之差的平均,这是回归问题常用的损失函数。平均绝对误差MAE(mean absolute error),预测值与目标值之差的绝对值
  return model

3.6.4 利用K折验证来验证你的方法

K折交叉,将可用数据划分为K个分区(4、5),实例化K个相同模型,每个模型K-1个分区上训练,并在剩下的一个分区上进行评估,模型的验证分数等于K个验证分数的平均值。

python 深度学习-第3章 神经网络入门_第5张图片

#3-27 K折验证
import numpy as np
k=4
num_val_samples = len(train_data)//k
num_epochs = 100
all_scores = []

for i in range(k):
  print('processing flod #',i)
  val_data = train_data[i * num_val_samples:(i+1) * num_val_samples]#准备验证数据:第k个分区的数据
  val_targets=train_targets[i * num_val_samples:(i+1) * num_val_samples]

  partial_train_data=np.concatenate([train_data[:i* num_val_samples],#准备训练数据:其他所有分区的数据
                                      train_data[(i+1)*num_val_samples:]],
                                    axis=0)
    
  partial_train_targets=np.concatenate([train_targets[:i* num_val_samples],
                                        train_targets[(i+1)*num_val_samples:]],
                                       axis=0)
  
  model = build_model()#构建Keras模型已经编译
  model.fit(partial_train_data,partial_train_targets,#训练模型(静默模式,verbose=0)
            epochs = num_epochs, batch_size=1, verbose=0
           )
  val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0)#在验证数据上评估模型
  all_scores.append(val_mae)
print(all_scores)
print(np.mean(all_scores))
#3-28 保存每折的验证结果
import numpy as np
num_epochs = 500
all_mae_histories = []

for i in range(k):
  print('processing flod #',i)
  val_data = train_data[i * num_val_samples:(i+1) * num_val_samples]#准备验证数据:第k个分区的数据
  val_targets=train_targets[i * num_val_samples:(i+1) * num_val_samples]

  partial_train_data=np.concatenate([train_data[:i* num_val_samples],#准备训练数据:其他所有分区的数据
                                      train_data[(i+1)*num_val_samples:]],
                                    axis=0)
    
  partial_train_targets=np.concatenate([train_targets[:i* num_val_samples],
                                        train_targets[(i+1)*num_val_samples:]],
                                       axis=0)
  
  model = build_model()#构建Keras模型已经编译
  history = model.fit(partial_train_data, partial_train_targets,#训练模型(静默模式,verbose=0)
                      validation_data=(val_data, val_targets),
                      epochs=num_epochs, batch_size=1, verbose=0)
  mae_history = history.history['val_mean_absolute_error']
  all_mae_histories.append(mae_history)
#3-29 计算所有轮次中K折验证分数平均值
average_mae_history=[np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]
#3-30 绘制验证分数
import matplotlib.pyplot as plt
plt.plot(range(1, len(average_mae_history)+1), average_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()
#3-31 绘制分数验证(删除钱10个数据点)
def smooth_curve(points, factor=0.9):
  smoothed_points = []
  for point in points:
    if smoothed_points:
      previous = smoothed_points[-1]#每个数据点替换为前面数据点指数移动平均值,得到光滑曲线
      smoothed_points.append(previous * factor + point * (1-factor))
    else:
      smoothed_points.append(point)
  return smoothed_points
smooth_mae_history = smooth_curve(average_mae_history[10:])#因为前10个数据点,取值范围与曲线上其他点不同

plt.plot(range(1,len(smooth_mae_history)+1),smooth_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation MAE')
plt.show()
#3-32 训练最终模型
model = build_model()#一个全新的编译好的模型
model.fit(train_data, train_targets,
         epochs=80,batch_size=16,verbose=0)#在素偶有训练数据上训练模型
test_mse_score, test_mae_score = model.evaluate(test_data, test_targets)
print(test_mae_score)

3.6.5 小结

  • 回归常用损失函数是均方误差(MSE)

  • 回归指标是平均绝对误差(MAE)
  • 输入数据特征值具有不同取值范围,应先进行预处理,对每个特征值单独进行放缩。
  • 如果可用数据很少,使用K折验证可依可靠的苹果模型
  • 如果训练数据很少,最好使用隐藏层比较少的小型网络,以避免严重过拟合。

本章小结

 

 

 

你可能感兴趣的:(python)