【创新实训】深度学习个人学习总结+使用InceptionV4完成图像多标记功能

整个四月和五月上半月使用GooLeNet-InceptionV4完成图像多标记功能,该功能的效果是,给定一张图片url,可以产生一系列标签,进一步得,可以利用这些标签来做其他的事情,比如图像检索或者图像匹配等等。


学习博客和论文链接、知识总结、心得体会与收获。Paper分别是VGG、Resnet、InceptionV1、InceptionV2、InceptionV3、InceptionV4。最终得到InceptionV4的网络模型结构。

1.https://www.cnblogs.com/charlotte77/p/5629865.html《一文看懂神经神经网络中的反向传播算法》

总结:神经网络中最重要的就是反向传播算法,原理就是根据前向传播结果和预期目标结果,选择一个损失函数得到Loss,然后反过去求对每一个权重w的偏导数,即梯度,然后沿着负梯度的方向更新权重w。当迭代多次后,loss几乎稳定,此时模型收敛。

2.http://www.199it.com/archives/634008.html《一文读懂卷积神经网络工作原理》

总结:每一个卷积层会包含很多卷积核,每个卷积核是m*m大小的滤波器,因此有m*m个权重参数。卷积核的作用就是对特定的模式有较高的激活,训练cnn的过程就是得到这些卷积核的过程。从一个随机初始化的权重,修改权重使其能够检测某一特定模式。卷积神经网络中第一个卷积层用来检测低阶特征,后面的卷积层用来学习特征的组合,更加抽象。

3.https://blog.csdn.net/maweifei/article/details/52446938《一文读懂卷积神经网络》

权值共享:就是每个神经元对应的卷积核的权值矩阵是一样的,卷积核不会因神经元而异。这样可以大量降低权值参数个数。

多卷积核:每个卷积核可以学到一种特征,产生一张feature map,

平均/最大池化:feature map通常较大,为了描述这张大的图像,使用池化来对不同的区域进行统计聚合,池化的意义就是保留了这张ferature map的重要特征来代替它本身,以减少计算量、防止过拟合。

4.https://www.jianshu.com/p/c56a37093cfa《深度学习图片卷积输出大小计算公式》

N = (W − F + 2P )/S+1

5.https://www.cnblogs.com/skyfsm/p/8451834.html《CNN网络架构演进》

LeNet:开山鼻祖

AlexNet:使用了数据增广-随机裁剪;Relu激活函数;Dropout-让全连接层的神经元以一定概率失活,避免过拟合;LRN局部响应归一化-后来研究没啥用,不介绍了

VGGNet:Pre-training-先训练一部分小网络,然后再确保这部分网络稳定之后,再在这基础上逐渐加深;卷积层使用更小的filter尺寸和间隔,都是1*1、3*3的卷积核,多个小卷积比一个大卷积有更多的非线性,更少的参数;

GoogLeNet:引入Inception结构;使用1*1卷积核进行降维;全局平均pooling代替全连接层;更多内容后面会详细研究。

Resnet:Residual module解决深层模型退化问题;

心得体会:CNN的发展历程,就是模型越来越深,这样可以提供更好的特征学习能力,但是网络的复杂程度要越来越低,参数要适中或者更少,而不能过于膨胀,这样才能更加容易学习。概括之:发挥深层网络的优势,同时设计利于学习的方法。

6.https://blog.csdn.net/u013709270/article/details/78667531《一文看懂常用的梯度下降算法》

BGD:批量梯度下降,训练是在整个数据集上,适用于数据集比较小的情况;

SGD:一个样本就更新一次参数,收敛速度会快一些

小批量梯度下降:分batch训练,目前最常用

----Momentum optimization:冲量梯度下降,参数更新时不仅考虑当前梯度值,而且加上了一个积累项,就像滚雪球,加速收敛

----AdaGrad :学习速率自适应,其学习速率是逐渐衰减的,计算梯度平方的积累量,在进行参数更新时,学习速率要除以这个积累量的平方根

----RMSprop:对Adagrad算法的改进,主要是解决学习速率过快衰减的问题。解决思路就是在计算梯度平方积累量的时候引入一个超参数。

----Adam:结合了Momentum和RMSprop算法的思想。相比Momentum算法,其学习速率是自适应的,而相比RMSprop,其增加了冲量项

理想的学习速率是:刚开始设置较大,有很快的收敛速度,然后慢慢衰减,保证稳定到达最优点。

7.https://blog.csdn.net/qq_25737169/article/details/78847691 《详解详解机器学习中的梯度消失、爆炸原因及其解决方法》

总结:求梯度的时候使用链式求导法则,其中包含了对激活函数的求导。在层数较多时,链式会很长,很可能会带来梯度消失或梯度爆炸问题,即前面层的梯度很大或者很小。表现上来说,不同层的学习速度差异很大。根本原因在于反向传播训练。

解决梯度消失的办法:relu、leakrelu、elu等激活函数代替sigmoid/batchnorm层

8.https://blog.csdn.net/qq_25737169/article/details/79048516《batchnorm原理及代码解读》

