目标检测领域的实例分割网络 PSPnet,基于像素级的分类,提出了一种金字塔池化模块,金字塔层级的数量和每一层的大小都可以进行调整

主题结构是一个提去特征的基础网络(resnet/mobilenet)+金字塔池化。

项目中为了减小网络参数大小和部署方便,backbone采用的mobilenetv1。

mobilenet_v1.py代码(mobilenet_v1输出 f1,f2,f3,f4,f5不同尺度的特征)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @time: 2020/6/22 19:27"""
标准的mobilenet_v1
只能接受输入224*224大小的图片
输出 f1,f2,f3,f4,f5不同尺度的特征图"""import tensorflow as tf
import tensorflow.contrib.slim as slimdef mobilenet(inputs,num_classes=100,is_training=True,width_multiplier=1,scope='mobilenet'):""":param inputs: [batch_size,h,w,c]:param num_classes::param is_training::param width_multiplier::param scope::return: logits: the pre_softmax activationsend_points: 包含了特征图的dict"""def _depthwise_separable_conv(inputs,num_pwc_filters,width_multiplier,sc,downsample=False):"""depth-wise separable 卷积层:param inputs::param num_pwc_filters: 点卷积和的个数:param width_multiplier::param sc:命名空间:param dowmnsample::return:"""num_pwc_filters = round(num_pwc_filters * width_multiplier)_stride = 2 if downsample else 1 # 如果下采样就为2,否则为1# skip pointwise by setting num_outputs=None ,# pointwise 卷积的卷积核个数,如果为空,将跳过pointwise卷积的步骤.# 深度可分离卷积depthwise_conv = slim.separable_convolution2d(inputs,num_outputs=None,stride=_stride,depth_multiplier=1,kernel_size=[3, 3],scope=sc + '/depthwise_conv')bn = slim.batch_norm(depthwise_conv, scope=sc + '/dw_batch_norm')#点卷积 就是1*1的普通卷积pointwise_conv = slim.conv2d(bn,num_pwc_filters,kernel_size=[1, 1],scope=sc + '/pointwise_conv')bn = slim.batch_norm(pointwise_conv, scope=sc + '/pw_batch_norm')return bnwith tf.variable_scope(scope) as sc:end_points_collection=sc.name+'_end_points'with slim.arg_scope([slim.conv2d,slim.separable_convolution2d],activation_fn=None,outputs_collections=[end_points_collection]):with slim.arg_scope([slim.batch_norm],is_training=is_training,activation_fn=tf.nn.relu,fused=True):net=slim.conv2d(inputs,round(32*width_multiplier),[3,3],stride=2,padding='SAME',scope='conv_1') # [batch_size,h/2,w/2,32]net=slim.batch_norm(net,scope='conv_1/batch_norm')net=_depthwise_separable_conv(net,64,width_multiplier,sc='conv_ds_2') # [batch_size,h/2,w/2,64]net=_depthwise_separable_conv(net,128,width_multiplier,downsample=True,sc='conv_ds_3')# 下采样 [batch_size,h/4,w/4,128]net=_depthwise_separable_conv(net,128,width_multiplier,sc='conv_ds_4') #[batch_size,h/4,w/4,128]net = _depthwise_separable_conv(net, 256, width_multiplier, downsample=True, sc='conv_ds_5')  # 下采样 [batch_size,h/8,w/8,256]net=_depthwise_separable_conv(net,256,width_multiplier,sc='conv_ds_6') #[batch_size,h/8,w/8,256]net = _depthwise_separable_conv(net, 512, width_multiplier, downsample=True, sc='conv_ds_7')  # 下采样 # [batch_size,h/16,w/16,256]net = _depthwise_separable_conv(net, 512, width_multiplier, sc='conv_ds_8') # [batch_size,h/16,w/16,512]net = _depthwise_separable_conv(net, 512, width_multiplier, sc='conv_ds_9') # [batch_size,h/16,w/16,512]net = _depthwise_separable_conv(net, 512, width_multiplier, sc='conv_ds_10') # [batch_size,h/16,w/16,512]net = _depthwise_separable_conv(net, 512, width_multiplier, sc='conv_ds_11')# [batch_size,h/16,w/16,512]net = _depthwise_separable_conv(net, 512, width_multiplier, sc='conv_ds_12')# [batch_size,h/16,w/16,512]net = _depthwise_separable_conv(net, 1024, width_multiplier, downsample=True, sc='conv_ds_13')# [batch_size,h/32,w/32,1024]net = _depthwise_separable_conv(net, 1024, width_multiplier, sc='conv_ds_14')# [batch_size,h/32,w/32,1024]net=slim.avg_pool2d(net,[7,7],scope='avg_pool_15') # [batch_size,h/32*7,w/32*7,1024]#end_points=slim.utils.convert_collection_to_dict(end_points_collection)# net=tf.squeeze(net,[1,2],name='SpatialSqueeze')# end_points['squeeze']=net# logits=slim.fully_connected(net,num_classes,activation_fn=None,scope='fc_16')# predictions=slim.softmax(logits,scope='Predictions')## end_points['Logits']=logits# end_points['Predictions']=predictionsf1=end_points['mobilenet/conv_ds_2/pointwise_conv'] #[None,112,112,64]f2=end_points['mobilenet/conv_ds_4/pointwise_conv']#[None,56,56,128]f3=end_points['mobilenet/conv_ds_6/pointwise_conv'] #[None,28,28,256]f4=end_points['mobilenet/conv_ds_12/pointwise_conv']  #[None.14,14,512]f5=end_points['mobilenet/conv_ds_14/pointwise_conv']return inputs,  [f1 , f2 , f3 , f4 , f5 ]
mobilenet.default_image_size = 224def mobilenet_arg_scope(weight_decay=0.0):"""定义默认的scope参数:param weight_decay:  正则的衰减率:return:"""with slim.arg_scope([slim.convolution2d, slim.separable_convolution2d],weights_initializer=slim.initializers.xavier_initializer(),biases_initializer=slim.init_ops.zeros_initializer(),weights_regularizer=slim.l2_regularizer(weight_decay)) as sc:return scif __name__ == '__main__':batch_size = 5height, width = 224, 224num_classes = 100sess = tf.InteractiveSession()sess.run(tf.global_variables_initializer())inputs = tf.random_uniform((batch_size, height, width, 3))inputs_2,  [f1 , f2 , f3 , f4 , f5 ] = mobilenet(inputs, num_classes)

