1、FCN网络架构

FCN的前半段与VGG19架构相同,直接使用了VGG19预训练好的权重。

前半段的具体架构如下:

layers = (

'conv1_1', 'relu1_1', 'conv1_2', 'relu1_2', 'pool1',

'conv2_1', 'relu2_1', 'conv2_2', 'relu2_2', 'pool2',

'conv3_1', 'relu3_1', 'conv3_2', 'relu3_2', 'conv3_3',

'relu3_3', 'conv3_4', 'relu3_4', 'pool3',

'conv4_1', 'relu4_1', 'conv4_2', 'relu4_2', 'conv4_3',

'relu4_3', 'conv4_4', 'relu4_4', 'pool4',

'conv5_1', 'relu5_1', 'conv5_2', 'relu5_2', 'conv5_3',

'relu5_3', 'conv5_4', 'relu5_4'

)

输入层(理论上对图像大小无限制,复现时resize统一到了224*224,且经过了批归一化的预处理) -------------共16个卷积层(卷积+偏置),对应16个relu层,5个pool层。 其中卷积层卷积步长为1,padding=‘SAME’。所以经过卷积层后图像的大小不变。pool层采用平均池化,核大小为2*2,步长[1,2,2,1],padding='SAME',因此每经过一个pool层,图像的长和款就变为原本的二分之一。经过5个池化层后,map变为原来的1/32。

架构中段:

conv6 (卷积核[7,7,512,4096])+relu----drop_out层----conv7 (卷积核[1,1,4096,4096])+relu----dropout

卷积层卷积步长为1,padding=‘SAME’ 权重使用截断正态分布初始化。就是说产生正太分布的值如果与均值的差值大于两倍的标准差,那就重新生成。

架构后半段:

根据搭建方式的不同,FCN分为3种:FCN-32s,FCN-16s,FCN-8s

经过前、中段以后,conv8输出的map变为原来的1/32,后续不特指的话,缩小都是指长和宽。要实现端到端的像素分类,需要对其做反卷积,将map变为原本的大小。关于反卷积的原理,下文有讲述。所使用的函数是tf.nn.conv2d_transpose() 长宽扩大多少倍由参数stride决定。与stride=2 可以理解为将map反卷积成为原本的两倍。需要注意的是,与conv时的kernel [size,size,in,out]不同,tf.nn.conv2d_transpose()使用的kernel是[size,size,out,in]

FCN-8s: ((conv7*2+pool4)*2+pool3)*8    2*2*8=2^5 恢复到了原本的大小

FCN-16s:(conv7*2+pool4)*16

FCN-32s: conv7*32

我复现了FCN-8s的源码,这种skip layer可以将浅层的和深层的特征组合在一起。

三个反卷积核的大小依次是:[4,4,pool4.shape[-1].value,4096],[4,4,pool3.shape[-1].value,pool4.shape[-1].value],[16,16,NUM_OF_CLASSESS,pool3.shape[3].value]

stride依次是2,2,8。

最后一个反卷积层的输出是[batchsize,224,224,NUM_CLASSES]  通过softmax(在损失函数优化器中自带)计算出像素点属于各类别的置信度,选择置信度最高的作为预测值,得到pre

由pre和gt计算损失函数。

2、复现过程中的小trick

1)命令行参数

FCN.py

FLAGS=tf.flags.FLAGS

tf.flags.DEFINE_integer('batchsize','8','trainning batchsize') #参数 默认值 说明

tf.flags.DEFINE_float('learning_rate','1e-4','learning_rate')

tf.flags.DEFINE_bool('train', "True", "Debug mode: True/ False")

python FCN.py会直接使用默认的参数

python FCN.py --batchsize 32  --learning_rate 0.05  --train False   参数可以根据需求进行修改

后续代码调用参数的话:

FLAGS.batchsize

FLAGS.learning_rate

FLAGS.train

2)np.squeeze()

去除array中为1的维度

3)tf.variable_scope和tf.name_scope的区别:

tf.variable_scope可以让变量有相同的命名,包括tf.get_variable得到的变量,还有tf.Variable的变量

tf.name_scope可以让变量有相同的命名,只是限于tf.Variable的变量

所以如果

with tf.namescope('V1'):

with tf.namescope('V2'):

中都使用tf.get_variable得到了name为 'kernel' 的variable 会报错

但如果都使用tf.Variable得到了name为 'kernel' 的variable 不会报错

4)tf.variable与tf.get_variable

tf.Variable() 每次都在创建新对象,所有reuse=True 和它并没有什么关系。对于get_variable(),来说,如果已经创建的变量对象,就把那个对象返回,如果没有创建变量对象的话,就创建一个新的。

具体参数说明参考:https://blog.csdn.net/u012436149/article/details/53696970

5)tf.nn.conv2d_transpose

反卷积

tf.nn.conv2d_transpose(input_tensor,kernel,out_shape,[1,strider,strider,1],padding='SAME')

