首页
壁纸
留言板
友链
更多
统计归档
Search
1
TensorBoard:训练日志及网络结构可视化工具
12,588 阅读
2
主板开机跳线接线图【F_PANEL接线图】
7,036 阅读
3
Linux使用V2Ray 原生客户端
6,151 阅读
4
移动光猫获取超级密码&开启公网ipv6
4,687 阅读
5
NVIDIA 显卡限制功率
3,131 阅读
好物分享
实用教程
linux使用
wincmd
学习笔记
mysql
java学习
nginx
综合面试题
大数据
网络知识
linux
放码过来
python
javascript
java
opencv
蓝桥杯
leetcode
深度学习
开源模型
相关知识
数据集和工具
模型轻量化
语音识别
计算机视觉
杂七杂八
硬件科普
主机安全
嵌入式设备
其它
bug处理
登录
/
注册
Search
标签搜索
好物分享
学习笔记
linux
MySQL
nvidia
typero
内网穿透
webdav
vps
java
cudann
gcc
cuda
树莓派
CNN
图像去雾
ssh安全
nps
暗通道先验
阿里云
jupiter
累计撰写
354
篇文章
累计收到
71
条评论
首页
栏目
好物分享
实用教程
linux使用
wincmd
学习笔记
mysql
java学习
nginx
综合面试题
大数据
网络知识
linux
放码过来
python
javascript
java
opencv
蓝桥杯
leetcode
深度学习
开源模型
相关知识
数据集和工具
模型轻量化
语音识别
计算机视觉
杂七杂八
硬件科普
主机安全
嵌入式设备
其它
bug处理
页面
壁纸
留言板
友链
统计归档
搜索到
62
篇与
的结果
2021-02-06
YOLOv3学习:(二)网络结构推导与实现
YOLOv3学习:(二)网络结构推导与实现网络结构图简版:网络结构图简版+特征图的大小变换:网络结构-详细版网络结构模块化网络结构图展开(超详细版)网络结构+示例-3D版(利用多尺度特征进行对象检测)9种尺度的先验框随着输出的特征图的数量和尺度的变化,先验框的尺寸也需要相应的调整。YOLO2已经开始采用K-means聚类得到先验框的尺寸,YOLO3延续了这种方法,为每种下采样尺度设定3种先验框,总共聚类出9种尺寸的先验框。在COCO数据集这9个先验框是:(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。分配上,在最小的1313特征图上(有最大的感受野)应用较大的先验框(116x90),(156x198),(373x326),适合检测较大的对象。中等的2626特征图上(中等感受野)应用中等的先验框(30x61),(62x45),(59x119),适合检测中等大小的对象。较大的52*52特征图上(较小的感受野)应用较小的先验框(10x13),(16x30),(33x23),适合检测较小的对象。感受一下9种先验框的尺寸,下图中蓝色框为聚类得到的先验框。黄色框式ground truth,红框是对象中心点所在的网格。输入到输出的映射(包含输出参数的解释)不考虑神经网络结构细节的话,总的来说,对于一个输入图像,YOLO3将其映射到3个尺度的输出张量,代表图像各个位置存在各种对象的概率。我们看一下YOLO3共进行了多少个预测。对于一个416416的输入图像,在每个尺度的特征图的每个网格设置3个先验框,总共有 13133 + 26263 + 5252*3 = 10647 个预测。每一个预测是一个(4+1+80)=85维向量,这个85维向量包含边框坐标(4个数值),边框置信度(1个数值),对象类别的概率(对于COCO数据集,有80种对象)。对比一下,YOLO2采用13135 = 845个预测,YOLO3的尝试预测边框数量增加了10多倍,而且是在不同分辨率上进行,所以mAP以及对小物体的检测效果有一定的提升。代码实现代码import torch import torch.nn as nn # Darknet53 中的基本块--卷积块,由Conv+BN+LeakyReLU共同组成 class ConvBNReLU(nn.Module): def __init__(self,in_channels,out_channels,kernel_size,stride,padding): super(ConvBNReLU,self).__init__() self.conv = nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding) self.BN = nn.BatchNorm2d(out_channels) self.leaky_relu = nn.ReLU6(inplace=True) def forward(self,x): x = self.conv(x) x = self.BN(x) x = self.leaky_relu(x) return x # Darknet53 中的基本块--下采样块,用卷积(stride=2)实现 class DownSample(nn.Module): def __init__(self,in_channels,out_channels): super(DownSample,self).__init__() self.down_samp = nn.Conv2d(in_channels,out_channels,3,2,1) def forward(self,x): x = self.down_samp(x) return x # Darknet53 中的基本块--ResBlock class ResBlock(nn.Module): def __init__(self, nchannels): super(ResBlock, self).__init__() mid_channels = nchannels // 2 self.conv1x1 = ConvBNReLU(nchannels, mid_channels,1,1,0) self.conv3x3 = ConvBNReLU(mid_channels, nchannels,3,1,1) def forward(self, x): out = self.conv3x3(self.conv1x1(x)) return out + x # YOLOv3 骨干网络 -DarkNet53 class DarkNet53_YOLOv3(nn.Module): def __init__(self): super(DarkNet53_YOLOv3, self).__init__() self.conv_bn_relu = ConvBNReLU(3,32,3,1,1) self.down_samp_0 = DownSample(32,64) self.res_block_1 = ResBlock(64) self.down_samp_1 = DownSample(64,128) self.res_block_2 = ResBlock(128) self.down_samp_2 = DownSample(128,256) self.res_block_3 = ResBlock(256) self.down_samp_3 = DownSample(256,512) self.res_block_4 = ResBlock(512) self.down_samp_4 = DownSample(512,1024) self.res_block_5 = ResBlock(1024) def forward(self, x): out1 = self.conv_bn_relu(x) out1 = self.down_samp_0(out1) out1 = self.res_block_1(out1) out1 = self.down_samp_1(out1) out1 = self.res_block_2(out1) out1 = self.res_block_2(out1) out1 = self.down_samp_2(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out1 = self.res_block_3(out1) out2 = self.down_samp_3(out1) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out2 = self.res_block_4(out2) out3 = self.down_samp_4(out2) out3 = self.res_block_5(out3) out3 = self.res_block_5(out3) out3 = self.res_block_5(out3) out3 = self.res_block_5(out3) out3 = self.res_block_5(out3) return out1,out2,out3 # YOLOv3 13*13 输出分支的darknet53后的几层 class Out1LastLayers(nn.Module): #input_shape = (1024, 13, 13) out_shape = (255,13,13) out_branck_shape = (512,13,13) def __init__(self): super(Out1LastLayers, self).__init__() self.conv1x1 = ConvBNReLU(1024,512,1,1,0) self.conv3x3 = ConvBNReLU(512, 1024,3,1,1) self.conv1x1_last = ConvBNReLU(1024,255,1,1,0) def forward(self,x): out = self.conv1x1(x) out = self.conv3x3(out) out = self.conv1x1(out) out = self.conv3x3(out) out = self.conv1x1(out) out_branch = out out = self.conv3x3(out) out = self.conv1x1_last(out) return out,out_branch # YOLOv3 26*26 输出分支的darknet53后的几层 class Out2LastLayers(nn.Module): #input_shape = (512, 26, 26) out_shape = (255,26,26) out_branck_shape = (256,26,26) def __init__(self): super(Out2LastLayers, self).__init__() self.conv1x1 = ConvBNReLU(512,256,1,1,0) self.conv3x3 = ConvBNReLU(256,512,3,1,1) self.up_sample = nn.Upsample(scale_factor=2, mode='nearest') self.conv1x1_after_concat = ConvBNReLU(768,256,1,1,0) self.conv1x1_last = ConvBNReLU(512,255,1,1,0) def forward(self,x,x_branch): out = self.conv1x1(x_branch) out = self.up_sample(out) out = torch.cat([x,out],1) out = self.conv1x1_after_concat(out) out = self.conv3x3(out) out = self.conv1x1(out) out = self.conv3x3(out) out = self.conv1x1(out) out_branch = out out = self.conv3x3(out) out = self.conv1x1_last(out) return out,out_branch # YOLOv3 52*52 输出分支的darknet53后的几层 class Out3LastLayers(nn.Module): #input_shape = (256, 52, 52) out_shape = (255,52,52) def __init__(self): super(Out3LastLayers, self).__init__() self.conv1x1 = ConvBNReLU(256,128,1,1,0) self.conv3x3 = ConvBNReLU(128,256,3,1,1) self.up_sample = nn.Upsample(scale_factor=2, mode='nearest') self.conv1x1_after_concat = ConvBNReLU(384,128,1,1,0) self.conv1x1_last = ConvBNReLU(256,255,1,1,0) def forward(self,x,x_branch): out = self.conv1x1(x_branch) out = self.up_sample(out) out = torch.cat([x,out],1) out = self.conv1x1_after_concat(out) out = self.conv3x3(out) out = self.conv1x1(out) out = self.conv3x3(out) out = self.conv1x1(out) out = self.conv3x3(out) out = self.conv1x1_last(out) return out # YOLOv3模型 class YOLOv3(nn.Module): def __init__(self): super(YOLOv3, self).__init__() self.darknet53 = DarkNet53_YOLOv3() self.out1_last_layers = Out1LastLayers() self.out2_last_layers = Out2LastLayers() self.out3_last_layers = Out3LastLayers() def forward(self, x): out3,out2,out1 = self.darknet53(x) # out1.shape,out2.shape,out3.shape = (256, 52, 52),(512, 26, 26),(1024, 13, 13) out1,out1_branch = self.out1_last_layers(out1) out2,out2_branch = self.out2_last_layers(out2,out1_branch) out3 = self.out3_last_layers(out3,out2_branch) return out1,out2,out3输入输出测试fake_input = torch.zeros((1,3,416,416)) print(fake_input.shape) model = YOLOv3() out1,out2,out3= model(fake_input) print(out1.shape,out2.shape,out3.shape)torch.Size([1, 3, 416, 416]) torch.Size([1, 255, 13, 13]) torch.Size([1, 255, 26, 26]) torch.Size([1, 255, 52, 52])参考资料YOLOv3网络结构和解析:https://blog.csdn.net/dz4543/article/details/90049377Darknet53网络各层参数详解:https://blog.csdn.net/qq_40210586/article/details/106144197目标检测0-02:YOLO V3-网络结构输入输出解析:https://blog.csdn.net/weixin_43013761/article/details/98349080YOLOv3 深入理解:https://www.jianshu.com/p/d13ae1055302
2021年02月06日
951 阅读
0 评论
0 点赞
2021-02-06
YOLOv3学习:(一)Darknet-53结构推导与实现
YOLOv3学习:(一)Darknet-53结构推导与实现原生Darknet-53网络结构代码实现-1(更易读)模型代码import torch import torch.nn as nn # Darknet53 中的基本块--卷积块,由Conv+BN+LeakyReLU共同组成 class ConvBNReLU(nn.Module): def __init__(self,in_channels,out_channels,kernel_size,stride,padding): super(ConvBNReLU,self).__init__() self.conv = nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding) self.BN = nn.BatchNorm2d(out_channels) self.leaky_relu = nn.ReLU6(inplace=True) def forward(self,x): x = self.conv(x) x = self.BN(x) x = self.leaky_relu(x) return x # Darknet53 中的基本块--下采样块,用卷积(stride=2)实现 class DownSample(nn.Module): def __init__(self,in_channels,out_channels): super(DownSample,self).__init__() self.down_samp = nn.Conv2d(in_channels,out_channels,3,2,1) def forward(self,x): x = self.down_samp(x) return x # Darknet53 中的基本块--ResBlock class ResBlock(nn.Module): def __init__(self, nchannels): super(ResBlock, self).__init__() mid_channels = nchannels // 2 self.conv1x1 = ConvBNReLU(nchannels, mid_channels,1,1,0) self.conv3x3 = ConvBNReLU(mid_channels, nchannels,3,1,1) def forward(self, x): out = self.conv3x3(self.conv1x1(x)) return out + x num_classes=1000 darknet53= nn.Sequential() darknet53.add_module('conv_bn_relu',ConvBNReLU(3,32,3,1,1)) darknet53.add_module('down_samp_0',DownSample(32,64)) darknet53.add_module('res_block_1_1',ResBlock(64)) darknet53.add_module('down_samp_1',DownSample(64,128)) darknet53.add_module('res_block_2_1',ResBlock(128)) darknet53.add_module('res_block_2_2',ResBlock(128)) darknet53.add_module('down_samp_2',DownSample(128,256)) darknet53.add_module('res_block_3_1',ResBlock(256)) darknet53.add_module('res_block_3_2',ResBlock(256)) darknet53.add_module('res_block_3_3',ResBlock(256)) darknet53.add_module('res_block_3_4',ResBlock(256)) darknet53.add_module('res_block_3_5',ResBlock(256)) darknet53.add_module('res_block_3_6',ResBlock(256)) darknet53.add_module('res_block_3_7',ResBlock(256)) darknet53.add_module('res_block_3_8',ResBlock(256)) darknet53.add_module('down_samp_3',DownSample(256,512)) darknet53.add_module('res_block_4_1',ResBlock(512)) darknet53.add_module('res_block_4_2',ResBlock(512)) darknet53.add_module('res_block_4_3',ResBlock(512)) darknet53.add_module('res_block_4_4',ResBlock(512)) darknet53.add_module('res_block_4_5',ResBlock(512)) darknet53.add_module('res_block_4_6',ResBlock(512)) darknet53.add_module('res_block_4_7',ResBlock(512)) darknet53.add_module('res_block_4_8',ResBlock(512)) darknet53.add_module('down_samp_4',DownSample(512,1024)) darknet53.add_module('res_block_5_1',ResBlock(1024)) darknet53.add_module('res_block_5_2',ResBlock(1024)) darknet53.add_module('res_block_5_3',ResBlock(1024)) darknet53.add_module('res_block_5_4',ResBlock(1024)) darknet53.add_module('avg_pool',nn.AvgPool2d(kernel_size=8,stride=1)) darknet53.add_module('flatten',nn.Flatten()) darknet53.add_module('linear',nn.Linear(in_features=1024,out_features=num_classes)) darknet53.add_module('softmax',nn.Softmax(dim=1)) print(darknet53)输入输出验证fake_imput = torch.zeros((1,3,256,256)) print(fake_imput.shape) output = darknet53(fake_imput) print(output.shape)torch.Size([1, 3, 256, 256]) torch.Size([1, 1000])代码实现-2(代码更少)import torch import torch.nn as nn def Conv3x3BNReLU(in_channels,out_channels,stride=1): return nn.Sequential( nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=3,stride=stride,padding=1), nn.BatchNorm2d(out_channels), nn.ReLU6(inplace=True) ) def Conv1x1BNReLU(in_channels,out_channels): return nn.Sequential( nn.Conv2d(in_channels=in_channels,out_channels=out_channels,kernel_size=1,stride=1,padding=0), nn.BatchNorm2d(out_channels), nn.ReLU6(inplace=True) ) class Residual(nn.Module): def __init__(self, nchannels): super(Residual, self).__init__() mid_channels = nchannels // 2 self.conv1x1 = Conv1x1BNReLU(in_channels=nchannels, out_channels=mid_channels) self.conv3x3 = Conv3x3BNReLU(in_channels=mid_channels, out_channels=nchannels) def forward(self, x): out = self.conv3x3(self.conv1x1(x)) return out + x class Darknet53(nn.Module): def __init__(self, num_classes=1000): super(Darknet53, self).__init__() self.first_conv = Conv3x3BNReLU(in_channels=3, out_channels=32) self.block1 = self._make_layers(in_channels=32,out_channels=64, block_num=1) self.block2 = self._make_layers(in_channels=64,out_channels=128, block_num=2) self.block3 = self._make_layers(in_channels=128,out_channels=256, block_num=8) self.block4 = self._make_layers(in_channels=256,out_channels=512, block_num=8) self.block5 = self._make_layers(in_channels=512,out_channels=1024, block_num=4) self.avg_pool = nn.AvgPool2d(kernel_size=8,stride=1) self.linear = nn.Linear(in_features=1024,out_features=num_classes) self.softmax = nn.Softmax(dim=1) def _make_layers(self, in_channels,out_channels, block_num): _layers = [] _layers.append(Conv3x3BNReLU(in_channels=in_channels, out_channels=out_channels, stride=2)) for _ in range(block_num): _layers.append(Residual(nchannels=out_channels)) return nn.Sequential(*_layers) def forward(self, x): x = self.first_conv(x) x = self.block1(x) x = self.block2(x) x = self.block3(x) x = self.block4(x) x = self.block5(x) x = self.avg_pool(x) x = x.view(x.size(0),-1) x = self.linear(x) out = self.softmax(x) return x model = Darknet53() print(model) input = torch.randn(1,3,256,256) out = model(input) print(out.shape)YOLOv3中的Darknet53的网络各层参数详解参考资料Pytorch实现Darknet-53:https://blog.csdn.net/qq_41979513/article/details/102680028Darknet53网络各层参数详解:https://blog.csdn.net/qq_40210586/article/details/106144197
2021年02月06日
1,034 阅读
0 评论
0 点赞
2021-02-04
【YOLOv2论文翻译】YOLO9000:更好、更快、更强
【YOLOv2论文翻译】YOLO9000:更好、更快、更强论文原文:YOLO9000:Better, Faster, Stronger项目主页:YOLO: Real-Time Object Detection摘要我们引入了一个先进的实时目标检测系统YOLO9000,可以检测超过9000个目标类别。首先,我们提出了对YOLO检测方法的各种改进,既有新发明的一些东西,也参考了前人的工作。改进后的模型YOLOv2在PASCAL VOC和COCO等标准检测任务上性能是最好的。使用一种新颖的、多尺度训练方法,同样的YOLOv2模型可以以不同的尺度运行,从而在速度和准确性之间获得了良好的权衡。以67FPS的检测速度,YOLOv2在VOC 2007上获得了76.8 mAP。而检测速度40FPS时,YOLOv2获得了78.6 mAP,比使用ResNet的Faster R-CNN和SSD等先进方法表现更出色,同时仍然运行速度显著更快。最后我们提出了一种联合训练目标检测与分类的方法。使用这种方法,我们在COCO检测数据集和ImageNet分类数据集上同时训练YOLO9000。我们的联合训练允许YOLO9000预测未标注的检测数据目标类别的检测结果。我们在ImageNet检测任务上验证了我们的方法。YOLO9000在ImageNet检测验证集上获得19.7 mAP,尽管200个类别中只有44个具有检测数据。不在COCO中的156个类别上,YOLO9000获得16.0 mAP。但YOLO可以检测到200多个类别;它预测超过9000个不同目标类别的检测结果。并且它仍然能实时运行。1. 引言通用目的的目标检测系统应该是快速的、准确的,并且能够识别各种各样的目标。自从引入神经网络以来,检测框架变得越来越快速和准确。但是,大多数检测方法仍然受限于一小部分目标。与分类和标记等其他任务的数据集相比,目前目标检测数据集是有限的。最常见的检测数据集包含成千上万到数十万张具有成百上千个标签的图像3[2]。分类数据集有数以百万计的图像,数十或数十万个类别20。我们希望检测能够扩展到目标分类的级别。但是,标注检测图像要代价比标注分类或贴标签要大得多(标签通常是用户免费提供的)。因此,我们不太可能在近期内看到与分类数据集相同规模的检测数据集。我们提出了一种新的方法来利用我们已经拥有的大量分类数据,并用它来扩大当前检测系统的范围。我们的方法使用目标分类的分层视图,允许我们将不同的数据集组合在一起。我们还提出了一种联合训练算法,使我们能够在检测和分类数据上训练目标检测器。我们的方法利用有标签的检测图像来学习精确定位物体,同时使用分类图像来增加词表和鲁棒性。使用这种方法我们训练YOLO9000,一个实时的目标检测器,可以检测超过9000种不同的目标类别。首先,我们改进YOLO基础检测系统,产生最先进的实时检测器YOLOv2。然后利用我们的数据集组合方法和联合训练算法对来自ImageNet的9000多个类别以及COCO的检测数据训练了一个模型。我们的所有代码和预训练模型都可以在http://pjreddie.com/yolo9000/在线获得。2. 更好与最先进的检测系统相比,YOLO有许多缺点。YOLO与Fast R-CNN的误差分析比较表明,YOLO存在大量的定位误差。此外,与基于region proposal的方法相比,YOLO召回率相对较低。因此,我们主要侧重于提高召回率和改进目标精确定位,同时保持分类准确性。计算机视觉一般趋向于更大、更深的网络6[17]。更好的性能通常取决于训练更大的网络或将多个模型组合在一起。但是,在YOLOv2中,我们需要一个更精确的检测器,而且需要它仍然很快。我们不是扩大我们的网络,而是简化网络,然后让表示更容易学习。我们将过去的工作与我们自己的新概念汇集起来,以提高YOLO的性能。表2列出了结果总结。批归一化。会获得收敛性的显著改善,同时消除了对其他形式正则化的需求[7]。通过在YOLO的所有卷积层上添加批归一化,我们在mAP中获得了超过2%的改进。批归一化也有助于模型正则化。通过批归一化,我们可以从模型中删除dropout而不会过拟合。高分辨率分类器。有最先进的检测方法都使用在ImageNet[16]上预训练的分类器。从AlexNet开始,大多数分类器对小于256×256[8]的输入图像进行操作。YOLO初始版本以224×224分辨率的图像训练分类器网络,并在检测时将分辨率提高到448。这意味着网络必须同时切换到学习目标检测和调整到新的输入分辨率。对于YOLOv2,我们首先在ImageNet上以448×448的分辨率对分类网络进行10个迭代周期的fine tune。这使得网络来调整其卷积核以便更好地处理更高分辨率的输入。然后我们对得到的网络进行fine tune并用于检测任务。这个高分辨率分类网络使我们增加了近4%的mAP。具有Anchor框的卷积。YOLO直接使用卷积特征提取器顶部的全连接层来预测边界框的坐标。Faster R-CNN使用手动选择的先验来预测边界框而不是直接预测坐标[15]。Faster R-CNN中的region proposal网络(RPN)仅使用卷积层来预测Anchor框的偏移和置信度。由于预测层是卷积类型的层,所以RPN在特征图的每个位置上预测这些偏移。预测偏移而不是坐标简化了问题,并且使网络更容易学习。我们从YOLO中移除全连接层,并使用Anchor框来预测边界框。首先,我们去除了一个池化层,使网络卷积层输出具有更高的分辨率。我们还缩小了网络,操作416×416的输入图像而不是448×448。我们这样做是因为我们要在我们的特征图中位置个数是奇数,所以只会有一个中心格子。目标,特别是大目标,往往占据图像的中心,所以在中心有一个单独的位置来预测这些目标的很好的,而不是四个都相邻的位置。YOLO的卷积层将图像下采样32倍,所以通过使用416的输入图像,我们得到了13×13的输出特征图。当我们移动到Anchor框时,我们也将类预测机制与空间位置分离,预测每个Anchor框的类别和目标。与YOLO类似,是否为目标的预测仍然预测了真值和proposal的边界框的IOU,并且类别预测预测了当存在目标时该类别的条件概率。使用Anchor框,我们的精度发生了一些小的下降。YOLO对每张图像只预测98个边界框,但是使用Anchor框我们的模型预测超过一千个。如果不使用Anchor框,我们的中间模型将获得69.5的mAP,召回率为81%。使用Anchor框的模型得到了69.2 mAP,召回率为88%。尽管mAP下降了一点,但召回率的上升意味着我们的模型有更大的改进空间。维度聚类。当Anchor框与YOLO一起使用时,我们遇到了两个问题。首先是边界框尺寸是手工挑选的。网络可以学习到如何适当调整边界框,但如果我们为网络选择更好的先验,我们可以使网络更容易学习它以便获得更好的检测结果。我们不用手工选择先验,而是在训练集边界框上运行k-means聚类,自动找到好的先验。如果我们使用欧式距离的标准k-means,那么较大的边界框比较小的边界框产生更多的误差。然而,我们真正想要的是产生好的IOU分数的先验,这是独立于边界框大小的。因此,对于我们的距离度量,我们使用:d(box,centroid)=1−IOU(box,centroid)如图2所示,我们运行不同k值的k-means,并画出平均IOU与最接近的几何中心的关系图。我们选择k=5时模型复杂性和高召回率之间的具有良好的权衡。聚类中心与手工挑选的Anchor框明显不同。聚类结果有更短更宽的边界框,也有更高更细的边界框。在表1中我们将平均IOU与我们聚类策略中最接近的先验以及手工选取的Anchor框进行了比较。仅有5个先验中心的平均IOU为61.0,其性能类似于9个Anchor框的60.9。如果我们使用9个中心,我们会看到更高的平均IOU。这表明使用k-means来生成我们的边界框会以更好的表示开始训练模型,并使得任务更容易学习。直接定位预测。当YOLO使用Anchor框时,我们会遇到第二个问题:模型不稳定,特别是在早期的迭代过程中。大部分的不稳定来自预测边界框的(x,y)位置。在region proposal网络中,网络预测值tx和ty,(x, y)中心坐标计算如下:例如,预测tx=1会将边界框向右移动Anchor框的宽度,预测tx=−1会将其向左移动相同的宽度。这个公式是不受限制的,所以任何Anchor框都可以在图像任一点结束,而不管在哪个位置预测该边界框。随机初始化模型需要很长时间才能稳定以预测合理的偏移量。我们没有预测偏移量,而是按照YOLO的方法预测相对于网格单元位置的位置坐标。这使得真值落到了0和1之间。我们使用logistic激活函数来限制网络的预测值落在这个范围内。网络预测输出特征图中每个格子的5个边界框。网络预测每个边界框的5个坐标,tx、ty、tw、th和to。如果格子相对于图像的左上角偏移量为(cx, cy),边界框先验的宽度和高度为pw, ph,那么预测结果对应为:由于我们限制位置预测参数化更容易学习,使网络更稳定。使用维度聚类以及直接预测边界框中心位置的方式比使用Anchor框的版本将YOLO提高了近5%。细粒度特征。这个修改后的YOLO在13×13特征图上预测检测结果。虽然这对于大型目标来说已经足够了,但它通过更细粒度的特征定位出更小的目标。Faster R-CNN和SSD都在网络的各种特征图上运行他们提出的网络,以获得一系列的分辨率。我们采用不同的方法,仅仅添加一个passthrough层,从26x26分辨率的更早层中提取特征。passthrough层通过将相邻特征堆叠到不同的通道而不是空间位置来连接较高分辨率特征和较低分辨率特征,类似于ResNet中的恒等映射。将26×26×512特征图变成13×13×2048特征图(译者注:如何将26×26×512变成13×13×2048?26×26×512首先变成4个13×13×512,然后在通道方向上将4个拼接在一起就成了13×13×2048),其可以与原始特征连接。我们的检测器运行在这个扩展的特征图之上,以便它可以访问细粒度的特征。这会使性能提高1%。多尺度训练。原来的YOLO使用448×448的输入分辨率。通过添加Anchor框,我们将分辨率更改为416×416。但是,由于我们的模型只使用卷积层和池化层,因此它可以动态调整大小。我们希望YOLOv2能够鲁棒地运行在不同大小的图像上,因此我们可以将该特性训练到模型中。我们没有固定输入图像的大小,而是每隔几次迭代就改变网络。每隔10个批次我们的网络会随机选择一个新的图像尺寸大小。由于我们的模型缩减了32倍,我们从下面的32的倍数中选择:{320,352,…,608}。因此最小的是320×320,最大的是608×608。我们将网络调整到这些尺寸并继续训练。这个模型架构迫使网络学习如何在各种输入维度上完成较好的预测。这意味着相同的网络可以预测不同分辨率下的检测结果。在更小尺寸上网络运行速度更快,因此YOLOv2在速度和准确性之间得到了一个简单的折衷。分辨率较低时YOLOv2可以作为一个低成本、相当准确的检测器。在288×288时,其运行速度超过90FPS,mAP与Fast R-CNN差不多。这使其成为小型GPU、高帧率视频或多视频流的理想选择。在高分辨率下,YOLOv2是VOC 2007上最先进的检测器,mAP达到了78.6,同时能够保持实时检测的速度要求。如表3所示为YOLOv2与其他框架在VOC 2007上的比较。图4进一步实验。我们在VOC 2012上训练YOLOv2检测模型。表4所显为YOLOv2与其他最先进的检测系统性能比较的结果。YOLOv2取得了73.4 mAP的同时运行速度比比对方法快的多。我们在COCO上进行了训练,并与表5中其他方法进行比较。在VOC指标(IOU = 0.5)上,YOLOv2得到44.0 mAP,与SSD和Faster R-CNN相当。![表5:在COCO test-dev2015数据集上的结果。表改编自[11]](/usr/uploads/auto_save_image/f017206828388e0fedf5e4b4cd5b27c6.png)3. 更快我们不仅希望检测是准确的,而且我们还希望它速度也快。大多数检测应用(如机器人或自动驾驶机车)依赖于低延迟预测。为了最大限度提高性能,我们从头开始设计YOLOv2。大多数检测框架依赖于VGG-16作为的基础特征提取器[17]。VGG-16是一个强大的、准确的分类网络,但它有些过于复杂。在单张图像224×224分辨率的情况下,VGG-16的卷积层运行一次前向传播需要306.90亿次浮点运算。YOLO框架使用基于GoogLeNet架构[19]的自定义网络。这个网络比VGG-16更快,一次前向传播只有85.2亿次的计算操作。然而,它的准确性比VGG-16略差(译者注:ILSVRC2014竞赛中GoogLeNet获得分类任务第一名,VGG第二名,但是在定位任务中VGG是第一名)。在ImageNet上,对于单张裁剪图像,224×224分辨率下的top-5准确率,YOLO的自定义模型获得了88.0%,而VGG-16则为90.0%。Darknet-19。我们提出了一个新的分类模型作为YOLOv2的基础。我们的模型建立在网络设计先前工作以及该领域常识的基础上。与VGG模型类似,我们大多使用3×3卷积核,并在每个池化步骤之后使得通道数量加倍[17]。按照Network in Network(NIN)的工作,我们使用全局平均池化的结果做预测,并且使用1×1卷积核来压缩3×3卷积之间的特征表示[9]。我们使用批归一化来稳定训练、加速收敛,并正则化模型[7]。我们的最终模型叫做Darknet-19,它有19个卷积层和5个最大池化层。完整描述请看表6。Darknet-19只需要55.8亿次运算来处理图像,但在ImageNet上却达到了72.9%的top-1准确率和91.2%的top-5准确率。分类训练。我们使用Darknet神经网络结构,使用随机梯度下降、初始学习率为0.1、学习率多项式衰减系数为4、权重衰减为0.0005、动量为0.9,在标准ImageNet 1000类分类数据集上训练网络160个迭代周期[13]。在训练过程中,我们使用标准的数据增强技巧,包括随机裁剪、旋转、以及色调、饱和度和曝光的改变。如上所述,在我们对224×224的图像进行初始训练之后,我们对网络在更大的尺寸448上进行了fine tune。对于这种fine tune,我们使用上述参数进行训练,但是只有10个迭代周期,并且以10−3的学习率开始(译者注:fine-tune时通常会使用较低的学习率)。在这种更高的分辨率下,我们的网络达到了76.5%的top-1准确率和93.3%的top-5准确率。检测训练。我们修改这个网络使得可以用于检测任务,删除了最后一个卷积层,加上了三层具有1024个卷积核的3×3卷积层,每层后面接1×1卷积层,卷积核数量与我们检测输出数量一致。对于VOC,我们预测5个边界框,每个边界框有5个坐标和20个类别,所以有125个卷积核。我们还添加了从最后的3×3×512层到倒数第二层卷积层的直通层,以便我们的模型可以使用细粒度特征。我们训练网络160个迭代周期,初始学习率为10−3,在60个和90个迭代周期时将学习率除以10。我们使用0.0005的权重衰减和0.9的动量。我们对YOLO和SSD进行类似的数据增强:随机裁剪、色彩改变等。我们对COCO和VOC使用相同的训练策略。4. 更强我们提出了一个联合训练分类和检测数据的机制。我们的方法使用标记为检测的图像来学习边界框坐标预测和目标之类的特定检测信息以及如何对常见目标进行分类。它使用仅具有类别标签的图像来扩展可检测类别的数量。在训练期间,我们混合来自检测数据集和分类数据集的图像。当我们的网络看到标记为检测的图像时,我们可以基于完整的YOLOv2损失函数进行反向传播。当它看到一个分类图像时,我们只能从该架构特定的分类部分反向传播损失。这种方法存在一些挑战。检测数据集只有常见目标和通用标签,如“狗”或“船”。分类数据集具有更广更深的标签范围。ImageNet有超过一百种品种的狗,包括Norfolk terrier,Yorkshire terrier和Bedlington terrier。如果我们想在两个数据集上训练,我们需要一个连贯的方式来合并这些标签。大多数分类方法使用跨所有可能类别的softmax层来计算最终的概率分布。使用softmax假定这些类是互斥的。这给数据集的组合带来了问题,例如你不想用这个模型来组合ImageNet和COCO,因为类Norfolk terrier和dog不是互斥的。我们可以改为使用多标签模型来组合不假定互斥的数据集。这种方法忽略了我们已知的关于数据的所有结构,例如,所有的COCO类是互斥的。分层分类。ImageNet标签是从WordNet中提取的,这是一个构建概念及其相互关系的语言数据库[12]。在WordNet中,Norfolk terrier和Yorkshire terrier都是terrier的下义词,terrier是一种hunting dog,hunting dog是dog,dog是canine等。分类的大多数方法假设标签是一个扁平结构,但是对于数据集的组合,结构正是我们所需要的。WordNet的结构是有向图,而不是树,因为语言是复杂的。例如,dog既是一种canine(犬),也是一种domestic animal(家畜),它们都是WordNet中的同义词。我们不是使用完整的图结构,而是通过从ImageNet的概念中构建分层树来简化问题。为了构建这棵树,我们检查了ImageNet中的视觉名词,并查看它们通过WordNet图到根节点的路径,在这种情况下是“物理对象”。许多同义词通过图只有一条路径,所以首先我们将所有这些路径添加到我们的树中。然后我们反复检查我们留下的概念,并尽可能少地添加生长树的路径。所以如果一个概念有两条路径到一个根,一条路径会给我们的树增加三条边,另一条只增加一条边,我们选择更短的路径。最终的结果是WordTree,一个视觉概念的分层模型。为了使用WordTree进行分类,我们预测每个节点的条件概率,以得到同义词集合中每个同义词下义词的概率。例如,在terrier节点我们预测:Pr(Norfolk terrier|terrier)Pr(Yorkshire terrier|terrier)Pr(Bedlington terrier|terrier)...如果我们想要计算一个特定节点的绝对概率,我们只需沿着通过树到达根节点的路径,再乘以条件概率。所以如果我们想知道一张图片是否是Norfolk terrier,我们计算:Pr(Norfolk terrier)=Pr(Norfolk terrier|terrier)*Pr(terrier|hunting dog)…*Pr(mammal|Pr(animal)*Pr(animal|physical object)对于分类任务,我们假定图像只包含一个目标:Pr(physical object)=1。为了验证这种方法,我们在使用1000类ImageNet构建的WordTree上训练Darknet-19模型。为了构建WordTree1k,我们添加了所有将标签空间从1000扩展到1369的中间节点。在训练过程中,我们将真实标签向树上面传播,以便如果图像被标记为Norfolk terrier,则它也被标记为dog和mammal等。为了计算条件概率,我们的模型预测了具有1369个值的向量,并且我们计算了相同概念的下义词在所有同义词集上的softmax,见图5。使用与之前相同的训练参数,我们的分层Darknet-19达到71.9%的top-1准确率和90.4%的top-5准确率。尽管增加了369个额外的概念,而且我们的网络预测了一个树状结构,但我们的准确率仅下降了一点点。以这种方式进行分类也有一些好处。在新的或未知的目标类别上性能不会下降太多。例如,如果网络看到一只狗的照片,但不确定它是什么类型的狗,它仍然会高度自信地预测“狗”,但是扩展到下义词后可能有更低的置信度。这个构想也适用于检测。现在,我们不是假定每张图像都有一个目标,而是使用YOLOv2的目标预测器给我们Pr(physical object)的值。检测器预测边界框和概率树。我们遍历树,在每个分割中采用最高的置信度路径,直到达到某个阈值,然后我们预测目标类。使用WordTree组合数据集。我们可以使用WordTree以合理的方式将多个数据集组合在一起。我们只需将数据集中的类别映射到树中的同义词集(synsets)即可。图6显示了使用WordTree来组合来自ImageNet和COCO的标签的示例。WordNet是非常多样化的,所以我们可以在大多数数据集中使用这种技术。联合分类和检测。现在我们可以使用WordTree组合数据集,我们可以在分类和检测上训练联合模型。我们想要训练一个非常大规模的检测器,所以我们使用COCO检测数据集和完整的ImageNet版本中的前9000个类来创建我们的组合数据集。我们还需要评估我们的方法,因此还添加了ImageNet检测挑战中未包含的类。该数据集的对应的WordTree有9418个类别。ImageNet相比于COCO是一个更大的数据集,所以我们通过对COCO进行过采样来平衡数据集,使得ImageNet仅仅大于4:1的比例。使用这个数据集我们训练YOLO9000。我们使用基础的YOLOv2架构,但只有3个先验(priors)而不是5个来限制输出大小。当我们的网络看到一个检测图像时,我们正常地对损失进行反向传播。对于分类损失,我们仅在等于或高于标签对应的层对损失进行反向传播。例如,如果标签是“狗”,我们将沿着树向下进一步预测“德国牧羊犬”与“金毛猎犬”之间的差异,因为我们没有这些信息。当它看到分类图像时,我们只能反向传播分类损失。要做到这一点,我们只需找到预测该类别最高概率的边界框,然后计算其预测树上的损失。我们还假设预测边界框与真实标签重叠至少0.3的IOU,并且基于这个假设反向传播目标损失。使用这种联合训练,YOLO9000学习使用COCO中的检测数据来查找图像中的目标,并学习使用来自ImageNet的数据对各种目标进行分类。我们在ImageNet检测任务上评估了YOLO9000。ImageNet的检测任务与COCO共有的目标类别有44个,这意味着YOLO9000只能看到大多数测试图像的分类数据,而不是检测数据。YOLO9000在从未见过任何标记的检测数据的情况下,整体上获得了19.7 mAP,在不相交的156个目标类别中获得了16.0 mAP。这个mAP高于DPM的结果,但是YOLO9000在不同的数据集上训练,只有部分监督[4]。它也同时检测9000个其他目标类别,所有的都是实时的。当我们分析YOLO9000在ImageNet上的性能时,我们发现它很好地学习了新的动物种类,但是却在像服装和设备这样的学习类别中效果不好。新动物更容易学习,因为目标预测可以从COCO中的动物泛化的很好。相反,COCO没有任何类型的衣服的边界框标签,只有针对人的检测标签,因此YOLO9000很难建模好“墨镜”或“泳裤”等类别。5. 结论我们介绍了YOLOv2和YOLO9000,两个实时检测系统。YOLOv2在各种检测数据集上都是最先进的,也比其他检测系统更快。此外,它可以运行在各种图像大小,以提供速度和准确性之间的平滑折衷。YOLO9000是一个通过联合优化检测和分类来检测9000多个目标类别的实时框架。我们使用WordTree将各种来源的数据和我们的联合优化技术相结合,在ImageNet和COCO上同时进行训练。YOLO9000是在检测和分类之间缩小数据集大小差距的重要一步。我们的许多技术都可以泛化到目标检测之外。我们对ImageNet的WordTree表示为图像分类提供了更丰富、更详细的输出空间。使用分层分类的数据集组合在分类和分割领域将是有用的。像多尺度训练这样的训练技术可以为各种视觉任务提供益处。对于未来的工作,我们希望使用类似的技术来进行弱监督的图像分割。我们还计划使用更强大的匹配策略来改善我们的检测结果,以在训练期间将弱标签分配给分类数据。计算机视觉需要大量标记的数据。我们将继续寻找方法,将不同来源和数据结构的数据整合起来,形成更强大的视觉世界模型。参考文献[1] S. Bell, C. L. Zitnick, K. Bala, and R. Girshick. Inside-outside net: Detecting objects in context with skip pooling and recurrent neural networks. arXiv preprint arXiv:1512.04143, 2015. 6[2] J. Deng, W. Dong, R. Socher, L.-J. Li, K. Li, and L. Fei- Fei. Imagenet: A large-scale hierarchical image database. In Computer Vision and Pattern Recognition, 2009. CVPR 2009. IEEE Conference on, pages 248–255. IEEE, 2009. 1[3] M. Everingham, L. Van Gool, C. K. Williams, J. Winn, and A. Zisserman. The pascal visual object classes (voc) challenge. International journal of computer vision, 88(2):303– 338, 2010. 1[4] P. F. Felzenszwalb, R. B. Girshick, and D. McAllester. Discriminatively trained deformable part models, release 4. http://people.cs.uchicago.edu/pff/latent-release4/. 8[5] R. B. Girshick. Fast R-CNN. CoRR, abs/1504.08083, 2015. 4, 5, 6[6] K. He, X. Zhang, S. Ren, and J. Sun. Deep residual learning for image recognition. arXiv preprint arXiv:1512.03385, 2015. 2, 4, 5[7] S. Ioffe and C. Szegedy. Batch normalization: Accelerating deep network training by reducing internal covariate shift. arXiv preprint arXiv:1502.03167, 2015. 2, 5[8] A. Krizhevsky, I. Sutskever, and G. E. Hinton. Imagenet classification with deep convolutional neural networks. In Advances in neural information processing systems, pages 1097–1105, 2012. 2[9] M. Lin, Q. Chen, and S. Yan. Network in network. arXiv preprint arXiv:1312.4400, 2013. 5[10] T.-Y. Lin, M. Maire, S. Belongie, J. Hays, P. Perona, D. Ramanan, P. Dollar, and C. L. Zitnick. Microsoft coco: Common objects in context. In European Conference on Computer Vision, pages 740–755. Springer, 2014. 1, 6[11] W. Liu, D. Anguelov, D. Erhan, C. Szegedy, and S. E. Reed. SSD: single shot multibox detector. CoRR, abs/1512.02325, 2015. 4, 5, 6[12] G. A. Miller, R. Beckwith, C. Fellbaum, D. Gross, and K. J. Miller. Introduction to wordnet: An on-line lexical database. International journal of lexicography, 3(4):235–244, 1990. 6[13] J. Redmon. Darknet: Open source neural networks in c. http://pjreddie.com/darknet/, 2013–2016. 5[14] J. Redmon, S. Divvala, R. Girshick, and A. Farhadi. You only look once: Unified, real-time object detection. arXiv preprint arXiv:1506.02640, 2015. 4, 5[15] S. Ren, K. He, R. Girshick, and J. Sun. Faster r-cnn: Towards real-time object detection with region proposal net- works. arXiv preprint arXiv:1506.01497, 2015. 2, 3, 4, 5, 6[16] O. Russakovsky, J. Deng, H. Su, J. Krause, S. Satheesh, S. Ma, Z. Huang, A. Karpathy, A. Khosla, M. Bernstein, A. C. Berg, and L. Fei-Fei. ImageNet Large Scale Visual Recognition Challenge. International Journal of Computer Vision (IJCV), 2015. 2[17] K. Simonyan and A. Zisserman. Very deep convolutional networks for large-scale image recognition. arXiv preprint arXiv:1409.1556, 2014. 2, 5[18] C. Szegedy, S. Ioffe, and V. Vanhoucke. Inception-v4, inception-resnet and the impact of residual connections on learning. CoRR, abs/1602.07261, 2016. 2[19] C. Szegedy, W. Liu, Y. Jia, P. Sermanet, S. Reed, D. Anguelov, D. Erhan, V. Vanhoucke, and A. Rabinovich. Going deeper with convolutions. CoRR, abs/1409.4842, 2014. 5[20] B. Thomee, D. A. Shamma, G. Friedland, B. Elizalde, K. Ni, D. Poland, D. Borth, and L.-J. Li. Yfcc100m: The new data in multimedia research. Communications of the ACM, 59(2):64–73, 2016. 1参考资料目标检测经典论文——YOLOv2论文翻译(纯中文版):YOLO9000:更好、更快、更强:https://blog.csdn.net/jwenxue/article/details/107749188?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-18&spm=1001.2101.3001.4242
2021年02月04日
472 阅读
0 评论
0 点赞
2021-02-03
【YOLOv1论文翻译】:YOLO: 一体化的,实时的物体检测
【YOLOv1论文翻译】:YOLO: 一体化的,实时的物体检测论文原文:You Only Look Once Unified, Real-Time Object Detection摘要 我们介绍一种新的物体检测方法YOLO。与先前的物体检测方法是重新设置分类器来执行检测不同,我们将物体检测方法看做一个回归问题,去预测空间分离的边界框和相关类别概率。单个神经网络从整个图片中一次性预测边界框和类别概率。由于整个检测流程是一个单一网络,所以可以进行端到端的直接对检测性能进行优化。 我们的这种单一网络结构体系速度非常快。我们的基本YOLO模型实时处理图像速度为每秒45帧。较小的YOLO模型版本,Fast YOLO可以实现每秒155帧的实时检测速度,同时实现mAP是其他物体检测网络的两倍左右。与当前最先进的物体检测方法相比,YOLO会出现较多的定位误差,但是从背景中检测出假阳性目标较少。最后,YOLO可以学习物体非常抽象的特征,所以在自然图像之外的其他检测领域比如艺术品的检测中,YOLO优于包括DPM和R-CNN在内的其他检测方法。1.介绍 人们只需瞥一眼图片就知道图片中有什么物体,物体的位置及它们之间的联系。人类的视觉系统是快速而准确的,使我们可以做很复杂的事,比如开车时不用刻意去思考。快速,准确的物体检测算法将允许计算机在没有专用传感器的情况下驾驶汽车,使辅助设备能够向人类用户传达实时场景信息,并释放通用,响应式机器人系统的潜力。 当前的检测系统重新利用分类器来执行检测。 为了检测物体,这些系统为该物体提供一个分类器,并在不同的位置评估它,并在测试图像中进行缩放。 像可变形零件模型(DPM)这样的系统使用滑动窗口方法,其中分类器在整个图像上以均匀间隔的位置运行[10]。 最近的方法比如R-CNN使用候选区域的方法,首先在图像中生成候选框,然后在候选框上运行分类器。分类之后,后续的操作是优化边界框、消除重复检测,最后根据图像中其他物体来重新定位边界框。这些复杂的流程很慢而且优化困难,因为每个组件都需要单独训练。 我们将物体检测系统,输入图像像素输出边界框坐标和类概率,重新设计为一个回归问题。使用我们的系统,只需运行一次就可以知道图像中有什么物体以及物体的位置。 YOLO非常简单:参考图片1,单个神经网络可以同时预测多个边界框和类概率 ,YOLO直接在整个图像上训练,并直接优化检测性能。这个统一的模型比传统的物体检测方法有几个优势。 第一,YOLO速度非常快。由于我们的检测是当做一个回归问题,不需要很复杂的流程。在测试的时候我们只需将一个新的图片输入网络来检测物体。在Titan X GPU上我们的基本网络检测速度可以实现45帧每秒,快速版本检测速度可以达到155帧每秒。这意味着我们可以以小于25毫秒的延迟处理流媒体视频。此外YOLO相比其他实时检测系统可以达到两倍的mAP,请参阅我们的项目网页http://pjreddie.com/yolo/.,上面有我们项目在网络摄像头上的实时运行演示。 第二,YOLO在预测时可以整体的检测图像。与基于滑动窗口和候选区域的方法不同,在训练和测试期间YOLO可以看到整个图像,所以它隐式的编码相关类的上下文信息及外观。Fast R-CNN是一种顶级的检测方法,由于它无法看到更大的上下文信息所以会从背景中检测出错误的物体,YOLO出现背景误差的概率是Fast R-CNN的一半。 第三,YOLO学习图像的抽象特征。当在自然图像上进行训练,并在艺术品上测试时,YOLO的效果大幅优于DPM和R-CNN等顶级检测方法。由于YOLO是高度抽象化的,所以在应用到新的领域或者有意外输入时不太会出现故障。 YOLO 在检测准确率上仍然大幅落后于最好的检测方法。虽然YOLO可以很快的识别出图像中的物体,但是在精准定位物体尤其是较小的物体位置上还需要更多的努力。我们在实验中正进一步测试如何平衡这些方面。 我们所有的训练和测试代码都是开源的,还提供一些预训练的模型可供下载。2.统一检测 我们将物体检测的单独组件集成到一个神经网络中。我们的网络使用整个图像的特征来预测每个边界框,网络还同时预测所有类的所有边界框,这也就意味着我们的网络全面的预测整个图像和图像中的所有的类。YOLO网络的设计保证能够实现端到端的训练和实时检测的速度,同时实现较高的检测平均精度。 我们的系统将输入图像划分成S × S个网格。如果一个物体的中心点在某个网格中,则这个网格负责检测这个物体。每个网格单元预测B个边界框以及每个边界框的confidence(置信度)。这些confidence反映了网络模型对该边界框是否含有物体的信心,以及边界框位置预测的准确度。 在形式上我们将confidence定义为 C = Pr(Object) ∗ IOU truth pred( Pr(Object)网格存在物体为1,不存在为0),如果网格中不包含物体则Pr(Object) = 0则confidence为0,包含物体Pr(Object) = 1则confidence等于预测边界框和真实边界框的IOU(交并比)。 每个边界框有5个预测值:x,y,w,h,confidence,(x,y)代表预测边界框的中心点坐标,w,h是边界框的宽度和高度,confidence是预测边界框和真实边界框的IOU。 每个网格预测C个条件类别概率, Pr(Class i |Object),这是网格中含有物体的条件下属于某个类别的概率,每个网格只预测一组条件类别概率,B个边界框公用。 测试时我们将条件类概率和confidence相乘,为我们提供了每个边界框在各个类别的得分值 ,这些得分值代表该类别物体出现在框中的概率和边界框与物体的拟合程度。 在PASCAL VOC数据集上评估YOLO,S = 7,B = 2,C = 20(因为PASCAL VOC数据集中有20个标记类) ,我们的最终预测结果是7 × 7 × 30张量。2.1设计 我们将模型以卷积神经网络来实现,在PASCAL VOC数据集上评估。网络的初始卷积层用来提取图像特征,全连接层用来预测类别概率和坐标。 我们的网络结构受到图像分类网络GoogLeNet[34]的启发,我们的网络包括24层卷积层和2层全连接层,不同于GoogLeNet使用的Inception块,我们使用和Lin等人【22】一样的结构,一个1×1卷积层后面跟一个3×3卷积层。完整的网络结构可以查看图片3。 为了加快检测速度我们还训练了一个快速的YOLO版本。Fast YOLO 使用较少的卷积层,9层而不是普通版的24层,和更小的卷积核。除了网络较小,Fast YOLO和YOLO训练和测试参数是一样的。我们的网络最终输出是7 × 7 × 30的预测张量。2.2训练 我们在ImageNet 1000类数据集上预训练我们的卷积层。预训练时我们使用图3中的前20为向量、一个平均池化层、一个全连接层。我们训练这个网络一周时间, 在ImageNet 2012数据集中获得了88%准确率排名位于前5名,与 Caffe上训练的模型中的GoogLeNet模型相当。我们使用 Darknet框架进行所有的训练和预测。 然后我们转化网络执行检测。Ren等人提出在预训练模型中加入卷积层和全连接层可以提高性能[29]。根据他们的想法,我们添加了随机初始化参数的4个卷积层和2个全连接层。检测任务需要细粒度的视觉信息,所以我们将网络输入的分辨率从224×224增加到448×448。 我们在最后一层输出类别概率和边界框坐标。我们通过图像的宽度和高度来标准化边界框的宽度和高度至0到1之间,我们将边界框x和y坐标参数化为相对特定网格的偏移量,使其值处于0到1之间。我们对最后一层使用线性激活函数,其他层使用以下激活函数。 我们使用平方和误差来优化模型。使用平方和误差较容易优化,但是不能完全符合我们最大化平均精度的目标。它将定位误差和分类误差同等对待是不太合理的,而且在图像中有很多网格不包含任何物体,将这些网格的置信度趋向于零时的梯度将会超过含有物体的网格的梯度,这会导致网络不稳定,从而使网络在训练初期就出现梯度爆炸。 为了弥补这一点,我们增加了边界框坐标预测损失的权重,并减少了不包含物体的边界框的置信度预测损失的权重。我们使用两个参数λcoord和λnoobj来完成这个。我们设置λcoord = 5和λnoobj =0 .5。 平方和误差计算损失时将大框和小框同等对待,同样的一个损失值对大框的影响小于对小框的影响。为了解决这个问题,我们计算损失时先对框的宽度和高度求根号再计算平方和。 YOLO为每个网格预测多个边界框。在训练时我们希望每个物体只有一个边界框负责检测这个物体。我们选择和真实物体位置IOU最大的边界框作为负责检测这个物体的边界框。这使得我们的边界框预测变量都负责预测特定物体。所以每个预测变量可以更好地预测边界框尺寸,纵横比或物体类别,从而改善整体召回率。 训练期间我们优化下图中的损失函数: 其中的$1^{obj}_{ij}$代表的是第i个网格中是否含有物体,以及第i个网格中的第j个边界框负责预测这个物体。 请注意,如果网格中含有物体,损失函数只需考虑分类损失(因此条件类概率在前面讲)。如果这个预测器负责预测真实边界框(和网格中的所有预测器都有最高的IOU),损失函数只考虑预测坐标损失。 我们在PASCAL VOC 2007和2012的训练和验证数据集上对网络进行了大约135个epochs的训练。当在VOC 2012上测试的时候,我们也包含了VOC 2007的测试数据用来训练。训练中我们的batch size为64,momentum为0.9,decay为0.0005。 我们的learning rate(学习率)计划如下:在第一个epoch中我们将learning rate慢慢的从0.001提高到0.01,如果我们从较高的学习率开始训练,由于不稳定的梯度会导致网络发散。我们以0.01训练75个epoch,再以0.001训练30个epoch,以0.0001训练30个epoch。 为了避免过拟合我们使用了dropout (神经元随机失效)层和数据增强的办法。在第一个连接层之后,速率为0.5的dropout层防止了层之间的联合性(dropout强迫一个神经单元,和随机挑选出来的其他神经单元共同工作,达到好的效果。消除减弱了神经元节点间的联合适应性,增强了泛化能力。)[18]。对于数据增强,我们引入达到原始图像大小20%的随机缩放和平移。我们还在HSV色彩空间中随机调整图像的曝光和饱和度达1.5倍。2.3前向传播 和训练时一样,在检测测试图像时只需网络执行一次预测。在PASCAL VOC上为每个图像预测98个边界框,每个边界框预测一个置信度得分。不像基于分类器的检测方法,YOLO因为只需运行一个网络,所以执行速度很快。 网格的设计在边界框预测中强制实现空间多样性。通常我们很清楚物体落入哪个网格中,并且模型为每个物体只预测一个边界框。但是,一些比较大的物体或者是在跨越多个网格边界的物体,可以被多个网格都很好的检测出来(即一个物体被多次检测出来造成多重检测问题)。可以使用NMS(非极大值抑制)来解决这种多重检测的问题。虽然NMS对YOLO性能的影响不像对R-CNN、DPM性能影响那么大,但也能提升2-3%的mAP值。2.4 YOLO的局限性 YOLO对边界框预测施加了强烈的空间约束,因为每个网格单元只预测两个框,并且只能有一个类。这种空间约束限制了模型能预测网格附近物体的数量。我们的模型在图像中出现的成群的小物体(比如鸟群)时将会出现物体间的竞争。 由于我们的模型从数据中学习如何预测边界框,因此它遇到新的数据或数据不寻常的高宽比或配置时将较难适应。因为我们的模型在输入图像中有多个下采样层,所以我们的模型是使用相对粗糙的特征来预测边界框。最后,我们在训练一个损失函数不断提高检测性能时,我们将小边框和大边框的损失同等对待。一个较小损失值对较大的边界框来说影响较小,但是对较小的边界框则意味着会极大地影响IOU。我们的误差主要来自检测定位误差。3.与其他检测系统对比 物体检测是计算机视觉领域的核心问题。检测流程通常是从输入图像中提取一组特征开始的(Haar [25], SIFT [23],HOG [4], convolutional features [6]) 。然后分类器[36, 21, 13, 10] 或定位器 [1, 32] 在特征空间中识别物体。这些分类器或定位器在整个图像上或在图像中某些区域子集上以滑动窗口方式运行[35,15,39]。我们将YOLO检测系统与几个顶级检测框架进行了比较,突出了主要的相似点和不同点。 Deformable Parts Model DPM 使用sliding window(滑动窗口)方法执行物体检测[10]。DPM使用不相交的管道来提取静态特征,对区域分类,预测高分边界框等。我们的系统用单个卷积神经网络取代了以上各个部分。网络是同时执行特征提取,边界框预测,非最大抑制和上下文推理这些操作。我们的网络不是静态的,而是在线训练和优化的。我们的网络是统一架构的比DPM速度更快更准确。 R-CNN R-CNN是使用region proposals(候选区域)的方式而不是滑动窗口的方式。Selective Search(选择性搜索)[35]生成候选的边界框,一个卷积网络提取特征,一个SVM给边界框评分,线性模型调整边界框,NMS消除重复检测。需要精确调整复杂的检测管道的每个阶段,这导致训练得到的系统运行缓慢,测试时每张图片耗时超过40s。 YOLO和R-CNN有一些相似之处。每个网格使用卷积特征预测候选框并对其评分。但是我们的系统对网格的预测施加空间限制,这一定程度上减少了重复检测问题。相比R-CNN提出约2000候选框,我们的YOLO提出较少的候选框只有98个。最后,我们整合了这些单独的组件,形成一个单一的同时优化的模型。 其他快速检测系统 Fast 和 Faster R-CNN 专注于通过共享计算和使用网络 候选区域取代选择性搜索来提高R-CNN的速度。虽然它们的速度和准确性都比R-CNN有所提高,但两者仍然达不到实时检测的要求。 许多工作集中在提高DPM速度上[31] [38] [5]。他们通过级联的方式加快HOG计算,并泛华到GPUs上。但是,DPM的实时速度只有30HZ。YOLO不是试图优化复杂的检测管道中的单个组件,而是完全抛出管道,并且设计的运行速度很快。单一类别的检测器比如人脸检测或者人员检测可以得到很好的优化,因为这些任务处理的特征变化较少。YOLO是一种通用的检测器,可以同时检测多种物体。 Deep MultiBox. 与R-CNN不同,Szegedy等人训练一个卷积网络而不是使用选择性搜索来预测感兴趣的区域。MultiBox还可以通过用单个类别预测替换置信预测来执行单个目标检测。但是MultiBox不能执行通用检测,因为它只是复杂管线中的一部分,还需要进一步的图像分类补丁。YOLO和MultiBox都使用卷积网络来预测图像中的边界框,但YOLO是一个完整的检测系统。 OverFeat Sermanet等人训练卷积神经网络以执行定位并使该定位器适于执行检测[32]。 OverFeat有效地执行滑动窗口检测,但它仍然是一个不相交的系统。OverFeat优化了定位,而不是检测性能。像DPM一样,定位器在进行预测时仅看到本地信息。OverFeat不能推测全局上下文,因此需要大量的后处理来产生相关检测。 MultiGrasp 我们的工作在设计方面类似于Redmon [27] 等人的抓取检测的工作。我们的网格预测边界框的方式是基于MultiGrasp为抓取检测的设计。但是抓取检测比物体检测要简单得多。MultiGrasp只需要从包含一个物体的图像中预测单个可抓取区域即可,它不必估计物体的大小,位置或边界或预测它的类,只需要找到适合抓取的区域。YOLO预测图像中多个类的多个对象的边界框和类概率。4.实验 首先我们在PASCAL VOC 2007上对比YOLO和其他实时检测系统。为了理解YOLO和多个R-CNN变体的区别,我们探讨了在VOC 2007上YOLO和Fast R-CNN(R-CNN系列变体中性能最高的版本[14])的损失。基于不同的错误文件,我们展示了YOLO可以重新调整Fast R-CNN的检测并且减少背景误报的错误,从而显著的提高性能。我们还展示了在VOC 2012上的测试性能,并和当前最先进的方法的mAP对比。最后,我们展示了在两个艺术品数据集上,YOLO比其他检测器更容易迁移到其他领域。4.1和其他实时系统对比 对象检测的许多研究工作都集中在快速制作标准检测管道上。 [5] [38] [31] [14] 17 。然而,只有Sadeghi等人,创造了一个实时检测系统(每秒30帧或更快)[31],我们将YOLO与他们在30Hz或100Hz下运行的DPM的GPU实现进行比较。而其他人的努力没有达到实时检测的要求。我们还比较了它们的相对mAP和速度,以检查物体检测系统的准确性和性能之间的权衡。 Fast YOLO是在PASCAL上最快的物体检测方法,而且据我们所知它也是目前最快的物体检测方法。它达到了52.7%的mAP,这比以前的实时检测系统的准确率高出一倍以上。YOLO在保持实时性能的同时将mAP提高到63.4%。 我们也用VGG-16来训练YOLO。这个模型比YOLO准确率更高但是速度降低很多。它与依赖于VGG-16的其他检测系统相比是更有效的,但由于它达不到实时系统速度要求,所以本文的其他部分将重点放在我们的这个更快的模型上。 最快的DPM可以在不牺牲太多mAP的情况下有效加速DPM,但仍然会将实时性能降低2倍[38]。与神经网络方法相比,它还受到DPM检测精度相对较低的限制。 R-CNN减去R用静态边界框提议取代选择性搜索[20]。虽然它的速度比R-CNN速度快得多,但是它还还达不到实时的要求, 而且因为没有很好的建议框所以精度很受影响。 快速R-CNN加速了R-CNN的分类阶段,但仍然依赖于选择性搜索,每个图像大约需要2秒才能生成建议边界框。所以虽然它的mAP很高,但是速度只有0.5 fps达不到实时速度要求。 目前的Fast R-CNN使用一个神经网络替代选择性搜索来生成建议边界框。比如:Szegedy等人。在我们的测试中,他们最精确的模型速度达到7 fps,而较小的,不太精确的模型以速度达到18 fps。VGG-16版本的Fast R-CNN比YOLO的mAP高10,但是速度比YOLO慢6倍。Zeiler-Fergus Faster R-CNN仅比YOLO慢2.5倍,但是精度还是不及YOLO。4.2. VOC 2007误差分析 为了进一步研究YOLO和最先进的检测器之间的差异,我们将详细分析在VOC 2007上的检测结果。我们将YOLO与Fast R-CNN进行比较,因为Fast R-CNN是P ASCAL上性能最高的检测器之一,它的检测是公开的。 我们使用Hoiem等人的方法和工具[19]。对于测试时的每个类别,我们查看该类别的前N个预测。 每个预测都是正确的,或者根据错误类型进行如下分类: 正确:正确类别 并且 IOU>.5 定位:正确类别 并且 .5>IOU>.1 相似:相似的类别 并且 IOU>.1 其他:类别错误 并且IOU>.1 背景:所有类别上IOU<.1 图4显示了所有20个类中平均每种错误类型的细分。YOLO努力的去准确定位物体。YOLO中的定位错误比其他所有类型错误之和还多。Fast R-CNN的定位错误更少但是背景错误更多,它最好的检测结果中有13.6%是假阳(本来不含有物体误报为有物体)。Fast R-CNN对背景的误报错误是YOLO的三倍。 4.3. Fast R-CNN和YOLO相结合 与Fast R-CNN相比,YOLO的背景误报错误要少得多。 通过使用YOLO减小Fast R-CNN的背景误报错误,我们可以显着提升性能。对于R-CNN预测的每个边界框,我们检查YOLO是否预测了一个类似的框。如果确实如此,我们会根据YOLO预测的概率和两个框之间的重叠来提高该预测得分。 最好的Fast R-CNN模型在VOC 2007测试集上获得了71.8%的mAP。当与YOLO结合使用时,其mAP增加了3.2%达到75.0%。 我们还尝试将最好的Fast R-CNN模型与其他几个版本的Fast R-CNN相结合。 这些结合使mAP小幅增加0.3%和0.6%之间,详见表2。 YOLO带来的性能提升不是模型集成的结果,因为集成不同版本的Fast R-CNN几乎没有什么性能提升。相反,正是因为YOLO在测试中犯了各种各样的错误,导致它能很有效地提升Fast R-CNN的性能。不幸的是因为我们是分别训练各个模型然后结合结果,所以系统没有从YOLO的快速性上受益,速度没有什么提高。但是,因为YOLO速度很快,所以相对单独的Fast R-CNN,结合YOLO之后不会增加多少计算时间。4.4 VOC 2012结果 在VOC 2012测试集中,YOLO的mAP分数为57.9%。这低于现有技术水平,更接近使用VGG-16的原始R-CNN,参见表3。与最接近的竞争对手相比,我们的系统在小物体检测时有物体间竞争。在瓶子,羊,电视/监视器等类别上,YOLO得分比R-CNN或Feature Edit低8-10%。然而,在其他类别如猫和火车上,YOLO实现了更高的性能。我们的Fast R-CNN + YOLO组合模型是性能最高的检测方法之一。 Fast R-CNN从与YOLO的组合中获得了2.3%的提升,使其在公共排行榜上提升了5位。4.5抽象性 艺术作品中的人物检测 用于对象检测的学术数据集是从同一分布中提取训练和测试数据。 在实际应用中,很难预测所有可能的用例,测试数据可能与系统之前的情况不同[3]。我们将YOLO与其他检测系统在毕加索数据集[12]和人物艺术数据集[3]上进行了比较,这两个数据集是用来测试艺术品中的人员检测。 图5展示了YOLO和其他系统的性能比较。作为参考,我们提供了只在VOC2007上训练的模型的人员检测AP。 Picasso模型在VOC 2012上训练,而People-Art 在VOC2010上训练。 R-CNN在VOC 2007上有较高的AP,但是在艺术品领域性能就急剧下降。R-CNN使用选择性搜索来调整自然图像的建议边界框。 R-CNN中的分类器步骤只能看到小区域,所以需要很好的建议边界框。 DPM在应用于艺术品时可以很好的保持它的AP。之前的工作认为DPM表现良好是因为它具有物体的形状和布局的空间模型。虽然DPM不会像R-CNN那样退化,但是它的起始AP比较低。5.实地场景的实时检测 YOLO是一款快速而准确的检测器,非常适合应用在计算机视觉领域。我们将YOLO连接到网络摄像头,并验证它是否保持实时性能,计算时间时包括从摄像头获取图像并显示检测结果的时间。由此生成的系统是交互式的。虽然YOLO可以单独处理图像,但是当它和网络摄像头连接起来时就像一个追踪系统,在物体运动或者变化的时候实时检测系统。系统演示和源代码可以在我们的项目网站上找到:http://pjreddie.com/yolo/。6:结论 我们介绍了一款一体化(端到端)的物体检测系统YOLO。我们的模型结构很简单,可以在整个图像上进行训练。与基于分类器的方法不同,YOLO针对与检测性能直接相关的损失函数来训练,而且整个模型是联合训练的。 Fast YOLO是目前文献中最快的通用物体检测系统,YOLO引领目前最先进的实时物体检测技术。YOLO还可以很好的迁移到新的领域,这使它成为需要快速高效的物体检测系统的应用的理想选择。致谢:本项工作得到了ONR N00014-13-1-0720,NSF IIS-1338054和艾伦杰出研究员奖的部分支持。参考文献[1] M. B. Blaschko and C. H. Lampert. Learning to localize ob- jects with structured output regression. In Computer Vision– ECCV 2008, pages 2–15. Springer, 2008. 4[2] L. Bourdev and J. Malik. Poselets: Body part detectors trained using 3d human pose annotations. In International Conference on Computer Vision (ICCV), 2009. 8[3] H. Cai, Q. Wu, T. Corradi, and P. Hall. The cross- depiction problem: Computer vision algorithms for recog- nising objects in artwork and in photographs. arXiv preprint arXiv:1505.00110, 2015. 7[4] N. Dalal and B. Triggs. Histograms of oriented gradients for human detection. In Computer Vision and Pattern Recogni- tion, 2005. CVPR 2005. IEEE Computer Society Conference on, volume 1, pages 886–893. IEEE, 2005. 4, 8[5] T. Dean, M. Ruzon, M. Segal, J. Shlens, S. Vijaya- narasimhan, J. Yagnik, et al. Fast, accurate detection of 100,000 object classes on a single machine. In Computer Vision and Pattern Recognition (CVPR), 2013 IEEE Confer- ence on, pages 1814–1821. IEEE, 2013. 5[6] J. Donahue, Y. Jia, O. Vinyals, J. Hoffman, N. Zhang, E. Tzeng, and T. Darrell. Decaf: A deep convolutional acti- vation feature for generic visual recognition. arXiv preprint arXiv:1310.1531, 2013. 4[7] J. Dong, Q. Chen, S. Yan, and A. Yuille. Towards unified object detection and semantic segmentation. In Computer Vision–ECCV 2014, pages 299–314. Springer, 2014. 7[8] D. Erhan, C. Szegedy, A. Toshev, and D. Anguelov. Scalable object detection using deep neural networks. In Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Confer- ence on, pages 2155–2162. IEEE, 2014. 5, 6[9] M. Everingham, S. M. A. Eslami, L. Van Gool, C. K. I. Williams, J. Winn, and A. Zisserman. The pascal visual ob- ject classeschallenge: A retrospective. International Journal of Computer Vision, 111(1):98–136, Jan. 2015. 2[10] P.F.Felzenszwalb, R.B.Girshick, D.McAllester, andD.Ra- manan. Object detection with discriminatively trained part based models. IEEE Transactions on Pattern Analysis and Machine Intelligence, 32(9):1627–1645, 2010. 1, 4[11] S. Gidaris and N. Komodakis. Object detection via a multi- region & semantic segmentation-aware CNN model. CoRR, abs/1505.01749, 2015. 7[12] S. Ginosar, D. Haas, T. Brown, and J. Malik. Detecting peo- pleincubistart. InComputerVision-ECCV2014Workshops, pages 101–116. Springer, 2014. 7[13] R. Girshick, J. Donahue, T. Darrell, and J. Malik. Rich fea- ture hierarchies for accurate object detection and semantic segmentation. In Computer Vision and Pattern Recognition (CVPR), 2014 IEEE Conference on, pages 580–587. IEEE, 2014. 1, 4, 7[14] R. B. Girshick. Fast R-CNN. CoRR, abs/1504.08083, 2015. 2, 5, 6, 7[15] S. Gould, T. Gao, and D. Koller. Region-based segmenta- tion and object detection. In Advances in neural information processing systems, pages 655–663, 2009. 4[16] B. Hariharan, P. Arbeláez, R. Girshick, and J. Malik. Simul- taneous detection and segmentation. In Computer Vision– ECCV 2014, pages 297–312. Springer, 2014. 7[17] K.He, X.Zhang, S.Ren, andJ.Sun. Spatialpyramidpooling in deep convolutional networks for visual recognition. arXiv preprint arXiv:1406.4729, 2014. 5[18] G. E. Hinton, N. Srivastava, A. Krizhevsky, I. Sutskever, and R. R. Salakhutdinov. Improving neural networks by pre- venting co-adaptation of feature detectors. arXiv preprint arXiv:1207.0580, 2012. 4[19] D.Hoiem, Y.Chodpathumwan, andQ.Dai. Diagnosingerror in object detectors. In Computer Vision–ECCV 2012, pages 340–353. Springer, 2012. 6[20] K. Lenc and A. Vedaldi. R-cnn minus r. arXiv preprint arXiv:1506.06981, 2015. 5, 6[21] R. Lienhart and J. Maydt. An extended set of haar-like fea- tures for rapid object detection. In Image Processing. 2002. Proceedings. 2002 International Conference on, volume 1, pages I–900. IEEE, 2002. 4[22] M. Lin, Q. Chen, and S. Yan. Network in network. CoRR, abs/1312.4400, 2013. 2[23] D. G. Lowe. Object recognition from local scale-invariant features. In Computer vision, 1999. The proceedings of the seventh IEEE international conference on, volume 2, pages 1150–1157. Ieee, 1999. 4[24] D. Mishkin. Models accuracy on imagenet 2012 val. https://github.com/BVLC/caffe/wiki/ Models-accuracy-on-ImageNet-2012-val. Ac- cessed: 2015-10-2. 3[25] C. P. Papageorgiou, M. Oren, and T. Poggio. A general framework for object detection. In Computer vision, 1998. sixth international conference on, pages 555–562. IEEE, 1998. 4[26] J. Redmon. Darknet: Open source neural networks in c. http://pjreddie.com/darknet/, 2013–2016. 3[27] J.RedmonandA.Angelova. Real-timegraspdetectionusing convolutional neural networks. CoRR, abs/1412.3128, 2014. 5[28] S. Ren, K. He, R. Girshick, and J. Sun. Faster r-cnn: To- wards real-time object detection with region proposal net- works. arXiv preprint arXiv:1506.01497, 2015. 5, 6, 7[29] S. Ren, K. He, R. B. Girshick, X. Zhang, and J. Sun. Object detection networks on convolutional feature maps. CoRR, abs/1504.06066, 2015. 3, 7[30] O. Russakovsky, J. Deng, H. Su, J. Krause, S. Satheesh, S. Ma, Z. Huang, A. Karpathy, A. Khosla, M. Bernstein, A. C. Berg, and L. Fei-Fei. ImageNet Large Scale Visual Recognition Challenge. International Journal of Computer Vision (IJCV), 2015. 3[31] M. A. Sadeghi and D. Forsyth. 30hz object detection with dpm v5. In Computer Vision–ECCV 2014, pages 65–79. Springer, 2014. 5, 6[32] P. Sermanet, D. Eigen, X. Zhang, M. Mathieu, R. Fergus, and Y. LeCun. Overfeat: Integrated recognition, localiza- tion and detection using convolutional networks. CoRR, abs/1312.6229, 2013. 4, 5[33] Z.ShenandX.Xue. Domoredropoutsinpool5featuremaps for better object detection. arXiv preprint arXiv:1409.6911, 2014. 7[34] C. Szegedy, W. Liu, Y. Jia, P. Sermanet, S. Reed, D. Anguelov, D. Erhan, V. Vanhoucke, and A. Rabinovich. Going deeper with convolutions. CoRR, abs/1409.4842, 2014. 2[35] J. R. Uijlings, K. E. van de Sande, T. Gevers, and A. W. Smeulders. Selective search for object recognition. Inter- national journal of computer vision, 104(2):154–171, 2013. 4[36] P. Viola and M. Jones. Robust real-time object detection. International Journal of Computer Vision, 4:34–47, 2001. 4[37] P. Viola and M. J. Jones. Robust real-time face detection. International journal of computer vision, 57(2):137–154, 2004. 5[38] J. Yan, Z. Lei, L. Wen, and S. Z. Li. The fastest deformable part model for object detection. In Computer Vision and Pat- tern Recognition (CVPR), 2014 IEEE Conference on, pages 2497–2504. IEEE, 2014. 5, 6[39] C. L. Zitnick and P. Dollár. Edge boxes: Locating object pro- posals from edges. In Computer Vision–ECCV 2014, pages 391–405. Springer, 2014. 4参考资料YOLOv1论文翻译:https://blog.csdn.net/woduoxiangfeiya/article/details/80866155
2021年02月03日
730 阅读
0 评论
0 点赞
2021-01-24
机器学习——几种距离度量方法
机器学习——几种距离度量方法1. 欧氏距离(Euclidean Distance)欧氏距离是最容易直观理解的距离度量方法,我们小学、初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离。二维平面上点a(x1,y1)与b(x2,y2)间的欧氏距离:三维空间点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离:n维空间点a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的欧氏距离(两个n维向量):2. 曼哈顿距离(Manhattan Distance)顾名思义,在曼哈顿街区要从一个十字路口开车到另一个十字路口,驾驶距离显然不是两点间的直线距离。这个实际驾驶距离就是“曼哈顿距离”。曼哈顿距离也称为“城市街区距离”(City Block distance)。二维平面两点a(x1,y1)与b(x2,y2)间的曼哈顿距离:n维空间点a(x11,x12,…,x1n)与b(x21,x22,…,x2n)的曼哈顿距离:3. 切比雪夫距离 (Chebyshev Distance)国际象棋中,国王可以直行、横行、斜行,所以国王走一步可以移动到相邻8个方格中的任意一个。国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离。二维平面两点a(x1,y1)与b(x2,y2)间的切比雪夫距离:n维空间点a(x11,x12,…,x1n)与b(x21,x22,…,x2n)的切比雪夫距离:4.标准化欧氏距离 (Standardized Euclidean Distance)定义: 标准化欧氏距离是针对欧氏距离的缺点而作的一种改进。标准欧氏距离的思路:既然数据各维分量的分布不一样,那先将各个分量都“标准化”到均值、方差相等。假设样本集X的均值(mean)为m,标准差(standard deviation)为s,X的“标准化变量”表示为:标准化欧氏距离公式:如果将方差的倒数看成一个权重,也可称之为加权欧氏距离(Weighted Euclidean distance)。5 余弦距离(Cosine Distance)几何中,夹角余弦可用来衡量两个向量方向的差异;机器学习中,借用这一概念来衡量样本向量之间的差异。二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式:两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n)的夹角余弦为:即:夹角余弦取值范围为[-1,1]。余弦越大表示两个向量的夹角越小,余弦越小表示两向量的夹角越大。当两个向量的方向重合时余弦取最大值1,当两个向量的方向完全相反余弦取最小值-1。参考资料机器学习——几种距离度量方法比较:https://my.oschina.net/hunglish/blog/787596
2021年01月24日
599 阅读
0 评论
0 点赞
2021-01-24
Kmeans算法简介
Kmeans算法简介算法介绍人的“物以类聚”新生入学后根据各自的喜好加入对应的社团。数据的“物以类聚”如果把人类比机器学习中的数据,那么聚类就很好理解了每当这个类别中有了新的数据加入的时候,我们要做的就是更新这个类别的中心位置,以方便这个新样本去适应这个类别,这便是kmeans算法的主要逻辑了。如何定义相似用两个点的距离:如欧式距离引入cluster的相关概念Kmean聚类实例处理步骤:随机从数据集中选取K个样本当做centroid对于数据集中的每个点,计算它距离每个centroid的距离,并把它归为距离最近的那个cluster更新新的centroid位置重复2.3,直到centroid的位置不再改变KMEANS的优缺点优点非监督类的算法不需要样本的标注信息缺点不能利用到数据的标注信息,意味着模型的性能不如其他监督学习对于K的取值,也就是你认为数据集中的样本应该分为几类,这个参数的设置极为敏感!对于数据集本身样本的分布也很敏感参考资料【五分钟机器学习】物以类聚的Kmeans:https://www.bilibili.com/video/BV1ei4y1V7hX?from=search&seid=12931680004886943436
2021年01月24日
632 阅读
0 评论
0 点赞
2021-01-24
VOC数据集分为train、val、test、trainval
VOC数据集分为train、val、test、trainval分割示意图代码实现import os import random xml_dir='./labels_voc/' #xml文件路径(Annotations) txt_save_dir = './ImageSets/Main' # txt文件 save path if not os.path.exists(txt_save_path): os.makedirs(txt_save_path) # 设置数据分割比例 trainval_percent = 0.9 train_percent = 0.8 # 获取所有的xml文件名 total_xml = os.listdir(xml_dir) # xml文件计数 num = len(total_xml) # 根据xml文件计数结果生成索引list并根据索引list分割为train、val、test、trainval xml_index_list = range(num) trainval_num = int(num * trainval_percent) train_num = int(trainval_num * train_percent) trainval_index_list = random.sample(xml_index_list, trainval_num) train_index_list = random.sample(trainval_index_list, train_num) # 根据分割完的索引文件将对应的文件名分别写入对应文件 ftrainval = open(txt_save_dir + '/trainval.txt', 'w') ftest = open(txt_save_dir + '/test.txt', 'w') ftrain = open(txt_save_dir + '/train.txt', 'w') fval = open(txt_save_dir + '/val.txt', 'w') for i in xml_index_list: file_name = total_xml[i][:-4] + '\n' if i in trainval_index_list: ftrainval.write(file_name) if i in train_index_list: ftrain.write(file_name) else: fval.write(file_name) else: ftest.write(file_name) ftrainval.close() ftrain.close() fval.close() ftest.close()结果ImageSets/ └── Main ├── test.txt ├── train.txt ├── trainval.txt └── val.txt参考资料制作VOC数据集时生成trainval.txt,train.txt,val.txt代码:https://blog.csdn.net/weixin_41868104/article/details/89886697
2021年01月24日
1,006 阅读
0 评论
0 点赞
2021-01-24
VOC数据集转YOLO数据集
VOC数据集转YOLO数据集VOC数据集样例<annotation> <folder>VOC2007</folder> <filename>009947.jpg</filename> <source> <database>The VOC2007 Database</database> <annotation>PASCAL VOC2007</annotation> <image>flickr</image> <flickrid>317223454</flickrid> </source> <owner> <flickrid>vaio_2002</flickrid> <name>Jonathan</name> </owner> <size> <width>332</width> <height>500</height> <depth>3</depth> </size> <segmented>1</segmented> <object> <name>boat</name> <pose>Left</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>115</xmin> <ymin>92</ymin> <xmax>250</xmax> <ymax>321</ymax> </bndbox> </object> <object> <name>person</name> <pose>Unspecified</pose> <truncated>1</truncated> <difficult>1</difficult> <bndbox> <xmin>165</xmin> <ymin>288</ymin> <xmax>186</xmax> <ymax>312</ymax> </bndbox> </object> </annotation>对应YOLO数据集样例格式说明:每行对应一个box,每个box分别有五个参数label indexcenter_xcenter_ywidthheight10 0.5496987951807228 0.413 0.4066265060240964 0.458 5 0.5286144578313253 0.6 0.06325301204819277 0.048代码实现import xmltodict import os from progressbar import * xml_dir='./labels_voc' #原xml路径 txt_dir='./labels' #转换后txt文件存放路径 # 所有待检测的labels class_names = ['aeroplane', 'cat', 'car', 'dog', 'chair', 'person', 'horse', 'bird', 'tvmonitor', 'bus', 'boat', 'diningtable', 'bicycle', 'bottle', 'sofa', 'pottedplant', 'motorbike', 'cow', 'train', 'sheep'] # 将voc xml中的object转化为对应的一条yolo数据 def get_yolo_data(obj,img_width,img_height): # 获取voc格式的数据信息 name = obj['name'] xmin = float(obj['bndbox']['xmin']) xmax = float(obj['bndbox']['xmax']) ymin = float(obj['bndbox']['ymin']) ymax = float(obj['bndbox']['ymax']) # 计算yolo格式的数据信息 class_idx = class_names.index(name) x_center = (xmin + xmax) / 2 / img_width y_center = (ymin + ymax) / 2 / img_height box_width = (xmax - xmin) / img_width box_height = (ymax - ymin) / img_height yolo_data = "{} {} {} {} {}\n".format(class_idx,x_center,y_center,box_width,box_height) return yolo_data # 逐一处理xml文件,转换为YOLO所需的格式 #进度条支持 count = 0 #计数器 widgets = ['VOC2YOLO: ',Percentage(), ' ', Bar('#'),' ', Timer(),' ', ETA()] pbar = ProgressBar(widgets=widgets, maxval=len(os.listdir(xml_dir))).start() for xml_file in os.listdir(xml_dir): xml_file_path = os.path.join(xml_dir,xml_file) txt_file_path = os.path.join(txt_dir,xml_file[:-4]+".txt") yolo_data = "" with open(xml_file_path) as f: xml_str = f.read() # 转为字典 xml_dic = xmltodict.parse(xml_str) # 获取图片的width、height img_width = float(xml_dic["annotation"]["size"]["width"]) img_height = float(xml_dic["annotation"]["size"]["height"]) # 获取xml文件中的object objects = xml_dic["annotation"]["object"] if isinstance(objects,list): # xml文件中包含多个object for obj in objects: yolo_data += get_yolo_data(obj,img_width,img_height) else: # xml文件中包含1个object obj = objects yolo_data += get_yolo_data(obj,img_width,img_height) with open(txt_file_path,'w') as f: f.write(yolo_data) #更新进度条 count += 1 pbar.update(count) pbar.finish()实现结果原始数据labels_voc ├── 000005.xml ├── 000007.xml ├── 000009.xml ├── 000012.xml ├── 000016.xml ├── 000017.xml ├── 000019.xml ├── 000020.xml ├── 000021.xml生成数据labels ├── 000005.txt ├── 000007.txt ├── 000009.txt ├── 000012.txt ├── 000016.txt ├── 000017.txt ├── 000019.txt ├── 000020.txt ├── 000021.txt参考资料PASCAL VOC 数据集转化为yolo数据集格式:https://blog.csdn.net/guo_python/article/details/107984940
2021年01月24日
715 阅读
0 评论
0 点赞
2021-01-24
VOC数据集类别统计
1.数据统计核心代码import xmltodict import os from tqdm import tqdm xml_dir = input(prompt="请输入xml文件夹地址:") #xml文件路径(Annotations) if not os.path.exists(xml_dir): print("[发生错误]:",xml_dir,"不存在") else: statistical_results = {} #进度条功能 pbar = tqdm(total=len(os.listdir(xml_dir))) pbar.set_description("VOC数据集类别统计:") # 设置前缀 for xml_file in os.listdir(xml_dir): # 拼接xml文件的path xml_file_path = os.path.join(xml_dir,xml_file) # 读取xml文件到字符串 with open(xml_file_path) as f: xml_str = f.read() # xml字符串转为字典 try: xml_dic = xmltodict.parse(xml_str) except Exception as e: print("[发生错误]:",xml_file_path,"解析失败") # 获取xml文件中的所有objects obj_list = xml_dic["annotation"]["object"] if not isinstance(obj_list,list): # xml文件中包含多个object obj_list = [obj_list] # labels分布统计 for obj in obj_list: if not obj['name'] in statistical_results.keys(): statistical_results[obj['name']] = 1 else: statistical_results[obj['name']] += 1 #更新进度条 pbar.update(1) #释放进度条 pbar.close() #输出统计结果 cls_list = list(statistical_results.keys()) print("=================================================") print("[统计报告]:") print("class list:",cls_list) print("类别总数:",len(cls_list)) print("类别分布情况:",statistical_results) print("=================================================")请输入xml文件夹地址:csf [发生错误]: csf 不存在请输入xml文件夹地址:C:\Users\itrb\Desktop\AirportApronDatasetLabel\label-finished\105-normal\Annotations VOC数据集类别统计:: 100%|████████████████████████████████████████████████████████| 1943/1943 [00:01<00:00, 1416.14it/s] ?it/s] ================================================= [统计报告]: class list: ['BridgeVehicle', 'Person', 'FollowMe', 'Plane', 'LuggageTruck', 'RefuelingTruck', 'FoodTruck', 'Tractor'] 类别总数: 8 类别分布情况: {'BridgeVehicle': 1943, 'Person': 2739, 'FollowMe': 4, 'Plane': 1789, 'LuggageTruck': 83, 'RefuelingTruck': 401, 'FoodTruck': 378, 'Tractor': 748} =================================================2.统计结果可视化2.1 根据统计结果绘制条形图# 绘制条形图 import matplotlib.pyplot as plt import numpy as np # 初始化画布 fig = plt.figure(figsize=(13,5),dpi=200) # 添加一个子图 ax = plt.subplot(1,1,1) # 绘制条形图 y_pos = np.arange(len(statistical_results)) ax.barh(y_pos,list(statistical_results.values())) # 设置y轴的ticklabels ax.set_yticks(y_pos) ax.set_yticklabels(list(statistical_results.keys())) # 设置图片的标题 ax.set_title("The total number of objects = {} in {} images".format( np.sum(list(statistical_results.values())),len(os.listdir(xml_dir)) )) plt.show()2.2 根据统计结果绘制折线图# 绘制折线图 import matplotlib.pyplot as plt import numpy as np # 初始化画布 fig = plt.figure(figsize=(13,5),dpi=200) # 添加一个子图x ax = plt.subplot(1,1,1) # 绘制折线图 x_pos = np.arange(len(statistical_results)) ax.plot(x_pos,list(statistical_results.values())) # 设置x轴的ticklabels ax.set_xticks(x_pos) ax.set_xticklabels(list(statistical_results.keys()),rotation = 45) # 设置图片的标题 ax.set_title("The total number of objects = {} in {} images".format( np.sum(list(statistical_results.values())),len(os.listdir(xml_dir)) )) plt.show()
2021年01月24日
896 阅读
0 评论
0 点赞
2021-01-20
统计VOC数据集中的所有标签(class_name_list)
1. PASCAL VOC数据格式<?xml version='1.0' encoding='utf-8'?> <annotation verified="no"> <folder>JPEGImages</folder> <filename>2018_06_05_09_06_55_065</filename> <path>F:\receive\VOC2007\JPEGImages\2018_06_05_09_06_55_065.jpg</path> <source> <database>Unknown</database> </source> <size> <width>2048</width> <height>1536</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>1</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>530</xmin> <ymin>752</ymin> <xmax>1498</xmax> <ymax>1326</ymax> </bndbox> </object> </annotation>2.获取voc数据集标签所有的类别数即下的所有的的import xmltodict import os # VOC xml文件所在文件夹 annotation_dir="./labels_voc/" label_list = list() # 逐一处理xml文件 for file in os.listdir(annotation_dir): annotation_path = os.path.join(annotation_dir,file) # 读取xml文件 with open(annotation_path,'r') as f: xml_str = f.read() #转为字典 xml_dic = xmltodict.parse(xml_str) # 获取label并去重加入到label_list objects = xml_dic["annotation"]["object"] if isinstance(objects,list): # xml文件中包含多个object for obj in objects: label = obj['name'] if label not in label_list: label_list.append(label) else:# xml文件中只包含1个object obj = objects label = object_['name'] if label not in label_list: label_list.append(label) print(label_list)['aeroplane', 'cat', 'car', 'dog', 'chair', 'person', 'horse', 'bird', 'tvmonitor', 'bus', 'boat', 'diningtable', 'bicycle', 'bottle', 'sofa', 'pottedplant', 'motorbike', 'cow', 'train', 'sheep']
2021年01月20日
783 阅读
0 评论
0 点赞
2021-01-15
Pytorch 实战:卷积神经网络(CNN)实现MINIST手写数字识别
实验环境torch = 1.6.0torchvision = 0.7.0matplotlib = 3.3.3 # 绘图用progressbar = 2.5 # 绘制进度条用easydict # 超参数字典功能增强使用数据集手写数字集MINIST导入相关的包# 导包 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader import torchvision from torchvision import datasets,transforms import matplotlib.pyplot as plt import random from progressbar import *设置超参数from easydict import EasyDict #增强python的dict的功能用 # 定义超参数 super_param = { "batch_size":256, "device": torch.device('cuda:0' if torch.cuda.is_available() else 'cpu'), "epochs":10, "lr":0.3, } super_param = EasyDict(super_param) print(super_param){'batch_size': 16, 'device': device(type='cuda', index=0), 'epochs': 10, 'lr': 0.3, 'hidden_num': 15}数据处理(下载、处理、加载数据到DataLoader)# 下载、加载数据 # 构transform(pipeline),对图像做处理 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,),(0.3081,)) #正则化 ]) # 下载数据 trainsets = datasets.MNIST('data',train=True,download=True,transform=transform) testsets = datasets.MNIST('data',train=False,download=True,transform=transform) # dataloader 加载数据 train_loader = DataLoader(trainsets,batch_size=super_param.batch_size,shuffle=True) test_loader = DataLoader(trainsets,batch_size=super_param.batch_size,shuffle=True)查看数据样例查看数据样例【单张】# 查看数据样例-单张 image,label = trainsets[random.randint(0,len(trainsets))] print('label=',label) plt.imshow(image.permute(1,2,0),cmap='gray') plt.show()查看数据样例【一批】# 查看数据样例-一批 images,labels = next(iter(test_loader)) data_sample_img = torchvision.utils.make_grid(images).numpy().transpose(1,2,0) print('labels=',labels) plt.figure(dpi=200) plt.xticks([]) plt.yticks([]) plt.imshow(data_sample_img) plt.show()构建CNN网络模型 -简单版- 使用Sequential## 构建CNN模型-简单版-使用Sequential model = nn.Sequential( nn.Conv2d(in_channels=1,out_channels=10,kernel_size=5,stride=1,padding=0),# b*1*28*28-->b*10*24*24 nn.ReLU(), nn.MaxPool2d(2),# b*10*24*24-->b*10*12*12 nn.Conv2d(10,20,3,1,0),# b*10*12*12-->b*20*10*10 nn.ReLU(), nn.Flatten(),#b*20*10*10-->b*2000 nn.Linear(2000,500),#b*2000-->b*500 nn.ReLU(), nn.Linear(500,10),#b*500-->b*10 nn.ReLU(), nn.Softmax(), ) print(model)Sequential( (0): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1)) (1): ReLU() (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (3): Conv2d(10, 20, kernel_size=(3, 3), stride=(1, 1)) (4): ReLU() (5): Flatten(start_dim=1, end_dim=-1) (6): Linear(in_features=2000, out_features=500, bias=True) (7): ReLU() (8): Linear(in_features=500, out_features=10, bias=True) (9): ReLU() (10): Softmax(dim=None) )构建CNN网络模型 -使用自定义类# 构建网络模型 - 使用自定义类 class Digit_Rec(nn.Module): def __init__(self): super(Digit_Rec,self).__init__() self.conv1 = nn.Conv2d(1,10,5) #1:灰度图片的通道,10:输出通道,5:kernel self.relu1 = nn.ReLU() self.max_pool = nn.MaxPool2d(2,2) self.conv2 = nn.Conv2d(10,20,3) #10:输入通道,20:输出通道,3:Kernel self.relu2 = nn.ReLU() self.fc1 = nn.Linear(20*10*10,500) # 20*10*10:输入通道,500:输出通道 self.relu3 = nn.ReLU() self.fc2 = nn.Linear(500,10) # 500:输入通道,10:输出通道 self.relu4 = nn.ReLU() self.softmax = nn.Softmax(dim=1) def forward(self,x): batch_size = x.size(0) # x的格式:batch_size x 1 x 28 x 28 拿到了batch_size x = self.conv1(x) # 输入:batch*1*28*28 输出:batch*10*24*24 x = self.relu1(x) x = self.max_pool(x) # 输入:batch*10*24*24输出:batch*10*12*12 x = self.conv2(x) x = self.relu2(x) x = x.view(batch_size,-1) #fatten 展平 -1自动计算维度,20*10*10=2000 x = self.fc1(x) # 输入:batch*2000 输出:batch*500 x = self.relu3(x) x = self.fc2(x) # 输入:batch*500 输出:batch*10 x = self.relu4(x) output = self.softmax(x) # 计算分类后,每个数字的概率值 return output model = Digit_Rec() print(model)Digit_Rec( (conv1): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1)) (relu1): ReLU() (max_pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False) (conv2): Conv2d(10, 20, kernel_size=(3, 3), stride=(1, 1)) (relu2): ReLU() (fc1): Linear(in_features=2000, out_features=500, bias=True) (relu3): ReLU() (fc2): Linear(in_features=500, out_features=10, bias=True) (relu4): ReLU() (softmax): Softmax(dim=1) )定义损失函数和优化器# 定义损失函数和优化 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(),lr=super_param.lr)定义模型训练单个epoch函数# 定义模型训练单个epoch函数 def train_model_epoch(model,train_loader,super_param,criterion,optimzer,epoch): model.train()#训练声明 for batch_index,(images,labels) in enumerate(train_loader): # 数据上device images,labels = images.to(super_param.device),labels.to(super_param.device) # 梯度清零 optimzer.zero_grad() # 前向传播 output = model(images) # 计算损失 loss = criterion(output,labels) # 反向传播,计算梯度 loss.backward() # 参数更新(优化) optimzer.step() # 打印训练参考信息,每1000个batch打印一次 if batch_index % 1000 == 0: print("Epoch:{} Batch Index(batch_size={}):{}/{} Loss:{}". format(epoch,super_param.batch_size,batch_index,len(train_loader),loss.item()))定义模型验证方法# 定义模型验证方法 def test_model(model,test_loader,super_param,criterion): model.eval()#测试声明 # 数据统计 correct_num,test_loss = 0.0,0.0 #正确数,测试损失 #定义进度条 widgets = ['模型测试中: ',Percentage(), ' ', Bar('#'),' ', Timer(),' ', ETA()] pbar = ProgressBar(widgets=widgets, maxval=100).start() # 取消计算梯度,避免更新模型参数 with torch.no_grad(): for batch_index,(images,labels) in enumerate(test_loader): # 数据上devics images,labels = images.to(super_param.device),labels.to(super_param.device) # 模型预测 output = model(images) # 计算测试损失 test_loss += criterion(output,labels).item() # 确定预测结果是哪个数字 pred = output.argmax(dim=1) #argmax返回 值,索引 dim=1表示要索引 # 统计预测正确数量 correct_num += pred.eq(labels.view_as(pred)).sum().item() #更新进度条进度 pbar.update(batch_index/len(test_loader)*100) #释放进度条 pbar.finish() #打印测试信息 test_loss = test_loss/len(test_loader.dataset) test_accuracy = correct_num / len(test_loader.dataset) print("Test --- Avg Loss:{},Accuracy:{}\n".format(test_loss,test_accuracy)) return test_loss,test_accuracy模型训练和测试# 模型训练和测试 #模型上device mode = model.to(super_param.device) #记录每个epoch的测试数据、用于绘图 epoch_list = [] loss_list = [] accuracy_list = [] for epoch in range(super_param.epochs): train_model_epoch(model,train_loader,super_param,criterion,optimizer,epoch) test_loss,test_accuracy = test_model(model,test_loader,super_param,criterion) # 数据统计 epoch_list.append(epoch) loss_list.append(test_loss) accuracy_list.append(test_accuracy)查看数据统计结果# 查看数据统计结果 fig = plt.figure(figsize=(12,12),dpi=70) #子图1 ax1 = plt.subplot(2,1,1) title = "bach_size={},lr={}".format(super_param.batch_size,super_param.lr) plt.title(title,fontsize=15) plt.xlabel('Epochs',fontsize=15) plt.ylabel('Loss',fontsize=15) plt.xticks(fontsize=13) plt.yticks(fontsize=13) plt.plot(epoch_list,loss_list) #子图2 ax2 = plt.subplot(2,1,2) plt.xlabel('Epochs',fontsize=15) plt.ylabel('Accuracy',fontsize=15) plt.xticks(fontsize=13) plt.yticks(fontsize=13) plt.plot(epoch_list,accuracy_list,'r') plt.show()
2021年01月15日
2,230 阅读
2 评论
0 点赞
2021-01-15
Pytorch 实战:BP神经网络实现MINIST实现手写数字识别(单层感知机)
Pytorch 实战:BP神经网络实现MINIST实现手写数字识别(单层感知机)实验环境torch = 1.6.0torchvision = 0.7.0matplotlib = 3.3.3 # 绘图用progressbar = 2.5 # 绘制进度条用easydict # 超参数字典功能增强使用数据集手写数字集MINIST导入相关的包# 导包 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader import torchvision from torchvision import datasets,transforms import matplotlib.pyplot as plt import random from progressbar import *设置超参数from easydict import EasyDict #增强python的dict的功能用 # 定义超参数 super_param = { "batch_size":128, "device": torch.device('cuda:0' if torch.cuda.is_available() else 'cpu'), "epochs":10, "lr":0.3, 'hidden_num':15, #隐藏层神经元数量 } super_param = EasyDict(super_param) print(super_param){'batch_size': 16, 'device': device(type='cuda', index=0), 'epochs': 10, 'lr': 0.3, 'hidden_num': 15}数据处理(下载、处理、加载数据到DataLoader)# 下载、加载数据 # 构transform(pipeline),对图像做处理 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,),(0.3081,)) #正则化 ]) # 下载数据 trainsets = datasets.MNIST('data',train=True,download=True,transform=transform) testsets = datasets.MNIST('data',train=False,download=True,transform=transform) # dataloader 加载数据 train_loader = DataLoader(trainsets,batch_size=super_param.batch_size,shuffle=True) test_loader = DataLoader(trainsets,batch_size=super_param.batch_size,shuffle=True)查看数据样例查看数据样例【单张】# 查看数据样例-单张 image,label = trainsets[random.randint(0,len(trainsets))] print('label=',label) plt.imshow(image.permute(1,2,0),cmap='gray') plt.show()查看数据样例【一批】# 查看数据样例-一批 images,labels = next(iter(test_loader)) data_sample_img = torchvision.utils.make_grid(images).numpy().transpose(1,2,0) print('labels=',labels) plt.figure(dpi=200) plt.xticks([]) plt.yticks([]) plt.imshow(data_sample_img) plt.show()构建BP网络模型 -简单版- 使用Sequential## 构建网络模型-BP model = nn.Sequential( nn.Flatten(), nn.Linear(28*28,super_param.hidden_num), nn.ReLU(), nn.Linear(super_param.hidden_num,10), nn.ReLU(), nn.Softmax(), ) print(model)Sequential( (0): Flatten() (1): Linear(in_features=784, out_features=15, bias=True) (2): ReLU() (3): Linear(in_features=15, out_features=10, bias=True) (4): ReLU() (5): Softmax(dim=None) )构建BP网络模型 -使用自定义类## 构建BP网络模型 -使用自定义类 class Digit_Rec(nn.Module): def __init__(self,hidden_num): super(Digit_Rec,self).__init__() self.fc1 = nn.Linear(28*28,hidden_num) self.relu1 = nn.ReLU() self.fc2 = nn.Linear(hidden_num,10) self.relu2 = nn.ReLU() self.softmax = nn.Softmax(dim=1) def forward(self,x): batch_size = x.size(0) # x的格式:batch_size x 1 x 28 x 28 拿到了batch_size x = x.view(batch_size,28*28) # flatten out = self.fc1(x) out = self.relu1(out) out = self.fc2(out) out = self.relu2(out) out = self.softmax(out) return out model = Digit_Rec(super_param.hidden_num) print(model)Digit_Rec( (fc1): Linear(in_features=784, out_features=50, bias=True) (relu1): ReLU() (fc2): Linear(in_features=50, out_features=10, bias=True) (relu2): ReLU() (softmax): Softmax(dim=1) )定义损失函数和优化器# 定义损失函数和优化 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(),lr=super_param.lr)定义模型训练单个epoch函数# 定义模型训练单个epoch函数 def train_model_epoch(model,train_loader,super_param,criterion,optimzer,epoch): model.train()#训练声明 for batch_index,(images,labels) in enumerate(train_loader): # 数据上device images,labels = images.to(super_param.device),labels.to(super_param.device) # 梯度清零 optimzer.zero_grad() # 前向传播 output = model(images) # 计算损失 loss = criterion(output,labels) # 反向传播,计算梯度 loss.backward() # 参数更新(优化) optimzer.step() # 打印训练参考信息,每1000个batch打印一次 if batch_index % 1000 == 0: print("Epoch:{} Batch Index(batch_size={}):{}/{} Loss:{}". format(epoch,super_param.batch_size,batch_index,len(train_loader),loss.item()))定义模型验证方法# 定义模型验证方法 def test_model(model,test_loader,super_param,criterion): model.eval()#测试声明 # 数据统计 correct_num,test_loss = 0.0,0.0 #正确数,测试损失 #定义进度条 widgets = ['模型测试中: ',Percentage(), ' ', Bar('#'),' ', Timer(),' ', ETA()] pbar = ProgressBar(widgets=widgets, maxval=100).start() # 取消计算梯度,避免更新模型参数 with torch.no_grad(): for batch_index,(images,labels) in enumerate(test_loader): # 数据上devics images,labels = images.to(super_param.device),labels.to(super_param.device) # 模型预测 output = model(images) # 计算测试损失 test_loss += criterion(output,labels).item() # 确定预测结果是哪个数字 pred = output.argmax(dim=1) #argmax返回 值,索引 dim=1表示要索引 # 统计预测正确数量 correct_num += pred.eq(labels.view_as(pred)).sum().item() #更新进度条进度 pbar.update(batch_index/len(test_loader)*100) #释放进度条 pbar.finish() #打印测试信息 test_loss = test_loss/len(test_loader.dataset) test_accuracy = correct_num / len(test_loader.dataset) print("Test --- Avg Loss:{},Accuracy:{}\n".format(test_loss,test_accuracy)) return test_loss,test_accuracy模型训练和测试# 模型训练和测试 #模型上device mode = model.to(super_param.device) #记录每个epoch的测试数据、用于绘图 epoch_list = [] loss_list = [] accuracy_list = [] for epoch in range(super_param.epochs): train_model_epoch(model,train_loader,super_param,criterion,optimizer,epoch) test_loss,test_accuracy = test_model(model,test_loader,super_param,criterion) # 数据统计 epoch_list.append(epoch) loss_list.append(test_loss) accuracy_list.append(test_accuracy)查看数据统计结果# 查看数据统计结果 fig = plt.figure(figsize=(12,12),dpi=70) #子图1 ax1 = plt.subplot(2,1,1) title = "hidden_neuron_num={},bach_size={},lr={}".format(super_param.hidden_num,super_param.batch_size,super_param.lr) plt.title(title,fontsize=15) plt.xlabel('Epochs',fontsize=15) plt.ylabel('Loss',fontsize=15) plt.xticks(fontsize=13) plt.yticks(fontsize=13) plt.plot(epoch_list,loss_list) #子图2 ax2 = plt.subplot(2,1,2) plt.xlabel('Epochs',fontsize=15) plt.ylabel('Accuracy',fontsize=15) plt.xticks(fontsize=13) plt.yticks(fontsize=13) plt.plot(epoch_list,accuracy_list,'r') plt.show()隐藏层神经元数量=15隐藏层神经元数量=30隐藏层神经元数量=50
2021年01月15日
744 阅读
0 评论
0 点赞
2021-01-13
各类比赛数据集
各类比赛数据集【注意】所有数据仅限于科研所用,请勿用于商业用途!【Kaggle比赛】1.Kaggle-猫狗大战链接:https://pan.baidu.com/s/1cnnZXytaaCQjtsAxYE2s1w 密码:2mpc2.Kaggle-LUNA 2016肺部CT图像链接:https://pan.baidu.com/s/1S6VohLttXAr0dyx4qYx1Dw 密码:hy1b3.Kaggle-DSB2018链接:https://pan.baidu.com/s/10jbEZ6v6_mwoios08RlCSA 密码:74jr4.Kaggle-DSB2017链接:https://pan.baidu.com/s/1Io7IbusxfTe-SkfrvRNjOA 密码:vazw【天池大赛】1.天池大赛-肺部结节诊断链接:https://pan.baidu.com/s/1NDYJcXGqXf4uGgNkYVAG3Q 密码:84e52.Fashion-AI 服饰关键点定位链接:https://pan.baidu.com/s/1ZXzHCdbfTuegjSv8IFewOQ 密码:lhx53.Fashion-AI 服饰属性标签识别链接:https://pan.baidu.com/s/1DprZywohaqIioTvcNKzLFA 密码:0dom4.全球数据智能大赛(2019)——肺部CT多病种智能诊断链接:https://pan.baidu.com/s/1lZpJrJuER6NPnlcE2SQmWw 密码:0ng9【AI全球挑战赛】1.AI挑战赛-场景分类链接:https://pan.baidu.com/s/1rBqy7rUXrcLgeX45IRrHUQ 密码:7kn12.AI挑战赛-图像中文描述链接:https://pan.baidu.com/s/1m-yFj6ST2KJlx7D77de6DQ 密码:cprk【ICDAR比赛】1.ICDAR 2015自然场景文字识别数据链接:https://pan.baidu.com/s/1q03Lkat8Xw92iKJ8lhsqYw 密码:surk2.ICDAR 2017自然场景文字识别数据链接:https://pan.baidu.com/s/1UusfROUT4btNnoXF9yjdNw 密码:ndsa3.ICDAR 2019扫描小票数据(SROIE)链接:https://pan.baidu.com/s/1-2bYU6ufWOVNuxqzGuq2pQ 密码:uubm 4.ICDAR 2019商家招牌文本检测识别数据(ReCTS)链接:https://pan.baidu.com/s/1aJyJzOgSPVLZ6hoRilG8pw 密码:hcdp 5.ICDAR 2019自然场景文字识别数据(LSVT)链接:https://pan.baidu.com/s/1oJ2pPClwgXTKPIidElWi0Q 密码:x6ct 【其他类】1.RIDER LUNG CT 肺癌CT图像链接:https://pan.baidu.com/s/1n500txInMzoU1TUbqQQWUw 密码:ddpa2.RIDER Breast MRI数据链接:https://pan.baidu.com/s/1aEZjiR8_uvJLDvjOxTtG8Q 密码:s60s3.2018百度西交大大数据竞赛-商家招牌的分类与检测链接:https://pan.baidu.com/s/1jkNIaWPzEOKEx363iDrmCA 密码:ylyj4.Fundus Image Registration(FIRE) 眼底图像数据链接:https://pan.baidu.com/s/1sgDmo5rTe-HjsmFDhtKh1Q 密码:w7jm5.Digital Retinal Images for Vessel Extraction(DRIVE)眼底血管图像数据集链接:https://pan.baidu.com/s/1UpQtbhgtVdlqc0QGbESx3A 密码:4l7v参考资料各类比赛数据集:https://blog.csdn.net/u013063099/article/details/79467531
2021年01月13日
875 阅读
0 评论
0 点赞
2021-01-12
YOLOv1学习:(二)损失函数理解和实现
YOLOv1学习:(二)损失函数理解和实现损失函数形式损失函数理解1预测框的中心点(x, y) 造成的损失(即对损失函数有贡献)是图中的第一行。其中$||_{ij}^{obj}$为控制函数,在标签中包含物体的那些格点处,该值为1;若格点不含有物体,该值为 0。也就是只对那些有真实物体所属的格点进行损失计算,若该格点不包含物体则不进行此项损失计算,因此预测数值不对此项损失函数造成影响(因为这个预测数值根本不带入此项损失函数计算)。预测框的高度(w, h)造成的损失(即对损失函数有贡献)是图中的第二行。其中 $||_{ij}^{obj}$为控制函数,含义与预测中心一样。1、2项就是边框回归。第三行与第四行,都是预测框的置信度C。当该格点不含有物体时,该置信度的标签为0;若含有物体时,该置信度的标签为预测框与真实物体框的IOU数值(IOU计算公式为:两个框交集的面积除以并集的面积)。其中第三行函数的$||_{ij}^{obj}$依然为控制函数,在标签中包含物体的那些格点处,该值为1;若格点不含有物体,该值为 0。也就是只对那些有真实物体所属的格点进行损失计算,若该格点不包含物体则不进行此项损失计算,因此预测数值不对此项损失函数造成影响(因为这个预测数值根本不带入此项损失函数计算)。第四行的$||_{ij}^{obj}$也控制函数,只是含义与第三项的相反,在标签中不含物体的那些格点处,该值为1;若格点含有物体,该值为 0。也就是只对那些没有真实物体所属的格点进行损失计算,若该格点包含物体(包含物体置信度损失已经在第三项计算了)则不进行此项损失计算,因此预测数值不对此项损失函数造成影响(因为这个预测数值根本不带入此项损失函数计算)。第五行为物体类别概率P,对应的类别位置,该标签数值为1,其余位置为0,与分类网络相同。其中此项$||_{ij}^{obj}$也为控制函数,在标签中包含物体的那些格点处,该值为1;若格点不含有物体,该值为 0。也就是只对那些有真实物体所属的格点进行物体类别损失计算,若该格点不包含物体则不进行此项损失计算,因此预测数值不对此项损失函数造成影响(因为这个预测数值根本不带入此项损失函数计算)。此时再来看${\lambda}_{coord}$ 与${\lambda}_{noobj}$ ,Yolo面临的物体检测问题,是一个典型的类别数目不均衡的问题。其中49个格点,含有物体的格点往往只有3、4个,其余全是不含有物体的格点。此时如果不采取点措施,那么物体检测的mAP不会太高,因为模型更倾向于不含有物体的格点。因此${\lambda}_{coord}$ 与 ${\lambda}_{noobj}$的作用,就是让含有物体的格点,在损失函数中的权重更大,让模型更加“重视”含有物体的格点所造成的损失。在论文中, ${\lambda}_{coord}$ 与 ${\lambda}_{noobj}$ 的取值分别为5与0.5。损失函数理解2-损失函数分为三个部分$$ ||_{ij}^{obj}表示cell中是否含有真实物体的中心,含有则1,否则取0 $$① 坐标误差为什么宽和高要带根号???对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏一点更不能忍受。作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width(主要为了平衡小目标检测预测的偏移)② IOU误差这里的$\hat{C_i}$分别表示 1 和 0 $,C_i=Pr(Object)*IOU_{pred}^{truth}$③ 分类误差这个很容易理解(激活函数的输出)。损失函数代码实现实现""" + input + pred: (batch_size,30,7,7)的网络输出数据 + labels: (batch_size,30,7,7)的样本标签数据 + output + 当前批次样本的平均损失 """ """ + YOLOv1 的损失分为3部分 + 坐标预测损失 + 置信度预测损失 + 含object的box的confidence预测损失 + 不含object的box的confidence预测损失 + 类别预测损失 """ class Loss_YOLOv1(nn.Module): def __init__(self,batch_size=1): super(Loss_YOLOv1,self).__init__() self.batch_size = batch_size """ box格式转换 + input + src_box : [box_x_lefttop,box_y_lefttop,box_w,box_h] + output + dst_box : [box_x1,box_y1,box_x2,box_y2] """ def convert_box_type(self,src_box): x,y,w,h = tuple(src_box) x1,y1 = x,y x2,y2 = x+w,y+w return [x1,y1,x2,y2] """ iou计算 """ def cal_iou(self,box1,box2): # 求相交区域左上角的坐标和右下角的坐标 box_intersect_x1 = max(box1[0], box2[0]) box_intersect_y1 = max(box1[1], box2[1]) box_intersect_x2 = min(box1[2], box2[2]) box_intersect_y2 = min(box1[3], box2[3]) # 求二者相交的面积 area_intersect = (box_intersect_y2 - box_intersect_y1) * (box_intersect_x2 - box_intersect_x1) # 求box1,box2的面积 area_box1 = (box1[2] - box1[0]) * (box1[3] - box1[1]) area_box2 = (box2[2] - box2[0]) * (box2[3] - box2[1]) # 求二者相并的面积 area_union = area_box1 + area_box2 - area_intersect # 计算iou(交并比) iou = area_intersect / area_union return iou def forward(self,pred,target): lambda_noobj = 0.5 # lambda_noobj参数 lambda_coord = 5 # lambda_coord参数 site_pred_loss = 0 # 坐标预测损失 obj_confidence_pred_loss = 0 # 含object的box的confidence预测损失 noobj_confidence_pred_loss = 0 #不含object的box的confidence预测损失 class_pred_loss = 0 # 类别预测损失 for batch_size_index in range(self.batch_size): # batchsize循环 for x_index in range(7): # x方向网格循环 for y_index in range(7): # y方向网格循环 # 获取单个网格的预测数据和真实数据 pred_data = pred[batch_size_index,:,x_index,y_index] # [x,y,w,h,confidence,x,y,w,h,confidence,cls*20] true_data = target[batch_size_index,:,x_index,y_index] #[x,y,w,h,confidence,x,y,w,h,confidence,cls*20] if true_data[4]==1:# 如果包含物体 # 解析预测数据和真实数据 pred_box_confidence_1 = pred_data[0:5] # [x,y,w,h,confidence1] pred_box_confidence_2 = pred_data[5:10] # [x,y,w,h,confidence2] true_box_confidence = true_data[0:5] # [x,y,w,h,confidence] # 获取两个预测box并计算与真实box的iou iou1 = self.cal_iou(self.convert_box_type(pred_box_confidence_1[0:4]),self.convert_box_type(true_box_confidence[0:4])) iou2 = self.cal_iou(self.convert_box_type(pred_box_confidence_2[0:4]),self.convert_box_type(true_box_confidence[0:4])) # 在两个box中选择iou大的box负责预测物体 if iou1 >= iou2: better_box_confidence,bad_box_confidence = pred_box_confidence_1,pred_box_confidence_2 better_iou,bad_iou = iou1,iou2 else: better_box_confidence,bad_box_confidence = pred_box_confidence_2,pred_box_confidence_1 better_iou,bad_iou = iou2,iou1 # 计算坐标预测损失 site_pred_loss += lambda_coord * torch.sum((better_box_confidence[0:2]- true_box_confidence[0:2])**2) # x,y的预测损失 site_pred_loss += lambda_coord * torch.sum((better_box_confidence[2:4].sqrt()-true_box_confidence[2:4].sqrt())**2) # w,h的预测损失 # 计算含object的box的confidence预测损失 obj_confidence_pred_loss += (better_box_confidence[4] - better_iou)**2 # iou比较小的bbox不负责预测物体,因此confidence loss算在noobj中 # 因此还需计算不含object的box的confidence预测损失 noobj_confidence_pred_loss += lambda_noobj * (bad_box_confidence[4] - bad_iou)**2 # 计算类别损失 class_pred_loss += torch.sum((pred_data[10:] - true_data[10:])**2) else: # 如果不包含物体,则只有置信度损失--noobj_confidence_pred_loss # [4,9]代表取两个预测框的confidence noobj_confidence_pred_loss += lambda_noobj * torch.sum(pred[batch_size_index,(4,9),x_index,y_index]**2) loss = site_pred_loss + obj_confidence_pred_loss + noobj_confidence_pred_loss + class_pred_loss return loss/self.batch_size调用测试label1 = torch.rand([1,30,7,7]) label2 = torch.rand([1,30,7,7]) print(label1.shape,label2.shape) print(loss(label1,label2))torch.Size([1, 30, 7, 7]) torch.Size([1, 30, 7, 7]) tensor(14.6910)参考资料YOLO V1损失函数理解:http://www.likecs.com/show-65912.htmlYOLOv1算法理解:https://www.cnblogs.com/ywheunji/p/10808989.html【目标检测系列】yolov1的损失函数详解(结合pytorch代码):https://blog.csdn.net/gbz3300255/article/details/109179751yolo-yolo v1损失函数理解:https://blog.csdn.net/qq_38236744/article/details/106724596
2021年01月12日
1,360 阅读
0 评论
0 点赞
2021-01-12
CNN中卷积运算
CNN中卷积运算卷积运算细节图卷积运算中的特征图尺寸变化参考资料CNN中卷积层的计算细节:https://zhuanlan.zhihu.com/p/29119239
2021年01月12日
751 阅读
0 评论
0 点赞
1
...
3
4
5