卷积神经网络
- 由一个或多个卷积层、池化层以及全连接层等组成。
- 与其他深度学习结构相比,卷积神经网络在图像等方面能够给出更好的结果。
- 这一模型也可以使用反向传播算法进行训练。
- 相比较其他浅层或深度神经网络,卷积神经网络需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。
文章目录
1 卷积层(Convolutions)
- 卷积运算的目的是提取输入的不同特征,某些卷积层可能只能提取一些低级的特征如边缘、线条和角等层级,更多层的网路能从低级特征中迭代提取更复杂的特征。
- 计算公式
- 假设我们有10 个Filter,每个Filter3 X 3 X 3(计算RGB图片),并且只有一层卷积,那么参数有多少?
- 计算:每个Filter参数个数为:3 X 3 X 3 + 1 bias = 28个权重参数,总共28 * 10 = 280个参数,即使图片任意大小,我们这层的参数也就这么多。
卷积层充当特征提取的角色,但是并没有减少图片的特征数量,在最后的全连接层依然面临大量的参数,所以需要池化层进行特征数量的减少
2 池化层(Pooling、Subsampling)
池化层主要对卷积层学习到的特征图进行亚采样(subsampling)处理,主要由两种
- 最大池化:Max Pooling,取窗口内的最大值作为输出
- 平均池化:Avg Pooling,取窗口内的所有值的均值作为输出
- 意义在于:
(1)降低了后续网络层的输入维度,缩减模型大小,提高计算速度
(2)提高了Feature Map 的鲁棒性,防止过拟合
对于一个输入的图片,我们使用一个过滤器filter大小为2 x 2,步长stride为2的参数进行求最大池化操作。同样池化也有一组参数 f,s,得到2 * 2的大小。当然如果我们调整这个超参数,比如说3 * 3,那么结果就不一样了,通常选择默认都是 f = 2 * 2, s = 2
池化超参数特点:不需要进行学习,不像卷积通过梯度下降进行更新。
3 全连接层(Full connection)
卷积层
+激活层
+池化层
可以看成是CNN的特征学习/特征提取层
,而学习到的特征(Feature Map)最终应用于模型任务(分类、回归):
- 先对所有 Feature Map 进行扁平化(flatten, 即 reshape 成 1 x N 向量)
- 再接一个或多个全连接层,进行模型学习
示例demo——CNN算法实现CIFAR100分类
模型网络设计:两层卷积层+两个神经网络层
CIFAR100输入的每批次若干图片数据大小为[None, 32, 32, 3],其中None表示图片数量,[32, 32, 3]表示图片大小。
1、两层 卷积层
-
第一层
- (1) 卷积:32个filter、大小5*5、strides=1、padding=“SAME”
- 图片数据:[None, 32, 32, 3]———>[None, 32, 32, 32]
32 = ( 32 − 5 + 2 ∗ p ) / 1 + 1 ⟹ p = 2 32=(32-5+2*p)/1+1\implies p=2 32=(32−5+2∗p)/1+1⟹p=2 - 权重数量:[5, 5, 3 ,32]
- 偏置数量:[32]
- 图片数据:[None, 32, 32, 3]———>[None, 32, 32, 32]
- (2) 激活:Relu
- 图片数据:[None, 32, 32, 32]———>[None, 32, 32, 32]
- (3) 池化:大小2x2、strides2
- 图片数据:[None, 32, 32, 32]———>[None, 16, 16, 32]
- (1) 卷积:32个filter、大小5*5、strides=1、padding=“SAME”
-
第二层
- (1) 卷积:64个filter、大小5*5、strides=1、padding=“SAME”
- 图片数据:[None, 16, 16, 32]———>[None, 16, 16, 64]
16 = ( 16 − 5 + 2 ∗ p ) / 1 + 1 ⟹ p = 2 16=(16-5+2*p)/1+1\implies p=2 16=(16−5+2∗p)/1+1⟹p=2 - 权重数量:[5, 5, 32 ,64]
- 偏置数量:[64]
- 图片数据:[None, 16, 16, 32]———>[None, 16, 16, 64]
- (2)激活:Relu
- 图片数据:[None, 16, 16, 64]———>[None, 16, 16, 64]
- (3) 池化:大小2x2、strides2
- 图片数据:[None, 16, 16, 64]———>[None, 8, 8, 64]
- (1) 卷积:64个filter、大小5*5、strides=1、padding=“SAME”
2、两层 神经网络
- 第一层 隐层1024个神经元
- 先对所有 Feature Map 进行扁平化(flatten, 即 reshape 成 1 x N 向量)
- 图片数据:[None, 8, 8, 64]——>[None, 8 * 8 * 64] x [8 * 8 * 64, 1024] = [None, 1024]
- 权重数量:[8 * 8 * 64, 1024]
- 偏置数量:[1024]
- 第二层 全连接层 100个神经元(100个分类)
- 图片数据:[None,1024] x [1024, 100]——>[None, 100]
- 权重数量:[1024, 100]
- 偏置数量:[100]
import tensorflow as tf
from tensorflow.python import keras
class CNNCifar100(object):
model = keras.Sequential([
keras.layers.Conv2D(32, kernel_size=5, strides=1,
padding='same', data_format='channels_last', activation=tf.nn.relu),
keras.layers.MaxPool2D(pool_size=2, strides=2, padding='same'), # 池化层此处padding='same'与卷积层的效果不同
keras.layers.Conv2D(64, kernel_size=5, strides=1,
padding='same', data_format='channels_last', activation=tf.nn.relu),
keras.layers.MaxPool2D(pool_size=2, strides=2, padding='same'),
keras.layers.Flatten(),
keras.layers.Dense(1024, activation=tf.nn.relu),
keras.layers.Dense(100, activation=tf.nn.softmax),
])
def __init__(self):
(self.train, self.train_label), (self.test, self.test_label) = keras.datasets.cifar100.load_data()
# print(self.train)
# print(self.train.shape, self.train_label.shape)
self.train = self.train.reshape(-1, 32, 32, 3) / 255.0 # "-1":代表未知数,原始数据本来就是(?, 32, 32, 3) 可以不用reshape
self.test = self.test.reshape(-1, 32, 32, 3) / 255.0
def compile(self):
CNNCifar100.model.compile(optimizer=keras.optimizers.Adam(),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])
return None
def fit(self):
CNNCifar100.model.fit(self.train, self.train_label, epochs=1, batch_size=32)
return None
def evaluate(self):
test_loss, test_acc = CNNCifar100.model.evaluate(self.test, self.test_label)
print(test_loss, test_acc)
return None
if __name__ == '__main__':
cnn = CNNCifar100()
cnn.compile()
cnn.fit()
cnn.evaluate()
print(CNNCifar100.model.summary())
===运行结果:==========================================================
Epoch 1/1
32/50000 [..............................] - ETA: 26:10 - loss: 4.6117 - acc: 0.0000e+00
64/50000 [..............................] - ETA: 14:58 - loss: 4.6596 - acc: 0.0156
96/50000 [..............................] - ETA: 11:18 - loss: 4.6906 - acc: 0.0104
......
49952/50000 [============================>.] - ETA: 0s - loss: 3.4632 - acc: 0.1822
49984/50000 [============================>.] - ETA: 0s - loss: 3.4631 - acc: 0.1822
50000/50000 [==============================] - 238s 5ms/step - loss: 3.4631 - acc: 0.1822
32/10000 [..............................] - ETA: 28s
96/10000 [..............................] - ETA: 16s
160/10000 [..............................] - ETA: 14s
......
9888/10000 [============================>.] - ETA: 0s
9952/10000 [============================>.] - ETA: 0s
10000/10000 [==============================] - 12s 1ms/step
损失评估结果: 2.957594190597534
准确率评估结果: 0.275
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) multiple 2432
_________________________________________________________________
max_pooling2d (MaxPooling2D) multiple 0
_________________________________________________________________
conv2d_1 (Conv2D) multiple 51264
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 multiple 0
_________________________________________________________________
flatten (Flatten) multiple 0
_________________________________________________________________
dense (Dense) multiple 4195328
_________________________________________________________________
dense_1 (Dense) multiple 102500
=================================================================
Total params: 4,351,524
Trainable params: 4,351,524
Non-trainable params: 0
_________________________________________________________________
None