小言_互联网的博客

深度神经网络——从单隐层神经网络到深度神经网络各个超参数介绍和案例(找出可能流失的客户)

402人阅读  评论(0)

深度神经网络

一、神经网络原理

1.传统机器学习算法的局限性

越简单的关系越容易过拟合。
对于特征的变换、升阶,以及多个特征相互组合形成新特征的过程,就是机器学习过程中既耗时又耗力的特征工程。

特征空间是数据特征所形成的空间,特征维度越高,特征空间越复杂。而假设空间则是假设函数形成的空间,特征越多,特征和标签之间的对应的关系越难拟合,假设空间也就越复杂。

维度灾难:高维度带来了超高的复杂度和超巨大的特征空间。比如,尾气特征维度是19x19,但是它的有效状态数量超过了10170

2.神经网络优势

当用神经网络去识别猫的时候,不需要手工去编写猫的定义,他的定义只存在于网络中的大量“分道器”中。这些分道器负责控制在网络的每一个分岔口把图片往目的地输送。而神经网络 就像一张无比旁大、带有大量分岔路的铁轨网。

在这密密麻麻的铁轨的一边是输入的图片,另一边则是对应的输出结果,也是道路的终点。网络会通过调整其中的每一个分道器来确保输入映射到正确的输出。训练数据越多,这个网络中的轨道越多,分岔路口越多,网络也就是越复杂。一旦训练好了,我们就有了大量的预定轨道,对新图片也能做出可靠的预测,这就是神经网络的自我学习原理

数据越多,投票者越多,就能获得越多的模式。

那些机械化的定义在神经网络面前变得不再有任何用处。

深度学习的机理:他是用一串一串的函数,也就是层,堆叠起来,作用域输入数据,进行从原始数据到分类结果的过滤于提纯。这些层通过权重来参数化 ,通过损失函数来判断当前网络的效能,然后通过优化器来调整权重,寻找从输入到输出的最佳函数。

注意以下两点:

  • 学习:就是为了神经网络的每个层中的每个神经元寻找最佳的权重。
  • 知识:就是学到的权重。

二、从感知层到单隐层网络

神经网络由神经元组成,最简单的神经网络只有一个神经元,叫感知器

Sigmiod函数,在逻辑回归中叫做逻辑函数,在神经网络中则被称作激活函数,用以类比人类神经系统中神经元的“激活”过程。

根据不同的数据输入,感知器适当的调整权重,在不同的功能之间切换(也就是拟合),形成了一个简单的自适应系统,人们就说它有了“感知"事物的能力。

单神经元,也就是感知器,通过训练可以用作逻辑回归分类器。

  • 输入空间:x,输入值的集合。
  • 输出空间:y,输出值的耳机和,通常,输出空间会小于输入空间。
  • 特征空间:每一个样本被称作一个实例,通常由特征向量表示,所有特征向量存在的空间称为特征空间,特征空间有时候与输入空间相同,有时候不同。因为有时候经过特征工程之后,输入空间可通过某种映射生成新的特征空间。
  • 假设空间:假设空间一般是对于学习到的模型而言的。模型表达了输入到输出的一种映射集合,这个集合就是假设空间,假设空间代表着模型学习过程中能够覆盖的最大范围。

基本的原则:模型的假设空间,一定要大到覆盖特征空间,否则模型就不可能精准地完成任务。

无论我们如何调整感知器的权重和偏置,都无法拟合”同或“数据集从特征到标签的逻辑。感知器是有局限性的。

神经网络隐层的出现把手工的特征工程丢给了神经网络,网络第一层权重和偏置自己去学,网络的第二层的权重和偏置自己去学,网络其他层的权重和偏置也是自己去学。我们除了提供数据以及一些网络的初始参数之外,剩下的事情都让网络自己完成。
哪怕特征数量再大,特征空间在复杂,神经网络通过多层框架也可以将其搞定。

注意神经网络的上下标符号。

三、用Keras单隐层网络预测客户流失率

