vlambda博客
学习文章列表

数字化高分辨率图像识别、分类和定位

数字化高分辨率图像识别、分类和定位


数字化高分辨率图像识别、分类和定位


人工神经网络(Artificial Neural Network,ANN)简称神经网络(ANN),是基于生物学中神经网络的基本原理,在理解和抽象了人脑结构和外界刺激响应机制后,以网络拓扑知识为理论基础,模拟人脑的神经系统对复杂信息的处理机制的一种数学模型。它实际上是一个大量简单元件相互连接而成的复杂网络,具有高度的非线性,能够进行复杂的逻辑操作和非线性关系实现的系统。


本文使用SSD网络模型对图片中的物体进行识别与检测,并标记物体的位置。主要实现过程包括SSD网络的设计、数据集的选取、数据集的划分、样本的标记、图片的压缩、图像数据的预处理、网络的训练与网络的预测效果测试。


1 SSD网络结构


本文所使用的是SSD算法,其英文全名是Single Shot MultiBox Detector。SSD算法属于one-stage方法,MultiBox指明了SSD是多框预测。对于Faster R-CNN,先通过CNN得到候选框,然后进行分类和回归,而YOLO和SSD可以一步完成检测,相比YOLO,SSD采用CNN来直接进行检测,而不是像YOLO那样采用全连接层后做检测。相比于YOLO而言,还有其他两个特点:


第一,SSD提取了不同尺度的特征图来做检测,大尺度特征图可以用来检测小物体,而小特征图用来检测大物体;


第二,SSD采用了不同尺度和长宽比的验框,在Faster R-CNN中称为Anchors。YOLO算法缺点是难以检测小物体,而且定位不准,但是对于这几点,SSD在一定程度上克服这些缺点。


图1示出了SSD的整体结构,整个网络为全卷积网络结构,backbone使用VGG16网络。SSD将backbnone中fc6改为卷积层,fc7改为卷积层,池化层pool5由原来的stride=2的 变成stride=1的。为了不改变特征图的大小,同时获得更大的感受野,Conv6为空洞卷积,dilation=6。在backbnone之后增加了8个卷积层(Extra Feature Layers)。网络中共有6个卷积层(Conv4_3,Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2)的特征图被用来进行检测,6个特征图分别预测不同大小和长宽比的边界框。


SSD为每个检测层都预定了不同大小的先验框(Prior boxes),Conv4_3、Conv10_2和Conv11_2分别有4种先验框,而Conv7、Conv8_2和Conv9_2分别有6种先验框,即对应于特征图上的每个像素,都会生成K(prior box种类)个prior box。Prior box类似于Faster R-CNN中的anchor。网络6个检测层总共预测的边界框数目为8732。

数字化高分辨率图像识别、分类和定位

图 1 SSD网络结构

2 数据处理与样本标记


2.1 数据来源与预处理


本文使用的训练数据集来源于Microsoft公司提供的一个大型的、丰富的物体检测,分割和字幕数据集——COCO数据集。本文使用COCO 2017数据集中10000张图片(包含20个物体类别)对SSD网络进行训练,使用手机、相机拍摄若干张照片或从互联网上获取相关图片,图片中包含的物体为训练集图片(20个物体类别)包含物体的一部分,使用这些照片对SSD网络进行效果预测,测试模型的物体检测与识别能力。本文所使用的图片数据需要进行预处理,预处理包括图片的压缩与数据的标准化。


2.2 样本的标记


训练数据不直接采用SSD网络生成的8732张default box,而是将全部default box与ground truth box做匹配,进行置信度筛选,完成正负样本的标记,以获取训练所需的正样本和负样本,正负样本标记规则如下:


(1)正样本(positive)

  • 与GT(ground truth)重合度最高的default box,其输出对应label设为对应的物体,进行置信度的训练。

  • GT与default boxes的Iou(交并比)满足大于0.5,进行物体位置的训练


(2)负样本(negative):其它情况标记为负样本

在训练过程中,对default boxes进行置信度的筛选时,需按照比例对正负样本数量进行控制,具体比例为positive:negative = 1:3。


3 网络测试结果


本文中SSD网络模型的设计、训练与预测均使用Python语言编写,集成开发环境为PyCharm,网络采用离线训练和在线预测的方式进行图像处理,通过GitHub下载开源的COCO数据集,使用Keras框架完成SSD网络模型的搭建,TensorFlow框架辅助完成网络的训练与预测。本次使用的软硬件、语言、框架、数据集版本等配置信息如表1所示:


表1 相关环境配置信息

配置类型

配置参数

显卡

GeForce GTX 1660Ti

处理器

Intel Core® i7-9750H

语言环境

Python 3.6.5

深度学习框架

TensorFlow 1.12.0、keras 1.2.2

