AI学习笔记之卷积神经网络

  • 卷积神经网络简介
  • 卷积层
  • 池化层
  • 卷积神经网络
    • 卷积核
    • 填充padding
    • 常见的卷积神经网络
  • cifar-10预测实例
    • 数据预处理--图像增强
      • 图像增强常用方法
  • Alex-Net

卷积神经网络简介

CNN(Convolutional Neural Network)就是著名的卷积神经网络,是一种前馈神经网络。
CNN不同于传统的神经网络只有线性连接,CNN包括卷积(convolution)操作、池化(pooling)操作和非线性激活函数映射(即线性连接)等等。
经典的CNN网络由Alex-Net、VGG-Nets、Resnet等。

深度学习在计算图像识别上的应用非常成功。利用深度学习,我们能够对图片进行高精度识别,实现这一功能的,主要依靠神经网络的一种分支即卷积网络。卷积网络可以直接接受多维向量,而以往的网络智能接受一维向量。

卷积通道

卷积神经网络

卷积层

  • 卷积操作,其实就是把一张大图片分为多个小的部分,然后依次对这些小部分进行识别;
  • 通常我们会把一张图片分解为多个33或55的"小片",然后分别识别这些小片段,最后把识别的结果集合在一起输出给下一层网络。
  • 这种做法在图像识别中很有效,因为它能对不同区域进行识别,假设识别的图片时猫脸,那么我们就可以把猫脸分解成耳朵,嘴巴,眼睛,胡子等多个部位取各自识别,然后再把各个部分的识别结果综合起来作为对猫脸的识别。

池化层

池化的作用在于对数据进行压缩,卷积操作产生了太多的数据,如果没有pooling操作对这些数据进行压缩,那么网络的运算量将会非常巨大,而且数据参数过于冗余就非常容易导致过拟合。常见的池化分位最大池化和均值池化。

卷积神经网络

当我们的图片(黑白图片channel为1,彩色图片channel为3)输入到神经网络后,通过卷积神经网络将图片的长宽进行压缩,然后增加channel。最后变成了一个长宽很小,channel很高的像素块,然后将结果放入普通神经网络(全连接)中处理,最后连接一个分类器如softmax,从而分辨如图片是什么。

卷积核

图片的采样器也可以叫做共享权值,用来在图片上采集信息。卷积核有自己的长宽,也可以定义自己的步长stride,每跨多少步进行一次抽离信息,跨的步长越多就越容易丢失图片信息。然后对抽取的信息进行像素的加权求和得到Feature Map增加了采集结果的channel。
总而言之卷积是用来不断提取特征的,每提取一个特征就会增加一个feature map,所以采集后的图片channel不断增加。
可以通过高斯滤波、sobel滤波等等设定好卷积核的滤波方法。那么,若果不是由人来设计一个滤波器,而是一个随机滤波器开始,根据某种目标,用某种方法去逐渐调整它,直到它接近我们想要的样子,这就是CNN的思想了,可调整的滤波器时CNN的“卷积”部分;如何调整滤波器则是CNN的“神经网络”那部分(训练)。
把卷积滤波器和神经网络两个思想结合起来。卷积滤波无非是一套权值。而神经网络也可以有(除全连接外的)其他拓扑结构。

  • 左边的平面包含n×nn\times nn×n个格子,每个格子中是一个[0,255]的整数值,它就是输入图像,也是这个神经网络的输入;
  • 右边也是n×nn\times nn×n个格子,每个格子是一个神经元。每个神经元根据二维位置关系连接到输入上它周围3×33\times 33×3范围的值;
  • 每个链接有一个权值www
  • 所有神经元都如此连接(图中只画出了一个,出了输入图像边缘的连接就认为连接到常数0,有时会考虑pad操作)。
  • 右边的神经元的输出就是该神经网络的输出。
    这个网络与全连接神经网络的不同在于:
    1、它不是全连接的:右层的神经元并非连接全部输入,而只是连接了一部分。这里的一部分就是输入图像的一个局部区域。我们常听说CNN能够把握图像的局部特征,alphaGO从棋局局部状态提取信息等等,就是这个意思。这样一来权值少了很多,因为连接少了;
    2、权值其实更少,因为一个神经元的9个权值都是和其他神经元共享的。全部n×nn\times nn×n个神经元都用这共享一组的9个权值。那么这个神经网络其实一共只有9个参数需要调整。
    综上,这个神经网络其实可以看做是一个卷积滤波器,只不过卷积核的参数未确定,需要去训练,它是一个“可训练滤波器”,这个神经网络就已经是一个拓扑结构特别简单的CNN了。

