赞
踩
CNN:神经网络在前面的学习中我们已经了解过很多了,其本质就是多层感知机,卷积神经网络其实也一样,但是我们可以将其看成多层感知机的变种。它成功的原因在于其所采用的局部连接和权值共享的方式:
该优点在网络的输入是图像时表现的更为明显,使得图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建的过程,在二维图像的处理过程中有很大的优势。
2.模型构建:
CNN:首先了解卷积神经网络的四个组件:
model.add(Conv2D(32,(3,3),activation='relu',padding='valid',input_shape=((28,28,1))))
model.add(MaxPool2D(2))
model.add(Flatten())
接下来我主要介绍卷积层和池化层
卷积操作其实并不算复杂,但是他有很多种卷积方式,我们在进行卷积之后输出的图像也会和我们选择的卷积核有关,能够让维度下降、不变、甚至上升。
一般的池化操作我们会使用最大池化,即在选定的部分像素中,我们选择其中最大的一个像素值来作为这一部分的像素的代表,这就使得整体的数据降维,我们生活中常见的马赛克,就是池化操作产生的。
模型相对简单,层数也较少
AlexNet模型:
Conv-Pool-Conv-Pool-Conv-Conv-Conv-Pool-FC-FC-Softmax
VGG-16模型:
Conv-Conv-Pool-Conv-Conv-Pool-Conv-Conv-Conv-Pool-Conv-Conv-Conv-Pool-FC-FC-FC-Softmax
GoogleNet模型(Inception V1)
是一种既有深度又有宽度的模型,具有以下功能:
3.实验过程:
# TensorFlow 卷积池化 import tensorflow as tf import matplotlib.pyplot as plt import numpy as np (x_train,y_train),(x_test,y_test) = tf.keras.datasets.mnist.load_data() x_train = x_train.reshape((-1,28,28,1))/255.0 x_test = x_test.reshape((-1,28,28,1))/255.0 filter = tf.constant([[-1,-1,-1],[-1,9,1],[-1,-1,-1]],dtype='float32') filter = tf.reshape(filter,(3,3,1,1)) img = tf.constant(x_train[0:1]/255.0,dtype='float32') conv_img = tf.nn.conv2d(img,filter,strides=[1,2,2,1],padding='SAME') pool_img = tf.nn.max_pool(img,[1,2,2,1],[1,2,2,1],padding="VALID") # window_size,stride print(conv_img.shape) plt.subplot(131) plt.imshow(tf.squeeze(img)) plt.subplot(132) plt.imshow(tf.squeeze(conv_img)) plt.subplot(133) plt.imshow(tf.squeeze(pool_img)) plt.show()
由于我们采用的卷积核的特性,将一些较大的值都滤掉了,反观池化,虽然较大的值都保留了,但是同样损失了很多细节。
import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Sequential (x_train,y_train),(x_test,y_test) = tf.keras.datasets.mnist.load_data() #tf.keras.datasets.mnist.load_data() #tf.keras.datasets.fashion_mnist.load_data() x_train = x_train.reshape((-1,28,28,1))/255.0 x_test = x_test.reshape((-1,28,28,1))/255.0 y_train = tf.keras.utils.to_categorical(y_train,10) y_test = tf.keras.utils.to_categorical(y_test,10) model = Sequential() model.add(Conv2D(32,(3,3),activation='relu',padding='valid',input_shape=((28,28,1)))) model.add(MaxPool2D(2)) model.add(Conv2D(32,(3,3),activation='relu',padding='same')) model.add(Flatten()) #FC,将二维图片展平成一维向量 model.add(Dense(128,activation='relu')) model.add(Dense(10,activation='softmax')) model.compile(optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.categorical_crossentropy,metrics=['accuracy']) model.fit(x_train,y_train,batch_size=128,epochs=20) print(model.evaluate(x_test,y_test))
从上述代码中,我们可以发现,这个卷积神经网络中,我们使用了两个卷积层、两个最大池化层、两个全连接层
该模型初次的精度如下:
我们知道,卷积核可以提取突破的特征,初步设想,给定较多的卷积核,便能提取更多特征,那么最后的精度应该会高。所以将原来的卷积核个数翻倍,得到的结果如下:
看来这招在这里并不合适
既然增加卷积核的个数行不通,索性让神经网络变得更深一些
精度下降了,看来单纯地深化神经网络,也不一定就能达到最好的效果,太复杂的模型很有可能会过拟合,导致精度下降。
删去一层深度之后,效果似乎有所好转
增加一条支路,让其模型变成5条支路,3层深度
总的来说对几个常见的卷积神经网络结构有了一定的了解,无非就是卷积、池化、归一化、全连接的各种组合,在调试优化模型的过程中我也进行了很多尝试,有了一定的收获。调参是门技术活,而我只会没脑子的瞎调
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。