前面的许多,都是为了了解神经网络的”分层
层,是神经网络的基本元素。 在实际应用中,神经网络是通过不同类型的”层“来构建的,而这个构建过程并不需要,具体到每层内部的神经元。

1.数据的准备于分析

标签 含义
Name 姓名
Gender 性别
Age 年龄
City 城市
Tenure 已经成为客户的年头
ProductsNo 拥有的产品数量
HasCard 是否有信用卡
ActiveMember 是否为活跃用户
Credit 信用等级
AccountBal 银行存款余额
Salary 薪水
Exited 客户是否已经流失

这些信息对于客户是否流失是具有指向性的。

读取文件
数据下载地址:https://download.csdn.net/download/sjjsaaaa/18176777

import numpy as np
import pandas as pd
df_bank = pd.read_csv(r'E:\Users\lenovo\Desktop\银行客户流失\数据集\BankCustomer.csv')


显示数据分布情况

import matplotlib.pyplot as plt
import seaborn as sns 
features = {
   'City','Gender','Age','Tenure','ProductsNo','HasCard','ActiveMember','Exited'}
fig = plt.subplots(figsize=(15,15))
for i,j in enumerate(features):
    plt.subplot(4,2,i+1)
    plt.subplots_adjust(hspace = 1.0)
    sns.countplot(x=j, data = df_bank)
    plt.title("No, of cnstumers")
plt.show()


从图中可以看出:北京的客户最多,男女客户比例大概一致,年龄和客户,数量呈正态分布。

数据预处理

  1. 性别。这是一个二元类别的特征,需要转为0/1代码格式进行读取处理。
  2. 城市。这是一个多元类别的特征,应把它转换为多个二元类别的哑变量。
  3. 姓名。这个字段对于客户流失与否的预测应该是完全不相关的,可以在进一步处理之前忽略。
    原始数据集中标签也应移除,放置于标签集。
#把二元类别文本数字化
df_bank['Gender'].replace("Female",0,inplace = True)
df_bank['Gender'].replace("Male",1,inplace = True)
df_bank

#把多元类别转成多个二元类别哑变量,然后放回原始集
a = pd.get_dummies(df_bank['City'],prefix='City')
b = [df_bank,a]
df_bank = pd.concat(b,axis=1)

df_bank = df_bank.drop(columns='City')

#构建特征集和标签
X = df_bank.drop(columns=['Name','Exited'])
y = df_bank['Exited']
#划分训练集和测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test =  train_test_split(X,y,test_size=0.2,random_state=0)

2.先尝试使用逻辑回归算法

from sklearn.linear_model import LogisticRegression # 导入Sklearn模型
lr = LogisticRegression() # 逻辑回归模型
history = lr.fit(X_train,y_train) # 训练机器
print("逻辑回归测试集准确率 {:.2f}%".format(lr.score(X_test,y_test)*100))

3. 单隐层神经网络的Keras实现

Keras构建出来的神经网络通过模块组装在一起,各个深度学习元件都是Keras模块,比如:神经网络层、损失函数、优化器、参数初始化、激活函数、模型正则化、都是可以组合起来构建新模型的模块。

(1)用序贯模型构建网路

去除警告模块:

import os
import warnings
os.environ['PYTHONHASHSEED'] = '0'
warnings.filterwarnings('ignore')

首先导入Keras库

import keras # 导入Keras库
from keras.models import Sequential # 导入Keras序贯模型
from keras.layers import Dense # 导入Keras密集连接层
  • 序贯模型,也可以叫做顺序模型,是最常用的深度网络层和层间的框架,也就是一个层接着一个层**,顺序地堆叠**。
  • 密集层,是最常用的深度网络层的类型,也称为全连接层,既当前层和其下一层的所有的神经元之间全有链接

搭建网络模型

#搭建神经网络
ann = Sequential()
ann.add(Dense(units=12, input_dim = 11,activation='relu'))  #添加输入层
ann.add(Dense(units = 24, activation = 'relu')) #添加隐层
ann.add(Dense(units = 1,activation = 'sigmoid'))  #添加输出层
ann.summary()  #显示网络模型