填充padding

有了填充之后,每次卷积之后的图像大小:
(h−f+2ps+1,h−f+2ps+1)\left(\frac{h-f+2p}s+1,\frac{h-f+2p}s+1\right)(sh−f+2p​+1,sh−f+2p​+1)
当遇到分数时,只取整数部分。而这种p=0p=0p=0,然后结果取整数部分的处理方式,就叫做“Valid(有效)”填充。还有一种填充方式为same,填充后使卷积之后大小根源大小一致。

常见的卷积神经网络


cifar-10预测实例

Cifar-10数据集包含共60000张32×3232\times 3232×32的彩色图片,每类6000张图片。包括50000张训练图片和10000张测试图片。

数据预处理–图像增强

由于深度学习堆数据集的大小有一定的要求,若原始的数据集比较小,无法很好地满足网络模型训练,从而影响模型的性能,而图像增强是对原始图像进行一定的处理以扩充数据集,能够在一定程度上提升模型的性能。
图像增强表示的是,在原始图像的基础上,对数据进行一定的改变,增加了数据样本的数量,但是数据的标签值并不发生改变。

这里的图像增强是指突出图像中感兴趣区域及特征,其主要分为两种:
1、增强“自我”:通过一定手段将感兴趣区域增强,直至从图像中脱颖而出的那种,也是正常思维下常用的方法;
2、削弱“别人”:是增强“自我”的反方法,指的是通过一定手段将不感兴趣区域削弱,直至感兴趣区域脱颖而出。

图像增强常用方法

1、翻转、平移、旋转、缩放
2、分离单个r、g、b三个颜色通道
3、添加噪声
4、直方图均衡化
5、Gamma变换
6、反转图像的灰度
7、增加图像的对比度
8、缩放图像的灰度
9、均值滤波、中值滤波、高斯滤波…

Alex-Net

Alex-Net是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的。也是在那年之后,更多的更深的神经网络被提出。


1、一张原始图片被resize到(224,224,3);
2、使用步长为4×44\times 44×4,大小为11的卷积核对图像进行卷积,输出的特征层为96层,输出的shape为(55,55,96);
3、使用步长为2的最大池化进行池化,此时输出的shape为(27,27,96);
4、使用步长为1×11\times 11×1,大小为5的卷积核对图像进行卷积,输出的特征层为256层,输出的shape为(27,27,256);
5、使用步长为2的最大池化进行池化,此时输出的shape为(13,13,256);
6、使用步长为1×11\times 11×1,大小为3的卷积核对图像进行卷积,输出的特征层为384层,输出的shape为(13,13,384);
7、使用步长为1×11\times 11×1,大小为3的卷积核对图像进行卷积,输出的特征层为384层,输出的shape为(13,13,384);
8、使用步长为1×11\times 11×1,大小为3的卷积核对图像进行卷积,输出的特征层为256层,输出的shape为(13,13,256);
9、使用步长为2的最大池化进行池化,此时输出的shape为(6,6,256);
10、两个全连接层,最后输出为1000类。
第一层
第一层输入数据为原始图像的24×24×324\times24\times324×24×3的图像,这个图像被11×11×311\times11\times311×11×3(3代表深度,如RGB的3通道)的卷积核进行卷积运算,卷积核对原始图像的每次卷积都会生成一个新的像素。
卷积核的步长为4个像素,朝着横向和纵向这两个方向进行卷积。
由此,会生成新的像素;
第一层96个卷积核,所以会形成55×55×9655\times55\times9655×55×96个像素层

pool池化层:这些像素层还需要经过pool运算(池化运算)的处理,池化运算的尺度有预先设定为3×33\times33×3,运算的步长为2,则池化后的图像尺寸为:(55−3)/2+1=27(55-3)/2+1=27(55−3)/2+1=27。即经过池化处理过的规模为27×27×9627\times27\times9627×27×96。
下面用keras实现Alex-net,仅以实现猫狗分类为例,其文件包含关系如下图:

