深度学习(5)数据预处理-resize

  • resize由来与发展
  • resize的方式
  • 不同插值算法对训练结果的影响
  • caffe数据转换成lmdb中的resize
  • 不同resize的影响(总)

resize由来与发展

对输入图像进行大小调整,为什么要这样做呢?

因为图像输入,是转为向量(矩阵)输入的,向量的纬度一般是固定的,所以要进行大小调整

输入向量维数 = 输入层节点数

举例,假如训练输入的是一张张图片,每张图片对应一个矩阵,在这个矩阵里面,将每行看作一个向量,这个向量的列数是固定的

tf.placeholder(tf.float32, [None, 32, 32, 3])

这个函数接收输入的大小就是32*32pixel,当然你可以指定其他的大小,那么在数据预处理的时候,就需要先将图片整理成这样的大小

几何变换的一个常规操作是要把图片的大小resize到相同尺寸,便于统一处理。同时也是要考虑到机器的配置,图片越大在进行运算处理时要求的配置就越高,常规情况下我们会把图片resize到500以下进行处理。很多预训练模型的图片size大小为299×299×3(Xception、InceptionV3…)、224×224×3(VGG16、ResNet50…)。

  • 将输入图像resize到一个固定的尺寸这件事贯穿了DL在目标检测领域的始终:

    1. r-cnn刚提出的阶段,由于网络结构的限制,进入 全连接层的输入维度必须是固定的,那么一个最简单的解决方案就是把输入图像归一化到固定的尺寸,得到输出后反变换回去。这种resize的做法实际上是为了适应卷积神经网络的一种让步。
    2. 随着人们对检测精度的追求,大家开始关注resize所带来的损失。不论是sppnet还是roi pooling,他们都致力于将任意维度的特征图转化成固定的维度以适应全连接的输入,这一思路从理论上解除了整个检测网络对输入的尺寸依赖,这也是fast r-cnn的一个改进点,从此输入图像可以是任意宽高。
    3. 然而各路算法在使用gpu做加速的过程中遇到了新的问题,每一个batch的计算必须拥有相同的size,这是算法本身之外的一个限制,但这个限制却成为了并行加速计算的拦路虎。yolo的作者针对这个情况,在不改变原始图像宽高比的前提下进行了resize操作,具体的做法是对不符合原图比例的区域进行padding。

    现在很多的检测网络都不使用全连接层,就是考虑到图像输入尺寸不一致的问题,从而构建全卷积网络!对于全卷积网络,输入图片的尺度可以为任意的,相当于滑动窗口检测,但为什么很多算法要在测试阶段也变成统一尺寸呢?这就是考虑训练阶段的问题,由于现在训练集的图片可能大小也不一致,而batch的读取方式就限制了必须保持训练图像尺寸的一致性,所以最终网络的感受野也就限定了那个尺度范围内,从而在测试时不能直接使用原图像,还是要进行相同的缩放操作!

但对于超大分辨率的图片,但目标却很小,如kaggle的卫星图船舶检测,上述操作就不太管用了,这时候就要考虑到对图像进行切割,分别送到现在的神经网络,所以还是看你的数据怎么训练的!

resize的方式

  • 对于图片尺寸变化时的插值算法:
    INTER_NEAREST - 最近邻插补
    INTER_LINEAR - 双线性插值(默认方法)
    INTER_AREA - 像素面积相关重采样,图片由大resize小时效果较好
    INTER_CUBIC - 双三次插值,图片由小resize大时效果较好
    INTER_LANCZOS4 - 兰索斯插值
img = cv2.imread(img_path) #读进来的为BGR
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #BGR转RGB
img4 = cv2.resize(img,(500,500)) #默认用INTER_LINEAR插值算法
plt.imshow(img4)

img5 = cv2.resize(img,(500,500),interpolation=cv2.INTER_AREA)
plt.imshow(img5)


其实改变效果很明显,特别是在图片处理任务中发现怎么样改变模型都提高不了效果时,不妨回过头来查看下插值算法有没有用好。

不同插值算法对训练结果的影响

很多时候在resize图片的时候,插值算法会影响到结果的训练结果的好坏。

pillow文档里给出了其各个插值算法的使用情况和优劣。

上表中Performance应该是速度表现的意思,越简单的插值算法速度越快但效果不会很理想。
下文档是对于图片缩小和放大均能保持较高的图片质量的Image.LANCZOS插值算法:

img_size = 500
img3 = img.resize((img_size,img_size),Image.LANCZOS)
img3

以上不同插值算法的选用对图片resize时质量的影响是巨大的。如果不注意到这个点,直接将很大的图片resize到较小的尺寸后进行训练,图片其实已经丢失掉了很多特征,最终的效果自然不会很好。

caffe数据转换成lmdb中的resize

caffe,将数据转换为lmdb/leveldb的convert_imageset.cpp源码可见,是使用ReadImageToDatum函数读入图片,根据输入参数可知,输出为resize后的图像

