精华内容
下载资源
问答
  • Inception V4

    2021-04-19 15:08:22
    Inception V4 参考: https://blog.csdn.net/qq_38807688/article/details/84590291?spm=1001.2014.3001.5501 https://blog.csdn.net/sinat_33487968/article/details/83588372 ...Motivation 将Inception结构和...

    Inception V4

    参考:
    https://blog.csdn.net/qq_38807688/article/details/84590291?spm=1001.2014.3001.5501
    https://blog.csdn.net/sinat_33487968/article/details/83588372
    https://zhuanlan.zhihu.com/p/52802896

    Motivation

    将Inception结构和Residual Connection相结合,结合 ResNet 可以极大地加速训练

    Method

    以往的inception网络,我们对inceptin结构方面的选择比较保守,没有在结构上做很大的改动。以前结构的保守、固定直接导致了网络和结构的灵活性欠佳。反而导致网络看起来更复杂。
    我们这次做的工作做了一个统一,为每一个Inception块做出统一的选择。

    Inception-V4

    Inception-V4三种Inception block的个数分别为4、7、3个
    Inception-V3三种Inception block的个数分别为3、5、2个
    因此新的Inception层次更深、结构更复杂,feature map的channel更多
    Inception-v4

    Inception-Resnet-V1/2

    在这里插入图片描述

    inception-V4 Blocks

    Stem

    Stem中使用了并行结构、不对称卷积核结构,保证信息损失足够小的情况下,使得计算量降低。
    结构中1*1的卷积核也用来降维,并且也增加了非线性。
    图中带V的标记说明该卷积核使用valid padding,其余的使用same padding。
    这个stem结构实际上是替代了Inception V3中第一个Inception block之前的结构:
    在V3中仅仅是一些3×3卷积核的堆积,输出的feature map为35×35×288
    而在这里结构更加复杂、层次更深,输出的feature map为35×35×384,比V3的也更多。
    在这里插入图片描述

    InceptionA/B/C

    无identity connection(源自于ResNet)
    见论文,不详叙

    RedutionA/B

    卷积的步长(stride)为2,都使用valid padding,来降低feature map的尺寸,增加filter个数

    Inception-Resnet-V1 Blocks

    值得一提的是,虽然层次变得更深了,这个Inception-ResNet-v1的计算量仍然只和Inception V3大致相同。

    Stem

    使用了和Inception V3中很类似的结构,只不过channel的数量有些许不同

    Inception-ResNet-A/B/C

    这三种block的数量分别为5、10、5个
    每一个block中都使用了identity connection(源自于ResNet)
    而block右部的residual function可以看成是简化版的Inception,结构和参数量都比传统的Inception block要小,并且后面都使用1×1的滤波器进行维度匹配。

    RedutionA/B

    Reduction-A/B的结构与Inception V4的一致

    Inception-ResNet-v2 Blocks

    Inception-ResNet-v2的整体框架和Inception-ResNet-v1的一致。

    只不过v2的计算量更加expensive

    stem

    与Inception V4的相同

    Inception-ResNet-A/B/C

    Inception-ResNet-A/B/C和与Inception-ResNet-v1的类似,只不过输出的channel数量更多

    Reduction

    Reduction-A与Inception-ResNet-v1的相同
    Reduction-B与Inception-ResNet-v1的类似
    总的来说,Inception-ResNet-v2与Inception V4的相近。
    在Inception-ResNet-v2中同样使用了dropout和BN。

    注意

    在网络的最后,softmax层之前, 使用了keep prob为0.8的dropout来防止过拟合。

    我们的残余和非残余Inception变体之间的另一个小的技术差异是,在Inception- resnet的情况下,我们只在传统的层之上使用批处理规范化,而不是在总和之上,并未在完成输入与输出相加的层使用BN。

    performance

    InceptionV3和Inception-Resnet-V1性能相当
    InceptionV4和Inception-Resnet-V2性能相当

    但是Inception-ResNet-v1/2的收敛速度明显比Inception-v3/4的快得多。
    在这里插入图片描述
    在这里插入图片描述

    discuss

    在这里插入图片描述

    作者发现,当一个Residual function中滤波器的数量超过1000时,这个block变得不稳定,训练容易出现‘died’的现象,产生的输出只为0,这明显是不可以的,并且通过降低学习率、增加额外的BN都无法解决这个问题。

    作者给出的解决办法是,在Residual function之后、激活函数之前,使用一个activation scaling的操作能够稳定训练,其中缩放因子为0.1到0.3。
    至于这么做的原因不得而知(缩放模块只是通过一个合适的常数来缩放最后一次线性激活,通常在0.1左右。)
    “尽管缩放在某些地方不是必须的,但是并未发现缩放会降低最终的准确性,而且缩放在一定程度上会使训练变得稳定。”

    核心处理方法

    • 使用并行结构(加入ResNet的identity connection,极大程度的提高收敛速度)
    • 使用不对称的卷积
    • 使用1*1的卷积进行维度变换
    展开全文
  • 使用Inception V4训练自己的数据集

    千次阅读 热门讨论 2019-07-02 21:20:52
    这节我们主要介绍一下Inception v1-v4各个模型的特点,并在最后实现一下使用Inception v4进行卫星图像的分类。在这里谈一下我对Inception系列的粗浅的认识。我们可以看到之前一系列深度卷积模型只是在关注如何在不过...

    前言:

    Inception v1-v4是谷歌推出的一系列产品。这节我们主要介绍一下Inception v1-v4各个模型的特点,并在最后实现一下使用Inception v4进行卫星图像的分类。在这里谈一下我对Inception系列的粗浅的认识。我们可以看到之前一系列深度卷积模型只是在关注如何在不过拟合的情况下加深网络的结构。但是他们却不关注网络的宽度,而Inception系列不仅着手加深网络的深度而且还要加深网络的宽度。看到这里不熟悉Inception 系列的人肯定不知道我说的是啥啦。 okay我们看一下大牛们是如何解释Inception 系列的

     

    Inception v1-v4各个模型的特点:

    第一:  Inception 系列整体的特点是什么?

    我的理解是:之前的网络就是一层层卷积, 并把结果输入到下一层,但是人家Inception不同,人家定义一个模块,模块里面进行不同的卷积操作,最后把不同的卷积操作拼接之后作为输出。为什么这样做呢?因为实验结果表明效果好啊。

     

    知乎上一篇文章中的说的是:

    GoogLeNet 最大的特点就是使用了 Inception 模块,它的目的是设计一种具有优良局部拓扑结构的网络,即对输入图像并行地执行多个卷积运算或池化操作,并将所有输出结果拼接为一个非常深的特征图。因为 1*1、3*3 或 5*5 等不同的卷积运算与池化操作可以获得输入图像的不同信息,并行处理这些运算并结合所有结果将获得更好的图像表征。

     

     

    第二: Inception 系列各自的特点是什么? 每个模型解决了什么问题?

    这种问题肯定要专业人士来回答啦!!!!!!!!!!!!

    先上Paper列表:

    大体思路:

    • Inception v1的网络,将1x1,3x3,5x5的conv和3x3的pooling,stack在一起,一方面增加了网络的width,另一方面增加了网络对尺度的适应性;
    • v2的网络在v1的基础上,进行了改进,一方面了加入了BN层,减少了Internal Covariate Shift(内部neuron的数据分布发生变化),使每一层的输出都规范化到一个N(0, 1)的高斯,另外一方面学习VGG用2个3x3的conv替代inception模块中的5x5,既降低了参数数量,也加速计算;
    • v3一个最重要的改进是分解(Factorization),将7x7分解成两个一维的卷积(1x7,7x1),3x3也是一样(1x3,3x1),这样的好处,既可以加速计算(多余的计算能力可以用来加深网络),又可以将1个conv拆成2个conv,使得网络深度进一步增加,增加了网络的非线性,还有值得注意的地方是网络输入从224x224变为了299x299,更加精细设计了35x35/17x17/8x8的模块;
    • v4研究了Inception模块结合Residual Connection能不能有改进?发现ResNet的结构可以极大地加速训练,同时性能也有提升,得到一个Inception-ResNet v2网络,同时还设计了一个更深更优化的Inception v4模型,能达到与Inception-ResNet v2相媲美的性能。

     

    Inception v4的架构图:

    这个之所以和之前介绍的模型优点不一样,是因为Inception系列将大部分的操作封装在某个层中,这个在后面的代码中有所体现。左边的图为粗略的结构图,右边的图为枝干图。这个就参考一下知乎上的文章,https://zhuanlan.zhihu.com/p/52802896

                  

     

    同样首先是程序的主程序:

    代码没有太多的修改,表明自己写的模板可适性还是比较不错的,因为简单,所以可适性比较强。

    # -*- coding: utf-8 -*-
    # @Time    : 2019/7/2 20:39
    # @Author  : YYLin
    # @Email   : 854280599@qq.com
    # @File    : Inception_v4_train.py
    import inception_V4
    import tensorflow as tf
    import os
    import cv2
    import numpy as np
    from keras.utils import to_categorical
    
    # os.environ['CUDA_VISIBLE_DEVICES'] = "-1"
    # 定义一些模型中所需要的参数
    batch_size = 16
    img_high = 100
    img_width = 100
    Channel = 3
    label = 9
    
    # 定义一些仅仅用于 Densenet 的超参
    growth_k = 12
    nb_block = 2
    
    # 定义输入图像的占位符
    inputs = tf.placeholder(tf.float32, [batch_size, img_high, img_width, Channel], name='inputs')
    y = tf.placeholder(dtype=tf.float32, shape=[batch_size, label], name='label')
    keep_prob = tf.placeholder("float")
    is_train = tf.placeholder(tf.bool)
    
    
    # 第三个参数表示最后的类别 不能使用占位符
    score = inception_V4.inference(inputs, batch_size, label)
    softmax_result = tf.nn.softmax(score)
    
    # 定义损失函数 以及相对应的优化器
    cross_entropy = -tf.reduce_sum(y*tf.log(softmax_result))
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
    
    # 显示最后预测的结果
    correct_prediction = tf.equal(tf.argmax(softmax_result, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
    
    
    # 只需要最后一步 如何加载数据集 参考之前的AC-GAN 今天晚上完成!!!!!!!!!!!
    # 现在的我只需要加载图像和对应的label即可 不需要加载text中的内容
    def load_satetile_image(batch_size=128, dataset='train'):
        img_list = []
        label_list = []
        dir_counter = 0
    
        if dataset == 'train':
            path = '../Dataset/baidu/train_image/train'
    
            # 对路径下的所有子文件夹中的所有jpg文件进行读取并存入到一个list中
            for child_dir in os.listdir(path):
                child_path = os.path.join(path, child_dir)
                for dir_image in os.listdir(child_path):
                    img = cv2.imread(os.path.join(child_path, dir_image))
                    img = img/255.0
                    img_list.append(img)
                    label_list.append(dir_counter)
    
                dir_counter += 1
        else:
            path = '../Dataset/baidu/valid_image/valid'
    
            # 对路径下的所有子文件夹中的所有jpg文件进行读取并存入到一个list中
            for child_dir in os.listdir(path):
                child_path = os.path.join(path, child_dir)
                for dir_image in os.listdir(child_path):
                    img = cv2.imread(os.path.join(child_path, dir_image))
                    img = img / 255.0
                    img_list.append(img)
                    label_list.append(dir_counter)
    
                dir_counter += 1
    
        # 返回的img_list转成了 np.array的格式
        X_train = np.array(img_list)
        Y_train = to_categorical(label_list, 9)
        # print('to_categorical之后Y_train的类型和形状:', type(Y_train), Y_train.shape)
    
        # 加载数据的时候 重新排序
        # print('X_train.shape, Y_train.shape:', X_train.shape, Y_train.shape)
        data_index = np.arange(X_train.shape[0])
        np.random.shuffle(data_index)
        data_index = data_index[:batch_size]
        x_batch = X_train[data_index, :, :, :]
        y_batch = Y_train[data_index, :]
    
        return x_batch, y_batch
    
    
    # 开始feed 数据并且训练数据
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for i in range(500000//batch_size):
            # 加载训练集和验证集
            img, img_label = load_satetile_image(batch_size, dataset='train')
            img_valid, img_valid_label = load_satetile_image(batch_size, dataset='vaild')
            # print('使用 mnist.train.next_batch加载的数据集形状', img.shape, type(img))
    
            # print('模型使用的是dropout的模型')
            dropout_rate = 0.5
            # print('经过 tf.reshape之后数据的形状以及类型是:', img.shape, type(img))
            if i % 20 == 0:
                train_accuracy = accuracy.eval(feed_dict={inputs: img, y: img_label, keep_prob: dropout_rate})
                print("step %d, training accuracy %g" % (i, train_accuracy))
            train_step.run(feed_dict={inputs: img, y: img_label, keep_prob: dropout_rate})
    
            # 输出验证集上的结果
            if i % 50 == 0:
                dropout_rate = 1
                valid_socre = accuracy.eval(feed_dict={inputs: img_valid, y: img_valid_label, keep_prob: dropout_rate})
                print("step %d, valid accuracy %g" % (i, valid_socre))
    
    
    
    
    

     

    然后是本节的核心代码: Inception v4

    第一: Inception v4代码比较咱们就直接按照整体的命名来看吧,从上面的左图来看和程序主要部分的命名,我们可以看到 inception_A、reduction_A、inception_B、reduction_B、inception_C,主要模块是正确的。

     

    第二: 初始的函数(inference)卷积核大小为 3 * 3   步长为1 * 1 和上图的右边的步长是有点不一致的。说句实话因为Inception是封装成块的, 具体的还真不好说。但是看看生成结果和之前的相差不大,所以这个模型可以直接用没问题的。

     

    # -*- coding: utf-8 -*-
    # @Time    : 2019/7/2 9:57
    # @Author  : YYLin
    # @Email   : 854280599@qq.com
    # @File    : inception_V4.py
    # 参考的代码链接 https://github.com/cena001plus/inception 有训练集和测试集
    import tensorflow as tf
    
    
    # 定义变量函数初始化函数
    def define_variable(shape, name):
        return tf.Variable(tf.truncated_normal(shape,stddev=0.1),name)
    
    
    # 最大下采样操作
    def max_pool(name, l_input, k1, k2):
        return tf.nn.max_pool(l_input, ksize=[1, k1, k1, 1], strides=[1, k2, k2, 1], padding='SAME', name=name)
    
    
    # network structure: inception_A
    def inception_A(input):
        p1f11 = 96
        p2f11 = 64
        p2f22 = 96
        p3f11 = 64
        p3f22 = 96
        p3f33 = 96
        p4f11 = 96
        path1 = tf.layers.conv2d(input, p1f11, 1, padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(input, p2f11, 1, padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(path2, p2f22, 3, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(input, p3f11, 1, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f22, 3, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f33, 3, padding='same', activation=tf.nn.relu)
        path4 = tf.layers.average_pooling2d(input, pool_size=3, strides=1, padding='same')
        path4 = tf.layers.conv2d(path4, p4f11, 1, padding='same', activation=tf.nn.relu)
        out = tf.concat((path1, path2, path3, path4), axis=-1)
        return out
    
    
    # network structure: Reduction_A
    def reduction_A(input):
        channel = 384
        path1 = tf.layers.max_pooling2d(input, pool_size=3, strides=2, padding='same')
        path2 = tf.layers.conv2d(input, channel, 3, strides=2, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(input, channel, 1, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, channel, 3, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, channel, 3, strides=2, padding='same', activation=tf.nn.relu)
        out = tf.concat((path1, path2, path3), axis=-1)
        return out
    
    
    # network structure: inception_B
    def inception_B(input):
        p1f11 = 384
        p2f11 = 192
        p2f22 = 224
        p2f33 = 256
        p3f11 = 192
        p3f22 = 192
        p3f33 = 224
        p3f44 = 224
        p3f55 = 256
        p4f11 = 128
        path1 = tf.layers.conv2d(input, p1f11, 1, padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(input, p2f11, 1, padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(path2, p2f22, [1, 7], padding='same',activation=tf.nn.relu)
        path2 = tf.layers.conv2d(path2, p2f33, [7, 1], padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(input, p3f11, 1, padding='same',activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f22, [1, 7], padding='same',activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f33, [7, 1], padding='same',activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f44, [1, 7], padding='same',activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f55, [7, 1], padding='same',activation=tf.nn.relu)
        path4 = tf.layers.average_pooling2d(input, pool_size=3, strides=1, padding='same')
        path4 = tf.layers.conv2d(path4, p4f11, 1, padding='same',activation=tf.nn.relu)
        out = tf.concat((path1, path2, path3, path4), axis=-1)
        return out
    
    
    # network structure: Reduction_B
    def reduction_B( input):
        p2f11 = 192
        p2f22 = 192
        p3f11 = 256
        p3f22 = 256
        p3f33 = 320
        p3f44 = 320
        path1 = tf.layers.max_pooling2d(input, pool_size=3, strides=2, padding='same')
        path2 = tf.layers.conv2d(input, p2f11, 1,  padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(path2, p2f22, 3, strides=2, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(input, p3f11, 1, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f22, [1, 7], padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f33, [7, 1], padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f44, 3, strides=2, padding='same', activation=tf.nn.relu)
        out = tf.concat((path1, path2, path3), axis=-1)
        return out
    
    
    # network structure: inception_C
    def inception_C(input):
        p1f11 = 256
        p2f11 = 384
        p2f11_1 = 256
        p2f11_2 = 256
        p3f11 = 384
        p3f22 = 448
        p3f33 = 512
        p3f33_1 = 256
        p3f33_2 = 256
        p4f11 = 256
        path1 = tf.layers.conv2d(input, p1f11, 1, padding='same', activation=tf.nn.relu)
        path2 = tf.layers.conv2d(input, p2f11, 1, padding='same',activation=tf.nn.relu)
        path2_1 = tf.layers.conv2d(path2, p2f11_1, [1, 3], padding='same', activation=tf.nn.relu)
        path2_2 = tf.layers.conv2d(path2, p2f11_2, [3, 1], padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(input, p3f11, 1, padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f22, [1, 3], padding='same', activation=tf.nn.relu)
        path3 = tf.layers.conv2d(path3, p3f33, [3, 1], padding='same', activation=tf.nn.relu)
        path3_1 = tf.layers.conv2d(path3, p3f33_1, [3, 1], padding='same', activation=tf.nn.relu)
        path3_2 = tf.layers.conv2d(path3, p3f33_2, [1, 3], padding='same', activation=tf.nn.relu)
        path4 = tf.layers.average_pooling2d(input, pool_size=3, strides=1, padding='same')
        path4 = tf.layers.conv2d(path4, p4f11, 1, padding='same', activation=tf.nn.relu)
        out = tf.concat((path1, path2_1, path2_2, path3_1, path3_2, path4), axis=-1)
        return out
    
    
    # 网络结构定义
    # 输入参数:images,image batch、4D tensor、tf.float32、[batch_size, width, height, channels]
    # 返回参数:logits, float、 [batch_size, n_classes]
    def inference(images, batch_size,  n_classes):
        w_conv1 = define_variable([3, 3, 3, 192], name="W")
        b_conv1 = define_variable([192], name="B")
        conv1 = tf.nn.conv2d(images, w_conv1, strides=[1, 1, 1, 1], padding='SAME')
        relu1 = tf.nn.relu(conv1 + b_conv1)
    
        pool1 = tf.nn.max_pool(relu1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1],padding='SAME')
    
        # inception_A
        # 35*35 grid
        inception_a1 = inception_A(pool1)
        inception_a2 = inception_A(inception_a1)
        inception_a3 = inception_A(inception_a2)
        inception_a4 = inception_A(inception_a3)
    
        # reduction_A
        # from 35*35 to 17*17
        reduction_a = reduction_A(inception_a4)
    
        # inception_B
        # 17*17 grid
        inception_b1 = inception_B(reduction_a)
        inception_b2 = inception_B(inception_b1)
        inception_b3 = inception_B(inception_b2)
        inception_b4 = inception_B(inception_b3)
        inception_b5 = inception_B(inception_b4)
        inception_b6 = inception_B(inception_b5)
        inception_b7 = inception_B(inception_b6)
    
        # reduction_B
        # from 17*17 to 8*8
        reduction_b = reduction_B(inception_b7)
    
        # inception_C
        # 8*8 grid
        inception_c1 = inception_C(reduction_b)
        inception_c2 = inception_C(inception_c1)
        inception_c3 = inception_C(inception_c2)
    
        net = tf.layers.average_pooling2d(inception_c3, 7, 1, name="avgpool")  # -> [batch, 1, 1, 768]
    
        # dropout层
        with tf.variable_scope('dropout') as scope:
            drop_out = tf.nn.dropout(net, 0.8)
            print('最后一层的卷积层的形状是:', drop_out.shape)
    
        # 原始数据的形状是(64, 7, 7, 1536)  经过修改之后的数据形状是(64, -1)
        reshape = tf.reshape(drop_out, shape=[batch_size, -1])
        dim = reshape.get_shape()[1].value
        weights1 = tf.Variable(tf.truncated_normal(shape=[dim, 1024], stddev=0.005, dtype=tf.float32),name='weights', dtype=tf.float32)
        biases1 = tf.Variable(tf.constant(value=0.1, dtype=tf.float32, shape=[1024]),name='biases', dtype=tf.float32)
        local6 = tf.nn.relu(tf.matmul(reshape, weights1) + biases1)
    
        weights = tf.Variable(tf.truncated_normal(shape=[1024, n_classes], stddev=0.005, dtype=tf.float32), name='softmax_linear', dtype=tf.float32)
        biases = tf.Variable(tf.constant(value=0.1, dtype=tf.float32, shape=[n_classes]), name='biases', dtype=tf.float32)
        logits = tf.add(tf.matmul(local6, weights), biases, name='softmax_linear')
    
        return logits
    

     

     Inception v4实验结果分析:

    注意一大堆红色 提示GPU不够的问题,对于程序员而言,再多的红色都是okay,只要不报错就可以。

    展开全文
  • 本文介绍了 Inception 家族的主要成员,包括 Inception v1、Inception v2 、Inception v3、Inception v4Inception-ResNet。它们的计算效率与参数效率在所有卷积架构中都是顶尖的。Inception 网络是CNN分类器发展...

    本文介绍了 Inception 家族的主要成员,包括 Inception v1、Inception v2 、Inception v3、Inception v4 和 Inception-ResNet。它们的计算效率与参数效率在所有卷积架构中都是顶尖的。

    Inception 网络是CNN分类器发展史上一个重要的里程碑。在 Inception 出现之前,大部分流行 CNN 仅仅是把卷积层堆叠得越来越多,使网络越来越深,以此希望能够得到更好的性能。

    例如AlexNet,GoogleNet、 VGG-Net、ResNet等都是通过加深网络的层次和深度来提高准确率。

    GoogLeNet 最大的特点就是使用了 Inception 模块,它的目的是设计一种具有优良局部拓扑结构的网络,即对输入图像并行地执行多个卷积运算或池化操作,并将所有输出结果拼接为一个非常深的特征图。因为 1*1、3*3 或 5*5 等不同的卷积运算与池化操作可以获得输入图像的不同信息,并行处理这些运算并结合所有结果将获得更好的图像表征。

    Inception常见的版本有:

    Inception v1

    Inception v2 和 Inception v3

    Inception v4 和 Inception-ResNet

    每个版本都是前一个版本的迭代进化。了解 Inception 网络的升级可以帮助我们构建自定义分类器,优化速度和准确率。

    Inception v1

    Inception v1首先是出现在《Going deeper with convolutions》这篇论文中,作者提出一种深度卷积神经网络 Inception,它在 ILSVRC14 中达到了当时最好的分类和检测性能。

    Inception v1的主要特点:一是挖掘了1 1卷积核的作用*,减少了参数,提升了效果;二是让模型自己来决定用多大的的卷积核。

    1* 1卷积

    1* 1卷积

    1* 1卷积不仅可以减少神经网络的参数量,还可以压缩通道数,大大提高了计算效率。

    把不同大小的卷积核组合在一起

    把不同的卷积核组合在一起,不仅可以增大感受野,而且还可以提高神经网络的鲁棒性。在一层里把不同大小的卷积核叠在一起后,意味着一层里可以产生不同大小的卷积核处理之后的效果,也意味着不用人为的来选择这一层要怎么卷,这个网络自己便会学习用什么样的卷积(或池化)操作最好。

    下面是卷积神经网络Inception模块的基本组成部分:

    Inception v2

    Inception v2 和 Inception v3 来自同一篇论文《Rethinking the Inception Architecture for Computer Vision》,作者提出了一系列能增加准确度和减少计算复杂度的修正方法。

    将5* 5卷积分解为两个3* 3卷积

    将 5×5 的卷积分解为两个 3×3 的卷积运算以提升计算速度。如此可以有效地只使用约(3x3 + 3x3)/(5x5)=72%的计算开销。下图可看出此替换的有效性。

    所以升级后的Inception模块如下图所示:

    最左侧前一版 Inception 模块中的 5×5 卷积变成了两个 3×3 卷积的堆叠。

    将 n*n 的卷积核尺寸分解为 1×n 和 n×1 两个卷积。

    例如,一个 3×3 的卷积等价于首先执行一个 1×3 的卷积再执行一个 3×1 的卷积。这样同样可以只使用约(1x3 + 3x1) / (3x3) = 67%的计算开销。下图是此替换的有效性。作者更进一步发挥想象,认为任一个nxn conv都可通过替换为两个分别为1xn与nx1的convs层来节省计算与内存。

    更新后的Inception模块如下图所示:

    此处如果 n=3,则与上一张图像一致。最左侧的 5x5 卷积可被表示为两个 3x3 卷积,它们又可以被表示为 1x3 和 3x1 卷积。

    模块中的滤波器组被扩展(即变得更宽而不是更深),以解决表征性瓶颈。如果该模块没有被拓展宽度,而是变得更深,那么维度会过多减少,造成信息损失。如下图所示:

    Inception v3

    Inception v3 整合了前面 Inception v2 中提到的所有升级,还使用了:

    RMSProp 优化器;

    Factorized 7x7 卷积;

    辅助分类器使用了 BatchNorm;

    标签平滑(添加到损失公式的一种正则化项,旨在阻止网络对某一类别过分自信,即阻止过拟合)。

    Inception v2和Inception v3最终模型

    Inception v4

    Inception v4 和 Inception -ResNet 在同一篇论文《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》中提出来。

    Inception v4网络结构

    Inception v4

    首先stem分支,可以直接看论文的结构图:

    然后接下来它们有三个主要的Inception 模块和Reduction模块,称为 A、B 和 C(和 Inception v2 不同,这些模块确实被命名为 A、B 和 C)。它们看起来和 Inception v2(或 v3)变体非常相似。

    Inception v4 引入了专用的「缩减块」(reduction block),它被用于改变网格的宽度和高度。早期的版本并没有明确使用缩减块,但也实现了其功能。

    缩减块 A(从 35x35 到 17x17 的尺寸缩减)和缩减块 B(从 17x17 到 8x8 的尺寸缩减)。这里参考了论文中的相同超参数设置(V,I,k)。

    直接看其网络结构:

    Inception-ResNet

    在该论文中,作者将Inception 架构和残差连接(Residual)结合起来。并通过实验明确地证实了,结合残差连接可以显著加速 Inception 的训练。也有一些证据表明残差 Inception 网络在相近的成本下略微超过没有残差连接的 Inception 网络。作者还通过三个残差和一个 Inception v4 的模型集成,在 ImageNet 分类挑战赛的测试集上取得了 3.08% 的 top-5 误差率。

    (左起)Inception ResNet 中的 Inception 模块 A、B、C。注意池化层被残差连接所替代,并在残差加运算之前有额外的 1x1 卷积。

    主要 inception 模块的池化运算由残差连接替代。然而,你仍然可以在缩减块中找到这些运算。缩减块 A 和 Inception v4 中的缩减块相同。

    具体Inception-resnet A、B、C各个模块网络结构详见原论文

    针对深网络结构设计的衰减因子

    如果卷积核的数量超过 1000,则网络架构更深层的残差单元将导致网络崩溃。因此,为了增加稳定性,作者通过 0.1 到 0.3 的比例缩放残差激活值。

    激活值通过一个常数进行比例缩放,以防止网络崩溃。

    Inception-ResNet v1结构

    结果精度对比

    展开全文
  • Inception V4网络结构和代码解析

    千次阅读 2018-08-14 14:41:19
    学习了Inception V4卷积神经网络,总结一下对Inception V4网络结构和主要代码的理解。  GoogLeNet对网络中的传统卷积层进行了修改,提出了被称为 Inception 的结构,用于增加网络深度和宽度,提高深度神经网络性能...

           学习了Inception V4卷积神经网络,总结一下对Inception V4网络结构和主要代码的理解。

          GoogLeNet对网络中的传统卷积层进行了修改,提出了被称为 Inception 的结构,用于增加网络深度和宽度,提高深度神经网络性能。从Inception V1Inception V44个更新版本,每一版的网络在原来的基础上进行改进,提高网络性能。本文介绍Inception V4的网络结构和主要代码,Inception V4研究了Inception ModuleReduction Module的组合,通过多次卷积和非线性变化,极大的提升了网络性能。

     

    1  非Inception Module的普通卷积层

          首先定义一个非Inception Module的普通卷积层函数inception_v4_base,输入参数inputs为图片数据的张量。第1个卷积层的输出通道数为32,卷积核尺寸为【3x3】,步长为2,padding模式是VALID,第1个卷积层之后的张量尺寸变为(299-3)/2+1=149,即【149x149x32】。第2个卷积层的输出通道数为32,卷积核尺寸为【3x3】,步长为1,padding模式是VALID,第2个卷积层之后的张量尺寸变为(149-3)/1+1=147,即【147x147x32】。第3个卷积层的输出通道数为64,卷积核尺寸为【3x3】,步长为1,padding模式是默认的SAME,第3个卷积层之后的张量尺寸不变,输出通道数改变,最后张量尺寸变为【147x147x64】。这几个普通的卷积层主要使用了3x3的小卷积核,小卷积核可以低成本的跨通道的对特征进行组合。

    def inception_v4_base(inputs, scope=None):
        with tf.variable_scope(scope, 'InceptionV4', [inputs]):
            with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],stride=1, padding='SAME'):   # 299 x 299 x 3           
                net = slim.conv2d(inputs, 32, [3, 3], stride=2,padding='VALID', scope='Conv2d_1a_3x3')       # 149 x 149 x 32         
                net = slim.conv2d(net, 32, [3, 3], padding='VALID',scope='Conv2d_2a_3x3')                    # 147 x 147 x 32                 
                net = slim.conv2d(net, 64, [3, 3], scope='Conv2d_2b_3x3')                                    # 147 x 147 x 64           

     

    2  三个Inception模块组

            普通卷积层之后是三个连续的Inception Module,分别是:Mixed_3a,Mixed_4a,Mixed_5a,每个模块有多个分支。第1个Inception Module Mixed_3a的第1个分支是【3x3】的最大池化,第2个分支是输出通道数为96的【3x3】卷积,步长为2,最后用tf.concat将2个分支的输出合并在一起,输出通道之和为64+96=160,张量尺寸变为(147-3)/2+1=73,即【73x73x160】。第2个Inception Module Mixed_4a的第1个分支经过【1x1】和【3x3】两次卷积,第2个分支经过【1x1】、【1x7】、【7x1】和【3x3】四次卷积,张量尺寸最后变为【71x71x192】。第3个Inception Module Mixed_5a的第1个分支是输出通道数为192的【3x3】卷积,第2个分支是【3x3】的最大池化,卷积和最大池化的步长都是2,且padding模式是VALID,因此尺寸减小一半,最后张量尺寸变为【35x35x384】。

                with tf.variable_scope('Mixed_3a'):
                    with tf.variable_scope('Branch_0'):
                         branch_0 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID',scope='MaxPool_0a_3x3')
                    with tf.variable_scope('Branch_1'):
                         branch_1 = slim.conv2d(net, 96, [3, 3], stride=2, padding='VALID',scope='Conv2d_0a_3x3')
                    net = tf.concat(axis=3, values=[branch_0, branch_1])                          # 73 x 73 x 160
             
                with tf.variable_scope('Mixed_4a'):
                    with tf.variable_scope('Branch_0'):
                        branch_0 = slim.conv2d(net, 64, [1, 1], scope='Conv2d_0a_1x1')
                        branch_0 = slim.conv2d(branch_0, 96, [3, 3], padding='VALID', scope='Conv2d_1a_3x3')
                    with tf.variable_scope('Branch_1'):
                        branch_1 = slim.conv2d(net, 64, [1, 1], scope='Conv2d_0a_1x1')
                        branch_1 = slim.conv2d(branch_1, 64, [1, 7], scope='Conv2d_0b_1x7')
                        branch_1 = slim.conv2d(branch_1, 64, [7, 1], scope='Conv2d_0c_7x1')
                        branch_1 = slim.conv2d(branch_1, 96, [3, 3], padding='VALID',scope='Conv2d_1a_3x3')
                    net = tf.concat(axis=3, values=[branch_0, branch_1])                        # 71 x 71 x 192
               
                with tf.variable_scope('Mixed_5a'):
                    with tf.variable_scope('Branch_0'):
                        branch_0 = slim.conv2d(net, 192, [3, 3], stride=2, padding='VALID',scope='Conv2d_1a_3x3')
                    with tf.variable_scope('Branch_1'):
                        branch_1 = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID',scope='MaxPool_1a_3x3')
                    net = tf.concat(axis=3, values=[branch_0, branch_1])                       # 35 x 35 x 384 

     

    Inception Module和Reduction Module的组合

           三个Inception模块组之后是三个连续的Inception ModuleReduction Module的组合。每个组合都定义了block_inceptionblock_reduction函数,block_inception函数保持图片尺寸不变,只是对网络进行非线性变换,block_reduction函数缩减图片尺寸,同时对网络进行非线性变化,两者的组合更好的提炼网络特征,极大的提升了网络的性能。

       第一个模块组合Inception-A blocksReduction-A block,调用了四次block_inception_a函数,生成Mixed_5bMixed_5cMixed_5dMixed_5e四个模块。每个block_inception_a函数有4个分支,第1个分支是1个【1x1】卷积,第2个分支是1个【1x1】卷积和1个【3x3】卷积,第3个分支是1个【1x1】卷积和2个【3x3】卷积,第4个分支是1个【3x3】的最大池化和1个【1x1】卷积,因为padding模式是SAME,张量尺寸不变,还是【35x35x384】。调用了1次block_reduction_a函数,block_reduction_a函数有3个分支,第1个分支是1个3x3】卷积,第2个分支是1个【1x1】卷积和2个【3x3】卷积,第3个分支是1个【3x3】的最大池化,padding模式是VALID,步长为2,所以张量尺寸缩小一半,最后变为【17x17x1024】。

    def block_inception_a(inputs, scope=None, reuse=None):
        with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d],stride=1, padding='SAME'):
            with tf.variable_scope(scope, 'BlockInceptionA', [inputs], reuse=reuse):
                with tf.variable_scope('Branch_0'):
                    branch_0 = slim.conv2d(inputs, 96, [1, 1], scope='Conv2d_0a_1x1')
                with tf.variable_scope('Branch_1'):
                    branch_1 = slim.conv2d(inputs, 64, [1, 1], scope='Conv2d_0a_1x1')
                    branch_1 = slim.conv2d(branch_1, 96, [3, 3], scope='Conv2d_0b_3x3')
                with tf.variable_scope('Branch_2'):
                    branch_2 = slim.conv2d(inputs, 64, [1, 1], scope='Conv2d_0a_1x1')
                    branch_2 = slim.conv2d(branch_2, 96, [3, 3], scope='Conv2d_0b_3x3')
                    branch_2 = slim.conv2d(branch_2, 96, [3, 3], scope='Conv2d_0c_3x3')
                with tf.variable_scope('Branch_3'):
                    branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3')
                    branch_3 = slim.conv2d(branch_3, 96, [1, 1], scope='Conv2d_0b_1x1')
                return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3])
    
    def block_reduction_a(inputs, scope=None, reuse=None):
          with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d],stride=1, padding='SAME'):
                with tf.variable_scope(scope, 'BlockReductionA', [inputs], reuse=reuse):
                    with tf.variable_scope('Branch_0'):
                        branch_0 = slim.conv2d(inputs, 384, [3, 3], stride=2, padding='VALID',scope='Conv2d_1a_3x3')
                    with tf.variable_scope('Branch_1'):
                        branch_1 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1')
                        branch_1 = slim.conv2d(branch_1, 224, [3, 3], scope='Conv2d_0b_3x3')
                        branch_1 = slim.conv2d(branch_1, 256, [3, 3], stride=2,padding='VALID',scope='Conv2d_1a_3x3')
                    with tf.variable_scope('Branch_2'):
                        branch_2 = slim.max_pool2d(inputs, [3, 3], stride=2, padding='VALID',scope='MaxPool_1a_3x3')
                    return tf.concat(axis=3, values=[branch_0, branch_1, branch_2])
    
    # 4 x Inception-A blocks
    for idx in range(4):
        block_scope = 'Mixed_5' + chr(ord('b') + idx)
        net = block_inception_a(net, block_scope)           # 35 x 35 x 384
    
    # Reduction-A block
    net = block_reduction_a(net, 'Mixed_6a')                # 17 x 17 x 1024

       第二个模块组合Inception-B blocksReduction-B block,调用了七次block_inception_b函数,生成Mixed_6bMixed_6cMixed_6dMixed_6eMixed_6fMixed_6gMixed_6h七个模块。每个block_inception_b函数有4个分支。第1个分支是1个【1x1】卷积,。第2个分支是1个【1x1】卷积、1个【1x7】卷积和1个【7x1】卷积。第3个分支是1个【1x1】卷积、1个【7x1】卷积、1个【1x7】卷积、再1个【7x1】卷积、1个【1x7】卷积。第4个分支是1个【3x3】的最大池化和1个【1x1】卷积,因为padding模式是SAME,张量尺寸不变,还是17x17x1024】。调用了1次block_reduction_b函数,block_reduction_b函数有3个分支,第1个分支是1个【1x1】卷积和1个3x3】卷积,第2个分支是1个【1x1】卷积、1个【1x7】卷积、1个【7x1】卷积和1个【3x3】卷积,第3个分支是1个【3x3】的最大池化,padding模式是VALID,步长为2,所以张量尺寸缩小一半,最后变为【8x8x1536】。

    def block_inception_b(inputs, scope=None, reuse=None):
        with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d],stride=1, padding='SAME'):
            with tf.variable_scope(scope, 'BlockInceptionB', [inputs], reuse=reuse):
                with tf.variable_scope('Branch_0'):
                    branch_0 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1')
                with tf.variable_scope('Branch_1'):
                    branch_1 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1')
                    branch_1 = slim.conv2d(branch_1, 224, [1, 7], scope='Conv2d_0b_1x7')
                    branch_1 = slim.conv2d(branch_1, 256, [7, 1], scope='Conv2d_0c_7x1')
                with tf.variable_scope('Branch_2'):
                    branch_2 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1')
                    branch_2 = slim.conv2d(branch_2, 192, [7, 1], scope='Conv2d_0b_7x1')
                    branch_2 = slim.conv2d(branch_2, 224, [1, 7], scope='Conv2d_0c_1x7')
                    branch_2 = slim.conv2d(branch_2, 224, [7, 1], scope='Conv2d_0d_7x1')
                    branch_2 = slim.conv2d(branch_2, 256, [1, 7], scope='Conv2d_0e_1x7')
                with tf.variable_scope('Branch_3'):
                    branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3')
                    branch_3 = slim.conv2d(branch_3, 128, [1, 1], scope='Conv2d_0b_1x1')
                return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3])
    
    def block_reduction_b(inputs, scope=None, reuse=None):
        with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d],stride=1, padding='SAME'):
            with tf.variable_scope(scope, 'BlockReductionB', [inputs], reuse=reuse):
                with tf.variable_scope('Branch_0'):
                    branch_0 = slim.conv2d(inputs, 192, [1, 1], scope='Conv2d_0a_1x1')
                    branch_0 = slim.conv2d(branch_0, 192, [3, 3], stride=2,padding='VALID', scope='Conv2d_1a_3x3')
                with tf.variable_scope('Branch_1'):
                    branch_1 = slim.conv2d(inputs, 256, [1, 1], scope='Conv2d_0a_1x1')
                    branch_1 = slim.conv2d(branch_1, 256, [1, 7], scope='Conv2d_0b_1x7')
                    branch_1 = slim.conv2d(branch_1, 320, [7, 1], scope='Conv2d_0c_7x1')
                    branch_1 = slim.conv2d(branch_1, 320, [3, 3], stride=2,padding='VALID', scope='Conv2d_1a_3x3')
                with tf.variable_scope('Branch_2'):
                    branch_2 = slim.max_pool2d(inputs, [3, 3], stride=2, padding='VALID',scope='MaxPool_1a_3x3')
                return tf.concat(axis=3, values=[branch_0, branch_1, branch_2])
    
    # 7 x Inception-B blocks
    for idx in range(7):
        block_scope = 'Mixed_6' + chr(ord('b') + idx)
        net = block_inception_b(net, block_scope)           # 17 x 17 x 1024
    
    # Reduction-B block
    net = block_reduction_b(net, 'Mixed_7a')                # 8 x 8 x 1536

        第三个模块组合只有Inception-C blocks,主要是对网络的非线性变换。调用了三次block_inception_c函数,生成Mixed_7bMixed_7cMixed_7d三个模块。每个block_inception_c函数有4个分支。第1个分支是1个【1x1】卷积,。第2个分支是1个【1x1】卷积,然后1个【1x3】卷积和1个【3x1】卷积拼接。第3个分支是1个【1x1】卷积、1个【3x1】卷积、1个【1x3】卷积,然后1个【1x3】卷积和1个【3x1】卷积拼接。第4个分支是1个【3x3】的最大池化和1个【1x1】卷积,因为padding模式是SAME,张量尺寸不变,还是【8x8x1536

    def block_inception_c(inputs, scope=None, reuse=None):
        with slim.arg_scope([slim.conv2d, slim.avg_pool2d, slim.max_pool2d],stride=1, padding='SAME'):
            with tf.variable_scope(scope, 'BlockInceptionC', [inputs], reuse=reuse):
                with tf.variable_scope('Branch_0'):
                    branch_0 = slim.conv2d(inputs, 256, [1, 1], scope='Conv2d_0a_1x1')
                with tf.variable_scope('Branch_1'):
                    branch_1 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1')
                    branch_1 = tf.concat(axis=3, values=[slim.conv2d(branch_1, 256, [1, 3], scope='Conv2d_0b_1x3'),
                                                         slim.conv2d(branch_1, 256, [3, 1], scope='Conv2d_0c_3x1')])
                with tf.variable_scope('Branch_2'):
                    branch_2 = slim.conv2d(inputs, 384, [1, 1], scope='Conv2d_0a_1x1')
                    branch_2 = slim.conv2d(branch_2, 448, [3, 1], scope='Conv2d_0b_3x1')
                    branch_2 = slim.conv2d(branch_2, 512, [1, 3], scope='Conv2d_0c_1x3')
                    branch_2 = tf.concat(axis=3, values=[slim.conv2d(branch_2, 256, [1, 3], scope='Conv2d_0d_1x3'),
                                                         slim.conv2d(branch_2, 256, [3, 1], scope='Conv2d_0e_3x1')])
                with tf.variable_scope('Branch_3'):
                    branch_3 = slim.avg_pool2d(inputs, [3, 3], scope='AvgPool_0a_3x3')
                    branch_3 = slim.conv2d(branch_3, 256, [1, 1], scope='Conv2d_0b_1x1')
                return tf.concat(axis=3, values=[branch_0, branch_1, branch_2, branch_3])
    
    # 3 x Inception-C blocks
    for idx in range(3):
        block_scope = 'Mixed_7' + chr(ord('b') + idx)
        net = block_inception_c(net, block_scope)                   # 8 x 8 x 1536      

     

    4  AuxLogits、全局平均池化、Softmax分类

             Inception V4网络的最后一部分是辅助分类AuxLogits、全局平均池化、Softmax分类。首先是AuxLogits,作为辅助分类的节点。先通过end_points['Mixed_6h']得到Mixed_6h后的特征张量【17x17x1024】,之后接一个【5x5】的平均池化,步长为3,padding为VALID,张量尺寸从【17x17x1024】变为【5x5x1024】。接着连接一个输出通道为128的【1x1】卷积和输出通道为768的【5x5】卷积,输出尺寸变为【1x1x768】,然后通过slim.flatten转换为【1x768】的二维向量,最后是一个输出通道数为num_classes的全连接层,变为【1x1000】的二维向量,并将辅助分类节点的输出存储到字典表end_points中。

        end_points = {}
        with tf.variable_scope(scope, 'InceptionV4', [inputs], reuse=reuse) as scope:
            with slim.arg_scope([slim.batch_norm, slim.dropout],is_training=is_training):
                net, end_points = inception_v4_base(inputs, scope=scope)
                with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d],stride=1, padding='SAME'):
                    if create_aux_logits and num_classes:
                        with tf.variable_scope('AuxLogits'):                        
                            aux_logits = end_points['Mixed_6h']                # 17 x 17 x 1024
                            aux_logits = slim.avg_pool2d(aux_logits, [5, 5], stride=3,padding='VALID',scope='AvgPool_1a_5x5')
                            aux_logits = slim.conv2d(aux_logits, 128, [1, 1], scope='Conv2d_1b_1x1')
                            aux_logits = slim.conv2d(aux_logits, 768, aux_logits.get_shape()[1:3],padding='VALID', scope='Conv2d_2a')
                            aux_logits = slim.flatten(aux_logits)
                            aux_logits = slim.fully_connected(aux_logits, num_classes,activation_fn=None,scope='Aux_logits')
                            end_points['AuxLogits'] = aux_logits

            对最后一个卷积层的输出Mixed_7d进行一个【8x8】的全局平均池化,padding为VALID,输出张量从【8 x 8 x 1536】变为【1 x 1 x 1536】。然后连接一个Dropout层,再通过slim.flatten转换为【1x1536】的二维向量。最后是一个输出通道数为num_classes的全连接层,变为【1x1000】的二维向量。再用Softmax得到最终分类结果。返回分类结果logits和包含各个卷积后的特征图字典表end_points。

                    with tf.variable_scope('Logits'):                   
                        kernel_size = net.get_shape()[1:3]    # net: 8 x 8 x 1536
                        if kernel_size.is_fully_defined():
                            net = slim.avg_pool2d(net, kernel_size, padding='VALID',scope='AvgPool_1a')
                        else:
                            net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool')
                        end_points['global_pool'] = net                   
                        if not num_classes:
                            return net, end_points
                                           
                        net = slim.dropout(net, dropout_keep_prob, scope='Dropout_1b')  # net: 1 x 1 x 1536
                        net = slim.flatten(net, scope='PreLogitsFlatten')
                        end_points['PreLogitsFlatten'] = net
                          
                        logits = slim.fully_connected(net, num_classes, activation_fn=None,scope='Logits') # (1 x 1000)
                        end_points['Logits'] = logits
                        end_points['Predictions'] = tf.nn.softmax(logits, name='Predictions')
                return logits, end_points

     

    版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/fxfviolet/article/details/81666396

    展开全文
  • 在介绍Inception v4之前,首先说明一下Inception v4没有使用残差学习的思想。大部分小伙伴对Inception v4存在一个误解,认为它是Inception module与残差学习的结合,其实并不是这样,Inception ...
  • 【Keras-Inception v4】CIFAR-10

    千次阅读 2019-01-02 20:59:08
    系列连载目录 请查看博客 《Paper》 4.1 小节 【Keras】Classification in CIFAR-10 系列连载 学习借鉴 ...Inception v4 Caffe 代码:https://github.com/soeaver/caffe-model/blob/master/cls/i...
  • Inception v4, Inception-ResNet 论文笔记

    千次阅读 2018-06-03 22:51:33
    Inception v4, Inception-ResNet:Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning 摘要:最近几年,非常深的卷积网络已经成为图像识别性能大提高的核心。一个例子是Inception...
  • inception V4

    2019-03-10 16:34:45
    iniception和resnet之间的关系可以直接参考这篇文章,写的很清楚https://www.cnblogs.com/shouhuxianjian/p/7786760.html
  • Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》 2016,Google,Inception V4Inception ResNet V1、V2 Inception结构有着良好的性能,且计算量低。Residual ...
  • 最近在学习Inception系列的网络,把自己的总结一下。 2014年GoogleNet(论文地址)取得了第一名,和VGG网络同年,那时候的Inception Net称为V1版本,我们来看一下Inception V1的Inception module。这个左边的是一般...
  • Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning_v1
  • Inception v4的网络结构

    2021-08-21 11:15:13
    一、Inception v4整体架构 Inception v4的整体框架如图9所示: 分为6大模块:Stem;Inception-A、B、C;Reduction-A、B。每个模块针对性的设计。这也是缺点吧,适用性很差。换一个数据集谁知道行不行,谁知道改...
  • 2014年,GoogLeNet和VGG是当年ImageNet挑战赛(ILSVRC14)的双雄,GoogLeNet获得了第一名、VGG获得了第二名,这两类模型结构的共同特点是层次更深了。VGG继承了LeNet以及AlexNet的一些框架结构(详见 大话CNN经典模型...
  • 在残差逐渐当道时,google开始研究inception和残差网络的性能...Inception-v4, Inception-ResNet andthe Impact of Residual Connections on Learning论证残差和Inception结合对性能的影响(抛实验结果)1.残差连接能...
  • Inception的系列文章: 1. Inception v1 -《Going deeper with convolutions》 https://arxiv.org/abs/1409.4842 2. Inception v2 - 《Batch Normalization: Accelerating Deep Network Training by Reducing ...
  • 一、前言 读完GoogLeNet的四篇论文之后,一是感觉...因此这里只对Inception V4结构做一下简单的说明,有兴趣的可以去单独看以下Inception V4这篇论文。 二、Inception V4网络结构的细节 Inception V4仅仅是一些组
  • inception v4 -resnet

    2019-06-08 23:19:48
    在残差逐渐当道时,google开始研究inception和残差网络的性能差异以及结合...Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning 论证残差和Inception结合对性能的影响(抛实...
  • 介绍Inception系列模型设计的核心思想讲至Inception v3基本已经尽了。但2015年Resnet的提出及其在ILSVRC 2015的成功使得Google team开始重新评估CNN深度模型的设计。他们自然不肯屈服于Resnet的强大,同行相轻,古今...
  • [paper] Inception V4

    2018-09-27 14:28:24
    Inception V4 论文名称:Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning 论文地址:https://arxiv.org/abs/1602.07261
  • Inception v4

    2018-08-12 16:04:22
    Inception v4主要利用残差连接(Residual Connection)来改进v3结构,代表作为,Inception-ResNet-v1,Inception-ResNet-v2,Inception-v4 论文地址: Inception[V4]: Inception-v4, Inception-ResNet and the ...
  • Inception v4 & Inception-ResNet:https://arxiv.org/abs/1602.07261 前言   主要受ResNet 网络的启发,他们基于inception v3的基础上,引入了残差结构,提出了inception-resnet-v1和inception-resnet-v2,...
  • https://www.jianshu.com/p/006248a3fd7f 转载于:https://www.cnblogs.com/leebxo/p/10431614.html
  • 论文地址:Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning 此论文主要是作者尝试将inception与residual结合,而提出了inception-resnet-v1和inception-resnet-v2网络,并且...
  • Sina Weibo:小锋子Shawn Tencent E-mail:403568338@qq.com ...Inception和ResNet的结合。另外,v1-v4,历时一年多,谷歌高产啊,1412-1602。 [1] Inception-v4, Inception-ResNet ...
  • GoogLeNet Inception v4

    2021-11-14 14:03:23
    这篇文章在Inception v3的基础上,再次将网络加深加宽,提出了Inception v4,并且研究了Inception结构与ResNet的结合,提出了Inception v3的变体Inception-ResNet-v1,以及Inception v4的变体Inceptio
  • Google的Inception是比较特别的网络结构,利用多个size不同的卷积核对input进行处理,最后在channel上进行拼接。...本文主要很浅很浅地介绍下v4以及与ResNet相结合的网络。(因为Inception的motiv...
  • Keras入门之Inception-V4

    千次阅读 2018-12-11 17:05:17
    文章目录1.... Inception-resnet-v22.1 Inception-resnet-v1的组成模块2.2 Inception-resnet-v2的组成模块3. 模型训练4. 代码4.1 Inception-V44.2 inception_resnet_v14.3 inception_resnet_v2 在下...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,032
精华内容 1,212
关键字:

inceptionv4

友情链接: HDU1001-Hdu-Girls-Day.rar