数据集

COCO 2017

集成开发环境

Pycharm 2020.1


使用手机、相机拍摄若干张照片、或从互联网上获取相关图片,图片中包含的物体为训练集图片(20种物体类别为Aeroplane、Bicycle、Bird、Boat、Bottle、Bus、Car、Cat、Chair、Cow、Diningtable、Dog、Horse、Motorbike、Person、Pottedplant、Sheep、Sofa、Train、Tvmonitor,以及Background背景类)包含物体的一部分,使用这些照片作为输入,送入训练好的SSD网络中,进行物体检测与识别的效果验证。测试结果见图2,图中的标注信息格式为:置信度,类别。

数字化高分辨率图像识别、分类和定位数字化高分辨率图像识别、分类和定位数字化高分辨率图像识别、分类和定位图 2网络测试结果


通过以上结果可知,该SSD网络的训练已达到预期,对于训练集中包含的20种物体类别,能够对进行识别、检测并标注其位置,说明SSD网络在物体识别与检测任务中具有较强泛用性能,能够应用于实际的生产任务中。现实生活中,SSD网络本身也已经受到了广泛的应用。


4 代码


部分代码给出如下:

  1. import pickle  

  2. from utils.detection_generate import Generator  

  3. from utils.ssd_utils import BBoxUtility  

  4. from nets.ssd_net import SSD300  

  5. from utils.ssd_losses import MultiboxLoss  

  6. from tensorflow.python.keras.callbacks import ModelCheckpoint, TensorBoard  

  7. import keras  

  8. import tensorflow as tf  


  9. class SSDTrain(object):  

  10.     def __init__(self, num_classes=9, input_shape=(300, 300, 3), epochs=30):

  11.         """初始化网络指定一些参数,训练数据类别,图片需要指定模型输入大小迭代次数 

  12.         """  

  13.         self.num_classes = num_classes  

  14.         self.batch_size = 32  

  15.         self.input_shape = input_shape  

  16.         self.epochs = epochs  

  17.         # 指定训练和读取数据的相关参数  

  18.         self.gt_path = "./datasets/commodity_groundtruth.pkl"  

  19.         self.image_path = "./datasets/commodity/JPEGImages/"  

  20.         prior = pickle.load(open("./datasets/prior_boxes_ssd300.pkl", 'rb'))

  21.         self.bbox_util = BBoxUtility(self.num_classes, prior)  

  22.         self.pre_trained = "./ckpt/pre_trained/weights_SSD300.hdf5"  

  23.         # 初始化模型  

  24.         self.model = SSD300(self.input_shape, num_classes=self.num_classes) 

  25.     def get_detection_data(self):  

  26.         """ 

  27.         获取检测的迭代数据 

  28.         :return: 

  29.         """  

  30.         gt = pickle.load(open(self.gt_path, 'rb'))  

  31.         keys = sorted(gt.keys())  

  32.         num_train = int(round(0.8 * len(keys)))  # 70  

  33.         train_keys = keys[:num_train]  # 70  

  34.         val_keys = keys[num_train:]  # 18  

  35.         # Generator获取数据  

  36.         gen = Generator(gt, self.bbox_util, 16, self.image_path,  

  37.                         train_keys, val_keys,  

  38.                         (self.input_shape[0], self.input_shape[1]), do_crop=False)  

  39.         return gen  

  40.     def init_model_param(self):  

  41.         """ 

  42.         初始化网络模型参数,指定微调的时候,训练部分 

  43.         :return: 

  44.         """  

  45.         # 1、加载本地预训练好的模型  

  46.         self.model.load_weights(self.pre_trained, by_name=True)  

  47.         # 2、指定模型当中某些结构freeze # 冻结模型部分为 SSD当中的VGG前半部分  

  48.         freeze = ['input_1', 'conv1_1', 'conv1_2', 'pool1',  

  49.                   'conv2_1', 'conv2_2', 'pool2',  

  50.                   'conv3_1', 'conv3_2', 'conv3_3', 'pool3']  

  51.         for L in self.model.layers:  

  52.             if L.name in freeze:  

  53.                 L.trainable = False  

  54.         return None  

  55.     def compile(self):  

  56.         """编译模型 

  57.         SSD网络的损失函数计算MultiboxLoss 的compute_loss 

  58.         """  

  59.         # keras 1.2.2 optimizers.Adam()  这个版本的函数可以  

  60.         self.model.compile(optimizer=keras.optimizers.Adam(),  

  61.                            loss=MultiboxLoss(self.num_classes).compute_loss)  

     
                    
数字化高分辨率图像识别、分类和定位                 

尹子松,重庆大学无线通信技术实验室硕士研究生,主研方向为智能信号与信息处理。

  



扫描二维码

获取更多精彩

WCTL@CQU