Q:很多CNN架构模型的输入都是限制了图片大小的,如VGG、ResNet默认是 224224, Xception默认是299299,如果在我们自己定义model的时候,该如何选择图片尺寸呢?
一般输入图片越大最后的accuracy越高;
首先我们要知道的是一般情况下,图片越大(严格说分辨率越高),图片展现的信息就越多,CNN能提取到的特征就越多,最后的accuracy就越高。但是图片越大带来的计算量也就越大,训练时间也会更长,而且predict的时候耗时也会更多,所以这里需要在你的目标准确率和算力以及耗时之间进行权衡了。结合现有的图片进行评估。
另外就是要结合你的图片进行一个评估,最好让你的图片都可以比较合理地resize到同一个尺寸。比如你的图片大都都是A4纸这样的长方形,那么你可以resize到100 140这种,但如果你都要resize到100100的话就会导致图片有所变形,从而有可能会导致特征减少。
Q:如果要固定统一的尺寸大小,而我的图片尺寸大小差别很大,改如何resize呢?
一般有两种方式:
-
插值缩放(Interpolation);
opencv带有多种插值方式,可以搜索相关资料了解,而我使用的是Python,所以下面是Python使用PIL library的nearest插值的效果。
-
零填充(Zero-padding);
就是按比例缩放,然后不够目标尺寸的就用0进行填充,如下图(因为转成了灰度图,matplotlib显示如此,所以颜色请忽略)
具体实现方式可以参考我的代码:
https://github.com/vance-coder/OCR/blob/master/dataAumentation.ipynb
这两种resize方式如何选择呢?
- 首先我们要知道,插值缩放是可能一定程度上会导致图片变形的,这会影响最后的accuracy。但是也是看具体应用场景的,譬如我最近做的检测图像的文本方向,采用的是interpolation,在我的实际应用中看到这种影响也并不大,最后得到的accuracy还是蛮高的;但是如果你做的是文字识别,那么就不能随意缩放了,这很容易导致字体变形等问题。
- 零填充似乎解决了图片变形的问题,但是图片引入了一些不相干的黑块部分(就是0填充的部分),但这一部分实际上是没有用的、不影响结果的,模型得花代价去学习适应它,那么训练上可能会花的时间比较长,这样训练集的数量也就不能太少。
所以总结就是如果训练集少,resize变形时对accuracy影响不大的场景可以考虑interpolation,如果训练集足够多、算力够强,对accuracy要求较高的则可以采用Zero-padding方式。