tensorflow梳理(二)

1. inception块

inception网络的思路是从同一个节点分别进行不同卷积核的卷积操作,进行拼接来提取特征。网络的输入都是[批次,图像的高,图像的宽,通道数 ],以第四维度进行拼接即[3],要求前面三个维度是一致才可以拼接,就跟叠凳子一样,一样大小的凳子才能叠放在一起。

随便写了个例子,比较粗糙,看网上都是那种建立磊一个命名空间的方法方式,google的inception网络具体细节输入输出参数、卷积核的个数得具体实现的时候看。1×3卷积+3*1卷积取代替一个3×3卷积,卷积参数会少很多。 tf.layers.conv2d中kernel_size参数,即可以写成kernel_size=3,代表3×3卷积核,也可以kernel_size=[1,3] 代表1×3的卷积核。

    image = tf.random_normal([2,112, 112, 3])
    conv1 = tf.layers.conv2d(image, filters=64, kernel_size=3, strides=(1, 1), padding='SAME',
                             name='conv1')

    branch_0 = tf.layers.conv2d(conv1,filters=48,kernel_size=1,strides=(1,1),padding='SAME',
                                name='part_1_branch_0_1')

    branch_1 = tf.layers.average_pooling2d(inputs=conv1, pool_size=[2, 2], strides=1,padding='SAME',
                                           name='part_1_branch_1_1')
    branch_1 = tf.layers.conv2d(branch_1,filters=48,kernel_size=1,strides=(1,1),padding='SAME',
                                name='part_1_branch_1_2')

    branch_2 = tf.layers.conv2d(conv1, filters=48, kernel_size=1, strides=(1, 1), padding='SAME',
                                name='part_1_branch_2_1')
    branch_2 = tf.layers.conv2d(branch_2, filters=48, kernel_size=3, strides=(1, 1), padding='SAME',
                                name='part_1_branch_2_3')

    branch_3 = tf.layers.conv2d(conv1, filters=48, kernel_size=1, strides=(1, 1), padding='SAME',
                                name='part_1_branch_3_1')
    branch_3 = tf.layers.conv2d(branch_3, filters=48, kernel_size=3, strides=(1, 1), padding='SAME',
                                name='part_1_branch_3_2')
    branch_3 = tf.layers.conv2d(branch_3, filters=48, kernel_size=3, strides=(1, 1), padding='SAME',
                                name='part_1_branch_3_3')

    #前几个维度要一样才可以拼接[3]
    net = tf.concat([branch_0, branch_1, branch_2, branch_3], 3)

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        writer = tf.summary.FileWriter("logs/", sess.graph)
        print(net.get_shape()) #[2,112,112,192],192=48+48+48+48

 

tensorflow梳理(二) 

2.ResNet残差块

残差块的思想就是一条路不做特征处理,一条路做卷积特征处理,然后将两部分相加,让网络自己决定这个残差块是做处理好还是不做处理好。残差网络是参数相加,即tf.add函数。H(x)=F(x)+x。

具体实现还得看具体的输入图像大小和batch_size,这里用到了批量规范化和leaky_relu**函数是参照darknet53的残差层。

    image = tf.random_normal([2,112, 112, 3])
    conv0 = tf.layers.conv2d(image, filters=64, kernel_size=3, strides=(1, 1), padding='SAME',name='conv0')
    bnorm0 = tf.layers.batch_normalization(conv0, training=True, name='bnorm0')
    leaky0 = tf.nn.leaky_relu(bnorm0,name='leaky0')

    conv1 = tf.layers.conv2d(leaky0, filters=32, kernel_size=3, strides=(1, 1), padding='SAME',name='conv1')
    bnorm1 = tf.layers.batch_normalization(conv1, training=True, name='bnorm1')
    leaky1 = tf.nn.leaky_relu(bnorm1,name='leaky1')

    conv2 = tf.layers.conv2d(leaky1, filters=64, kernel_size=3, strides=(1, 1), padding='SAME', name='conv2')
    bnorm2 = tf.layers.batch_normalization(conv2, training=True, name='bnorm2')
    leaky2 = tf.nn.leaky_relu(bnorm2, name='leaky2')

    net = tf.add(leaky0,leaky2,name='add_1')


    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        writer = tf.summary.FileWriter("logs/", sess.graph)
        print(net.get_shape()) # 2,112,112,64

tensorflow梳理(二)