神经网络的结构信息。

每个层的类型,输出张量的形状,参数数量以及整个网络的参数数量。这个网络只有3层,493个参数(就是每个神经元的权重),对于神经网络来说,参数数量已经算是很少了。

展示神经网络的型状结构代码:


#输出神经网络的型状结构

from IPython.display import SVG  #实现神经网络结构的图形化显示
from keras.utils.vis_utils import model_to_dot
SVG(model_to_dot(ann,show_shapes = True).create(prog = 'dot',format = 'svg'))

解释上面的代码

  • 模型的创建:ann = Sequential() 创建了一个序贯神经网络模型
  • 输入层:通过add方法,可开始神经网络的堆叠,序贯模型们也就是一层一层的顺序堆叠。
    – Dense就是层的类型,代表密集层网络,是神经网络中最基本的层,也叫全连接层。
    – input_dim 是输入维度,输入维度必须与特征维度相同。这里指定的网络能接受的输入维度是11,如果和实际输入的网络的特征维度不匹配就会报错,见后面!
    – units 是输出维度,设置为12,也可以写成output_dim= 12,甚至忽略参数名。。
    – activation 是激活函数,这是每一层都需要设置参数。
  • 隐层:仍然通过add方法
  • 输出层:仍然是一个全连接层,指定的输出维度是1。对于二分类问题的输出层,Sigmoid是固定的选择,如果是用神经网络解决回归问题的化,那么输出层不用指定任何激活函数。

编译搭建好 的网络:

# 编译神经网络,指定优化器,损失函数,以及评估标准
ann.compile(optimizer = 'adam',           #优化器
            loss = 'binary_crossentropy', #损失函数  
            metrics = ['acc'])       #评估指标

用Sequential模型的compile方法对整个网络进行编译时,需要制定以下参数。

  • 优化器(optimizer):一般选用"adam”或者"rmsprop’,都是很好的优化器选项。
  • 损失函数(loss):对于二分类问题来说,基本上二元交叉熵函数(binary_crossentropy)是固定选项;如果使用神经网络解决线性分回归问题,那么均方误差哈傻女胡是合适的选择。
  • 评估指标(metrics):这采用acc作为评估网络性能的标准;对于回归问题,平均误差函数是合适的选择。准确率,也就是正确地预测占全部数据的比重,是最为常用的分类评估指标。

(2)全连接层

全连接层,是最常见的神经网络层,用于处理最普通的机器学习向量数据及,既2D张量数据集。
可设置的参数:

keras.layers.Dense(units=12,
                  activation = None,
                  use_bias = True,
                #  kernel_initializer = 'glorot_unifrom',
                  bias_initializer='zeros',
                  kernel_regularizer = None,
                  bias_regularizer=None,
                  activity_regularizer=None,
                  kernel_constraint=None,
                  bias_constraint=None
                  )

层内参数通常都是由机器学习通过梯度下降自动优化的。

(3)神经网络中其他类型的层

  • 循环层:用于处理保存在形状维(样本,时戳,标签)的3D张量中的序列数据。
  • 二维卷积层:用于处理保存形状在(样本,帧数,图像高度,图像宽度,颜色深度)的4D张量中的图像数据。

层就像是深度学习的乐高积木快,将相互兼容的,相同或者不同类型的多个层拼接在一起,建立起各种神经网络模型。

4.训练单隐层神经网络

神经网络的拟合过程也是通过fit方法实现,通过history变量把训练过程中的信息保存下来,留待以后分析。

这里会出现一个错误,应该将:

ann.add(Dense(units=12, input_dim = 11,activation='relu'))  #添加输入层

改为:

ann.add(Dense(units=12, input_dim = 12,activation='relu'))  #添加输入层

在重新运行即可。

