优秀的编程知识分享平台

网站首页 > 技术文章 正文

用Keras实现深度学习网络

nanyue 2024-11-23 20:17:57 技术文章 1 ℃

在这篇文章中,主要介绍三类神经网络以及如何应用Keras的函数来实现神经网络的编程。第一类为全链接网络,它主要是由tf.keras.layers.Dense()函数来实现;第二类为卷积神经网络,它主要是tf.keras.layers.Conv2D()函数来实现;第三类为循环神经网络,它主要是利用tf.keras.layers.SimpleRNN()函数来实现。下面就具体的函数和参数进行介绍。

  1. 用Keras构建神经网络

用Keras构建神经网络总共分为六个步骤。第一步为import模块,即引入Keras关于深度学习网络的库函数,第二步为指定深度学习网络的训练和测试集,第三步为利用Keras的API搭建深度学习网络的网络架构,第四步为配置神经网络中相关参数,例如优化器的方式,损失函数和最终评价指标等,第五步为设置训练过程中相关参数,例如训练集和测试集的输入值和标签、每个batch的大小以及数据迭代的次数等,第六步为评价网络模型。具体分析如下:

第一步: import相关模块

import tensorflow as tf

from sklearn import datasets

import numpy as np

第二步:指定训练集和测试集

x_train = datasets.load_iris().data

y_train = datasets.load_iris().target

在训练集中划出一部分作为测试集,重新赋值给x_test和y_test。同时为了得到更好的测试效果,可以把整个测试集打乱次序。

np.random.seed(116)

np.random.shuffle(x_train)

np.random.seed(116)

np.random.shuffle(y_train)

tf.random.set_seed(116)

第三步:搭建深度学习网络

搭建深度学习网络有两种方法,一种方法是利用sequential,另一种方法是利用Class方法。

model= tf.keras.models.Sequential([

tf.keras.layers.Dense(3,activation=’softmax’,

kernel_regularizer=tf.keras.regularizers.l2())

])

这就是利用Sequential来进行神经网络的搭建,Dense中第一个参数表示神经元的个数,第二个参数表示激活函数,第三个参数为正则化的方法。Sequential可以包含各类网络结构,例如:

拉直层: tf.keras.layers.Flatten()

全链接层: tf.keras.layers.Dense(Number of neurons, activation=‘’, kernel_regularizer=‘’)

卷积层: tf.keras.layers.Conv2D(filters=‘’,kernel_size=‘’,strides=‘’,padding=‘’)

LSTM层: tf.keras.layers.LSTM()

其中activation可以选relu,softmax,sigmoid,tanh等;kernel_regularizer可选tf.keras.regularizers.l1() 和 tf.keras.regularizers.l2()

利用Class来进行网络搭建则为:

class MyModel(Model):

def __init__(self):

super(MyModel,self).__init__()

self.d1=Dense(3,activation=’softmax’,kernel_regularizer=tf.keras.regularizers.l2())

def call(self,x):

y=self.d1(x)

return y

model = MyModel(Model)

MyModel 表示声明的神经网络的名字,括号中的 Model 表示创建的类需要继承 tensorflow 库中 的 Model 类。类中需要定义两个函数,__init__()函数为类的构造函数用于初始化类的参数,spuer(MyModel,self).__init__()这行表示初始化父类的参数,之后便可初始化网络结构,搭建出神经网络所需的各种网络结构块。call() 函数中调用__init__()函数中完成初始化的网络块,实现前向传播并返回推理 值。最后需要实例化一个模型model。

第四步:配置神经网络的参数

model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),

metrics=['sparse_categorical_accuracy'])

这里用了model.compile()来设置神经网络训练时的一些参数,包括优化器的方法(SGD),并将学习率设置为0.1。利用了SparseCategoricalCrossentropy的方法来计算损失函数,衡量的标准为sparse_categorical_accuracy。

Optimizer可选为:

sgd or tf.keras.optimizers.SGD(lr=学习率,momentum=动量参数)

adagrad or tf.keras.optimizers.Adagrad(lr=学习率)

adadelta or tf.keras.optimizers.Adadelta(lr=学习率)

adam or tf.keras.optimizers.Adam(lr=学习率, beta_1=0.9, beta_2=0.999)

loss 可选为:

mse or tf.keras.losses.MeanSquaredError()

sparse_categorical_crossentropy or

tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False)

Metrics可选为:

accuracy: y_和y都是数值

categrocial_accuracy: y_和y都是概率分布

sparse_categorical_accuracy:y_是数值,y是独热码;例如y_=1,y=[0.2,0.5,0.3]

