第一章.什么是深度学习
机器学习的技术定义:在预先定义好的可能性空间中,利用反馈信号的指引寻找输入数据的有用表示。
深度学习的深度是指一系列连续的表示层。分层表示通过叫做神经网络的模型来学习。
决策树类似于流程图结构,对输入数据点进行分类或根据给定输入来预测输出值。
特征工程:为初试输入数据选择合适的方法,手动为数据设计好的表示层。
深度学习特征:渐进逐层方式形成越来越复杂的表示,对中间渐进的表示共同进行学习。
第二章,神经网络的数学基础
张量(Tensor)是一个数据容器,包含的数据几乎是数值数据,是数字容器,张量的维度叫轴(axis)。
0D张量为标量,1D张量为向量,2D张量为矩阵。通过.ndim查询张量轴的个数。
批量张量中,第一个轴叫批量轴或者批量维度。
广播:向较小的张量添加轴,使其与较大的张量相同;较小的张量沿着新轴重复。
张量变形:reshape重新生成形状;transpose&T转置。
张量形状:TensorFlow中通道在后(samples,height,width,color_depth)。
Theano中通道在前(samples,color_depth,height,width)。
第三章,神经网络剖析
层的分类及处理方式:
1.向量数据保存在2D数据中,用密集连接层(全连接层,密集层,对应于Keras的Dense类)来处理。电邮ReLu激活的全连接层的简单堆叠。
2.序列数据保存在3D张量中,用循环层(keras中的LSTM层)来处理。
3.图像数据保存在4D张量中,用二维卷积层(Keras中的Conv2D)来处理Keras中,模型中添加的层会自动匹配输入层的形状。
具有多个输出的神经网络可能有多个损失函数,但梯度下降必须基于单个标量损失值。所有对于多个损失函数的网络,需要使用tf.reduce_mean取平均,变为一个标量值。
损失函数选择原则:二分类---二元交叉熵binary_crossentropy; 多分类---分类交叉熵categorical_crossentropy; 回归问题---均方误差mean_squared_error; 序列学习---联结主义时序分类CTC。
Keras后端引擎:TensorFlow,Theano,微软认知工具包CNTK。
Keras工作流程:
Keras实例1,电影评论分类(二分类)
#互联网电影数据库获取数据集
from keras.datasets import imdb
(train_data,train_label),(test_data,test_label)=imdb.load_data(num_words=10000)
#word_index是一个将单词映射成整数索引的字典
word_index=imdb.get_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]])
#整数序列编码为二进制矩阵
import numpy as np
def vectoirze_sequences(sequences,dimension=10000):
results=np.zeros((len(sequences),dimension))
#enummerate枚举出索引值和对应的值
for i, sequence in enumerate(sequences):
results[i,sequence]=1.0
return results
#将训练数据和测试数据向量化
x_train=vectoirze_sequences(train_data)
x_test=vectoirze_sequences(test_data)
#标签向量化
y_train=np.asarray(train_label).astype('float32')
y_test=np.asarray(test_label).astype('float32')
#架构选择:两个中间层,每层都有16个隐藏单元,使用relu作为激活函数,。
#第三层输出一个标量,预测当前评论的情感。
#最后一层使用sigmod激活输出概率值
#完成对模型的定义
from keras import models
from keras import layers
model=models.Sequential()#按顺序
model.add(layers.Dense(16,activation='relu',input_shape=(10000,)))#Dense表示一个全连接层
model.add(layers.Dense(16,activation='tanh'))
model.add(layers.Dense(1,activation='sigmoid'))
#配置优化器
from keras import optimizers
from keras import losses
from keras import metrics
#模型编译(选择优化器,选择损失函数)
#model.compile(optimizer='resprop',loss='binary_crossentropy',metrics=['accuracy'])
#自定义优化器,损失和指标
model.compile(optimizer=optimizers.RMSprop(lr=0.001),loss=losses.binary_crossentropy,metrics=[metrics.binary_accuracy])
#在训练集中流出样本作为验证集
x_val=x_train[:10000]
partial_x_train=x_train[10000:]
y_val=y_train[:10000]
partial_y_train=y_train[10000:]
#训练模型
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])
history=model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=512,validation_data=(x_val,y_val))
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)
#设置x轴数据,y轴数据,曲线格式,设置图例名称
plt.plot(epochs,loss_values,'bo',label='Training loss')
plt.plot(epochs,val_loss_values,'b',label='Validation loss')
#设置标题
plt.title('Training and Validation loss')
#设置横纵坐标名称
plt.xlabel('Epochs')
plt.ylabel('loss')
#显示图例
plt.legend()
plt.show()
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('Accuracy')
plt.legend()
plt.show()
#重新训练模型
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)
#修改处:1修改隐藏层层数,2修改隐藏单元,3使用mse替代binary_crossentropy, 4使用tanh激活函数替代relu
#原始数据预处理,化为张量转换到神经网络中
#二分类问题的sigmod标量输出,使用binary_crossentropy损失函数。
#rmsprop优化器通常都是不错的选择
#过拟合会导致数据效果越来越差
results=model.evaluate(x_test,y_test)
Keras实例2,新闻分类(多分类)
#数据包括短新闻和主题,文本分类数据集,46个不同主题,每个主题至少有10个样本
from keras.datasets import reuters
(train_data,train_labels),(test_data,test_labels)=reuters.load_data(num_words=10000)
#索引解码为新闻文本
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]])
#数据编码
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)
x_test=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)
#可用keras自带方法实现该操作
from keras.utils.np_utils import to_categorical
one_hot_train_labels=to_categorical(train_labels)
one_hot_test_labels=to_categorical(test_labels)
#模型定义
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'))
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
#留出验证集
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:]
#训练模型
history=model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=512,validation_data=(x_val,y_val))
#构造损失图像
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('Epoches')
plt.ylabel('Loss')
plt.legend()
plt.show()
#构造精度图像
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('Epoches')
plt.ylabel('Loss')
plt.legend()
plt.show()
#重新训练模型
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))
#修改隐藏单元数量
#修改隐藏层层数
Keras实例3,波士顿房价(回归问题)
#预测房屋价格中位数,数据点少,404训练和102测试
#加载数据
from keras.datasets import boston_housing
(train_data,train_targets),(test_data,test_targets)=boston_housing.load_data()
#数据标准化
#减去平均值
mean=train_data.mean(axis=0)
train_data-=mean
#除以标准差
std=train_data.std(axis=0)
train_data/=std
test_data-=mean
test_data/=std
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))
model.compile(optimizer='rmsprop',loss='mse',metrics=['mae'])
return model
#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 fold #',i)
#准备验证数据:第k个分区的数据
val_data=train_data[i*num_val_samples:(i+1)*num_val_samples]
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)
#构建Keras模型
model=build_model()
model.fit(partial_train_data,partial_train_targets,
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)
np.mean(all_scores)
#保存每折的验证结果
num_epochs=500
all_mae_histories=[]
for i in range(k):
print('processing fold # ', i)
#准备验证数据
val_data=train_data[i*num_val_samples:(i+1)*num_val_samples]
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()
history=model.fit(partial_train_data,partial_train_targets,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)
#计算所有k折验证分数平均值
average_mae_history=[np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]
#绘制验证分数
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()
#绘制验证分数(删除前10个数据点)
def smooth_curve(points,factor=0.9):
smoothed_pointed=[]
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:])
plt.plot(range(1,len(smooth_mae_history)+1),smooth_mae_history)
plt.xlabel('Epochs')
plt.ylabel('Validation mae')
plt.show()
#训练最终模型
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)
对于取值范围差异很大的数据输入到神经网络中,网络会自动适应这种取值范围不同的数据。普遍采用的最佳实践是对每个特征做标准化:输入数据的每个特征,减去特征平均值,除以标准差(总体各单位标准值 与其平均数离差平方的算术平均数的平方根),得到特征平均值为0,标准差为1。
对于数据点少,验证集小,验证分数上有很大的方差,采用K折交叉验证:数据划分为k个分区,实例化K个相同的模型,每个模型再k-1个分区上训练,并在下一分区上评估,模型验证分数等于K个验证分数的平均值
原始数据输入神经网络之前,需要对其进行预处理,若数据特征具有不同取值范围,则需要对每个特征单独缩放。
数据被分为多个类别,中间层过小会导致信息瓶颈。
回归问题使用的损失函数和评估指标都与分类问题不同。
处理数据很少,使用k折验证