Tensorflow 图像CNN分类解析

原创文章,转载请注明: 转载自慢慢的回味

本文链接地址: Tensorflow 图像CNN分类解析

自从Yann Lecun最早将CNN用于手写数字识别后,卷积神经网络在多个方向持续火爆:如语音识别、人脸识别、通用物体识别等。与普通神经网络的最大区别为:卷积神经网络包含了由卷积层和池化层构成的特征抽取器。卷积层由卷积核做卷积运算替代全连接神经网络的矩阵计算。卷积核表示一组共享的权值,位于不同地方的权值可以模拟人眼对图像识别的局部感受野:一般认为人对外界的认知是从局部到全局的,而图像的空间联系也是局部的像素联系较为紧密,而距离较远的像素相关性则较弱。共享的权值还可以大大降低权值参数量。所以卷积核的局部感受野可以解决全连接计算将图像展开为向量丢失的空间信息;共享权值减少的参数可以提高训练效率和避免网络过拟合。

CNN原理

下面的视频也详细介绍了CNN的原理:
10.卷积神经网络(CNN)_高清

测试程序


通过前文“Tensorflow Conv2D和MaxPool2D原理”的讲解,现在就比较容易理解下面的CNN程序了:
mnist

from __future__ import absolute_import, division, print_function, unicode_literals
 
import tensorflow as tf
 
from tensorflow.keras import datasets, layers, models
 
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
 
train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))
 
# Normalize pixel values to be between 0 and 1
train_images, test_images = train_images / 255.0, test_images / 255.0
 
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()
 
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
 
model.fit(train_images, train_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)

整个模型结构如下:
首先读取mnist数据,取出60000张28X28的1通道图片作为训练用,10000张作为测试用。
然后把颜色值正规化到0-1的值。
先接入一个Conv2D层,由32个 3X3 的filter构成,则输出为[None, 28-3+1, 28-3+1, 32]维矩阵。
接着进入池化层,由 2X2 的pool构成,输出为[None, (26-2+1 + (2-1) ) / 2 = 13, 13, 32]维矩阵。
同理,经过64个 3X3 的filter卷积,输出为[None, 13-3+1=11, 11, 64]维矩阵。
同理,经过池化,输出为[None, (11-2+1 + (2-1))/2=5, 5, 64]维矩阵。
最后再卷积一次,输出为[None, 2-3+1=3, 3, 64]维矩阵。
接着通过Flatten,打开输入数据,得到[None,3*3*64=576]维矩阵。
最后,通过常规的全连接,输出10个数字进行分类。

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 3, 3, 64)          36928     
_________________________________________________________________
flatten (Flatten)            (None, 576)               0         
_________________________________________________________________
dense (Dense)                (None, 64)                36928     
_________________________________________________________________
dense_1 (Dense)              (None, 10)                650       
=================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0
_________________________________________________________________

本作品采用知识共享署名 4.0 国际许可协议进行许可。

发表回复