打印出f1,f2,f3,f4,f5的shape

f1: Tensor("mobilenet/conv_ds_2/pointwise_conv/BiasAdd:0", shape=(5, 112, 112, 64), dtype=float32)
f2: Tensor("mobilenet/conv_ds_4/pointwise_conv/BiasAdd:0", shape=(5, 56, 56, 128), dtype=float32)
f3: Tensor("mobilenet/conv_ds_6/pointwise_conv/BiasAdd:0", shape=(5, 28, 28, 256), dtype=float32)
f4: Tensor("mobilenet/conv_ds_12/pointwise_conv/BiasAdd:0", shape=(5, 14, 14, 512), dtype=float32)
f5: Tensor("mobilenet/conv_ds_14/pointwise_conv/BiasAdd:0", shape=(5, 7, 7, 1024), dtype=float32)

PSPnet部分的代码

pspnet_model.py

import tensorflow as tf
from tensorflow.contrib import  slim
from nets.mobilenet_v1 import mobilenet_v1 as  get_mobilenet_encoder
import  numpy as np#
# MERGE_AXIS = -1 # 通道维度上链接def resize_image(input_images,s):""":param input_images: 4D tensor:param s: 缩放比例 (2,2) # 扩大的倍数:return:"""h,w=input_images.get_shape().as_list()[1],input_images.get_shape().as_list()[2]h_ratio=s[0]w_ration=s[1]h=int(h*h_ratio)w=int(w*w_ration)images=tf.image.resize_images(input_images,size=(h,w))return images#进场不同尺度池化的操作
def pool_block( x , pool_factor ,IMAGE_ORDERING = 'NHWC'):""":param x: 4D (1,224,224,3):param pool_factor: 2 池化的尺度:return:"""if IMAGE_ORDERING == 'NHWC':h, w = x.get_shape().as_list()[1], x.get_shape().as_list()[2]elif IMAGE_ORDERING == 'NCHW':h, w = x.get_shape().as_list()[2], x.get_shape().as_list()[3]# strides = [18,18],[9,9],[6,6],[3,3]pool_size = [int(np.round( float(h) /  pool_factor)), int(np.round(  float(w )/  pool_factor))]strides=pool_size# 进行不同程度的平均x=slim.avg_pool2d(x,kernel_size=pool_size,stride=strides,  padding='SAME') # [1,2,2,3]# x = AveragePooling2D(pool_size , data_format=IMAGE_ORDERING , strides=strides, padding='same')( feats )## 进行卷积x=slim.conv2d(x,512,kernel_size=(1,1),stride=1,padding='SAME') #[1,2,2,512]# x = Conv2D(512, (1 ,1 ), data_format=IMAGE_ORDERING , padding='same' , use_bias=False )( x )x=slim.batch_norm(x)# x = BatchNormalization()(x)# x=slim.relu(x)x=tf.nn.relu(x)# x = Activation('relu' )(x)x=resize_image( x , strides)# x = resize_image( x , strides , data_format=IMAGE_ORDERING )return xdef pspnet(input_images,num_classes,input_height=576, input_width=576):assert input_height%192 == 0assert input_width%192 == 0img_input , levels = get_mobilenet_encoder(inputs=input_images,num_classes=num_classes)[f1 , f2 , f3 , f4 , f5 ] = levels o = f5# 对f5进行不同程度的池化pool_factors = [ 1,2,3,6]pool_outs = [o ]for p in pool_factors:pooled = pool_block(  o , p  )pool_outs.append( pooled )# 连接o=tf.concat(pool_outs,axis=-1)# o = Concatenate( axis=MERGE_AXIS)(pool_outs )o=slim.conv2d(o,512,kernel_size=(1,1),stride=1,padding='SAME')# o = ( Conv2D(512, (1, 1), padding='valid', data_format=IMAGE_ORDERING))(o)o=slim.batch_norm(o)# o = ( BatchNormalization())(o)o=resize_image(o,(2,2))# o = resize_image(o,(2,2),data_format=IMAGE_ORDERING)o=tf.concat([o,f4],axis=-1)# o = Concatenate( axis=MERGE_AXIS)([o,f4])o = slim.conv2d(o,512, kernel_size=(1, 1), stride=1, padding='SAME')# o = ( Conv2D(512, (1, 1), padding='valid', data_format=IMAGE_ORDERING))(o)o = slim.batch_norm(o)# o = ( BatchNormalization())(o)# o = Activation('relu' )(o)o=tf.nn.relu(o)pool_outs = [o]# 对f4进行不同程度的池化for p in pool_factors:pooled = pool_block(  o , p  )pool_outs.append( pooled )# 连接o = tf.concat(pool_outs, axis=-1)# o = Concatenate( axis=MERGE_AXIS)(pool_outs )o = slim.conv2d(o, 512, kernel_size=(1, 1), stride=1, padding='SAME')# o = ( Conv2D(512, (1, 1), padding='valid', data_format=IMAGE_ORDERING))(o)# o = ( BatchNormalization())(o)o=slim.batch_norm(o)o = resize_image(o,(2,2))o = tf.concat([o, f3], axis=-1)# o = Concatenate( axis=MERGE_AXIS)([o,f3])o = slim.conv2d(o, 512, kernel_size=(1, 1), stride=1, padding='SAME')# o = ( Conv2D(512, (1, 1), padding='valid', data_format=IMAGE_ORDERING))(o)o = slim.batch_norm(o)# o = ( BatchNormalization())(o)# o = Activation('relu' )(o)o = tf.nn.relu(o)pool_outs = [o ]# 对f3进行不同程度的池化for p in pool_factors:pooled = pool_block(  o , p  )pool_outs.append( pooled )# 连接o = tf.concat(pool_outs, axis=-1)# o = Concatenate( axis=MERGE_AXIS)(pool_outs )# 卷积o = slim.conv2d(o, 512, kernel_size=(1, 1), stride=1, padding='SAME')# o = Conv2D(512, (1,1), data_format=IMAGE_ORDERING, use_bias=False )(o)o = slim.batch_norm(o)# o = ( BatchNormalization())(o)# o = Activation('relu' )(o)o = tf.nn.relu(o)# 此时输出为[144,144,nclasses]o=slim.conv2d(o,num_classes,kernel_size=(3,3),stride=1,padding='SAME')# o = Conv2D( n_classes,(3,3),data_format=IMAGE_ORDERING, padding='same' )(o)o = resize_image(o,(2,2))# print('o shape',o.get_shape())o=tf.reshape(o,(-1,(input_height*input_width)//16,num_classes))# o=slim.softmax(o)# o = Reshape((-1,n_classes))(o)# o = Softmax()(o)# model = Model(img_input,o)out_put=oreturn out_putif __name__ == '__main__':input_images=tf.ones((1,576,576,3),dtype=tf.float32)# images=resize_image(input_images,s=(2,2))out_put=pspnet(input_images,num_classes=100,input_height=576, input_width=576)