其中,model中alex-net代码如下:

from keras.models import Sequential
from keras.layers import Dense, Activation, Conv2D, MaxPooling2D, Flatten, Dropout, BatchNormalization
from keras.datasets import mnist
from keras.utils import np_utils
from keras.optimizers import Adam# 注意,为了加快收敛,我将每个卷积层的filter减半,全连接层减为1024
def AlexNet(input_shape=(224, 224, 3), output_shape=2):# AlexNetmodel = Sequential()# 使用步长为4x4,大小为11的卷积核对图像进行卷积,输出的特征层为96层,输出的shape为(55,55,96);# 所建模型后输出为48特征层model.add(Conv2D(filters=48, kernel_size=(11, 11), strides=(4, 4),padding='valid', input_shape=input_shape, activation='relu'))model.add(BatchNormalization())# 使用步长为2的最大池化层进行池化,此时输出的shape为(27,27,96)# 所建模型后输出为48特征层model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid'))# 使用步长为1x1,大小为5的卷积核对图像进行卷积,输出的特征层为256层,输出的shape为(27,27,256);# 所建模型后输出为128特征层model.add(Conv2D(filters=128, kernel_size=(5, 5), strides=(1, 1), padding='same', activation='relu'))model.add(BatchNormalization())# 使用步长为2的最大池化层进行池化,此时输出的shape为(13,13,256);# 所建模型后输出为128特征层model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid'))# 使用步长为1x1,大小为3的卷积核对图像进行卷积,输出的特征层为384层,输出的shape为(13,13,384);# 所建模型后输出为192特征层model.add(Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu'))# 使用步长为1x1,大小为3的卷积核对图像进行卷积,输出的特征层为384层,输出的shape为(13,13,384);# 所建模型后输出为192特征层model.add(Conv2D(filters=192, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu'))# 使用步长为1x1,大小为3的卷积核对图像进行卷积,输出的特征层为256层,输出的shape为(13,13,256);# 所建模型后输出为128特征层model.add(Conv2D(filters=128, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu'))# 使用步长为2的最大池化层进行池化,此时输出的shape为(6,6,256);# 所建模型后输出为128特征层model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='valid'))# 两个全连接层,最后输出为1000类,这里改为2类(猫和狗)# 缩减为1024model.add(Flatten())model.add(Dense(1024, activation='relu'))model.add(Dropout(0.25))model.add(Dense(1024, activation='relu'))model.add(Dropout(0.25))model.add(Dense(output_shape, activation='softmax'))return model

预处理相关函数utils.py相关代码如下:

import matplotlib.image as mpimg
import numpy as np
import cv2
import tensorflow as tf
from tensorflow.python.ops import array_opsdef load_image(path):# 读取图片,rgbimg = mpimg.imread(path)# 将图片修剪成中心的正方形short_edge = min(img.shape[:2])yy = int((img.shape[0] - short_edge) / 2)xx = int((img.shape[1] - short_edge) / 2)crop_img = img[yy: yy + short_edge, xx: xx + short_edge]return crop_imgdef resize_image(image, size):with tf.name_scope('resize_image'):images = []for i in image:i = cv2.resize(i, size)images.append(i)images = np.array(images)return imagesdef print_answer(argmax):with open("./data/model/index_word.txt", "r", encoding='utf-8') as f:synset = [l.split(";")[1][:-1] for l in f.readlines()]# print(synset[argmax])return synset[argmax]

数据集处理dataset_process.py代码如下:

import osphotos = os.listdir("./data/image/train/")with open("data/dataset.txt", "w") as f:for photo in photos:name = photo.split(".")[0]if name == "cat":f.write(photo + ";0\n")elif name == "dog":f.write(photo + ";1\n")
f.close()

训练train.py代码如下:

