神经网络(二)卷积神经网络

# 使用 CNN 对 CIFAR-10 数据集中的十类物品进行分类

# 导入序贯模型
from keras.models import Sequential

# 导入神经网络
# Conv2D 表示 2D 卷积层
# Maxpooling 表示 2D 最大池化层
from keras.layers import Conv2D, MaxPooling2D

# 导入神经网络的核心
# Dense 表示全连接层
# Dropout 表示丢失神经元之间的连接
# 目的是防止过拟合
# Activation 表示激活函数
# Flatten 表示多维数据到一维数据的转化
# 主要用来从将数据从卷积层过度到全连接层
from keras.layers.core import Dense, Dropout, Activation, Flatten

# 导入独热编码转换函数
# 对于多分类模型老说
# 独热编码是很必要的
from keras.utils import np_utils

# 导入回调函数
# 回调函数的功能是在模型的训练过程中
# 获取中间数据
from keras.callbacks import EarlyStopping

# 导入归一化函数
# 归一化函数可以减少上一层神经网络的输出变化
# 加快学习速度并抑制过拟合
from keras.layers.normalization import BatchNormalization

# 导入数据
# CIFAR-10 是包含十类物体的图片集
# X 的形状(数据组数, 32, 32, 3)
# X 中的数据为 32 × 32 的图片
# 图片中 1 个像素由 RGB 3 个字节描述
from keras.datasets import cifar10
(X_train, y_train), (X_val, y_val) = cifar10.load_data()

# 将自变量标准化
# 即将数据映射到 0 1 之间
# 由于颜色采用 RGB 编码
# 因此 数据 / 255
X_train = X_train.astype('float32') / 255
X_val = X_val.astype('float32') / 255

# 对分类进行独热编码
# 因为物品有十类
# 因此独热编码的长度为 10
# 独热编码的长度
num_classes = 10
y_train = np_utils.to_categorical(y_train, num_classes)
y_val = np_utils.to_categorical(y_val, num_classes)

# 输入层节点数量
input_shape = X_train[0].shape

# 构造 CNN
model = Sequential()

# 添加输入层
# 32 表示卷积核的数目
# 也即卷积层输出的维度
# kernel_size 表示核的形状
# 当参数只有一个整型数时
# 在各个维度上取相同的长度
# padding 表示是否对输入的边缘进行填充
# same 表示填充
# valid 表示不填充
# 也即输入的数据中的边缘数据值是否计算 1 次
model.add(Conv2D(32, kernel_size=(3, 3), input_shape=input_shape, padding='same'))

# 添加激活函数
# 激活函数最常用的有 3 种
# sigmoid & tanh & relu
model.add(Activation('relu'))

# 添加归一化层
model.add(BatchNormalization())

# 添加卷积层
# 对于相邻的卷积层
# 卷积核的数目最好呈现倍数非递减的关系
model.add(Conv2D(32, kernel_size=(3, 3), padding='same'))

model.add(BatchNormalization())

model.add(Activation('relu'))

# 添加池化层
# 池化一般来说有两种
# 最大池化对邻域取最大特征值
# 平均池化对邻域取平均特征值
# 这里是最大池化
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))

# 丢弃 25% 的连接
model.add(Dropout(0.25))

# 增加层数
model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(64, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))
model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(Conv2D(128, kernel_size=(3, 3), padding='same'))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dropout(0.25))

# 压平数据
model.add(Flatten())

# 添加全连接层
# 全连接层是指
# 每一个输入节点都有对下一层的全部神经元的输出
# 全连接层也是最基本的前馈神经网络
model.add(Dense(512, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(128, activation='relu'))

# 添加输出层
# 最终输出为 10 维的向量
# 对应CIFAR-10 的 10 个物品分类的概率
# softmax 会将每一个输出值 xi 映射到 e^xi
# 之后求出每一个 e^xi 占全部 e^xi 的比例
# 也即每一类的概率
model.add(Dense(num_classes, activation='softmax'))

# 编译模型
# loss 表示损失函数
# categorical_crossentropy 表示交叉熵
# optimizer 表示优化器
# adam 是一种高效的优化算法
# metrics 表示评价方式
# accuracy 表示评价方式为准确率
model.compile(loss='categorical_crossentropy', optimizer='adam',  metrics=['accuracy'])

# 获取网络的信息
model.summary()
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
activation_1 (Activation)    (None, 32, 32, 32)        0         
_________________________________________________________________
batch_normalization_1 (Batch (None, 32, 32, 32)        128       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 32, 32, 32)        9248      
_________________________________________________________________
batch_normalization_2 (Batch (None, 32, 32, 32)        128       
_________________________________________________________________
activation_2 (Activation)    (None, 32, 32, 32)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 16, 16, 32)        0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 16, 16, 32)        0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 16, 16, 64)        18496     
_________________________________________________________________
activation_3 (Activation)    (None, 16, 16, 64)        0         
_________________________________________________________________
batch_normalization_3 (Batch (None, 16, 16, 64)        256       
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 16, 16, 64)        36928     
_________________________________________________________________
activation_4 (Activation)    (None, 16, 16, 64)        0         
_________________________________________________________________
batch_normalization_4 (Batch (None, 16, 16, 64)        256       
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 8, 8, 64)          0         
_________________________________________________________________
dropout_2 (Dropout)          (None, 8, 8, 64)          0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 8, 8, 128)         73856     
_________________________________________________________________
activation_5 (Activation)    (None, 8, 8, 128)         0         
_________________________________________________________________
batch_normalization_5 (Batch (None, 8, 8, 128)         512       
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 8, 8, 128)         147584    
_________________________________________________________________
activation_6 (Activation)    (None, 8, 8, 128)         0         
_________________________________________________________________
batch_normalization_6 (Batch (None, 8, 8, 128)         512       
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 4, 4, 128)         0         
_________________________________________________________________
dropout_3 (Dropout)          (None, 4, 4, 128)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 2048)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               1049088   
_________________________________________________________________
batch_normalization_7 (Batch (None, 512)               2048      
_________________________________________________________________
dropout_4 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 128)               65664     
_________________________________________________________________
dense_3 (Dense)              (None, 10)                1290      
=================================================================
Total params: 1,406,890
Trainable params: 1,404,970
Non-trainable params: 1,920
_________________________________________________________________
'''

# 定义回调函数
# 回调函数监视训练过程中模型的变量
# EarlyStoping 函数可以提早结束训练
# monitor 表示要监视的变量
# patience 表示满足结束要求是等待的训练轮数
# verbose 表示日志展示模式
# verbose = 0 不打印日志信息
# verbose = 1 打印进度条记录
# verbose = 2 为每个epoch打印一行记录
callbacks = [EarlyStopping(monitor='val_acc', patience=5, verbose=1)]

# 一轮训练中的一次训练使用 256 组数据
batch_size = 256

# 使用全部数据的训练轮数
n_epochs = 300

# 训练模型
history = model.fit(X_train, y_train, batch_size=batch_size, epochs=n_epochs, verbose=1, validation_data=(X_val, y_val), callbacks=callbacks)

# 验证精度
val_acc = history.history['val_acc']

# 保存模型
# model.save(filepath)
# 加载模型
# keras.models.load_model(filepath)

参考书籍:《Python深度学习实战:75个有关神经网络建模、强化学习与迁移学习的解决方案》

猜你喜欢

转载自blog.csdn.net/lolimostlovely/article/details/82535139