草庐IT

深度学习与CV教程(12) | 目标检测 (两阶段,R-CNN系列)

ShowMeAI 2023-03-28 原文


本系列为 斯坦福CS231n 《深度学习与计算机视觉(Deep Learning for Computer Vision)》的全套学习笔记,对应的课程视频可以在 这里 查看。更多资料获取方式见文末。


引言

ShowMeAI在前面的内容中给大家做了很多图像分类的介绍,主要围绕卷积神经网络(LeNet / AlexNet / NIN / VGG / Google / ResNet / MobileNet / squeezenet)讲解,但计算机视觉领域有其他一些更为复杂的任务,例如本篇开始介绍的目标检测(object detection)问题。

1. 计算机视觉任务

大家知道人工智能领域的3大热点方向是计算机视觉(CV,computer vision)、自然语言处理(Natural Language Process, NLP )和语音识别(Speech Recognition) 应用 。而计算机视觉领域又有图像分类、目标检测、图像分割三大任务,如下图所示


这3大任务其实对应机器视觉理解图像的3个主要层次:

1.1 图像分类(Classification)

图像分类任务中,我们要将图像识别判定为某个类别。它是最简单、最基础的图像理解任务,也是深度学习模型最先取得突破和实现大规模应用的任务。大家在前面也了解到了 ImageNet 这个权威评测集,每年的ILSVRC催生了大量的优秀深度网络结构,为其他任务提供了基础。

有一些其他的应用,包括人脸识别、场景识别等都可以化归为分类任务来解决。

1.2 目标检测(Detection)

图像分类任务关心整体图片类别,而目标检测则关注特定的物体目标,要求在图片中,同时识别出目标物的类别信息和位置信息(是一个classification + localization的问题)。

相比分类,目标检测任务要求我们需要从背景中分离出感兴趣的目标,并确定这一目标的描述(类别和位置),检测模型的输出形式通常是一个列表,列表的每一项使用一个数组给出检出目标的类别和位置(常用矩形检测框的坐标表示)。

1.3 图像分割(Segmentation)

图像分割包括语义分割(semantic segmentation)和实例分割(instance segmentation),前者是对前背景分离的拓展,要求分离开具有不同语义的图像部分(相当于像素级别的分类),而后者是检测任务的拓展,要求描述出目标的轮廓(相比检测框更为精细)。

分割是对图像的像素级描述,它赋予每个像素类别意义,适用于理解要求较高的场景,如无人驾驶中对道路和非道路的分割,医疗影像中对于不同区域的划分。

1.4 总结

图像分类对应将图像划分为单个类别的过程,它通常对应于图像中最突出的物体。实际现实世界的很多图像通常包含多个物体,如果仅仅使用图像分类模型分配单一标签是非常粗糙的,并不准确。而目标检测(object detection)模型可以识别一张图片的多个物体,并可以给出不同物体的具体位置(边界框)。目标检测在很多场景有用,如无人驾驶和安防系统。

2. 常用目标检测(Object Detection)算法综述

2.1 总体介绍

常见的经典目标检测算法如下图所示:


目标检测的基本思路是:解决定位(localization) + 识别(Recognition) 两个任务。

一个大致的pipeline如下图所示,我们可以用同样的特征抽取过程,借助两个不同的分支输出。

  • 一个分支用于做图像分类,即全连接 + Softmax 判断目标类别,和单纯图像分类区别在于这里还另外需要一个「背景」类。
  • 另一个分支用于识别目标位置,即完成回归任务输出四个数字标记包围盒位置(例如中心点横纵坐标和包围盒长宽),该分支输出结果只有在分类分支判断不为「背景」时才使用。

2.2 传统方法

传统的目标检测框架,主要包括三个步骤:

  • ① 利用不同尺寸的滑动窗口框住图中的某一部分作为候选区域;
  • ② 提取候选区域相关的视觉特征。比如人脸检测常用的 Harr 特征;行人检测和普通目标检测常用的 HOG 特征等;
  • ③ 利用分类器进行识别,比如常用的 SVM 模型。