总结:深度神经网络主要是为了学习训练数据的分布,并且在测试集上达到很好的泛化效果。Internal Covariate Shift问题,即指数据经过一层层网络计算后,其数据分布也在发生着变化,这个问题会给训练带来困难。Batchnorm的意义就是数据做归一化,可以加快训练速度,对数据做去相关性,突出它们之间的分布相对差异。Batchnorm的过程是,对输入数据,首先计算均值和方差,然后归一化,然后缩放和平移。

9.https://blog.csdn.net/amds123/article/details/69621688《深度学习超参数简单理解》

weight decay:为了避免过拟合,必须对价值函数添加正则项,weight decay是放在正则项(regularization)前面的一个系数,weight decay的作用是调节模型复杂度对损失函数的影响,若weight decay很大,则复杂的模型损失函数的值也就大

10. https://blog.csdn.net/wang1127248268/article/details/77108312《深度学习调参》

参数初始化方式:uniform均匀分布初始化/normal高斯分布初始化

11《very deep convolutional networks for large-scale image recognition》VGG16、VGG19网络模型论文

文章分别使用了6种不同深度的网络进行对比

12.https://blog.csdn.net/wcy12341189/article/details/56281618《深度网络VGG理解》

本博客重点理解为什么几个小滤波器卷积层的组合比大滤波器卷积层要好。第一点是非线性提取能力强,第二点是使用的参数少,容易训练。

13 https://blog.csdn.net/u011576009/article/details/74332108 《VGG学习》

个人总结:

1, 小的卷积核的深层网络性能优于大卷积核的浅层网络 
2,小的卷积核的卷积层连用(中间没有pooling)和大的卷积核单用的感受野是相同的,比如2个3x3的卷积层连用和一个5x5的卷积层的感受野一样,3个3x3的卷积层和一个7x7的卷积层感受野一样。 
3,小的卷积核的连用可以让决策函数变得更有区分度,并且可以大大降低参数的数量,这就是文章里深层网络的参数却比浅层网络参数没多多少的原因 
4,深层网络适合于大的数据集 
5,关于1x1卷积核的作用:首先,增加决策函数的非线性,其次,对特征进行了转换,相当于“feature pooling”,比如把300x300x50的特征图可以降到300x300x20。 

6,使用预训练好的参数初始化可以加速训练

14 https://www.zhihu.com/question/23765351 《Softmax的特点和作用

softmax会把所有的选择都给出相应的概率,并且归一化了

15 http://iamaaditya.github.io/2016/03/one-by-one-convolution/ 《关于1x1卷积核更详细的解释》

16 https://stats.stackexchange.com/questions/104988/what-is-the-difference-between-a-loss-function-and-decision-function 《

loss function和decision function的区别》

17 https://www.zhihu.com/question/22334626/answer/21036590 《神经网络激励函数的作用》

18.https://blog.csdn.net/zuochao_2013/article/details/56024172《主流深度学习框架对比》

我们选用最流行的tensorflow,尽管很多开源代码是基于caffe的

19.https://arxiv.org/pdf/1512.03385.pdf《Resnet的论文》

何凯明等人发明的Resnet网络模型。

https://zhuanlan.zhihu.com/p/31852747《你必须知道的CNN模型:Resnet》

网络越深,其可以进行更加复杂的特征模式的提取,所以理论上模型越深效果越好。但是实验观察可知,深度网络会有退化问题(Degradation problem),例如一个56层的网络的性能还不如一个20层的网络。Resnet采用了残差学习,使深度网络易于训练,从而发挥出深度网络的优势。

Resnet 的典型结构就是这种残差模块,由shortcut connection实现identity mapping ,不会引入额外的参数,也不会带来计算量。残差学习模型学习的是残差Fx)而不是原始的函数Hx.对于短路连接,当输入和输出维度一致时,可以直接将输入加到输出上。但是当维度不一致时(对应的是维度增加一倍),这就不能直接相加。有两种策略:(1)采用zero-padding增加维度,此时一般要先做一个down samp,可以采用strde=2pooling,这样不会增加参数;(2)采用新的映射(projection shortcut),一般采用1x1的卷积,这样会增加参数,也会增加计算量。短路连接除了直接使用恒等映射,当然都可以采用projection shortcut

20 https://blog.csdn.net/qq_14845119/article/details/73648100《从Inception v1,v2,v3,v4,RexNeXt到Xception再到MobileNets,ShuffleNet,MobileNetV2》

InceptionV1:主要是提出了Inception module.1*1的卷积层的引入,降低了权重个数,同时增强了网络的非线性能力。同时使用了1*1,3*3,5*5的卷积,增加了网络对尺度的适应性

21 ===InceptionV1 论文 https://arxiv.org/abs/1409.4842《Going Deeper with Convolutions》