......
DEFINE_int32(resize_width, 0, "Width images are resized to");  //图像宽度重置
DEFINE_int32(resize_height, 0, "Height images are resized to");//图像高度重置
......//设置图像的长度,宽度  int resize_height = std::max<int>(0, FLAGS_resize_height);  int resize_width = std::max<int>(0, FLAGS_resize_width);
......
//检查图像尺寸  if (check_size) {  if (!data_size_initialized) {  data_size = datum.channels() * datum.height() * datum.width();  data_size_initialized = true;  } else {  const std::string& data = datum.data();  CHECK_EQ(data.size(), data_size) << "Incorrect data field size "  << data.size();  }  }
  • ReadImageToDatum 函数:

读入图像到Datum

bool ReadImageToDatum(const string& filename, const int label,const int height, const int width, const bool is_color,const std::string & encoding, Datum* datum) {cv::Mat cv_img = ReadImageToCVMat(filename, height, width, is_color);if (cv_img.data) {if (encoding.size()) {if ( (cv_img.channels() == 3) == is_color && !height && !width &&matchExt(filename, encoding) )return ReadFileToDatum(filename, label, datum);std::vector<uchar> buf;cv::imencode("."+encoding, cv_img, buf);datum->set_data(std::string(reinterpret_cast<char*>(&buf[0]),buf.size()));datum->set_label(label);datum->set_encoded(true);return true;}CVMatToDatum(cv_img, datum);//cvmat转为Datum格式datum->set_label(label);return true;} else {return false;}
}

ReadImageToDatum函数又是调用ReadImageToCVMat函数读入图像和resize的宽高进行缩放的

  • ReadImageToCVMat 函数:

以cvMat格式读入图像

cv::Mat ReadImageToCVMat(const string& filename,//is_color 为1读入彩色图像,0灰度图const int height, const int width, const bool is_color) {//height,width都不为0则把图像resize 到height*widthcv::Mat cv_img;int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :CV_LOAD_IMAGE_GRAYSCALE);cv::Mat cv_img_origin = cv::imread(filename, cv_read_flag);//读入图像if (!cv_img_origin.data) {LOG(ERROR) << "Could not open or find file " << filename;return cv_img_origin;}if (height > 0 && width > 0) {cv::resize(cv_img_origin, cv_img, cv::Size(width, height));} else {cv_img = cv_img_origin;}return cv_img;
}

可以看出caffe底层是使用opencv的 默认双线性差值的resize方法 ,通过比较可知opencv的resize属性只有area后的图像质量较好,保存信息较为丰富,不会失去边缘信息,因此改resize方式,重新make,使用area属性的caffe。

不同resize的影响(总)

  • 不同的 resize 方式对最终的结果有一定的影响,尤其是用随机图片评估时会更加明显。
    .
    看似用的是同一个神经网络,同一个训练集,但在输入的处理上仍然会有各种不同。比如 Inception 要求 299x299,你可以直接用 ImageMagick 将原始图片处理成 299x299 再输入,也可以用 OpenCV 读入图片后再转成 299x299,还可以直接用深度学习框架(TensorFlow/Caffe)进行 resize。甚至同一种方法也可能有各种不同的参数控制,比如最邻近插值、双线性插值、双立方插值等。 通过不同的 resize 方法训练出来的网络参数,或者同一张图片不同方法 resize 后预测的输出,数值是存在差异的。 如果使用的是质量较低的大规模数据集,差异可能会非常明显。

  • 不同的 resize 方式对最终结果的影响无法确定。
    .
    换种说法,这可能是个玄学。这算是一个经验总结,就不多讲了。也就是说,某种 resize 方式有时可能让结果变好,有时也可能让结果变差。

  • 训练、评估和线上预测时统一图片处理方式有一些好处。
    .
    有的公司在训练神经网络时使用一种框架,上线时使用另一种框架;或者训练时采取一种输入,上线时采取另一种输入。都会导致线上服务的预测结果跟评估结果不一致,导致排查问题较为复杂。
    .
    有时候为了性能考虑,必须在客户端完成图片处理,resize 成较小图片后再传给服务端。而客户端往往使用的不同的库,比如 iOS 可以使用 Core Graphics 库或者 UIKit 库,Android 的 Bitmap 库,这些库在服务端是基本上无法使用的。这时候就需要要知道这可能会导致线上效果与评估结果有不一致的可能,并且采取一定的措施来消减这样的不同。

综上,这一问题至今为止并没有人尝试去完美的解决,而更多的是在理论与工程,精度的速度上做取舍和权衡。

  • 得到的都是侥幸,失去才是人生!
  • 钱到用时方恨少,点赞不够吃不饱,手有余香请点赞,您要赏点我不敢!

参考文章
链接:https://www.jianshu.com/p/c45d89776d85
链接:https://zhuanlan.zhihu.com/p/43268790
链接:https://www.zhihu.com/question/310237588/answer/626222815

深度学习(5)数据处理-resize相关推荐

  1. 深度学习之数据处理——如何将图片和标签打乱并划分为训练集和测试集

    深度学习之数据处理--如何将图片和标签打乱并划分为训练集和测试集 记录我的第一篇CSDN博客 最近我在网上找到Office31数据集,这个数据集中包含了三个子数据集,分别为:Amazon.dslr.w ...

  2. 深度学习之数据处理方法概述

    一.数据对人工智能的重要性 在实现以深度学习为主的人工智能任务的过程中,有三大基本要素是缺一不可的,那就是算力.算法.数据(点击查看:实现人工智能的三要素). 其中算力的大小和硬件直接相关,比如GPU ...

  3. 复旦大学邱锡鹏教授:一张图带你梳理深度学习知识脉络

    Datawhale 作者:邱锡鹏,复旦大学教授 寄语:本文梳理了深度学习知识体系,分为机器学习.神经网络和概率图模型,同时对机器学习算法类型.深度学习原理框架等进行了梳理,帮助大家更好地学习和入手深度 ...

  4. 为什么医学影像AI已进入「后深度学习时代」?

    http://blog.itpub.net/29829936/viewspace-2644440/ "深度学习正走向两极化,大部分研究深度学习的人员会偏向于工程化,包括建立更加全面.便捷.快 ...

  5. 马库斯再批深度学习:20年毫无进展,无法处理语言复杂性

    https://mp.weixin.qq.com/s/QP_jQ8EvSNYFgmQcfEJ00w   新智元报道   来源:medium 作者:Gary Marcus  编辑:肖琴 [新智元导读]G ...

  6. 【神经网络与深度学习摘要】第1章 绪论

    [神经网络与深度学习摘要]第1章 绪论 文章目录 [神经网络与深度学习摘要]第1章 绪论 1.人工智能 1.1 图灵测试 1.2 人工智能的主要领域 1.3人工智能的发展历史 1.4 人工智能的流派 ...

  7. 零基础入门深度学习(二):用一个案例掌握深度学习方法

    导读 本课程是百度官方开设的零基础入门深度学习课程,主要面向没有深度学习技术基础或者基础薄弱的同学,帮助大家在深度学习领域实现从0到1+的跨越.从本课程中,你将学习到: 深度学习基础知识 numpy实 ...

  8. 【二】零基础入门深度学习:用一个案例掌握深度学习方法

    (给机器学习算法与Python学习加星标,提升AI技能) 作者 | 毕然  百度深度学习技术平台部主任架构师 内容来源 | 百度飞桨深度学习集训营 本文转自飞桨PaddlePaddle 导读 从本课程 ...

  9. 独热编码python实现_详解深度学习中的独热编码

    很多人开始接触深度学习,数据处理遇到第一个专业英文术语就是one-hot encode(独热编码),很多初学者就会迷茫,这个东西是什么意思,其实说的直白点所谓的独热编码最重要的就是把一组字符串或者数字 ...

最新文章

  1. JDK 13 的最新垃圾回收器ZGC,你了解多少?
  2. Springboot配置不当
  3. android butterknife使用详解
  4. 燧原科技首发国内第二代人工智能训练芯片“邃思2.0”
  5. 解决pytorch安装过程中下载总是出错的问题
  6. html页面调用高德地图,html前端使用高德地图入门教程,并在地图上标记位置-Go语言中文社区...
  7. 碰运气解决LATEX中中文颜色深浅不一的问题
  8. android开发---9.MediaPlayer实现音乐播放的demo
  9. 修改 jenkins 插件下载地址
  10. 网卡参数设置建议与各个网卡参数含义详解
  11. Hrbust 1788 Chocolate【Dp】
  12. 华为云文件夹服务器,华为云文件夹服务器
  13. ITパスポート5天学习笔记④_Rx
  14. 机器学习-----聚类kmeans肘部图、轮廓图的绘制、以及聚类和聚类中心散点图的绘制
  15. Linux操作系统下的权限设置
  16. CUBEMX教程—— STM32F407实现多步进电机型加减速全过程
  17. HA on yarn的搭建流程及JAVA代码对HDFS上大数据的处理(附代码)
  18. Spring学习详细代码+图片解释笔记
  19. 如何提高存货周转率?存货周转率真的越高越好吗?
  20. Word转PDF怎么转换?福昕阅读器来实现

热门文章

  1. 基于PHP的高效协同办公管理系统
  2. ElasticSearch(一)基本安装及操作
  3. hugeng007_RandomForestClassifier_demo
  4. 1094: 统计元音(函数专题)
  5. 【每日一题(8)】Mammoth's Genome Decoding CodeForces - 747B
  6. python和revit_Revit中Python脚本使用技术训练视频教程
  7. 斗地主排序和音乐系统管理
  8. 游戏开发-2022-11-30-马戏团
  9. Mac安装Aircrack-ng
  10. playwright 爬虫使用