长宽扩大多少倍由参数stride决定。与stride=2 可以理解为将map反卷积成为原本的两倍。需要注意的是,与conv时的kernel [size,size,in,out]不同,tf.nn.conv2d_transpose()使用的kernel是[size,size,out,in]

需要指定output_shape

反卷积原理可见:https://blog.csdn.net/mao_xiao_feng/article/details/71713358

6)tfrecord数据集的制作和读取

参考另一篇博客 tensorflow高效读取数据(tfrecord)

7) label_batch=tf.expand_dims(label_batch,-1)

增加维度,增加的是哪一维,可以通过dims= 制定

8)损失函数的选择:

参考另一篇博客:关于tensorflow交叉熵损失函数的一些理解

9)优化器的选择:

参考博客:https://blog.csdn.net/aliceyangxi1987/article/details/73210204

10)权重的保存和恢复

with tf.Session() as sess:

saver=tf.train.Saver(max_to_keep=5)# 只保存最近的5个

if FLAGS.train==True:

sess.run(init) #如果是训练的话 初始化 不载入

else:

ckpt = tf.train.get_checkpoint_state('log')

saver.restore(sess,ckpt.model_checkpoint_path) #恢复最新的权重到sess中

saver.save(sess,'log/model.ckpt',step) #保存第step步的权重

11)训练一段时间后报错:

OutOfRangeError (see above for traceback): RandomShuffleQueue '_2_shuffle_batch/random_shuffle_queue' is closed and has insufficient elements (requested 8, current size 0)

[[Node: shuffle_batch = QueueDequeueManyV2[component_types=[DT_UINT8, DT_UINT8], timeout_ms=-1, _device="/job:localhost/replica:0/task:0/device:CPU:0"](shuffle_batch/random_shuffle_queue, shuffle_batch/n)]]

可能原因:tfrecord存储和读取时候的数据类型不一致。

1、数据编码前是float  解码时指定为uint8。

2、编码方式与解码方式不配对。

3、数据集有图片是损坏的。

检查后发现是第三个原因。

12)ubuntu下移动数据集,当数据集比较大,尽量使用终端命令,会比较快。

mv ./training/ADE_train_000202*.png ./train_back/

13)tensorflow的可视化

tf.summary.histogram  直方图

tf.summary.scalar     变量

最后

merged =tf.summary.merge_all() 将所有需要可视化的合并

定义writer

train_writer = tf.summary.FileWriter(FLAGS.log + '/train')

训练时每隔几步并写入一次

summary=sess.run(merged)

train_writer.add_summary(summary,step)

训练结束后查看:

在终端输入 tensorboard --logdir=dir

其中dir是summary日志存储的目录。

13)采用

if __name__=='__main__':

tf.app.run()

时 也就是python文件有预设参数时,调用main函数的定义:

def main(argv=None):

14)对于大数据集 制作numpy非常麻烦,因此数据格式为tfrecord会比较好,但是数据集比较小的话,制作成numpy会比较快。

15)

print('\r%d',step,end='') #'\r'使得下一次的输出把上一次的覆盖掉。end=''确保不换行。

sys.stdout.flush() #刷新

这两行代码是一个 在原位置不断刷新输出的简单例子

16)logging日志

使用方法参考

https://blog.csdn.net/hallo_ween/article/details/64906838

17)滑动平均的使用

以损失函数为例,滑动平均可以防止损失随着epoch的变化不太剧烈,而是相对平稳的下降,如果loss没有急剧的上涨,可以不考虑使用滑动平均,如果不稳定的话,可以使用。

使用方法:

v1 = tf.Variable(0, dtype=tf.float32)

step = tf.Variable(tf.constant(0))

ema = tf.train.ExponentialMovingAverage(0.99, step)

maintain_average = ema.apply([v1])

with tf.Session() as sess:

init = tf.initialize_all_variables()

sess.run(init)

print sess.run([v1, ema.average(v1)]) #初始的值都为0

sess.run(tf.assign(v1, 5)) #把v1变为5

sess.run(maintain_average)

print sess.run([v1, ema.average(v1)]) # decay=min(0.99, 1/10)=0.1, v1=0.1*0+0.9*5=4.5

sess.run(tf.assign(step, 10000)) # steps=10000

sess.run(tf.assign(v1, 10)) # v1=10

sess.run(maintain_average)

print sess.run([v1, ema.average(v1)]) # decay=min(0.99,(1+10000)/(10+10000))=0.99, v1=0.99*4.5+0.01*10=4.555

18)assert 断言的用法

格式 : assert+空格+要判断语句+双引号“报错语句”

例子:

出错时候

assert 1>5, "chucuo"

输出值为:

---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

in ()

----> 1 assert 2>5, "chucuo"

AssertionError: chucuo

19)tf.identity()和tf.group()均可将语句变为操作

3、相关代码

1)代码架构:

准备数据(读入事先制作好的tfrecord)-------定义网络结构-------可视化------计算损失---定义优化器----初始化-----开启Session----训练(每训练20个batch进行一次验证)------测试

2)代码地址:

https://github.com/zlrai5895/FCN-writed