InceptionV2:加入了BN层,减少了Internal Covariate Shift(内部neuron的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯;用2个连续的3*3 conv替代inception模块中的5*5

22 ===IncepionV2 论文 https://arxiv.org/abs/1502.03167《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》

InceptionV3:在v2的基础上,提出了卷积分解。将7*7分解成两个一维的卷积(1*7,7*1),3*3也是一样(1*3,3*1),这样的好处,既可以加速计算(多余的计算能力可以用来加深网络),又可以将1个conv拆成2个conv,使得网络深度进一步增加,增加了网络的非线性

23===InceptionV3 轮文https://arxiv.org/abs/1512.00567 《Rethinking the Inception Architecture for Computer Vision

InceptionV4/Inception-Resnet-V1&2:后面两种利用残差连接(Residual Connection)来改进v3结构

24 ===InceptionV4/Inception-Resnet-V1&2 论文 https://arxiv.org/abs/1602.07261《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》

InceptionV4并没有引入Resnet connections模块,但是其性能与Inception-Resnet-V2相同。

25 https://www.cnblogs.com/myblog1993/p/6931007.html Windows下tensorflow安装过程

26 http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html tensorflow的教程,我们实现了其中的demo,使用MNIST数据集进行手写数字识别分类

27 https://blog.csdn.net/yangdashi888/article/details/70503874 《深度学习常用的数据集》

Imagenet数据集:1400多万图片,2万多个类别。大约1TB

COCO数据集:由微软赞助,对于图像的标注信息不仅有类别、位置信息,还有对图像的语义文本描述,用于图像语义分割和理解,大约40GB

PASCAL VOC:包括20个目录,用于图像分类、物体检测,其数据集图像质量好,标注完备,非常适合用来测试算法性能,约2GB

CIFAR:中小规模数据集;图像分类;100或10类;170MB

28 https://blog.csdn.net/bea_tree/article/details/51784026

InceptionV4的模型结构参考论文:

29 https://arxiv.org/abs/1602.07261《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》

InceptionV4论文中的模型结构:

【创新实训】深度学习个人学习总结+使用InceptionV4完成图像多标记功能_第1张图片


30 https://github.com/MachineLP/models/tree/master/research/slim#Pretrained tf-slim库中,提供了我们需要的InceptionV4模型,因此决定不需要重新训练,好好研究一下这个slim库和它的源代码


在研究了github上提供的介绍、以及tf-slim的源代码后,终于写出来了如何使用inceptionV4模型的代码:


工程框架:

【创新实训】深度学习个人学习总结+使用InceptionV4完成图像多标记功能_第2张图片

其中上面三个文件夹copy自tf-slim代码库

use-model代码:

import numpy as np
import os
import tensorflow as tf
import urllib.request

import datasets.imagenet as imagenet
import nets.inception_v4 as IV4
import preprocessing.inception_preprocessing as IP

slim = tf.contrib.slim
image_size = IV4.inception_v4.default_image_size
with tf.Graph().as_default():
    # 读取图片
    url = ("http://www.ichong123.com/uploads/2014/08/1264.jpg")

    image_string = urllib.request.urlopen(url).read()
    image = tf.image.decode_jpeg(image_string, channels=3)
    # 预处理图片
    processed_image = IP.preprocess_image(image,
                                          image_size,
                                          image_size,
                                          is_training=False)
    processed_images  = tf.expand_dims(processed_image, 0)
    with slim.arg_scope(IV4.inception_v4_arg_scope()):
        # 将图片送入模型得到返回结果logits
        logits, _ = IV4.inception_v4(processed_images,
                               num_classes=1001,
                               is_training=False)
        probabilities = tf.nn.softmax(logits)
        init_fn = slim.assign_from_checkpoint_fn(( './inception_v4.ckpt'),slim.get_model_variables('InceptionV4'))
        with tf.Session() as sess:

        # 加载权值
            init_fn(sess)
        # 图片经过缩放和裁剪,最终以numpy矩阵的格式传入网络模型
            np_image, network_input, probabilities = sess.run([image,
                                                               processed_image,
                                                               probabilities])
            probabilities = probabilities[0, 0:]
            sorted_inds = [i[0] for i in sorted(enumerate(-probabilities),
                                                key=lambda x:x[1])]

            names = imagenet.create_readable_names_for_imagenet_labels()
            for i in range(5):
                index = sorted_inds[i]
                # 打印top5的预测类别和相应的概率值。
                print('Probability %0.2f : [%s]' % (probabilities[index], names[index+1]))

            res = slim.get_model_variables()

测试输出:

Probability 0.74 : [cougar, puma, catamount, mountain lion, painter, panther, Felis concolor]
Probability 0.07 : [Egyptian cat]
Probability 0.02 : [tiger cat]
Probability 0.02 : [Persian cat]
Probability 0.01 : [leopard, Panthera pardus]

编程思路:

读取url中提供的Image,预处理后,送到网络模型中,得到输出。

注意送到网络前,需要processed_images  = tf.expand_dims(processed_image, 0) 来增加一个维度,这是根据tf-slim的函数得到的这样的要求。

至此完成了图像多标记的功能。

代码量不大,主要是需要学习和研究的内容太多。




VGG学习总结

你可能感兴趣的:(项目创新实训)