以下内容是在学习过程中的一些笔记,难免会有过错和疏忽的当地。假如造成任何困扰,很抱歉。
前言
卷积神经网络(Convolutional Neural Networks,CNN)是一类包含卷积核算且具有深度结构的前馈神经网络,强项是核算机视觉
卷积神经网络是一种带有卷积结构的深度神经网络,卷积结构能够削减深层网络占用的内存量,其三个关键的操作,其一是部分感触野,其二是权值同享,其三是 pooling 层,有用的削减了网络的参数个数,缓解了模型的过拟合问题。
其本质是一个多层感知机,成功的原因在于其所采用的部分衔接和权值同享的方法:
- 一方面削减了权值的数量使得网络易于优化
- 另一方面降低了模型的复杂度,也便是减小了过拟合的危险
一、结构解析
描绘:这儿能够添加本文要记载的大概内容
CNN的最重要的构建块是卷积层:第一卷积层的神经元不会衔接到输入图画中的每个像素,而只与其接受野内的像素相衔接。反过来,第二卷积层的每个神经元仅衔接到坐落第一层中的一个小矩阵内的神经元。
卷积神经网络全体架构分为:
- 输入层
- 卷积层
- 池化层
- 全衔接层
- 输出层
2.1 卷积运算
卷积层在卷积神经网络全体架构中,做了什么事情?
经过选择区域方框(卷积核尺度)
配合权重参数矩阵,并移动方框(滑动窗口步长)
去核算得到3×3的特征值,上述移动一个方块,即步长为1;至于说图画为什么是5x5x3,这个5是像素长宽,3是RGB三通道。
最开端的图仅仅把单个通道给核算了特征,而终究图画核算一般是上面这种,RGB三个通道核算完后汇聚成一个特征值。不同的权重及其他参数,也会早就多个不同的卷积核。
假如按照上面这种移动的法子,就会造成,有的区域块堆叠的次数许多,有的区域块根本不会产生堆叠例如边际区域,导致核算终究成果的时分会不精确,如何解决这个问题?
能够在边际进行填充,能够填充长度为1或者2都行,根据实际状况来,这样的区域移动就不会产生堆叠次数差距过大问题。
而同样的,不仅仅图画,文本也能够做卷积处理,例如:
我觉得今日气候真好啊
[我觉得][觉得今][今日天][气候真][真好啊]
[我觉得今日][天气候真好][气候真好啊]
一起也能够做边际填充处理,例如
我觉得今日气候真好啊
000我觉得今日气候真好啊000
总结卷积层触及的参数:
- 滑动窗口步长:移动多少格
- 卷积核尺度:区域的正方形巨细,也能够叫做
滤波器(Filters)
的巨细 - 边际填充:最外层加一圈0
- 卷积核个数:多少个特征图
卷积成果的核算公式为:
W1、H1代表输入的宽和长,W2、H2代表输出特征图的宽和长;F是卷积核长和宽的巨细;S是滑动窗口的步长;P是填充鸿沟。
输入数据是 32x32x3 的图画,用 10个 5x5x3 的filter来进行卷积操作指定步长为1,鸿沟填充为2,终究输入的规划为:(32-5+2×2)/1+1=32,终究输出规划是32x32x10,最终的10是由于卷积核数为10,经过卷积操作后也能够坚持特征图长度、宽度不变。
2.2 池化运算
并不是所有的特征都是有用的,所以池化层的作用:紧缩和保留特征图的重要信息。最常用的是最大池化法(Max Pooling),即取窗格中各个元素的最大值(降采样)。
履行池化运算的数据数缺乏的时分,为了便利核算,会对周围补充填0,一起也能够看出,池化运算会紧缩特征图的尺度,得到更强的特征。
池化完成后,咱们会对特征图进行平坦化,即将悉数特征图转化为向量,输入到全衔接层的神经网络进行分类。
最终经过反向传播算法更新卷积神经网络的权重,卷积层的权重便是卷积核(滤波器)
。
留意:特征图简单由于池化运算而紧缩变小,解决办法是咱们能够经过调整步幅或者补零的方法,让池化运算后的特征图不会紧缩的太小。
除了最大池化法以外,还有:
- 最小池化法
- 均匀池化法
2.3 Dropout层
Dropout层是神经网络的一种优化方法,不添加练习数据的状况下协助咱们对抗过度拟合,例如在神经网络中新增一层50%的Dropout层。
作用是Dropout层会随机选择50%的数据变成0。
目的是为了损坏各层神经元之间的共适性。
2.4 部分衔接与权值共享
首先对比全衔接层与部分衔接的差异
实际上,假如全衔接的方法,全衔接的神经网络会学习整张图片上所有的像素,学习到的是全域款式;而卷积层运用滤波器的小区域来提取特征,学习到的是部分款式,即运用小区域的部分链接。
别的部分链接还有一种叫堆叠。
权重同享是指,每一个部分衔接的神经元都是运用相同的权重
。
上面3个神经元运用相同的权重(不含偏移量),这个权重指的是卷积层的滤波器。
二、案例集
描绘:这儿能够添加本文要记载的大概内容
3.1 猫狗图画分类辨认
数据集在阿里云上找
import os
import datetime
from operator import le
import IPython
import IPython.display
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import tensorflow as tf
# 数据集途径
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
base_dir = 'E:/27_Python_Protect/数据集/猫狗辨认数据集'
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')
# 练习集
train_cats_dir = os.path.join(train_dir, 'cats')
train_dogs_dir = os.path.join(train_dir, 'dogs')
# 测验集
validation_cats_dir = os.path.join(validation_dir, 'cats')
validation_dogs_dir = os.path.join(validation_dir, 'dogs')
# 构建神经网络模型
model = tf.keras.models.Sequential(
[
# Conv2D 对图画卷积
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
# 为全衔接层预备-平坦层
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
# 二分类sigmoid就够了
tf.keras.layers.Dense(1, activation='sigmoid')
]
)
# 检查模型
# model.summary()
model.compile(
loss='binary_crossentropy',
# optimizer=Adam(lr=le - 4),
optimizer='Adam',
metrics=['acc']
)
# 数据预处理
train_datagen = ImageDataGenerator(rescale=1. / 255)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_dir, # 文件夹途径
target_size=(64, 64), # 指定resize成的巨细
batch_size=20,
# 假如one-hot便是categorical,二分类用binary就能够
class_mode='binary'
)
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(64, 64),
batch_size=20,
class_mode='binary'
)
# 开端练习网络模型
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=20,
validation_data=validation_generator,
validation_steps=50,
verbose=2
)
# 作用展现
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(len(acc))
plt.plot(epochs, acc, 'bo', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training Loss')
plt.plot(epochs, val_loss, 'b', label='Validation Loss')
plt.title('Training and validation loss')
plt.legend()
plt.show()
检查过拟合状况
检查损失状况,作用还行,能够依据实际状况把图画巨细调整大一些
3.2 MLP完成手写辨认
过程划分
- 数据预处理
- 载入数据集
- 特征转化
- 图画归一化:灰度图画
- 多元分类问题:One-hot编码
- 构建神经网络
- 神经元及层数承认
- 编译模型
- 练习模型
- 评价模型
- 解决过拟合问题
- 方案一:扩大神经元
- 方案二:添加躲藏层
- 方案三:添加Dropout层
- 投进运用
先上第一阶段代码
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical
# 指定乱数种子
seed = 7
np.random.seed(seed)
# 载入数据集
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# 将 28*28 图片转化成 784 的向量
X_train = X_train.reshape(X_train.shape[0], 28 * 28).astype("float32")
X_test = X_test.reshape(X_test.shape[0], 28 * 28).astype("float32")
# 由于是固定规模, 所以履行正规化, 从 0-255 至 0-1, 灰度图片归一化
X_train = X_train / 255
X_test = X_test / 255
# 多元分类问题 One-hot编码
Y_train = to_categorical(Y_train)
Y_test = to_categorical(Y_test)
# 界说模型
model = Sequential()
model.add(Dense(784, input_dim=784, activation="relu"))
model.add(Dense(10, activation="softmax"))
# model.summary() ##显示模型摘要资讯
# 编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",
metrics=["accuracy"])
# 练习模型
history = model.fit(X_train, Y_train, validation_split=0.2,
epochs=1000, batch_size=1280, verbose=2)
# 评价模型
print("\nTesting ...")
loss, accuracy = model.evaluate(X_train, Y_train)
print("练习数据集的精确度 = {:.2f}".format(accuracy))
loss, accuracy = model.evaluate(X_test, Y_test)
print("测验数据集的精确度 = {:.2f}".format(accuracy))
添加50% Dropout层解决过拟合问题
model = Sequential()
model.add(Dense(256, input_dim=28*28, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(256, activation="relu"))
model.add(Dense(10, activation="softmax"))
3.3 CNN完成手写辨认
常用卷积层网络阐明
卷积层 | 阐明 |
---|---|
Conv1D | 创立一维卷积层,能够在时间维度的序列数据履行卷积运算,例如:语义分析
|
Conv2D | 创立二维卷积层,能够在空间维度的二维数组做卷积运算,例如:图片分类辨认
|
UpSampling1D | 创立一维输入的上采样层,能够沿着时间轴 来将数据重复指定次数 |
UpSampling2D | 创立二维输入的上采样层,能够沿着二维空间 来将数据重复指定次数 |
MaxPooling1D | 创立序列数据的一维最大池化 |
MaxPooling2D | 创立空间数据的二维最大池化 |
AveragePooling1D | 创立序列数据的一维均匀池化 |
AveragePooling2D | 创立空间数据的二维均匀池化 |
数据预处理
import numpy as np
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Dropout
from keras.utils import to_categorical
# 指定乱数种子
seed = 7
np.random.seed(seed)
# 载入数据集
(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# 将图片转化成 4D 张量
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype("float32")
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype("float32")
# 由于是固定规模 所以履行正规化 从 0-255 至 0-1
X_train = X_train / 255
X_test = X_test / 255
# One-hot编码
Y_train = to_categorical(Y_train)
Y_test = to_categorical(Y_test)
print("Y_train.shape = ", Y_train.shape)
print("图片是5 所以One-hot编码是 = ", Y_train[0])
重头戏中心:模型界说
# 界说模型
model = Sequential()
# 16为滤波器数
# kernel_size为窗格尺度的元组 一般是正方形且为奇数
# padding为补零方法 默认参数valid为不补零 same为补零成相同尺度
# input_shape为输入的形状巨细
# strides指定步幅数
model.add(Conv2D(16, kernel_size=(5, 5), padding="same",
input_shape=(28, 28, 1), activation="relu", strides=(1, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, kernel_size=(5, 5), padding="same",
activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(128, activation="relu"))
model.add(Dropout(0.5))
model.add(Dense(10, activation="softmax"))
最终则开端编译练习并评价成果
# 编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",
metrics=["accuracy"])
# 练习模型
history = model.fit(X_train, Y_train, validation_split=0.2,
epochs=10, batch_size=128, verbose=2)
# 评价模型
print("\nTesting ...")
loss, accuracy = model.evaluate(X_train, Y_train)
print("练习数据集的精确度 = {:.2f}".format(accuracy))
loss, accuracy = model.evaluate(X_test, Y_test)
print("测验数据集的精确度 = {:.2f}".format(accuracy))
ov
地址 |
---|
主页 – Keras 中文文档 (keras-zh.readthedocs.io) |
关于TensorFlow | TensorFlow中文官网 (google.cn) |