第五步:配置神经网络在训练和测试过程中的参数

model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)

这里用了model.fit()来执行训练过程,其中x_train, y_train来表示网络的输入特征和标签,batch_size表示一次喂入神经网络的数据量,epochs表示数据集迭代的次数,validation_split()表示数据集中测试集的划分比例,validation_freq表示每次迭代多少次测试一次准确率。

第六步:使用model.summary()打印网络的结构,统计参数数目。

示例代码(MNIST手写识别):在keras的datasets中提供了MNIST的训练集和测试集。MNIST是手写0-9的数字图像和对应的标签,目标是需要训练神经网络去识别手写的数字,其中0-9的数字图像被表示为28*28像素的矩阵。

利用Sequential来实现

第3行到第5行是导入mnist的数据,分别为训练数据和测试数据,此外要把数据进行归一化处理。第7行到第11行为网络架构的搭建,这里用了Sequential来搭建神经网络,第一层为Flatten层,即把输入数据拉成为1维数组。第二层为全链接层,有128个神经元,激活函数为relu。第三层为全链接层,有10个神经元(这里主要是因为0-9总共10各数字需要进行辨别),使用的激活函数为softmax,利用softmax可以得出每个数字可能的概率,这里就输出概率最大的那个数字作为辨别的结果。第13行到第15行为模型编译时的参数设置,这里的算法为adam。第17行到第18行为模型训练过程中控制参数的设置(上面章节已经讲述)。

利用Class来实现上述神经网络

  1. 用Keras构建卷积神经网络

卷积可以认为是一种有效提取图像特征的方法。一般会用一个正方形的卷积核,按指定步长,在输入特征图上滑动,遍历输入特征图中的每个像素点。每一个步长,卷积核会与输入特征图出现重合区域,重合区域对应元素相乘、求和再加上偏置项得到输出特征的一个像素点。

输入特征图的深度决定了卷积核的深度,例如输入为单通道图像,则卷积如下所示:

如果输入图像为彩色图像(三个通道),则卷积如下所示:

通过卷积核和原始图形进行计算后,其输出的图像尺寸都小于原始图像,为了保持图像尺寸不变,则在原始图像中加入全零填充,如下图所示:

在Tensorflow中,参数padding=‘SAME’或padding=‘VALID’来表示是否进行全零填充。在Keras中,用以下方法来构建卷积网络:

tk.keras.layers.Conv2D(

input_shape=(高,宽,通道数),#仅在第一层,这里输入图像的信息

filters=卷积核个数,#filters=16,代表16个卷积核

kernel_size=卷积核尺寸,# kernel_size=(3,3)代表大小为3*3的卷积核

strides=卷积步长, # 默认为1,卷积核在输入图像上滑动的步长

padding=’SAME’ or ‘VALID’, # 是否是全零填充

activation=’relu’ or ‘sigmoid’ or ‘tanh’ or ‘softmax’# 激活函数的类型

)

通常在卷积层后,激活函数前加入一个批量标准化函数BN,即tf.keras.layers.BatchNormalization(),这个函数的主要作用是对一小批数据做标准化处理,使得数据符合0均值,标准差为1的分布。其目的是解决神经网络中梯度消失的问题。BN另一个重要的步骤是缩放和偏移,这两个参数都是可以作为训练参数。

池化:池化的作用是减少特征数据量,池化的方法分为最大池化和平均池化。

在Tensorflow的框架下,用tf.keras.layers.MaxPool2D函数和tf.keras.layers.AveragePooling2D函数来实现池化功能。具体方法如下:

tf.keras.layers.MaxPool2D(

pool_size=池化核尺寸,

strides=池化步长,

padding=‘SAME’or‘VALID’

)

tf.keras.layers.AveragePooling2D(

pool_size=池化核尺寸,

strides=池化步长,

padding=‘SAME’or‘VALID’

)

舍弃(Dropout):在神经网络训练的过程中,将一部分神经元按照一定的概率从网络中进行舍弃,使用时被舍弃的神经元恢复链接。在Tensorflow框架下,利用tf.keras.layers.Dropout来实现dropout层。

神经网络构建的主要步骤为卷积(Convolutional)、批标准化(BN)、激活(Activation)、池化(Pooling)以及舍弃(Dropout)。以下为一个卷积网络的结构示例:

model = tf.keras.models.Sequential([

Conv2D(filters=6,kernel_size=(5,5),padding=’same’),

BatchNormalization(),

Activation(‘relu’),

MaxPool2D(pool_size=(2,2),strides=2,padding=’same’),

Dropout(0.2),

])