2.3 两阶段vs一阶段 方法

现在主流的深度学习目标检测方法主要分为两类:两阶段(Two Stages)目标检测算法一阶段(One Stage)目标检测算法

1) 两阶段(Two Stages)

  • 首先由算法(algorithm)生成一系列作为样本的候选框,再通过卷积神经网络进行分类。
  • 常见的算法有 R-CNN、Fast R-CNN、Faster R-CNN 等等。

2) 一阶段(One Stage )

  • 不需要产生候选框,直接将目标框定位的问题转化为回归(Regression)问题处理(Process)。
  • 常见的算法有YOLO、SSD等等。

上述两类方法,基于候选区域(Region Proposal)的方法(两阶段)在检测准确率和定位精度上占优,基于端到端(一阶段)的算法速度占优。相对于R-CNN系列的「两步走」(候选框提取和分类),YOLO等方法只「看一遍」。

我们在本篇中给大家介绍两阶段的目标检测方法,主要是R-CNN系列目标检测方法,在下篇内容目标检测 (SSD,YOLO系列)中给大家介绍一阶段的目标检测方法(YOLO系列,SSD等)。

3.两阶段目标检测算法发展史

4.两阶段目标检测典型算法

4.1 R-CNN

如何将深度学习分类算法应用到目标检测?

  • 用深度学习分类模型提取特征方法代替传统图像特征提取算法。

R-CNN核心思想: 对每张图片选取多个区域,然后每个区域作为一个样本进入一个卷积神经网络来抽取特征。

1) R-CNN网络结构

R-CNN算法是较早提出的两阶段目标检测算法,它先找出 Region Proposal,再进行分类和回归。

  • 所谓 Region Proposal 就是图中目标可能出现的位置。
  • 因为传统方法需要枚举的区域太多了,所以通过利用图像中的纹理、边缘、颜色等信息,可以保证在选取较少窗口(几千甚至几百)的情况下保持较高的响应比。所以,问题就转变成找出可能含有物体的候选框,这些框之间是可以互相重叠互相包含的,这样我们就可以避免暴力枚举的所有框了。

2) R-CNN应用流程

对于每张输入的图像,R-CNN目标检测主要包括下述步骤:

  • ① 利用选择性搜索 Selective Search 算法在图像中从下到上提取 2000个左右的可能包含物体的候选区域 Region Proposal
  • ② 因为获取到的候选区域大小各不相同,所以需要将每个 Region Proposal 缩放(warp)成统一的 \(227 \times 227\) 的大小并输入到 CNN,将CNN的 fc7 层的输出作为特征
  • ③ 将每个 Region Proposal 提取到的CNN特征输入到SVM进行分类
  • ④ 使用这些区域特征来训练线性回归器对区域位置进行调整

3) R-CNN不足与优化

R-CNN 的效果如下图所示,它有一些不足之处(也是系列算法后续改进的点):

  • R-CNN 虽然不需要穷举所有框了,但是它需要对所有ss算法选取出的候选框region proposal (2000多个)进行CNN提取特征 + SVM分类,计算量很大,导致R-CNN检测速度很慢,一张图都需要47s。
  • Selective search提取的区域质量不够好
  • 特征提取与后续SVM分类器是独立训练的,没有联合优化,且训练耗时长

优化方式为:

  • 2000个region proposal是图像的一部分,可以对图像只进行一次卷积提取特征,然后将region proposal在原图的位置映射到卷积层特征图上,得到映射后的各个proposal的特征输入到全连接层做后续操作。
  • 每个region proposal的大小都不一样,而全连接层输入必须是固定的长度,因此不能将proposal的特征直接输入全连接层,后续改进向R-CNN模型引入了SPP-Net(也因此诞生了Fast R-CNN模型)。

4.2 SPP-Net

1) 设计出发点

我们通过前面的 CNN 相关知识学习知道,CNN 的卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入。所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行 crop(抠图)或者 wrap(图像resize)操作。