tensorflow系列之_pspnet网络相关推荐

  1. AI应用开发基础傻瓜书系列2-神经网络中反向传播与梯度下降的基本概念

    AI应用开发基础傻瓜书系列2-神经网络中反向传播与梯度下降的基本概念 Copyright © Microsoft Corporation. All rights reserved. 适用于Licens ...

  2. 【TensorFlow系列一】TensorFlow工作原理

    ↑ 点击上方[计算机视觉联盟]关注我们 今天开始,小编会更新TensorFlow系列文章,包括TensorFlow的使用和TensorFlow实践的项目等. 本篇主要介绍TensorFlow的计算模型 ...

  3. 首次运行 tensorflow 项目之 vgg 网络

    首次运行 tensorflow 项目之 vgg 网络 文章目录 1. 下载所需文件 2. 在 pycharm 中打开项目 3. 为项目设置 python 编译器 4. 调试代码 1. train.py ...

  4. Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager)

    Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager) 本篇主要讲解iOS开发中的网络监控 前言 在开发中,有时候我们需要获取这些信息: 手机是否联网 ...

  5. K8s系列之:网络原理

    K8s系列之:网络原理 一.K8s网络模型 二.Docker的网络模型 三.网络的命名空间 1.网络命名空间的实现 2.网络命名空间的操作 3.网络命名空间的一些技巧 四.Veth设备对 1.Veth ...

  6. 利用TensorFlow搭建CNN,DNN网络实现图像手写识别,总结。

    利用TensorFlow搭建CNN,DNN网络实现图像手写识别,总结. 摘要 一.神经网络与卷积网络的对比 1.数据处理 2.对获取到的数据进行归一化和独热编码 二.开始我们的tensorflow神经 ...

  7. TensorFlow 系列案例(3): 使用TensorFlow DNN分类器对数据进行分类

    TensorFlow 卷积神经网络系列案例(1):猫狗识别 https://blog.csdn.net/duan_zhihua/article/details/81156693 TensorFlow ...

  8. Docker重学系列之高级网络篇

    Docker重学系列之高级网络篇 高级网络配置 说明 veth-pair技术 网络小结 Docker 网络相关的命令列表 容器访问控制 容器访问外部网络 容器之间访问 访问所有端口 访问指定端口 映射 ...

  9. 深入理解DeepLab系列语义分割网络

    语义分割是指在像素级别上进行分类,从而转换得到感兴趣区域的掩膜.说起语义分割的发展则肯定绕不开DeepLab系列语义分割网络,该系列网络由谷歌团队提出并发展,在VOC2012等公用语义分割数据集上,取 ...

  10. DeepLab大盘点 | 深入理解DeepLab系列语义分割网络

    作者 | 深蓝AI  编辑 | 汽车人 点击下方卡片,关注"自动驾驶之心"公众号 ADAS巨卷干货,即可获取 点击进入→自动驾驶之心技术交流群 后台回复[分割综述]获取语义分割.实 ...