import keras # 导入Keras库
from keras.models import Sequential # 导入Keras序贯模型
from keras.layers import Dense # 导入Keras密集连接层
ann = Sequential() # 创建一个序贯ANN(Artifical Neural Network)模型
ann.add(Dense(units=12, input_dim=12, activation = 'relu')) # 添加输入层
ann.add(Dense(units=24, activation = 'relu')) # 添加隐层
ann.add(Dense(units=1, activation = 'sigmoid')) # 添加输出层

ann.compile(optimizer = 'adam',           #优化器
            loss = 'binary_crossentropy', #损失函数  
            metrics = ['acc'])       #评估指标
history = ann.fit(X_train, y_train, # 指定训练集
                  epochs=30,        # 指定训练的轮次
                  batch_size=64,    # 指定数据批量
                  validation_data=(X_test, y_test)) #指定验证集,这里为了简化模型,直接用测试集数据进行验证


参数:

  • batch_size:用于指定数据批量,也就是每一次梯度下降更新参数时,所同时训练的样本数量。
  • validation_data:用于指定验证集。
  • epochs:训练的轮次。
  • 训练集

5.训练过程的图形化显示

训练过程中输出的信息包括每轮训练的损失值、准确率等,下面这个函数,显示基于训练集和验证集的损失函数,以及准确率随迭代次数变化的曲线。

