CNN的主要结构就是(卷积层+池化层)*N + 全连接层 *M,一般来说,卷积神经网络的参数非常的多,这会导致非常占用计算的资源,以及很可能导致model的过拟合,所以一般采用局部连接和参数共享作为处理的方法,之所以可能采用这两种方法,就是因为图片的性质构成的,一个就是图片所具有的区域性(在一定小的区域内,图片所能采取的特征是近似的),其次就是图片所具有的位置无关性,而在卷积网络中最为重要的卷积核的作用就是提取特征,从而可以形成特征平面(一般来说没经过一次卷积层,图像的大小就会减小)。
下面就用tensorflow在搭建一个简单的CNN
#导入库
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
import random
import pandas as pd
import os
import sys
import sklearn
#导入fashion_mnist的数据集
(x_train_all , y_train_all),(x_test , y_test) = tf.keras.datasets.fashion_mnist.load_data()
#print(train_label)
print(x_train_all.shape)
x_vaild,x_train = x_train_all[:5000],x_train_all[5000:]
y_vaild,y_train = y_train_all[:5000],y_train_all[5000:]
#归一化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train_scaler = scaler.fit_transform(x_train.astype(np.float32).reshape(-1,1)).reshape(-1,28,28,1)#最后的参数是输入的通道数
x_vaild_scaler = scaler.transform(x_vaild.astype(np.float32).reshape(-1,1)).reshape(-1,28,28,1)
x_test_scaler = scaler.transform(x_test.astype(np.float32).reshape(-1,1)).reshape(-1,28,28,1)
#构建模型
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(filters = 32,
kernel_size = 3,
padding = 'same',
activation = 'selu',
input_shape = (28,28,1)))
model.add(tf.keras.layers.Conv2D(filters = 32,#卷积核的数目
kernel_size = 3,#卷积核的大小
padding = 'same',
activation = 'selu',
input_shape = (28,28,1)))
model.add(tf.keras.layers.MaxPool2D(pool_size = 2))#卷积核的大小和步长一般相同
model.add(tf.keras.layers.Conv2D(filters = 64,
kernel_size = 3,
padding = 'same',
activation = 'selu',
input_shape = (28,28,1)))
model.add(tf.keras.layers.Conv2D(filters = 64,#卷积核的数目
kernel_size = 3,#卷积核的大小
padding = 'same',
activation = 'selu',
input_shape = (28,28,1)))
model.add(tf.keras.layers.MaxPool2D(pool_size = 2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128,activation = 'relu'))
model.add(tf.keras.layers.Dense(10,activation = 'softmax'))
model.summary()
model.compile(loss = 'sparse_categorical_crossentropy' ,
optimizer = 'adam',
metrics = ['acc']
model.fit(x_train_scaler , y_train ,
validation_data=(x_vaild_scaler,y_vaild),
epochs = 10)
这样就可以搭建一个简单的CNN的模型,其中一般来说,每经过一个pooling的池化层以后,卷积核的数目都要增加一倍,这是为了缓解经过池化层以后,特征丢失的过多导致出现的问题。
像那种可以在手机端运行的CNN 都是通过深度可分离卷积来构成的。
深度可分离卷积就是把每一个卷积核的输入和输出都变成单通道的,这样可以大大减小计算量,一般来说,深度可分离的卷积的效率是普通卷积的9倍左右,用tensorflow代码写起来其实和普通的卷积很类型,只要把tf.keras.layers.Conv2D变为tf.keras.layers.SeparableConv2D就可以了。