TensorFlow2.0(九)--Keras实现基础卷积神经网络

1. 卷积神经网络基础

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一。卷积神经网络基础知识包括卷积运算、特征图与感受野,填充(padding)与步幅(stride)等,在我之前的博客:动手学深度学习(PyTorch实现)(六)–卷积神经网络基础中有详细的描述,在此不再赘述,本博客着重于利用TensorFlow中的tf.keras实现基础的卷积神经网络。

2. Keras实现卷积神经网络

本文以分类问题为例,通过keras来实现基出的卷积神经网络,数据集采用之前DNN使用的fashion_mnist 的数据集,里面是像素为28*28的黑白图像

2.1 导入相应的库

首先我们要导入要用到的python库

# matplotlib 用于绘图
import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
# 处理数据的库
import numpy as np
import sklearn
import pandas as pd
# 系统库
import os
import sys
import time
# TensorFlow的库
import tensorflow as tf
from tensorflow import keras
2.2 数据集的加载与处理

加载数据集:

# 下载数据集
fashion_mnist = keras.datasets.fashion_mnist
# 拆分训练集与测试集
(x_train_all, y_train_all),(x_test, y_test) = fashion_mnist.load_data()
# 对训练集进行拆分,前5000个数据集作为验证集,其余的作为数据集
x_valid, x_train = x_train_all[:5000], x_train_all[5000:]
y_valid, y_train = y_train_all[:5000], y_train_all[5000:]

数据归一化可以减少模型的过拟合现象,从而可以提高模型的分类准确率,这里我们使用sklearn中的Standardscaler库对数据进行归一化处理:

from sklearn.preprocessing import StandardScaler
# 初始化scaler对象
scaler = StandardScaler()
# x_train: [None, 28, 28] -> [None, 784]
# 因为数据是int型,但是归一化要做除法,所以先转化为float32型
# 训练集数据使用的是 fit_transform,和验证集与测试集中使用的 transform 是不一样的
# fit_transform 可以计算数据的均值和方差并记录下来
# 验证集和测试集用到的均值和方差都是训练集数据的,所以二者的归一化使用 transform 即可
# 归一化只针对输入数据, 标签不变
x_train_scaled = scaler.fit_transform(
    x_train.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)
x_valid_scaled = scaler.transform(
    x_valid.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)
x_test_scaled = scaler.transform(
    x_test.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28, 1)
2.3 构建模型

本文构建一个简单的卷积神经网络,由三个基本单元组成,每个单元由两层卷积层和一层最大池化层组成,最后由两层全连接层结束。

# tf.keras.models.Sequential()用于将各个层连接起来
model = keras.models.Sequential()

# 第一层卷积层
model.add(keras.layers.Conv2D(filters = 32,             # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu',      # 激活函数relu
                              input_shape = (28, 28, 1))) # 输入维度是1通道的28*28

# 第二层卷积层
model.add(keras.layers.Conv2D(filters = 32,             # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu'))      # 激活函数relu
                              
# 最大池化层
model.add(keras.layers.MaxPool2D(pool_size=2))


# 第三层卷积层
model.add(keras.layers.Conv2D(filters = 64,             # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu'))      # 激活函数relu

# 第四层卷积层
model.add(keras.layers.Conv2D(filters = 64,             # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu'))      # 激活函数relu

# 最大池化层
model.add(keras.layers.MaxPool2D(pool_size = 2))
          
# 第五层卷积层
model.add(keras.layers.Conv2D(filters=128,              # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu'))     # 激活函数relu

# 第六层卷积层
model.add(keras.layers.Conv2D(filters=128,              # 卷积核数量
                              kernel_size = 3,          # 卷积核尺寸
                              padding = 'same',         # padding补齐,让卷积之前与之后的大小相同
                              activation = 'relu'))     # 激活函数relu
# 最大池化层
model.add(keras.layers.MaxPool2D(pool_size = 2))

# 全连接层
model.add(keras.layers.Flatten())  # 展平输出
model.add(keras.layers.Dense(128, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = "softmax")) # 输出为 10的全连接层

我们看看模型的结构:

model.summary()

在这里插入图片描述

2.4 模型的编译与训练

我们在构建好神经网络模型之后需要对模型进行编译:

model.compile(loss = "sparse_categorical_crossentropy",  # 稀疏分类交叉熵损失函数
             optimizer = keras.optimizers.SGD(0.01),    # 优化函数为随机梯度下降 ,学习率为0.01
             metrics = ["accuracy"])                     # 优化指标为准确度

开始训练:

history = model.fit(x_train_scaled, y_train,                     # 训练数据
                   epochs = 10,                           # 训练周期,数据分为10次进行训练
                   validation_data = (x_valid_scaled, y_valid),) # 验证集

训练过程为:
在这里插入图片描述

2.5 学习曲线绘制
def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    plt.grid(True)
    plt.gca().set_ylim(0, 1)
    plt.show()

plot_learning_curves(history)

在这里插入图片描述

2.6 模型验证

我们在验证集上看看模型的表现:

model.evaluate(x_test_scaled, y_test, verbose = 0)

输出结果为:
在这里插入图片描述
我们训练了十次的CNN在验证集上能够达到89.82%的准确率。

发布了182 篇原创文章 · 获赞 243 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_42580947/article/details/105434493
今日推荐