卷积神经网络示例:cifar10数据集共有60000张彩色图片,每张尺寸为32*32,分为10类,每类6000张。如下图所示:

cifar10是一个用于图像分类的数据集,共10个分类,相对于mmist数据集它是彩色而且图像更为复杂,训练难度也更大。用这个训练集来测试卷积神经网络的分类效果。首先确定卷积层的架构,如下图所示。

由上面结构图所示,整个卷积神经网络可以四个部分,第一个部分为卷积的架构,即卷积、标准化、激活、池化和舍弃,第二个部分为拉直部分,即把卷积的输出变为1维数组,第三和第四部分为全链接网络。具体编程程序如下:

以上是整个卷积神经网络的架构,程序还要包含model.complie(),model.fit()和model.summary()等设置。此外程序还加入了一个保存功能,即下一次新的数据不需要重新开始训练,只需要把之前训练的模型调用,然后输入数据进行加强训练。

  1. 用Keras构建循环神经网络

在很多的应用场景中,都是一些时间序列的数据。和卷积神经网络提取的空间维度信息不同,循环神经网络提取的是时间维度信息,从而进行后续的预测。循环神经网络的最基本单元为循环核,其结构如下:

和全链接的神经元不同,循环核具有记忆力,记忆体内存储每个时刻的信息ht,ht的信息是和上一个时间序列ht-1以及权重参数Wxh、Whh、bh偏置有关。输出函数yt和记忆体ht,权重参数Why以及by偏置有关。在前向传播过程中,记忆体信息ht在每时每刻被刷新,但参数Wxh,Whh,Why和两个偏置bh、by都保持不变,只有在反向传播时(训练过程中),这些参数才会被更新。

基于循环核的基础上,就可以加入更多的循环核从而构造循环神经网络的基本架构。可以看出,循环神经网络就是借助循环核实现时间特征提取后把提取到的信息送入全连接网络,从而实现连续数据的预测。

在循环核的输出方向,可以加入更多的循环核来提升它能存储的信息,如下图所示,左图的网络 有一个循环核,构成了一层循环计算层;中图的网络有两个循环核,构成了两层循环计算层;右图的网络有三个循环核,构成了三层循环计算层。

在tensorflow中,利用如下API调用循环神经网络(RNN):

tf.keras.layers.SimpleRNN(记忆体个数,activation=’激活函数’,

return_sequences=是否每个时刻输出到ht,True为每个时间步输出,False为仅最后时间步输出)

对于RNN,其输入数据的格式也是有严格规定的,其为[送入样本数,循环核时间展开步数,每个时间步输入特征个数]。下图显示两个不同的示例。

RNN最典型的应用就是利用历史数据预测下一个时刻将发生什么。举例说明字母的预测,输入一个字母预测下一个字母,即输入a预测b,输入b预测c,输入c预测d,输入d预测e,输入e预测a。要进行这样的预测首先要对字母进行编码,这里用独热编码的方式,其编码为10000为a,01000为b,00100为c,00010为d,00001为e。加速使用一层RNN网络,记忆体的个数为3,假设输入字母为b,即输入Xt为[0,1,0,0,0],这时上一个时刻的记忆体状态ht-1为0。则可以得出ht=tanh(XtWxh+ht-1Whh+b)=tanh([-2.3 0.8 1.1]+0+[0.5 0.3 -0.2])=[-0.9 0.8 0.7],这样就更新了ht。对于输出层yt=softmax(htWhy+by)=softmax([-0.7 -0.6 2.9 0.7 -0.8]+[0 0.1 0.4 -0.7 0.1]) = [0.02 0.02 0.91 0.03 0.02]。也就是说模型认为91%的可能性为字母c。

具体的keras的程序如下,程序首先对字母进行编码,然后建立了两层神经网络,第一层为RNN,第二层为全链接层。Model.complie()和model.fit()的设置之前都有详细的说明。

  1. 小结

这篇文章重点讲解了神经网络的三个类型,即全连接神经网络,卷积神经网络和时间序列神经网络。这三个神经网络的应用场景是有所区别的。全连接神经网络主要应用于非线性函数关系的表达,卷积神经网络主要应用于图像识别或机器视觉方面的应用,循环神经网络主要是对时间序列的数据进行分析并对下一个时间段的输出做出预测。

在实际应用中,神经网络的类型还有非常多的分类和变化,对于具体的问题需要尝试找到合适的方法去解决,这就需要利用评价指标去评价每个模型最后的输出结果,最终我们需要选择一个最佳的模型去解决相关问题。

Tags:

最近发表
标签列表