在 R-CNN中,因为不同的 proposal 大小不同,所以需要先 resize 成相同大小再输入到 CNN 中。既然卷积层是可以接受任何尺寸的,可以在卷积层后面加上一部分结构使得后面全连接层的输入为固定的,这个「化腐朽为神奇」的结构就是 spatial pyramid pooling layer。

下图是 R-CNN 和 SPP-Net 检测流程的比较:


SPP-Net 和普通 CNN 的对比结构如下,在网络结构上,直接把 pool5 层替换成 SPP 层:


SPP-Net 的具体细节如下,由 features map 上确定的 region proposal 大小不固定,将提取的 region proposal 分别经过三个卷积 \(4 \ast 4\)\(2 \ast 2\)\(1 \ast 1\) ,都将得到一个长度为 21 的向量(21是数据集类别数,可以通过调整卷积核大小来调整),因此不需要对 region proposal 进行尺寸调整:


相比R-CNN,SPP-Net有两大优点。

① 通过「特征金字塔池化」模块,实现了 CNN 的多尺度输入,使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。

② R-CNN 要对每个区域计算卷积,而 SPPNet 只需要计算一次卷积,从而节省了大量的计算时间。

  • R-CNN 流程中,先用 ss 算法得到2000个proposal分别做卷积操作
  • SPP-Net 只对原图进行一次卷积计算,得到整张图的卷积特征feature map,然后找到每个候选框在 feature map 上的映射 patch,将此 patch 作为每个候选框的卷积特征,输入到 SPP 层以及之后的层,完成特征提取工作。

4.3 Fast R-CNN

对于 RCNN 速度过慢等问题,提出了基于 RCNN 的改善模型 Fast RCNN。

1) 核心改进

Fast RCNN 主要改进以下部分:

  • ① 将 classification 和 detection 的部分融合到 CNN 中,不再使用额外的 SVM 和 Regressor,极大地减少了计算量和训练速度。
  • ② Selective Search 后不再对 region proposal 得到的 2k 个候选框进行截取输入,改用 ROI Project,将 region proposal 映射到 feature map 上
  • ③ 使用 ROI pooling 将在 feature map 上不同尺度大小的ROI归一化成相同大小后就可以通过FC层。

2) 核心环节

如下图所示为Fast R-CNN流程与网络结构


Fast R-CNN具体包括的核心环节如下:

① Region Proposal:与 R-CNN 一致

跟RCNN一样,Fast-RCNN 采用的也是 Selective Search 的方法来产生 Region Proposal,每张图片生成 2k 张图片。但是不同的是,之后不会对 2k 个候选区域去原图截取,后输入 CNN,而是直接对原图进行一次 CNN,在 CNN 后的 feature map,通过 ROI project 在 feature map 上找到 Region Proposal的位置。

② Convolution & ROI 映射

就是对原图输入到 CNN 中去计算,Fast-RCNN 的工具包提供提供了 3 种 CNN 的结构,默认是使用 VGG-16 作为 CNN 的主干结构。根据 VGG-16 的结构,Fast-RCNN 只用了 4 个 MaxPooling 层,最后一个换成了 ROI Pooling,因此,只需要对 Region Proposal 的在原图上的 4 元坐标 \((x, y, w, h)\) 除以 \(16\),并找到最近的整数,便是 ROI Project 在 feature map 上映射的坐标结果。最终得到 \(2k\) 个 ROI。

③ ROI Pooling

对每一个 ROI 在 feature map 上截取后,进行 ROI Pooling,就是将每个 ROI 截取出的块,通过 MaxPooling 池化到相同维度。

ROI Pooling的计算原理是,将每个不同大小的 ROI 平均划分成 \(7 \times 7\) 的 grid,在每个 grid 中取最大值,最后所有 ROI 都会池化成大小为 \(7 \times 7\) 维度。

④ 全连接层 & 输出

