本节重点讲解通过代码构建CNN,具体理论知识会在以后专栏讲解,在此不过多赘述。

卷积神经网络主要由多个卷积层、池化层、激活函数和全连接层组成。首先输入数据进入卷积层进行特征提取,然后通过池化层进行下采样,降低特征维度。之后通过激活函数对特征进行非线性变换,增强模型表达能力。最后由全连接层进行分类或回归任务。

卷积神经网络是一类在图像识别相关学习任务汇总非常有效神经网络。相比于人工神经网络,卷积神经网络可以最大限度地保留图像数据的原始空间信息。目前卷积神经网络已经被广泛应用于人脸识别、场景标签、图像分类、动作识别和文档分析等各种实际问题。除此之外,在自然语言处理领域的语音识别和文本分类问题上,卷积神经网络也被证明能够达到最佳的准确率。

卷积神经网络通常由三种层组成:

  • 输入层
  • 隐藏层
  • 输出层
    注:隐藏层包含卷积层、池化层和全连接层

具体的卷积神经网络是有不同类型的层依次叠加而成:例如下图

CNN网络结构

  • 输入层
  • 卷积层
  • 池化层,使用最大池化
  • 卷积层
  • 池化层,使用最大池化
  • 全连接层
  • 输出层,使用softmax激活函数的全连接层

下面开始具体代码建模:

from sklearn.datasets import load_digits  # sklearn 为我们提供的手写数字数据集
import numpy as np

# 数据预处理
digits = load_digits()
X_data = digits.data.astype(np.float32)
y_data = digits.target.astype(np.float32).reshape(-1, 1)

X_data.shape, y_data.shape
# 数据的标准化(normalization)是将数据按比例缩放,
# 使之落入一个小的特定区间。这样去除数据的单位限制,
# 将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X = scaler.fit_transform(X_data)
X = X.reshape(-1, 8, 8, 1)
y = OneHotEncoder(categories='auto').fit_transform(
    y_data).todense()  # one-hot 编码

X.shape, y.shape
#实例化
model = tf.keras.models.Sequential()
#添加第一个卷积层,使用tf.keras.layers.Conv2D()实现
model.add(tf.keras.layers.Conv2D(
    filters=10,              # 卷积层神经元(卷积核)数目
    kernel_size=[3, 3],      # 卷积核大小
    strides=(1, 1),          # 步长
    padding='same',          # padding策略(vaild 或 same)
    activation=tf.nn.relu,   # 激活函数
    input_shape=(8, 8, 1)    # 指出输入的形状 (samples,rows,cols,channels),只指出后三维,第一维度按 batch_size 自动指定
))
  1. filters:表示卷积层神经元(卷积核)数目,对应于输出的维度;
  2. kernel_size:表示卷积的大小,它是一个整数,或者2个元素的元组/列表,用于指定2D卷积窗口的高度和宽度,当它是整数时表示高度和宽度相同;
  3. strides: 表示横向和纵向的步长,它是一个整数,或者2个整数的元组/列表,用于指定沿高度和宽度方向卷积的步长,当它是整数时表示两个方向的步长相同。
  4. padding:表示填充方式,same表示采用填充的方式,简单地理解为以0填充边缘,使得当stride=1时输入和输出的维度相同;valid表示采用不填充的方式,多余地进行丢弃。
#添加池化层,选择最大池化,使用,tf.keras.layers.MaxPool2D()实现
model.add(tf.keras.layers.MaxPool2D(
    pool_size=[3, 3],      # 池窗口大小
    strides=2,             # 步长
    padding='same'
))
  1. pool_size:表示池窗口的大小,它是一个整数,或者2个元素的元组/列表,用于指定2D池窗口的高度和宽度,当它是整数时表示高度和宽度相同;
  2. strides:表示横向和纵向的步长,它是一个整数,或者2个整数的元组/列表,指定沿高度和宽度方向的步长,当它是整数时表示两个方向的步长相同;
  3. padding:表示填充方式,same表示采用填充的方式,简单地理解为以0填充边缘,使得当stride=1时输入和输出的维度相同;valid表示采用不填充的方式,多余地进行丢弃。
#卷积层 + BN归一化层 + 激活层,使用tf.keras.layers.BatchNormalization()实现Batch归一化
model.add(tf.keras.layers.Conv2D(filters=5, kernel_size=[3, 3], strides=(2, 2), padding='same'))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation('relu'))
#池化层
model.add(tf.keras.layers.MaxPool2D(pool_size=[3, 3], strides=2, padding='same'))
#展开特征图
model.add(tf.keras.layers.Reshape(target_shape=(1*1*5,)))
#全连接层
model.add(tf.keras.layers.Dense(units=50, activation=tf.nn.relu))
#输出层
model.add(tf.keras.layers.Dense(units=10))
model.add(tf.keras.layers.Softmax())
#通过model.summary()输出模型各层的参数状况
model.summary()

结果_1

#配置训练过程
model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),    # 设置优化器,这里使用 Adam 优化器,设置学习率为 0.001
    loss=tf.keras.losses.categorical_crossentropy,              # 设置损失函数,这里使用交叉熵损失
    metrics=[tf.keras.metrics.categorical_accuracy]             # 设置评估指标,用于检查 y_ture 中最大值对应的 index 与 y_pred 中最大值对应的 index 是否相等
)
#开始训练
batch_size = 32  # 设定 batch_size 为 32
epochs = 50  # 迭代 50 个周期
model.fit(X, y, epochs=epochs, batch_size=batch_size)

result_2

可以看到准确率大于98%,说明模型取得了较好的结果。
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