from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
from keras.utils import np_utils
from keras.optimizers import Adam
from model.AlexNet import AlexNet
import numpy as np
import utils
import cv2
from keras import backend as K
# K.set_image_dim_ordering('tf')
K.image_data_format() == 'channels_first'def generate_arrays_from_file(lines, batch_size):# 获取总长度n = len(lines)i = 0while True:X_train = []Y_train = []# 获取一个batch_size大小的数据for b in range(batch_size):if i == 0:np.random.shuffle(lines)name = lines[i].split(';')[0]# 从文件中读取图像img = cv2.imread(r".\data\image\train" + '/' + name)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img = img / 255X_train.append(img)Y_train.append(lines[i].split(';')[1])# 读完一个周期后重新开始i = (i + 1) % n# 处理图像X_train = utils.resize_image(X_train, (224, 224))X_train = X_train.reshape(-1, 224, 224, 3)Y_train = np_utils.to_categorical(np.array(Y_train), num_classes=2)yield (X_train, Y_train)if __name__ == "__main__":# 模型保存的位置log_dir = "./logs/"# 打开数据集的txtwith open(r".\data\dataset.txt", "r") as f:lines = f.readlines()# 打乱行,这个txt主要用于帮助读取数据来训练# 打乱的数据更有利于训练np.random.seed(10101)np.random.shuffle(lines)np.random.seed(None)# 90%用于训练,10%用于估计。num_val = int(len(lines) * 0.1)num_train = len(lines) - num_val# 建立AlexNet模型model = AlexNet()# 保存的方式,3代保存一次checkpoint_period1 = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',monitor='acc', save_weights_only=False, save_best_only=True, period=3)# 学习率下降的方式,acc三次不下降就下降学习率继续训练reduce_lr = ReduceLROnPlateau(monitor='acc', factor=0.5, patience=3, verbose=1)# 是否需要早停,当val_loss一直不下降的时候意味着模型基本训练完毕,可以停止early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)# 交叉熵model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])# 一次的训练集大小batch_size = 128  # 128print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))# 开始训练model.fit_generator(generate_arrays_from_file(lines[:num_train], batch_size),steps_per_epoch=max(1, num_train // batch_size),validation_data=generate_arrays_from_file(lines[num_train:], batch_size),validation_steps=max(1, num_val // batch_size),epochs=50,  # 50initial_epoch=0,callbacks=[checkpoint_period1, reduce_lr])model.save_weights(log_dir + 'last1.h5')

训练后会生成模型“last1.h5”,然后通过predict.py加载该模型进行预测代码如下:

import numpy as np
import utils
import cv2
from keras import backend as K
from model.AlexNet import AlexNet
import matplotlib.pyplot as plt# K.set_image_dim_ordering('tf')
K.image_data_format() == 'channels_first'if __name__ == "__main__":model = AlexNet()model.load_weights("./logs/last1.h5")for i in range(4):img = cv2.imread("./test" + str(i) + ".jpg")img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img_nor = img_RGB / 255img_nor = np.expand_dims(img_nor, axis=0)img_resize = utils.resize_image(img_nor, (224, 224))result = utils.print_answer(np.argmax(model.predict(img_resize)))plt.subplot(2, 2, i+1), plt.imshow(img_RGB), plt.axis('off')plt.title('predict result is:' + result)plt.show()

运行结果如下:

