常见的计算机视觉问题有:
- 图像分类(Image Classification)2.目标检测(Object Detection)3.风格迁移(Neural Style Transfer)
引子:
在图像上,input size 会非常的大 6464的小图片就有12288维(3个channel)更不要说10001000的了,feature size 3million, 假设全连接,隐藏层节点数为1000,那么这一层的参数量为[1000,3million]也就是3billion,这么大的参数量,内存什么的要求非常高,计算量超级大。容易过拟合,要很大的数据量去支撑。想到两天前自己很蠢的input了一个14561456的,第二层的参数量还老高了512512*4,直接tensorflow就没跑起来,参数量超过表示范围了。哭脸.jpg
用CNN来address一下下。从边缘到局部再到整体。
edge detection example:
怎样检测到横的和纵的直线呢:图像处理里的边缘检测算子啊,他们的模版,图上的是prewitt算子。
light to dark 和dark to light 不一样的结果, 可以加绝对值变一样
sobel 是1 2 1比prewitt更鲁棒
CNN的话是自己去学习这些参数,其实也是一个滤波器,就是参数不是hand-craft而已。用反向传播来learn 这些参数。
padding:
why padding: 在卷积的时候图像存在shrink(收缩),会越来越小,但是我们并不想他变得那么小。其次, 在边边或者角落的像素被计算的次数和中间的比,少了很多,也就是说丢失了很多边缘上的信息。
valid convolution:说明没有padding, 卷积后的大小也就是n-f+1
same convolution:卷积后的大小和卷积前一样,size没有变化,即n+2p-f+1=n p=(f-1)/2 f一般是奇数(1,如果是偶数的话,padding就会不对称,左边padding和右边padding的不一样。2.奇数有central pixel,可以明确滤波器的position比如3*3最中间的那个像素)
Strided Convolutions:
窗口每次滑动的步长 (向右和向下)
卷积的话是向下取整的 Floor()
在数学上,卷积的操作是要先把卷积核旋转180度的,也就是x,y轴都要转,然后再算点乘,但是在这里,是默认没有旋转的(深度学习)里面。
convolutions over volume:
在3d里面怎么算,比如RGB通道 filter的通道也变多了,input有几个channels filter也有几个。之前只是把这个3*3的值加起来,现在的话是把3个通道的都加起来,也就是27个值加起来,得到最后的那一个数
有多个filter:
one layer of a convolutional network:
卷积操作完了之后+bias(维度只有1,就是一个值)然后在relu操作,得到最后的值
怎么算一层有多少参数
假设有10个filter 每个333
则 333=27 加上bias +1 = 28
10个 所以*10 = 280
要注意的是kenel都是三维的,然后卷积的size 是向下取整的
simple convolutional network examples:
feature map 的大小下降,但是数量越来越多
三种layer
pooling layer :
reduce the size of the representation to speed the computation . make features more robust
假设在3d里面算的话,之前输入多少个channel,输出也是多少个channel,每个channel是独立计算的
大部分情况下,用的都是max pooling ,很少用avg-pooling,除了global avg-pooling,就是在最后的那个。max pooling几乎不用padding
是一个fix function ,没有参数要去learn
CNN examples
lenet-5 示例 注意每个的通道数,然后FC层的参数,然后就是随着网络加深,feature map b变小,channel变多
参数量主要集中在FC,pooling 没有参数
why convolutions:
相比于全连接层,conv的优势在于 parameter
sharing参数共享 sparse of connection 局部连接
下图中可以看到 同样得到28286的feature map,卷积的参数量是26*6 156 FC层的话 14m
translation invariance 平移不变性 参数共享是从输入的角度,共享一个卷积核(特征提取器),在那里滑窗。局部连接是从输出角度出发的,输出的每一个值只和输入的某个部分有关系。