将每个 ROI Pooling 后的块,通过全连接层生成 ROI 特征向量,最后用一个 Softmax 和一个 bbox regressor 进行分类和回归预测,得到每个 ROI 的类别分数和 bbox 坐标。全连接层为矩阵相乘运算,运行消耗较多,速度较慢,作者在这里提出可以使用 SVD 矩阵分解来加快全连接层的计算。

⑤ 多任务损失

Fast-RCNN 的两个任务:

  • 一个是分类,分为 \(n(种类) + 1(背景)\) 类,使用的是Cross Entropy + Softmax 的损失函数
  • 第二个是 Bbox 的 Localization 回归,使用跟 Faster-RCNN 一样的基于 Offset 的回归,损失函数使用的是 Smooth L1 Loss,具体原理在下方 Faster-RCNN 中介绍。

3) Fast R-CNN网络效果


Fast R-CNN 效果如上图所示,相比之 R-CNN 它在训练和预测速度上都有了很大的提升,但它依旧有不足之处,大家观察整个流程,会发现在候选区域选择上,依旧使用的 Selective Search 方法,它是整个流程中的时间消耗瓶颈,无法用 GPU 硬件与网络进行加速。

4.4 Faster R-CNN

Faster-RCNN 在 Fast-RCNN 的基础上做了两个重大的创新改进:

  • ① 在 Region Proposal 阶段提出了 RPN(Region Proposal Network)来代替了 Selective Search
  • ② 使用到了 Anchor

1) Faster R-CNN网络结构

Faster R-CNN的总体流程结构如下,可分为Backbone、RPN、ROI+分类 / 回归 三个部分。


2) Anchor(锚框)

Anchor 是图像检测领域一个常用的结构,它可以用来表示原图中物体所在的区域,是一个以feature map 上某个点为中心的矩形框。

Faster-RCNN 的 anchor,在 feature map 上每个点,生成 3 种尺度和 3 种比例共 9 个 anchor。

  • 下图是一个 anchor 的示意图,每个点会生成尺度为小( \(128\times128\))、中(\(256\times256\))、大(\(512\times512\)),如图中红、绿、蓝色的anchor,\(1:1\), \(2:1\), \(1:2\) 三种比例共 9 个 anchor。
  • 这样充分考虑了被检测物体的大小和形状,保证物体都能由 anchor 生成 region proposal。


3) RPN网络结构

RPN 是一个全卷积的神经网络,它的工作原理可以分成 classification,regression 和 proposal 三个部分

① Classification/分类

Classification 部分将得到的 feature map 通过一个 \(3 \times 3\)\(1 \times 1\) 的卷积后,输出的维度为 \([1 \times 18 \times 38 \times 50]\),这18个channel可以分解成 \(2\times9\),2代表着是否是感兴趣物体备选区域(region proposal)的 0/1 的 score,9 代表着 9 个 anchors。

因此,特征图维度 \(38\times50\) 的每一个点都会生成 9 个 anchor,每个 anchor 还会有 0/1 的 score。

② Regression/回归

Regression 部分原理和 Classification 部分差不多,feature map通过一个 \(3 \times 3\)\(1 \times 1\) 的卷积后,输出的维度为 \([1 \times 36 \times 38 \times 50]\),其中 36 个channel可以分成 \(4 \times 9\),9就是跟 cls 部分一样的 9 个anchor,4 是网络根据 anchor 生成的 bbox 的 4 元坐标 target 的 offset。通过 offset 做 bbox regression,再通过公式计算,算出预测 bbox 的 4 元坐标 \((x, y, w, h)\) 来生成 region proposal。

③ Proposal/候选区

将前两部分的结果综合计算,便可以得出 Region Proposals。

  • 若 anchor 的 \(IoU > 0.7\),就认为是前景
  • \(IoU < 0.3\),就认为是背景
  • 其他的 anchor 全都忽略

一般来说,前景和背景的 anchor 保留的比例为 \(1:3\)

① RPN网络训练策略