AI学习笔记(十)卷积神经网络相关推荐

  1. 霹雳吧啦wz学习笔记1_卷积神经网络

    霹雳吧啦wz学习笔记1_卷积神经网络 全连接层: 全连接层就是由许许多多的神经元共同连接而得来的 卷积层: 卷积就是一个滑动窗口在我们的特征图上进行滑动并计算 卷积的目的:进行图像特征提取 卷积核的c ...

  2. 深度学习笔记:卷积神经网络的可视化--卷积核本征模式

    目录 1. 前言 2. 代码实验 2.1 加载模型 2.2 构造返回中间层激活输出的模型 2.3 目标函数 2.4 通过随机梯度上升最大化损失 2.5 生成滤波器模式可视化图像 2.6 将多维数组变换 ...

  3. 深度学习入门之PyTorch学习笔记:卷积神经网络

    深度学习入门之PyTorch学习笔记 绪论 1 深度学习介绍 2 深度学习框架 3 多层全连接网络 4 卷积神经网络 4.1 主要任务及起源 4.2 卷积神经网络的原理和结构 4.2.1 卷积层 1. ...

  4. 深度学习笔记:卷积神经网络的Tensorflow实现

    文章出处:深度学习笔记11:利用numpy搭建一个卷积神经网络 免费视频课程:Hellobi Live | 从数据分析师到机器学习(深度学习)工程师的进阶之路 在上一讲中,我们学习了如何利用 nump ...

  5. 吴恩达深度学习笔记- lesson4 卷积神经网络

    文章目录 Week 1 卷积神经网络基础 4.1.1 计算机视觉(Computer vision) 4.1.2 边缘检测示例(Edge detection example) 4.1.3 更多边缘检测内 ...

  6. tensorflow学习笔记七----------卷积神经网络

    卷积神经网络比神经网络稍微复杂一些,因为其多了一个卷积层(convolutional layer)和池化层(pooling layer). 使用mnist数据集,n个数据,每个数据的像素为28*28* ...

  7. [傅里叶变换及其应用学习笔记] 十. 卷积与中心极限定理

    这份是本人的学习笔记,课程为网易公开课上的斯坦福大学公开课:傅里叶变换及其应用. 中心极限定理(Central Limit Theorem) 中心极限定理,简称CLT.大多数概率事件,当有足够多的取样 ...

  8. 学习笔记 | 深度卷积神经网络在计算机视觉中的应用

    图像识别是一种利用计算机对图像进行处理.分析和理解,以识别各种不同模式的目标和对象的技术,是计算机视觉领域的一个主要研究方向,在以图像为主体的智能化数据采集与处理中具有十分重要 的作用和影响.目前图像 ...

  9. 深度学习笔记 6 卷积神经网络

    目录 1.概念 2. 结构及每层详解 3. CNN特征 4. 卷积神经网络的流程 5.可变形卷积(DCN) 6.一些小问题 1. 1x1卷积作用 2. 卷积层和池化层有什么区别? 3.怎样才能减少卷积 ...

  10. 深度学习笔记:卷积神经网络的可视化--特征图

    目录 1. 前言 2. 模型的训练 3. 特征图可视化 3.1 加载保存的模型¶ 3.2 图像预处理:将图像转换为张量 3.3 例化一个模型用于返回各层激活输出(即feature map) 3.5 各 ...

最新文章

  1. hdu 1495 非常可乐 (bfs)
  2. Linux 下 mail、mailx 和 sendmail、postfix的区别
  3. 【数据竞赛】“达观杯”文本智能处理挑战赛2
  4. [MyBatisPlus]代码生成器
  5. Cloud一分钟 | 蚂蚁金服估值超万亿;Google大举进军游戏市场
  6. android 混音 源码,FFmpegAndroid android 端基于 FFmpeg 实现音频剪切、拼接、转码、混音、编解码;视频剪切、水印、截图、转码、编 @codeKK c开源站...
  7. 高通骁龙712移动平台正式发布!整体性能提升10%
  8. 透过现象看本质,透析NAC系统几步走(4)
  9. 粤嵌GE6818实现识别触摸坐标的识别
  10. [转载] 包含对象的json格式_如何把JSON数据格式转换为Python的类对象?
  11. sbt 地址修改备注
  12. 第一个python程序-判断登陆用户名和密码是否正确
  13. swpu计算机科学学院推荐免试,西南石油大学2020届本科毕业生推荐免试硕士研究生结果公示 - 千里马招标网...
  14. spss因子分析结果解读_因子分析巴特利特球形度检验结果解读
  15. word总页数不包含封面_Word2016页码显示总页数不包含封面目录指导文档
  16. 超参数调优方法整理大全
  17. LED驱动程序的编写
  18. Hive之数据类型、查询操作
  19. 在OpenCV里实现直方图反向投影算法
  20. SSD(ECCV 2016)

热门文章

  1. java初始化配置_java – 初始化没有XML配置的数据库,但使用@Configuration
  2. JAVA_返回一个数值的相反数的几种方式.
  3. isinstance 判断归属
  4. CodeDom系列--事件(event)定义和反射调用
  5. webpack3+node+react+babel实现热加载(hmr)
  6. Django 找不到模版报错 django.template.exceptions.TemplateDoesNotExist: index.html
  7. [转]php连接postgresql
  8. loadrunner可用许可证
  9. Servlet容器原型(三)——Tomcat 4默认连接器浅谈
  10. css用边框实现圆角矩形