手把手教物体检测——SSD(新手必看)

简介: 手把手教物体检测——SSD(新手必看)
  1. 下载SSD代码:

https://github.com/amdegroot/ssd.pytorch

  1. 将下载的代码解压后在data文件夹下新建VOCdevkit文件夹,然后将VOC2007数据集复制到该文

tt.png


  1. 下载权重文件放在weights文件夹下面。下载地址:

https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth

  1. 修改config.py代码
1.# SSD300 CONFIGS
voc = {
    'num_classes': 3,//将类别改为:类别+1(背景)
    'lr_steps': (80000, 100000, 120000),
    'max_iter': 120000,//迭代次数
    'feature_maps': [38, 19, 10, 5, 3, 1],
    'min_dim': 300,
    'steps': [8, 16, 32, 64, 100, 300],
    'min_sizes': [30, 60, 111, 162, 213, 264],
    'max_sizes': [60, 111, 162, 213, 264, 315],
    'aspect_ratios': [[2], [2, 3], [2, 3], [2, 3], [2], [2]],
    'variance': [0.1, 0.2],
    'clip': True,
    'name': 'VOC',
}


修改VOC0712.py代码。

'''
VOC_CLASSES = (  # always index 0
    'aeroplane', 'bicycle', 'bird', 'boat',
    'bottle', 'bus', 'car', 'cat', 'chair',
    'cow', 'diningtable', 'dog', 'horse',
    'motorbike', 'person', 'pottedplant',
    'sheep', 'sofa', 'train', 'tvmonitor')
'''
VOC_CLASSES = (  # always index 0
    'aircraft', 'oiltank')//修改为自己数据集的类别。
# note: if you used our download scripts, this should be right
#VOC_ROOT = osp.join("", "data/VOCdevkit/")
VOC_ROOT = "data/VOCdevkit/" #修改为Win10路径

def __init__(self, root,
             image_sets=[('2007', 'trainval'), ('2012', 'trainval')],
             transform=None, target_transform=VOCAnnotationTransform(),
             dataset_name='VOC0712'):

修改为:

def __init__(self, root,
             image_sets=[('2007', 'trainval')],
             transform=None, target_transform=VOCAnnotationTransform(),
             dataset_name='VOC2007'):

修改coco.py

COCO_ROOT ='data/'


修改ssd.py

将32行的self.cfg = (coco, voc)[num_classes == 21]

修改为self.cfg = (coco, voc)[num_classes == 3]#3是我数据集的类别+1

修改multibox_loss.py

在97行的loss_c[pos] = 0  # filter out pos boxes for now

位置之上加入loss_c = loss_c.view(pos.size()[0], pos.size()[1])


如果没有这句话会引起张量不匹配的问题

如:

IndexError: The shape of the mask [4, 8732] at index 0 does not match the shape of the indexed tensor [34928, 1] at index 0

修改全局配置参数:


parser.add_argument('--dataset', default='VOC', choices=['VOC', 'COCO'],

                   type=str, help='VOC or COCO')#改为VOC

parser.add_argument('--batch_size', default=4, type=int,

                   help='Batch size for training')#Batch Size 按照显存的大小设置合适的值。

parser.add_argument('--start_iter', default=0, type=int,

                   help='Resume training at this iter')#迭代开始

parser.add_argument('--num_workers', default=4, type=int,

                   help='Number of workers used in dataloading')

parser.add_argument('--cuda', default=True, type=str2bool,

                   help='Use CUDA to train model')

parser.add_argument('--lr', '--learning-rate', default=1e-4, type=float,

                   help='initial learning rate')

parser.add_argument('--momentum', default=0.9, type=float,

                   help='Momentum value for optim')

parser.add_argument('--weight_decay', default=5e-4, type=float,

                   help='Weight decay for SGD')

parser.add_argument('--gamma', default=0.1, type=float,

                   help='Gamma update for SGD')

parser.add_argument('--visdom', default=False, type=str2bool,

                   help='Use visdom for loss visualization')

parser.add_argument('--save_folder', default='weights/',

                   help='Directory for saving checkpoint models')#保存权重的位置。

args = parser.parse_args()


将:

修改为:

————————————————

loc_loss += loss_l.item()
conf_loss += loss_c.item()
if iteration % 10 == 0:
    print('timer: %.4f sec.' % (t1 - t0))
    print('iter ' + repr(iteration) + ' || Loss: %.4f ||' % (loss.item()), end=' ')

不修改会引起错误:

.IndexError: invalid index of a 0-dim tensor. Use tensor.item() to convert a 0-dim tensor to a Python number

将165行的

images, targets = next(batch_iterator)

更改成:

try:

                  images, targets = next(batch_iterator)

except StopIteration:

                  batch_iterator = iter(data_loader)

                  images, targets = next(batch_iterator)

如果不改会引起跳出迭代的问题:

