【机器学习】彻底搞懂CNN

之前通过各种博客视频学习CNN,总是对参数啊原理啊什么的懵懵懂懂。。这次上课终于弄明白了,O(∩_∩)O~

上世纪科学家们发现了几个视觉神经特点,视神经具有局部感受眼,一整张图的识别由多个局部识别点构成;不同神经元对不同形状有识别能力,且视神经具有叠加能力,高层复杂的图案可以由低层简单线条组成。之后人们发现经过conclusional的操作,可以很好反映视神经处理计算的过程,典型的是1998年LeCun发明的LeNet-5,可以极大地提升识别效果。

本文主要就convolutional layer、pooling layer和整体CNN结构展开

一、Convolutional Layer卷积层

1、原理和参数

可以模拟局部感受眼的性质,同上一层不是全连接,而是一小块区域连接,这一小块就是局部感受眼(receptive field)。并且通过构造特定的卷积神经元,可以模拟不同神经元对不同形状刺激不同反应的性质。如下图所示,处理一层会形成一个feature map,多层叠加,层数逐渐加深。

【机器学习】彻底搞懂CNN

 

感受眼(kernel或filter)的尺寸可以看做fh*fw,由于感受眼本身具有尺寸,feature map会不断缩小,为了处理方便,使得每层大小不变,于是我们每层加值为0的边(zero padding),保证经过处理以后的feature map同前一层尺寸一样。多层之间的卷积运算操作,相当于和原来像素对应位置做乘法。如下左图所示,加了边后可以保证上下层大小一致,右图表示每层之间convolve的操作(如果不加zero padding)。

【机器学习】彻底搞懂CNN

【机器学习】彻底搞懂CNN

  但上图所示只是简单例子,一般扫描的是三维图像(RGB),就不是一个矩阵,而是一个立方体,我们用一个三维块去扫描它,原理同上图相同。

有时扫描时不是顺序去扫,而是跳跃着扫描,每次移动2-3个像素值(stride),但并非完全分离不会造成信息丢失,这样形成的feature map相较于原始图片缩小,实现信息聚集的效果。

【机器学习】彻底搞懂CNN

就像如下灰度图(2d)中所示,左边只提取竖线(vertical filter),右边只提取横线(horizontal filter)可看出横梁部分变亮,大量不同的这样的filter(比如可以识别边角、折线的filter)的叠加,可形成一张feature map

【机器学习】彻底搞懂CNN

下图是一个3d的RGB效果,每个kernel(filter)可以扫描出一张feature map,多个filter可以叠加出很厚的feature maps,前一层filter做卷积可以形成后一层的一个像素点

【机器学习】彻底搞懂CNN

 

如下图,可以代表i行j列k深度的一个neuron的一个输出像素值,k’代表第k个filter,w代表filter中的值,x代表输入,b是偏值。

【机器学习】彻底搞懂CNN

2、TensorFlow实现

以下是使用TensorFlow实现的代码,主要使用conv2d这个函数

 

import numpy as np from sklearn.datasets import load_sample_images # Load sample images dataset = np.array(load_sample_images().images, dtype=np.float32) # 一共4维,channel表示通道数,RGB是3 batch_size, height, width, channels = dataset.shape # Create 2 filters # 一般感受眼大小7*7,5*5,3*3,设置2个kernel,输出2层feature map filters_test = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32) # 第一个(0)filter的设定,7*7矩阵中,3是中间 filters_test[:, 3, :, 0] = 1 # vertical line # 第二个(1)filter的设定 filters_test[3, :, :, 1] = 1 # horizontal line # a graph with input X plus a convolutional layer applying the 2 filters X = tf.placeholder(tf.float32, shape=(None, height, width, channels)) # 虽然输入是一个四维图像,但是由于batch_size和channel都已经固定,所以使用conv2d # strides设定,第一个和第四个都是1表示不可以跳过batch_size和channel # 那两个2表示横纵向都缩减2,相当于整张图片缩减为原来四分之一,做了75%的缩减 convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME") with tf.Session() as sess: output = sess.run(convolution, feed_dict={X: dataset}) plt.imshow(output[0, :, :, 1]) # plot 1st image's 2nd feature map plt.show()

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygfpd.html