《Python深度学习》第三章笔记

深度学习的核心组件

1、层

可以将层看作深度学习的乐高积木,在 Keras 中,构建深度学习模型就是将相互兼容的多个层拼接在一起,以建立有用的数据变换流程
层兼容性(layer compatibility):每一层接受特定形状的输入张量,返回特定形状的输出张量

注意:Keras构建网络的过程中,第一层需要显示输入形状input_shape=(xxx) 后续的层不需要输入形状,因为可以从上一层中推导得出

2、模型

深度学习模型是层构成的有向无环图,一个模型就是一个网络拓扑结构,选定了一个模型就意味着定义了一个假设空间(hypothesis space),也就意味着将假设空间限定为一系列特定的张量运算,将输入数据映射为输出数据。

"温故知新"机器学习的一种定义:在预先定义好的假设空间中,利用反馈信号的指引来寻找输入数据的有用表示

3、损失函数与优化器

一般损失函数的选择:
二分类问题:二元交叉熵(binary crossentropy)损失函数;
多分类问题:分类交叉熵(categorical crossentropy)损失函数;
回归问题:均方误差(MSE,mean-squared error)损失函数;
序列学习问题:联结主义时序分类(CTC,connectionist temporal classification)损失函数

Keras开发基本流程

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

Keras示例

二分类问题

数据来源:互联网电影数据库(IMDB)的50000条严重两极分化的评论
训练集25000条,测试集25000条

from keras.datasets import imdb
from keras import models, layers
import numpy as np

##1、加载IMDB数据集
(train_data, train_labels),(test_data, test_labels) = imdb.load_data(num_words=10000)

##2、数据预处理(转换成可输入到神经网络的张量)
def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences),dimension))
    for i,sequence in enumerate(sequences):
        results[i,sequence] = 1  
#注意这里的sequence是个列表 
#也就是说第一次循环的时候results[0,list] = 1 
#这里其实隐含了一个循环 所做的操作是将results[i]的其中的指定索引设置为1
    return results

x_train = vectorize_sequences(train_data)  # 训练数据向量化  
x_test = vectorize_sequences(test_data)    # 测试数据向量化
y_train = np.asarray(train_labels).astype('float32')  #训练标签向量化
y_test = np.asarray(test_labels).astype('float32')    #测试标签向量化
#输入数据是向量,而标签是标量(1和0)

##3、定义模型
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'))

##4、编译模型
model.compile(optimizer='rmsprop',
            loss='binary_crossentropy',
            metrics=['accuracy'])

##5、训练模型
x_val = x_train[:10000]  # 这里留出一部分作为验证集
partial_x_train = x_train[10000:]
y_val = y_train[:10000] 
partial_y_train = y_train[10000:]

history = model.fit(partial_x_train, 
                  partial_y_train,
                  epochs=20,
                  batch_size=512, 
                  validation_data=(x_val, y_val))

## 6、在测试集(新数据)上生成预测结果  or 评估模型
model.predict(x_test)   
results = model.evaluate(x_test,y_test)

多分类问题

数据来源:路透社数据集,它包含许多短新闻及其对应的主题
训练集8982条,测试集2246条

from keras.datasets import reuters
import numpy as np
from keras.utils.np_utils import to_categorical
from keras import models, layers

##1、加载路透社数据集
(train_data, train_labels),(test_data, test_labels) 
= reuters.load_data(num_words=10000)

##2、数据预处理(转换成可输入到神经网络的张量)
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)    # 测试数据向量化
y_train = to_categorical(train_labels)    #训练标签分类编码
y_test = to_categorical(test_labels)     #测试标签分类编码

##3、定义模型
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'))

##4、编译模型
model.compile(optimizer='rmsprop',
            loss='categorical_crossentropy',
            metrics=['accuracy'])

##5、训练模型
x_val = x_train[:1000]  # 这里留出一部分作为验证集
partial_x_train = x_train[1000:]
y_val = y_train[:1000] 
partial_y_train = y_train[1000:]

history = model.fit(partial_x_train, 
                  partial_y_train,
                  epochs=20,
                  batch_size=512, 
                  validation_data=(x_val, y_val))

## 6、在测试集(新数据)上生成预测结果or评估模型
predictions = model.predict(x_test)  
#predictions中的每个元素都是长度为46的向量,向量的所有元素总和为1。
np.sum(predictions[0]) #输出1
np.argmax(predictions[0])  #最大的元素就是预测的类别,即概率最大的类别

results = model.evaluate(x_test,y_test)

注意:除了使用one-hot编码标签的方式,还可以使用另一种编码标签的方式-整型
使用的损失函数为 sparse_categorical_crossentropy

回归问题

数据来源: 20世纪70年代中期波士顿郊区房价信息
训练集: 404条 测试集: 102条

from keras.datasets import boston_housing 
from keras import models, layers
import numpy as np


##1、加载数据
(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

##2、数据预处理(转换成可输入到神经网络的张量)

输入数据的每个特征(比如犯罪率)都有不同的取值范围。
例如,有些特性是比例,取值范围为 0~1;有的取值范围为 1~12;还有的取值范围为0~100,等等
取值范围差异很大的数据输入到神经网络中,这是有问题的。
网络可能会自动适应这种取值范围不同的数据,但学习肯定变得更加困难
解决策略:
对每个特征做标准化,即对于输入数据的每个特征(输入数据矩阵中的列),减去特征平均值,再除以标准差
这样得到的每个特征平均值为0,标准差为1

#特征标准化
mean = train_data.mean(axis=0)
std = train_data.std(axis=0) 
train_data -= mean
train_data /= std
test_data -= mean 
test_data /= std

##3、构建模型(由于后续需要构建多个模型,所以直接写个函数)
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

##4、K折验证策略(解决样本数太少)

k=4
all_mae_histories = []
num_val_samples = len(train_data) // k 
num_epochs = 100
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,
                        epochs=num_epochs,
                        batch_size=1, verbose=0)

    mae_history = history.history['val_mean_absolute_error']
    all_mae_histories.append(mae_history)
    
##5、训练最终模型
通过上述的训练之后可以通过plot得到训练最佳轮次,另外还可以去尝试更改层数、隐藏单元个数
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)
 
>>> test_mae_score 2.5532484335057877
预测的房价和实际价格相差约 2550 美元。

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

3折交叉验证.png

你可能感兴趣的:(《Python深度学习》第三章笔记)