Traceback (most recent call last):

 File "E:/ssd.pytorch-master/ssd.pytorch-master/train.py", line 246, in <module>

   train()

 File "E:/ssd.pytorch-master/ssd.pytorch-master/train.py", line 159, in train

   images, targets = next(batch_iterator)

 File "D:\Users\WH\anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 345, in __next__

   data = self._next_data()

 File "D:\Users\WH\anaconda3\lib\site-packages\torch\utils\data\dataloader.py", line 831, in _next_data

   raise StopIteration

StopIteration

如果遇到loss为nan的现象,就需要降低出示学习率。

tt.png

将10e-3改为10e-4

将以上问题解决后就可以开始训练了。

测试

需要修改test.py的全局参数。


parser.add_argument('--trained_model', default='weights/ssd300_COCO_60000.pth',

                   type=str, help='Trained state_dict file path to open')#指定测试用的模型。

parser.add_argument('--save_folder', default='eval/', type=str,

                   help='Dir to save results')#生成的测试结果

parser.add_argument('--visual_threshold', default=0.6, type=float,

                   help='Final confidence threshold')#检测的最低置信度。


点击测试生成测试结果:

GROUND TRUTH FOR: aircraft_27

label: 650.0 || 101.0 || 753.0 || 227.0 || 0

label: 395.0 || 351.0 || 521.0 || 464.0 || 0

label: 320.0 || 479.0 || 465.0 || 606.0 || 0

label: 276.0 || 617.0 || 432.0 || 753.0 || 0

PREDICTIONS:

1 label: aircraft score: tensor(1.0000) 317.00345 || 479.0164 || 468.34143 || 604.06415

2 label: aircraft score: tensor(1.0000) 279.88608 || 614.7385 || 434.32086 || 752.4983

3 label: aircraft score: tensor(0.9999) 397.0827 || 352.3487 || 524.27655 || 462.45944

4 label: aircraft score: tensor(0.9990) 647.89233 || 100.57587 || 758.556 || 232.56816

GROUND TRUTH FOR: oiltank_349

label: 115.0 || 340.0 || 237.0 || 466.0 || 1

label: 104.0 || 498.0 || 231.0 || 637.0 || 1

label: 92.0 || 675.0 || 224.0 || 814.0 || 1

label: 369.0 || 378.0 || 492.0 || 507.0 || 1

label: 357.0 || 543.0 || 483.0 || 678.0 || 1

label: 350.0 || 715.0 || 485.0 || 856.0 || 1

label: 534.0 || 378.0 || 662.0 || 511.0 || 1

label: 527.0 || 541.0 || 656.0 || 678.0 || 1

label: 527.0 || 712.0 || 654.0 || 857.0 || 1

PREDICTIONS:

1 label: oiltank score: tensor(1.0000) 349.36838 || 709.4552 || 481.7989 || 854.8713

2 label: oiltank score: tensor(1.0000) 528.97327 || 546.3467 || 656.2798 || 676.9037

3 label: oiltank score: tensor(1.0000) 88.82061 || 667.3125 || 220.63167 || 812.9001

4 label: oiltank score: tensor(1.0000) 358.38913 || 373.05368 || 489.21268 || 510.5563

5 label: oiltank score: tensor(1.0000) 519.9066 || 709.3708 || 658.5541 || 863.88947

6 label: oiltank score: tensor(1.0000) 115.77756 || 339.24872 || 240.00787 || 466.19022

7 label: oiltank score: tensor(1.0000) 104.77564 || 500.64545 || 230.20764 || 636.5293

8 label: oiltank score: tensor(1.0000) 357.70694 || 547.2647 || 485.0283 || 679.9714

9 label: oiltank score: tensor(0.9999) 524.7541 || 375.12167 || 668.46106 || 511.2381

打印测试结果

import os

import sys

module_path = os.path.abspath(os.path.join('..'))

if module_path not in sys.path:

   sys.path.append(module_path)

import torch

import torch.nn as nn

import torch.backends.cudnn as cudnn

from torch.autograd import Variable

import numpy as np

import cv2

if torch.cuda.is_available():

   torch.set_default_tensor_type('torch.cuda.FloatTensor')

from ssd import build_ssd

net = build_ssd('test', 300, 3)    # initialize SSD

net.load_state_dict(torch.load('weights/ssd300_COCO_60000.pth'))#加载模型

net.eval()

image = cv2.imread('data/VOCdevkit/aircraft_27.jpg', cv2.IMREAD_COLOR)  # 加载图片

from matplotlib import pyplot as plt

rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)#读取图片

# View the sampled input image before transform

x = cv2.resize(image, (300, 300)).astype(np.float32)

x -= (104.0, 117.0, 123.0)

x = x.astype(np.float32)

x = x[:, :, ::-1].copy()

plt.imshow(x)

x = torch.from_numpy(x).permute(2, 0, 1)

xx = Variable(x.unsqueeze(0))     # wrap tensor in Variable