RPN 网络的训练样本有如下的策略和方式:

② RPN网络监督信息

RPN 网络是监督学习训练,包含分类和回归两个任务,分类分支和回归分支的预测值和 label 构建方式如下:

③ RPN网络LOSS

RPN 网络的总体 loss 由 2 部分构成,分别是分类 loss 和回归 loss,为其加权求和结构。其中分类 loss 使用常规的交叉熵损失,回归损失函数使用的是 Smooth L1 Loss,本质上就是L1 Loss 和 L2 Loss 的结合。

④ RPN网络回归分支Loss

特别说一下回归部分使用到的 Smooth L1 Loss,对比于 L1 Loss 和 L2 Loss,Smooth L1 Loss 可以从两方面限制梯度:

  • ① 当预测框与 ground truth 的 Loss 很大的时候,梯度不至于像 L2 Loss 那样过大
  • ② 当预测框与 ground truth 的 Loss 较小的时候,梯度值比 L1 Loss 更小,不至于跳出局部最优解。

4) 生成Proposals

结合分类和回归结果得出 Region Proposals。若 anchor 的 \(IoU > 0.7\),就认为是前景;若 \(IoU < 0.3\),就认为是背景,其他的anchor全都忽略。一般来说,前景和背景的anchor保留的比例为 \(1:3\)

得到 Region Proposal 后,会先筛选除掉长宽小于 16 的预测框,根据预测框分数进行排序,取前N(例如6000)个送去 NMS,经过 NMS 后再取前 \(top_k\)(例如300)个作为 RPN 的输出结果。

5) Rol Pooling

① Roi pooling核心思想

候选框共享特征图特征,并保持输出大小一致。

候选框分为若干子区域,将每个区域对应到输入特征图上,取每个区域内的最大值作为该区域的输出。

② Rol Pooling不足

在 ROI 映射中,涉及到 region proposal 的坐标映射变换问题,在这过程中难免会产生小数坐标。但是在 feature map 中的点相当于一个个的 pixel,是不存在小数的,因此会将小数坐标量化成向下取整,这就会造成一定的误差。

在 ROI Pooling 中,对每个 ROI 划分 grid 的时候又会有一次坐标量化向下取整。

这样,整个过程像素坐标会经过两次量化,导致 ROI 虽然在 feature map 上有不到 1 pixel 的误差,映射回原图后的误差可能会大于 10 pixel,甚至误差可能会大于整个物体,这对小物体的检测非常不友好。

6) Rol Align

Faster R-CNN 中通过 ROI Align 消除 RoI Pooling 中产生的误差。


ROI Align 的原理是,先将 ROI Project 和 ROI Pooling 时计算出的 ROI 带小数的坐标存储在内存中,不直接量化成像素坐标。

随后,ROI Align 不取每个 grid 的最大值,而是再将每个 grid 划分成 \(2\times2\) 的小格,在每个小格中找到中心点,将离中心点最近的四个点的值进行双线性差值,求得中心点的值,再取每个 \(grid\) 中四个中心点的最大值作为 \(Pooling\) 后的值。

7) BBox Head

下面是分类与回归的 BBox 头部分,它的处理流程展开后如下图所示:


而BBox训练阶段的样本构建方式如下,我们对比RPN阶段的样本构建方式:

① BBox Head中的监督信息

BBox头的分类与回归任务的标签构建方式如下,其中分类分支是典型的分类问题,学习每个预测框的类别;回归分支则是学习每个 RoI 到真实框的偏移量。

② BBox Head Loss

BBox 头的总体 loss 由分类 loss 和回归 loss 加权组合构成。

8) Faster R-CNN效果

Faster R-CNN的效果如下图所示

5.推荐学习

可以点击 B站 查看视频的【双语字幕】版本

斯坦福 CS231n 全套解读

ShowMeAI 系列教程推荐

有关深度学习与CV教程(12) | 目标检测 (两阶段,R-CNN系列)的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  7. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  8. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

随机推荐