从ResNet101到ResNet50
2017-12-29 13:15
309 查看
一直用VGG训练,几天前想看下ResNet的效果如何,因为SSD源码中有python实现的ResNet网络结构实现代码,包含ResNet101和ResNet152,直接拿ResNet101来训练,GTX1060配置,batchsize竟然只降到2才跑的起来,果然一直收敛不了。看了下model_libs.py里面的实现代码:
其中每次调用ResBody,当use_brabch1 = True,会创建4个卷积层,当use_brabch1 = False时,创建3个卷积层。ResNet101Body和ResNet152Body的区别在于两个for循环的次数不一样,101层和152层差的51层就是这里体现的,所以现在要创建ResNet50Body就容易多了。根据网上下载的模型对应的ResNet_50_train_val.prototxt,对上面代码进行修改即可。50层,batchsize=4,训练马上收敛。当然训练方式多种,可用直接利用已有ResNet_50_train_val.prototxt进行训练。
def ResNet101Body(net, from_layer, use_pool5=True, use_dilation_conv5=False, **bn_param): conv_prefix = '' conv_postfix = '' bn_prefix = 'bn_' bn_postfix = '' scale_prefix = 'scale_' scale_postfix = '' ConvBNLayer(net, from_layer, 'conv1', use_bn=True, use_relu=True, num_output=64, kernel_size=7, pad=3, stride=2, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) net.pool1 = L.Pooling(net.conv1, pool=P.Pooling.MAX, kernel_size=3, stride=2) ResBody(net, 'pool1', '2a', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=True, **bn_param) ResBody(net, 'res2a', '2b', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=False, **bn_param) ResBody(net, 'res2b', '2c', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=False, **bn_param) ResBody(net, 'res2c', '3a', out2a=128, out2b=128, out2c=512, stride=2, use_branch1=True, **bn_param) from_layer = 'res3a' for i in xrange(1, 4): block_name = '3b{}'.format(i) ResBody(net, from_layer, block_name, out2a=128, out2b=128, out2c=512, stride=1, use_branch1=False, **bn_param) from_layer = 'res{}'.format(block_name) ResBody(net, from_layer, '4a', out2a=256, out2b=256, out2c=1024, stride=2, use_branch1=True, **bn_param) from_layer = 'res4a' for i in xrange(1, 23): block_name = '4b{}'.format(i) ResBody(net, from_layer, block_name, out2a=256, out2b=256, out2c=1024, stride=1, use_branch1=False, **bn_param) from_layer = 'res{}'.format(block_name) stride = 2 dilation = 1 if use_dilation_conv5: stride = 1 dilation = 2 ResBody(net, from_layer, '5a', out2a=512, out2b=512, out2c=2048, stride=stride, use_branch1=True, dilation=dilation, **bn_param) ResBody(net, 'res5a', '5b', out2a=512, out2b=512, out2c=2048, stride=1, use_branch1=False, dilation=dilation, **bn_param) ResBody(net, 'res5b', '5c', out2a=512, out2b=512, out2c=2048, stride=1, use_branch1=False, dilation=dilation, **bn_param) if use_pool5: net.pool5 = L.Pooling(net.res5c, pool=P.Pooling.AVE, global_pooling=True) return netRenNet152Body为:
def ResNet152Body(net, from_layer, use_pool5=True, use_dilation_conv5=False, **bn_param): conv_prefix = '' conv_postfix = '' bn_prefix = 'bn_' bn_postfix = '' scale_prefix = 'scale_' scale_postfix = '' ConvBNLayer(net, from_layer, 'conv1', use_bn=True, use_relu=True, num_output=64, kernel_size=7, pad=3, stride=2, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) net.pool1 = L.Pooling(net.conv1, pool=P.Pooling.MAX, kernel_size=3, stride=2) ResBody(net, 'pool1', '2a', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=True, **bn_param) ResBody(net, 'res2a', '2b', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=False, **bn_param) ResBody(net, 'res2b', '2c', out2a=64, out2b=64, out2c=256, stride=1, use_branch1=False, **bn_param) ResBody(net, 'res2c', '3a', out2a=128, out2b=128, out2c=512, stride=2, use_branch1=True, **bn_param) from_layer = 'res3a' for i in xrange(1, 8): block_name = '3b{}'.format(i) ResBody(net, from_layer, block_name, out2a=128, out2b=128, out2c=512, stride=1, use_branch1=False, **bn_param) from_layer = 'res{}'.format(block_name) ResBody(net, from_layer, '4a', out2a=256, out2b=256, out2c=1024, stride=2, use_branch1=True, **bn_param) from_layer = 'res4a' for i in xrange(1, 36): block_name = '4b{}'.format(i) ResBody(net, from_layer, block_name, out2a=256, out2b=256, out2c=1024, stride=1, use_branch1=False, **bn_param) from_layer = 'res{}'.format(block_name) stride = 2 dilation = 1 if use_dilation_conv5: stride = 1 dilation = 2 ResBody(net, from_layer, '5a', out2a=512, out2b=512, out2c=2048, stride=stride, use_branch1=True, dilation=dilation, **bn_param) ResBody(net, 'res5a', '5b', out2a=512, out2b=512, out2c=2048, stride=1, use_branch1=False, dilation=dilation, **bn_param) ResBody(net, 'res5b', '5c', out2a=512, out2b=512, out2c=2048, stride=1, use_branch1=False, dilation=dilation, **bn_param) if use_pool5: net.pool5 = L.Pooling(net.res5c, pool=P.Pooling.AVE, global_pooling=True) return net
其中每次调用ResBody,当use_brabch1 = True,会创建4个卷积层,当use_brabch1 = False时,创建3个卷积层。ResNet101Body和ResNet152Body的区别在于两个for循环的次数不一样,101层和152层差的51层就是这里体现的,所以现在要创建ResNet50Body就容易多了。根据网上下载的模型对应的ResNet_50_train_val.prototxt,对上面代码进行修改即可。50层,batchsize=4,训练马上收敛。当然训练方式多种,可用直接利用已有ResNet_50_train_val.prototxt进行训练。
相关文章推荐
- Tensorflow使用的预训练的resnet_v2_50,resnet_v2_101,resnet_v2_152等模型预测,训练
- tensorflow 搭建resnet50(附代码)
- Resnet50源码-tensorflow+keras详细解析
- R-FCN+ResNet-50用自己的数据集训练模型(python版本)
- Tensorflow + ResNet101 + fasterRcnn 训练自己的模型 数据(一)
- 【开发日记】马桶识别之数据清洗,通过Resnet50清洗脏数据
- [数据结构与算法]栈的应用:计算 2*2+(10-2)/(101-50*2)*3-2+5 表达式的值
- R-FCN+ResNet-50 训练模型
- ResNet-101/152 Protofiles and Caffemodels
- ResNet-101/152 Protofiles and Caffemodels
- R-FCN+ResNet-50 训练模型
- [置顶] R-FCN+ResNet-50用自己的数据集训练模型(python版本)
- 实战 迁移学习 VGG19、ResNet50、InceptionV3 实践 猫狗大战 问题
- caffe 可视化网络及resnet50结构
- ResNet-101 for Face Recognition
- ResNet-101/152 Protofiles and Caffemodels
- [线段树][单调栈]HackerRank 101 Hack 50 .Boxes for Toys
- 使用Keras预训练模型ResNet50进行图像分类
- caffe2分布式样例resnet50_trainer.py运行时出现参数shared_model错误
- R-FCN+ResNet-50训练自己的数据集模型(python版本)