def show_history(history): # 显示训练过程中的学习曲线
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(1, len(loss) + 1)
    plt.figure(figsize=(12,4))
    plt.subplot(1, 2, 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()
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    plt.subplot(1, 2, 2)
    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()
show_history(history) # 调用这个函数,并将神经网络训练历史数据作为参数输入

四、分类数据不平衡问题:只看准确率够用嘛

1.混淆矩阵、准确率、召回率和F1分数

在机器学习中引入可视化评估工具,在监督学习中叫做混淆矩阵。

  • 一个标准是:准确率也叫查准率,其公式使用“被模型预测为证的正样本”除以“被模型预测为正的正样本”与被模型预测为负的正样本“的和。
  • 另一个标准:召回率,也叫查全率,就是不合格的产品过了之间的关,要召回,销毁掉。
  • 把精确率和召回率结合起来,就得到F1分数。这是一个可以同时体现上面两个评估效果的标准,数学上定义为精确率和召回率的调和均值。
  • 这3个标准的重要性在此时要远远高于准确率。

2.数用分类报告和混淆矩阵

用神经网络模型的predict方法预测测试集的分类标签,然后把真值和预测值作比较,并利用Sklearn中的分类报告功能来计算上面的这几类标准。

from sklearn.metrics import classification_report # 导入分类报告
def show_report(X_test, y_test, y_pred): # 定义一个函数显示分类报告
    if y_test.shape != (2000,1):
        y_test = y_test.values # 把Panda series转换成Numpy array
        y_test = y_test.reshape((len(y_test),1)) # 转换成与y_pred相同的形状 
    print(classification_report(y_test,y_pred,labels=[0, 1])) #调用分类报告   
show_report(X_test,y_test,y_pred)


对于标签为1的类别而言,准确率、召回率、F1分数据然都是0.
这时输出y_pred值,会是清一色的0.

下面画出混淆矩阵

from sklearn.metrics import confusion_matrix # 导入混淆矩阵
def show_matrix(y_test, y_pred): # 定义一个函数显示混淆矩阵
    cm = confusion_matrix(y_test,y_pred) # 调用混淆矩阵
    plt.title("ANN Confusion Matrix") # 标题
    sns.heatmap(cm,annot=True,cmap="Blues",fmt="d",cbar=False) # 热力图设定
    plt.show() # 显示混淆矩阵
show_matrix(y_test,y_pred)


混淆矩阵显示417个客户流失正样本竟然一列都没侧中。这样的神经网路尽管准确率为79%,但实际上是训练完全失败了。

3.特征缩放的魔力

**对于神经网络而言,特征缩放极为重要。**神经网络不喜欢大的取值范围,因此需要将输入神经网络的数据标准化,把数据约束在较小的区间,这样可消除离群样本对函数形状的影响。

这里对数据进行标准化,其步骤是:对于输入数据的每个特征,减去特征平均值,再除以标准差,之后得到的特征平均值为0,标准差为1.
代码如下:(按照公式来写:)

mean = X_train.mean(axis=0) # 计算训练集均值
X_train -= mean # 训练集减去训练集均值
std = X_train.std(axis=0) # 计算训练集方差
X_train /= std # 训练集除以训练集标准差
X_test -= mean # 测试集减去训练集均值
X_test /= std # 测试集减去训练集均值

(使用sklearn库):

from sklearn.preprocessing import StandardScaler # 导入特征缩放器
sc = StandardScalear() # 特征缩放器
X_train = sc.fit_transform(X_train) # 拟合并应用于训练集
X_test = sc.transform (X_test) # 训练集结果应用于测试集

无论使用哪种方法,特征缩放的代码必须要放在数据集拆分之后。

均值和标准差都是 在训练数据上计算而得的,然后将同样的均值和标准差应用于训练集和测试集。

将数据带入到逻辑回归模型中查看准确率:

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression() # 逻辑回归模型
history = lr.fit(X_train,y_train) # 训练机器
print("逻辑回归测试集准确率 {:.2f}%".format(lr.score(X_test,y_test)*100))

重新训练单隐层神经网络:

history = ann.fit(X_train, y_train, # 指定训练集
                  epochs=30,        # 指定训练的轮次
                  batch_size=64,    # 指定数据批量
                  validation_data=(X_test, y_test)) #指定验证集


达到了86.15%。

查看损失曲线和准确率曲线:

准确率,和召回率和F1分数也大幅度提高:

4.阈值调整、欠拟合、过采样

在面对数据极度不平衡的时候,实际还有以下一些方法。

  • 首先就是选择合适的评估指标。除了我们刚才选用的F1分数,还有ROC/AUC,以及G-mean等标准。
  • 还可以考虑调整分类阈值
  • 还由一种方法就是采样法,分为欠采样和过采样。
    – 过采样:认为地重复类别较少的数据,使数据集中各种类别的数据大致数目相同。
    – 欠采样:认为地丢弃大量类别较多的数据,使数据集中各种类别的数据大致数目相同。

五、从单隐层神经网络到深度神经网络

1.梯度下降:正向传播和反向传播

神经网络也是通过损失函数来衡量该输出与预测值之间的差距,并以此作为反馈信号微调权重,以降低损失值。

深度神经网络的梯度下降和参数优化过程是通过优化器实现的,其中包括正向传播算法和以及一个更为核心的深度学习算法反向传播

  • 正向传播,就是从数据的输入,一层一层进行输入和输出的传递,直到最后一层的预测结果,然后计算损失值的过程。
  • 反向传播,就是反向计算偏微分,信息会从神经网络的高层向底层反向传播,并在这个过程中根据输出来调整权重。就是参数优化的过程。

反向传播从最终损失值,并从反向作用至输入层,是利用链式求导法则计算每个参数对损失值的贡献大小。

2.深度神经网络中的一些可调超参数

通过正向传播和反向传播,神经网络实现了内部参数的调整。

  • 优化器
  • 激活函数
  • 损失函数
  • 评估指标

3.梯度下降优化器

#编译神经网络
ann.compile(optimizer= 'adam',
           loss = 'binary_crossentropy',
           metrics = ['acc'])
  1. 神经网络权重参数随机初始化
  2. 批量梯度下降(BGD)
  3. 随机梯度下降(SGD)
  4. 小批量随机梯度下降(MBGD)
  5. 动量SGD
  6. 上坡时减少动量NAG
  7. 各参数的不同学习速率——Adagrad
  8. 加权平均值计算二阶动量——RMSProp
  9. 多种优化思路的集大成者——Adam
  10. 涅斯捷罗夫Adam加速——Nadam

adam是最常用的,目前也是口碑最好的优化器。

4.激活函数:从Sigmoid和ReLU

  1. Sigmoid函数和梯度消失
  2. Tanh函数
  3. ReLU函数
  4. Leaky ReLU和PReLU
  5. eLU函数
  6. Sigmoid和Softmax函数用于分类输出

5.损失函数的选择

对于连续值向量的回归问题,使用均方误差损失函数:

#编译神经网络
ann.compile(optimizer= 'adam',#均方误差损失函数
           loss = 'mse')

对于二分类问题,使用同样熟悉的二元交叉熵损失函数:

#编译神经网络
ann.compile(optimizer= 'adam',
           loss = 'binary_crossentropy',#二元交叉熵损失函数
           metrics = ['acc'])

对于多分类问题,如果是输出one-hot编码,则用分类交叉熵函数:

#编译神经网络
ann.compile(optimizer= 'adam',
           loss = 'categorical_crossentropy',#分类交叉熵函数
           metrics = ['acc'])

对于多分类问题,如果输出是证书数值,则使用稀疏分类交叉熵损失函数:

#编译神经网络
ann.compile(optimizer= 'adam',
           loss = 'sparse_categorical_crossentropy',#稀疏分类交叉熵损失函数
           metrics = ['acc'])

6.评估指标的选择

超参数是神经网络的评估指标,也就死评估网络模型好不好的标准,这个标准叫做目标函数。

还可以自主开发评估标准,用代码自定义了一个目标函数:

#自定义评估指标
import keras.backend as K
def mean_pred(y_true,y_pred):
    return K.mean(y_pred)
ann.compile(optimizer='rmsprop',
            loss = 'binary_crossentropy',
           metrics = ['accuracy',mean_pred])

六、用Keras深度神经网络预测客户流失率

1.构建深度神经网络

搭建多层的神经网络,还是使用序贯模型。

from keras.models import Sequential
ann = Sequential()

ann.add(Dense(units=12,input_dim=12,activation = 'relu'))
ann.add(Dense(units=24,activation = 'relu'))
ann.add(Dense(units=48,activation = 'relu'))
ann.add(Dense(units=96,activation = 'relu'))
ann.add(Dense(units=192,activation='relu'))
ann.add(Dense(units=1,activation='sigmoid'))
ann.summary()
# 编译神经网络,指定优化器,损失函数,以及评估标准
ann.compile(optimizer = 'adam',           #优化器
            loss = 'binary_crossentropy', #损失函数  
            metrics = ['acc'])       #评估指标
history = ann.fit(X_train, y_train, # 指定训练集
                  epochs=30,        # 指定训练的轮次
                  batch_size=64,    # 指定数据批量
                  validation_data=(X_test, y_test)) #指定验证集,这里为了简化模型,直接用测试集数据进行验证

2.神经网络正则化:添加Dropout层

from keras.models import Sequential
from keras.layers import Dropout
ann = Sequential()

ann.add(Dense(units=12,input_dim=12,activation = 'relu'))
ann.add(Dense(units=24,activation = 'relu'))
ann.add(Dropout(0.5))
ann.add(Dense(units=48,activation = 'relu'))
ann.add(Dropout(0.5))
ann.add(Dense(units=96,activation = 'relu'))
ann.add(Dropout(0.5))
ann.add(Dense(units=192,activation='relu'))
ann.add(Dropout(0.5))
ann.add(Dense(units=1,activation='sigmoid'))
ann.summary()


训练:

ann.compile(optimizer='adam',
           loss = 'binary_crossentropy',
           metrics = ['acc'])

history = ann.fit(X_train,y_train,
                 epochs = 30,
                 batch_size = 64,
                 validation_data=(X_test,y_test))

# 这段代码参考《Python深度学习》一书中的学习曲线的实现
def show_history(history): # 显示训练过程中的学习曲线
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(1, len(loss) + 1)
    plt.figure(figsize=(12,4))
    plt.subplot(1, 2, 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()
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    plt.subplot(1, 2, 2)
    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()
show_history(history) # 调用这个函数,并将神经网络训练历史数据作为参数输入

七、深度神经网络的调试及性能优化

1.使用回调功能

在训练过程中,根据一些预设的指示对训练进行控制。

  • ModelCheckpoint:在训练过程中的不同时间点保存模型,也急速和i保存当前网络的所有权重。
  • EaylyStopping:如果验证损失不再改善,则中断巡礼那。保存最佳模型。
  • ReduceLROnPlateau:在训练过程中动态调节某些参数值。
  • TensorBoard:将模型训练过程可视化。
#回调功能

from keras.callbacks import ModelCheckpoint
from keras.callbacks import EarlyStopping
from keras.callbacks import ReduceLROnPlateau

earlystop = EarlyStopping(monitor = 'val_acc',
                          patience = 20,
                          verbose =1)
                      #    restore_best_weights = True)

reducelr = ReduceLROnPlateau(monitor = 'val_acc',
                             factor = 0.5, 
                             patience = 3,verbose = 1,
                             min_lr = 1e-7)

modelckpt = ModelCheckpoint(filepath = 'ann.h5', 
                            monitor = 'val_acc',
                            verbose = 1,
                            save_best_only =True,
                            mode='max')

callbacks = [earlystop,reducelr,modelckpt]  #设定回调

history = ann.fit(X_train,y_train,  #指定训练集
                 batch_size = 128,  #指定批量大小
                 validation_data = (X_test,y_test),  #指定验证集
                 epochs = 100, #指定轮次
                 callbacks = callbacks) #指定回调功能

2.使用TensorBoard

包括以下功能:

  • 在训练过程中监控指标
  • 建模型的架构可视化。
  • 显示激活和梯度的直方图
  • 以三维的形式显示词嵌入。
# 导入并激活TensorBoard
%load_ext tensorboard
%tensorboard --logdir logs
# 创建机器学习模型
import tensorflow as tf
mnist = tf.keras.datasets.mnist
((x_train, y_train), (x_test, y_test)) = mnist.load_data()
(x_train, x_test) = (x_train / 255.0, x_test / 255.0)
model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(
  optimizer='adam',
  loss='sparse_categorical_crossentropy',
  metrics=['accuracy'],
)
# 回调Tensorboard
tensorboard_callback = tf.keras.callbacks.TensorBoard("logs")
model.fit(
  x_train,
  y_train,
  epochs=5,
  callbacks=[tensorboard_callback],
)

3.神经网络中的过拟合

解决过拟合的思路主要有:

  1. 首先,根据奥卡姆剃刀定律,,网络越大,越容易过拟合,如果能用小型网络模型就不要用大型网络
  2. 在训练大型网络之前使用少量数据训练一个较小的模型,小模型的泛化好,再去训练更深更大的网络。
  3. 最常见且有效地降低神经网络过拟合的方法就是在全连接层之间添加Dropout层。
  4. 使用较低的学习速率配合神经元的权重正则化可能是解决过拟合问题的手段之一。

4.梯度消失和梯度爆炸

都是因为网络太深、网络权重更新不稳定造成的,本质上都是梯度反向传播中的连锁效应

解决方案:

  1. 选择合适的激活函数
  2. 权重正则化
  3. 批标准化
from keras.layers.normalization import BatchNormalization   #导入批标准化组件
ann = Sequential() # 创建一个序贯ANN(Artifical Neural Network)模型
ann.add(Dense(units=12, input_dim=12, activation = 'relu')) # 添加输入层
ann.add(BatchNormalization())#添加批标准化层
ann.add(Dense(units=24, activation = 'relu')) # 添加隐层
  1. 残差连接

小结

神经网络的优势:

  1. 利用现代计算机的强大算力,提高了机器学习的精度
  2. 使特征工程不再显得那么重要,非结构化数据的处理变得简单

深度学习的应用:

  • 图像分类、人脸识别
  • 自然语言处理
  • 智能助手
  • 棋类游戏
  • 推荐系统

尽管深度神经网络处理巨大数据集和复杂问题的优势以是毋庸置疑,但是不能直接得出结论认为网络越深越好。如果问题不复杂,我们还是应该先尝试较为简单的模型。


转载:https://blog.csdn.net/sjjsaaaa/article/details/116207985
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场