fcn网络结构代码_经典网络复现系列(一):FCN相关推荐

  1. 遗传算法经典实例代码_经典算法研究系列 之 深入浅出遗传算法

    关注数学,关注AI,关注我们公众号ID:Math-AI 经典算法研究系列 遗传算法 1 初探遗传算法 Ok,先看维基百科对遗传算法所给的解释: 遗传算法是计算数学中用于解决最优化的搜索算法,是进化算法 ...

  2. fcn网络结构代码_FCN实现2-模型结构及实现

    完整项目见 https://github.com/luoshiyong/LSY_semantic_segmentation/tree/main/FCN_VOC12​github.com 1.数据集 v ...

  3. vpc经典网络区别_经典网络与VPC

    1.VPC是什么? VPC(Virtual Private Cloud)是公有云上自定义的逻辑隔离网络空间,与用户在数据中心运行的传统网络相似,托管在VPC内的是用户在私有云上的服务资源,如云主机.负 ...

  4. c++编写手机小游戏代码_经典小游戏大集合(C++ 源码)

    [实例简介] 五子棋 贪吃蛇 俄罗斯方块 黑白棋 连连看 推箱子 扫雷等7个小游戏 C++源码 VC6.0 下编译运行. [实例截图] [核心代码] 经典小游戏大集合(C源码) └── 经典小游戏大集 ...

  5. fcn网络结构代码_FCN 的简单实现

    学习了沐神的 gluon 课程,觉得里面有关于 fcn 的课程 特别有用,于是总结一下,同时使用 pytorch 重新实现,不仅实现 gluon 教程中的部分,同时实现论文中更精细的形式. 介绍 语义 ...

  6. 广数980tc3尾座锁定代码_广州数控GSK980TC3系列 PLC及安装连接手册.pdf

    目 录 目 录 第一篇 编程说明篇 第一章 顺序程序编制流程 3 1.1 GSK980TC3 PLC 规格 3 1.2 顺序程序的概念 3 1.3 分配接口(步骤1) 4 1.4 编制梯形图(步骤2) ...

  7. vgg16 清华镜像_经典网络-使用VGG16进行迁移学习

    # 使用迁移学习的思想,以VGG16作为模板搭建模型,训练识别手写字体 # 引入VGG16模块 from keras.applications.vgg16 import VGG16 # 其次加载其他模 ...

  8. vgg16卷积层的计算量_深度学习_经典网络_VGG16和ResNet152哪个参数量更多

    首先,我们我们知道深度学习中网络的计算量代表时间复杂度,参数量代表空间复杂度. 从ResNet的论文中可知(ResNet论文可在这个文章中的第六部分找到)152层的残差网络在时间复杂度上和VGG16是 ...

  9. 登录页面html代码_【网络自动化平台开发】—— 登录组件

    今年的天气特别的冷,于是,继续缓慢更新. Django 其实有自己的权限认证组件,可以拿来用,其实本身代码量也不多,还是自己写吧. 新建了一个functions文件夹用于存放各种功能文件: 说说登录的 ...

最新文章

  1. 获取浏览器可视区域宽度和高度 兼容主流浏览器
  2. 自学python找工作工资-大四应届毕业生,学了两个月Python,找工作感觉好难啊?...
  3. Django框架之跨站请求伪造
  4. 关于leetcode第K个最大元素的几种解法
  5. iOS快速开发框架Bee-Framework应用和解析(二) - Bee framework架构概览
  6. JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
  7. h5的fetch方法_你不需要jQuery(三):新AJAX方法fetch()
  8. 软件测试流程进阶----两年软件测试总结[转]
  9. 你有没有靠谱的基因?一个人靠不靠谱,其实就看这三点:“凡事有交代,件件有着落,事事有回音。”...
  10. 理解CSS3 max/min-content及fit-content等width值
  11. .NET MVC Scripts.Render 上下文不存在问题解决方法
  12. Github Clone to local files
  13. RS232通信之C++实现---PC端
  14. [Python] 关键字 assert
  15. 深入理解JS中和||
  16. spark 的RDD各种转换和动作
  17. R60笔记本电脑风扇清理加油过程
  18. 如何用html语言制作圆角矩形,webGL中圆角矩形的绘制
  19. python - 正则表达式 与或非
  20. RxSwift-内存管理

热门文章

  1. Sqlmap功能及其使用(简单够用)
  2. python OMP error
  3. 4操作系统的系统调用
  4. 乐观锁实现接口幂等性_什么是幂等性,如何实现,以及乐观锁在项目中的实际用法...
  5. Mongoose aggregate
  6. (抄袭自网络文摘)Ping使用方法大全
  7. 2020 年 11 月编程语言排行榜:Python 势如破竹,超越 Java。
  8. 4049-33-6,1,2,3,4-TETRA-O-ACETYL-BETA-D-XYLOPYRANOSE,1,2,3,4-四-O-乙酰-β-D-吡喃木糖
  9. 在IPAD2中使用VMware View Client
  10. 《围炉音乐会》与第59届格莱美深度合作