RCNN:Rich feature hierarchies for accurate object detection and semantic segmentation
利用 CNN 进行目标检测的首个神经网络,首先利用选择性搜索提取图片的 2000 个左右的 Region Proposal,然后通过 AlexNet 提取得到固定长度的特征,接着使用支持向量机 (SVM) 分析这些特征,以实现获选区域的分类,使用边界框回归分析这些特征,获取获选框更精细位置
什么是 RCNN?
- 利用 CNN 进行目标检测的首个神经网络
- 利用选择性搜索 (SelectiveSearch,SS) 提取图片的 2000 个左右的 Region Proposal,然后通过 AlexNet 提取得到固定长度的特征,接着使用支持向量机 (SVM) 分析这些特征,以实现获选区域的分类,使用边界框回归 (Bounding box Regression) 分析这些特征,获取获选框更精细位置
RCNN 的目标识别任务步骤?
- (1) 图片输入
- (2) 获取获选框: 利用选择性搜索 (SelectiveSearch,SS) 算法在图像中提取 2000 个左右的 Region Proposal
- (3) 微调 CNN 分类模型: 将每个 Region Proposal 缩放成 227x227 的大小并输入到 CNN,做 N+1 的多分类分类
- (4) 训练 SVM 分类模型: 将 CNN 模型的 fc7 层的输出作为特征,训练 SVM 的目标及背景的二分类器
- (5) 边界框回归: 对被 SVM 分类为目标的获选框,用边界框回归 (Bounding box Regression) 校正原来的建议窗口,生成预测窗口坐标
RCNN 微调时,输入、输出是什么?损失如何计算?
- 输入: 使用 AlexNet 进行微调,输入是目标检测的候选框区域的图片,缩放到(227,227),根据 IOU>0.5 判定正样本,自定义数据采集器,使得每次训练 128 个图像,其中 32 个正样本,96 个负样本
- 输出:输出是 N+1 分类,判断该候选框内的目标类别
- 损失函数:使用交叉熵损失 (CrossEntropyLoss)
什么是选择性搜索 (Selective Search, SS) ?
- 使用一种过分割手段,将图像分割成小区域 (1k~2k 个)
- 查看现有小区域,按照合并规则合并可能性最高的相邻两个区域。重复直到整张图像合并成一个区域位置
- 优先合并以下四种区域: 颜色(颜色直方图)相近的, 纹理(梯度直方图)相近的,合并后总面积小的
RCNN 是如何训练候选框的分类模型的?
- 1)预训练模型:在 imageNet 上预训练 AlexNet 模型;
- 2)微调预训练模型:修改 AlexNet 模型最后一层,类别改为 (N+1),在 N 个获选框上微调模型。根据 IOU>0.5 判定正样本,并使得每个 batchsize 放入 96 负样本、32 正样本训练
- 3)训练 SVM 模型:完成微调后,输出每个获选框的 fc7 层 4096 维的特征,然后在 SVM 上训练该特征,获得获选框的分类模型。训练 SVM 给标签时,判断某个候选框是某个类别的正样本的要求是 IOU>0.3,为每个类别按正负样本训练 SVM 分类器
RCNN 为什么不使用微调后的 Alexnet 作为获选框的分类模型,而是重新构建 SVM?
- 两个模型训练时,对正样本的定义不同,微调 AlexNet 时,IOU>0.5 即可;训练 SVM 时,IOU=1,这意味着 AlexNet 的正负样本比例比 SVM 大
- AlexNet 更加容易过拟合:为了防止 AlexNet 向负样本过拟合,取 IOU=0.5 对正负样本进行划分,但是这样也导致和现实不符合,因为 SS 采样得到的样本负样本的数量占绝大比例(虽然 batchsize 正负样本按 96:32 输入,也存在该问题),进而导致 AlexNet 分类效果比 SVM 差
- SVM 仅依靠少数的支持向量就完成分类,不容易发生过拟合,按实际更小的正样本(IOU=1)比例即可完成分类,如果取 IOU>0.5 为正样本,mAp 反而变小
RCNN 中,图片 Resize 有几种方式?
- B 先扩充后裁剪: 直接在原始图片中,把 bounding box 的边界进行扩展延伸成正方形,然后再进行裁剪;如果已经延伸到了原始图片的外边界,那么就用 bounding box 中的颜色均值填充
- C 先裁剪后扩充:先把 bounding box 图片裁剪出来,然后用固定的背景颜色填充成正方形图片 (背景颜色也是采用 bounding box 的像素颜色均值)
- **D 强制裁剪:** 不管图片的长宽比例,管它是否扭曲,进行缩放就是了,全部缩放到 CNN 输入的大小
RCNN 如何做边界框回归 (Bounding box Regression)?
- 对每一类目标,使用一个线性脊回归器进行精修。 输入为深度网络 pool5 层的 4096 维特征,输出为 xy 方向的缩放和平移。 训练样本:判定为本类的候选框中和真值重叠面积大于 0.6 的候选框
- 例子:以密集连接层输出输出边界框的左上、右下的坐标点,说明使用候选框的 4096 维特征可以计算得到获选框坐标
搭建模型,输出为边界框的左上、右下的坐标点
1
2
3
4
5
6
7
8
9
10
11
12# load the VGG16 network, ensuring the head FC layers are left off
vgg = VGG16(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)))
vgg.trainable = False
flatten = vgg.output
flatten = Flatten()(flatten)
bboxHead = Dense(128, activation="relu")(flatten)
bboxHead = Dense(64, activation="relu")(bboxHead)
bboxHead = Dense(32, activation="relu")(bboxHead)
bboxHead = Dense(4, activation="sigmoid")(bboxHead) # 输出为边界框的左上、右下的坐标点
model = Model(inputs=vgg.input, outputs=bboxHead)
opt = Adam(lr=INIT_LR)
model.compile(loss="mse", optimizer=opt)模型训练:
BASE_PATH = "dataset" IMAGES_PATH = os.path.sep.join([BASE_PATH, "images"]) ANNOTS_PATH = os.path.sep.join([BASE_PATH, "airplanes.csv"]) data = [] targets = [] for row in rows: (filename, startX, startY, endX, endY) = row imagePath = os.path.sep.join([IMAGES_PATH, filename]) image = cv2.imread(imagePath) # 模型监督信息为:边界框的真实左上、右下的坐标点,按图片大小归一化 (h, w) = image.shape[:2] startX = float(startX) / w startY = float(startY) / h endX = float(endX) / w endY = float(endY) / h image = load_img(imagePath, target_size=(224, 224)) image = img_to_array(image) data.append(image) targets.append((startX, startY, endX, endY)) BASE_PATH = "dataset" IMAGES_PATH = os.path.sep.join([BASE_PATH, "images"]) ANNOTS_PATH = os.path.sep.join([BASE_PATH, "airplanes.csv"]) data = [] targets = [] for row in rows: (filename, startX, startY, endX, endY) = row imagePath = os.path.sep.join([IMAGES_PATH, filename]) image = cv2.imread(imagePath) # 模型监督信息为:边界框的真实左上、右下的坐标点,按图片大小归一化 (h, w) = image.shape[:2] startX = float(startX) / w startY = float(startY) / h endX = float(endX) / w endY = float(endY) / h image = load_img(imagePath, target_size=(224, 224)) image = img_to_array(image) data.append(image) targets.append((startX, startY, endX, endY))
模型输出
RCNN 有哪些缺点?
- 1、训练分多步:R-CNN 的训练先要 fine tuning 一个预训练的网络,然后针对每个类别都训练一个 SVM 分类器,最后还要用 regressors 对 bounding-box 进行回归,另外 region proposal 也要单独用 selective search 的方式获得,步骤比较繁琐
- 2、时间和内存消耗比较大。在训练 SVM 和回归的时候需要用网络训练的特征作为输入,特征保存在磁盘上再读入的时间消耗还是比较大的
- 3、测试的时候也比较慢,每张图片的每个 region proposal 都要做卷积,重复操作太多