最新文章

  1. liunx下的DNS配置
  2. nbns协议_网络协议详解1 - NBNS
  3. mysql读写分离和组复制_数据库主从复制,读写分离,负载均衡,分库分表分别表达的什么概念?...
  4. Tensorflow 2.0的这些新设计,你适应好了吗?
  5. android list contain的使用
  6. 第五章 - 图像形态学 - 基于图像金字塔的图像分割(cvPyrSegmentation)
  7. random()模块随机函数的用法总结
  8. Redis Spring集成
  9. 关于spring cloud的几个核心组件
  10. JAVA_java.util.Date与java.sql.Date相互转换
  11. 分布式模块化 Java 开发平台 Castle-Platform
  12. List(JDK1.7)(2)
  13. 数据结构和算法——线性结构(3)递归和斐波那契数列、汉诺塔问题
  14. 动力学建模~拉格朗日建模
  15. 盘点购物分享系统,有兴趣的来看看哦
  16. 【MATLAB】MATLAB三维曲面绘制【详细教程】
  17. CFSSL: 证书管理工具:2:创建CA私钥与CA证书
  18. appleID有必要开双重认证吗!
  19. 托格机器人_学无止尽:托格鲁塔人的七个秘密
  20. 码元和码点(字符串截取截取得是码元,汉字有一些偏僻字占据两个码元,字符的函数往往不是我们期待)

热门文章

  1. 我行我素购物管理系统
  2. 激活windows系统,你知道吗
  3. 电源模块-LM5117-BUCK- 电路
  4. 印象笔记 还回快捷_搭配这9款实用的第三方工具,小白也可以玩转印象笔记
  5. mac迅雷精简版(迅雷Mac)简约瘦身版
  6. 创建office一直转圈_Microsoft Office 2019 VL for Mac(office系列全套装)
  7. 单片机软件反破解 Hex反破解 破解后的hex不能量产
  8. 【交换安全】DAI - Dynamic ARP Inspection 详解/arp欺骗/gratuitous arp
  9. jqgrid列表显示时间控件
  10. 技术宅改变世界 如何在12306买到下铺