if torch.cuda.is_available():

   xx = xx.cuda()

y = net(xx)

from data import VOC_CLASSES as labels

top_k=10#选择前10个结果

plt.figure(figsize=(10,10))

colors = plt.cm.hsv(np.linspace(0, 1, 21)).tolist()

plt.imshow(rgb_image)  # plot the image for matplotlib

currentAxis = plt.gca()

detections = y.data

# scale each detection back up to the image

scale = torch.Tensor(rgb_image.shape[1::-1]).repeat(2)

for i in range(detections.size(1)):

   j = 0

   while detections[0,i,j,0] >= 0.35:

       score = detections[0,i,j,0]

       label_name = labels[i-1]

       display_txt = '%s: %.2f'%(label_name, score)

       pt = (detections[0,i,j,1:]*scale).cpu().numpy()

       coords = (pt[0], pt[1]), pt[2]-pt[0]+1, pt[3]-pt[1]+1

       color = colors[i]

       currentAxis.add_patch(plt.Rectangle(*coords, fill=False, edgecolor=color, linewidth=2))

       currentAxis.text(pt[0], pt[1], display_txt, bbox={'facecolor':color, 'alpha':0.5})

       j+=1

plt.show()

tt.png

目录
相关文章
|
7月前
|
机器学习/深度学习 数据采集 PyTorch
图像分类保姆级教程-深度学习入门教程(附全部代码)
图像分类保姆级教程-深度学习入门教程(附全部代码)
|
机器学习/深度学习 数据可视化 数据挖掘
初学者该如何选择最适合自己的图像分类模型
初学者该如何选择最适合自己的图像分类模型
1265 0
初学者该如何选择最适合自己的图像分类模型
|
2月前
|
Kubernetes 安全 Java
springCore完整学习教程2,入门级别
本文是Spring Core学习教程的第二部分,深入讲解了Spring Boot中的外部化配置,包括配置文件的加载规则、使用配置文件、配置属性的加密、YAML的使用、配置随机值、系统环境属性的配置,以及@ConfigurationProperties注解的详细使用和与@Value注解的比较。
18 2
springCore完整学习教程2,入门级别
|
2月前
|
JSON Java API
SpringCore完整学习教程5,入门级别
本文是Spring Core学习教程的第五部分,深入探讨了Spring Boot对JSON的支持,包括Jackson、Gson和JSON-B三个JSON映射库的集成,以及如何自定义序列化器、反序列化器和使用Mixins。
17 1
SpringCore完整学习教程5,入门级别
|
2月前
|
Java 应用服务中间件 数据库连接
SpringCore完整学习教程4,入门级别
本文是Spring Core学习教程的第四部分,详细介绍了Spring Boot中的日志记录功能,包括日志格式、控制台输出、文件输出、日志轮换、日志级别设置、日志组定义、使用日志关闭钩子、自定义日志配置以及Logback扩展等。
17 1
SpringCore完整学习教程4,入门级别
|
2月前
|
JSON Java API
SpringCore 完整学习教程1,入门级别
本文是Spring Core的学习教程第一部分,涵盖了SpringApplication的使用、启动失败处理、延迟初始化、自定义SpringApplication、事件监听、Web环境、访问应用程序参数、使用ApplicationRunner或CommandLineRunner、应用程序退出码以及管理应用程序可用性状态等基本概念。
28 1
SpringCore 完整学习教程1,入门级别
|
2月前
|
前端开发 Java 测试技术
SpringCore完整学习教程6,入门级别
本文是Spring Core学习教程的第六部分,涵盖了Spring Boot中的任务执行和调度、异步处理,以及使用@SpringBootTest进行集成测试的多种方式,包括使用MockMvc和WebTestClient进行模拟测试和使用随机端口启动服务器进行测试。
18 2
|
2月前
|
IDE Java Maven
SpringCore完整学习教程7,入门级别
如何创建Spring Boot的自定义自动配置,包括理解自动配置类、定位自动配置候选、使用条件注解、测试自动配置以及创建自定义启动器的完整教程。
25 2
|
7月前
|
机器学习/深度学习 数据可视化 PyTorch
OneFlow深度学习框架介绍:新手快速上手指南
【4月更文挑战第12天】OneFlow是一款高性能的深度学习框架,由一流科技公司研发,以其数据流编程模型、动态图执行和高效分布式训练等功能脱颖而出。其易用性、卓越性能和强大的分布式训练能力使其在AI领域备受关注。新手可以通过简单的安装和基础程序快速上手,利用OneFlow的Module构建模型,结合损失函数和优化器进行训练。此外,OneFlow支持ONNX模型导入导出、TensorBoard可视化及与其他Python库集成,助力无缝对接现有生态。深入了解和实践OneFlow,可提升深度学习开发效率。
222 2
|
机器学习/深度学习 存储 Cloud Native
【推荐】最适合新手的5个深度学习实战项目
【推荐】最适合新手的5个深度学习实战项目