如何用TensorFlow图像处理 高斯函数函数裁剪图像

TensorFlow 图像数据预处理及可视化 - 知乎专栏
{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"contributes":[{"sourceColumn":{"lastUpdated":,"description":"记录技术成长的每一步,分享给更多TensorFlow爱好者!","permission":"COLUMN_PUBLIC","memberId":,"contributePermission":"COLUMN_PUBLIC","translatedCommentPermission":"all","canManage":true,"intro":"记录技术成长的每一步,分享给更多TensorFlow爱好者!","urlToken":"c_","id":27917,"imagePath":"v2-d8a0e1fc7acee4e5c3b7c2d6.jpg","slug":"c_","applyReason":"0","name":"慢慢学TensorFlow","title":"慢慢学TensorFlow","url":"/c_","commentPermission":"COLUMN_ALL_CAN_COMMENT","canPost":true,"created":,"state":"COLUMN_NORMAL","followers":4029,"avatar":{"id":"v2-d8a0e1fc7acee4e5c3b7c2d6","template":"/{id}_{size}.jpg"},"activateAuthorRequested":false,"following":false,"imageUrl":"/v2-d8a0e1fc7acee4e5c3b7c2d6_l.jpg","articlesCount":22},"state":"accepted","targetPost":{"titleImage":"/v2-d8d49754cfbcc8a8534290e_r.jpg","lastUpdated":,"imagePath":"v2-d8d49754cfbcc8a8534290e.jpg","permission":"ARTICLE_PUBLIC","topics":[89794],"summary":"注:文章转自《慢慢学TensorFlow》微信公众号图像是人们喜闻乐见的一种信息形式,“百闻不如一见”,有时一张图能胜千言万语。图像处理是利用计算机将数值化的图像进行一定(线性或非线性)变换获得更好效果的方法。Photoshop,美颜相机就是利用图像处理技…","copyPermission":"ARTICLE_COPYABLE","translatedCommentPermission":"all","likes":0,"origAuthorId":0,"publishedTime":"T10:50:56+08:00","sourceUrl":"","urlToken":,"id":2315943,"withContent":false,"slug":,"bigTitleImage":false,"title":"TensorFlow 图像数据预处理及可视化","url":"/p/","commentPermission":"ARTICLE_ALL_CAN_COMMENT","snapshotUrl":"","created":,"comments":0,"columnId":27917,"content":"","parentId":0,"state":"ARTICLE_PUBLISHED","imageUrl":"/v2-d8d49754cfbcc8a8534290e_r.jpg","author":{"bio":"qq圈人","isFollowing":false,"hash":"47ad35a6f1d01b941a1e9e344d60a194","uid":437000,"isOrg":false,"slug":"dong-xiao-man-18","isFollowed":false,"description":"","name":"绿萝123","profileUrl":"/people/dong-xiao-man-18","avatar":{"id":"v2-4de0f89feb4fb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"memberId":,"excerptTitle":"","voteType":"ARTICLE_VOTE_CLEAR"},"id":553378}],"title":"TensorFlow 图像数据预处理及可视化","author":"dong-xiao-man-18","content":"注:文章转自《慢慢学TensorFlow》微信公众号图像是人们喜闻乐见的一种信息形式,“百闻不如一见”,有时一张图能胜千言万语。图像处理是利用计算机将数值化的图像进行一定(线性或非线性)变换获得更好效果的方法。Photoshop,美颜相机就是利用图像处理技术的应用程序。深度学习最重要的应用领域就是计算机视觉(CV, \nComputer Vision),历史上,MNIST 手写体数字识别和 ImageNet 大规模图像识别均得益于深度学习模型,取得了相比传统方法更高的准确率。从 \n2012 年的 AlexNet 模型开始,随后的 VGG, GoogLeNet, ResNet 等模型不断刷新 ImageNet \n图像识别准确率纪录,甚至超过了人类水平。为了获得良好的识别效果,除了使用更好的模型,数据集的预处理也是十分重要的一项内容,最常用的方法有尺度缩放、随机切片、随机翻转、颜色变换等。本文介绍如何使用 \nTensorFlow 完成图像数据的预处理,以及如何使用 tensorboard 工具将图像数据进行可视化。在使用 TensorFlow 实现图像识别、目标检测时会经常用到本文介绍的内容。首先看下输入图像,是一只猫:TensorFlow \n读取图片数据代码:reader \n= tf.WholeFileReader()key, \nvalue = reader.read(tf.train.string_input_producer(['cat.jpg']))image0 \n= tf.image.decode_jpeg(value)用过 \nCaffe 的读者可能会非常熟悉上面的图片(位于 caffe/examples/images/cat.jpg)。原图尺寸为 360 x 480。图像缩放代码:resized_image \n= tf.image.resize_images(image0, [256, 256], \\
method=tf.image.ResizeMethod.AREA)其中 \nmethod 有四种选择:ResizeMethod.BILINEAR \n:双线性插值ResizeMethod.NEAREST_NEIGHBOR \n: 最近邻插值ResizeMethod.BICUBIC \n: 双三次插值ResizeMethod.AREA \n:面积插值读者可以分别试试,看看缩放效果。图像裁剪代码:cropped_image \n= tf.image.crop_to_bounding_box(image0, 20, 20, 256, 256)图像水平翻转代码:flipped_image \n= tf.image.flip_left_right(image0)除此之外还可以上下翻转:flipped_image \n= tf.image.flip_up_down(image0)图像旋转代码:rotated_image \n= tf.image.rot90(image0, k=1)其中 \nk 值表示旋转 90 度的次数,读者可以尝试对原图旋转 180 度、270 度。图像灰度变换代码:grayed_image \n= tf.image.rgb_to_grayscale(image0)从上面看到,用 \nTensorFlow 实现上述图像预处理是非常简单的。TensorFlow 也提供了针对目标检测中用到的 bounding box 处理的 \napi,有兴趣的读者可以翻阅 api \n文档()学习。为了方便查看图像预处理的效果,可以利用 \nTensorFlow 提供的 tensorboard 工具进行可视化。使用方法也比较简单,直接用 tf.summary.image \n将图像写入 summary,对应代码如下:img_resize_summary \n= tf.summary.image('image resized', tf.expand_dims(resized_image, 0))cropped_image_summary \n= tf.summary.image('image cropped', tf.expand_dims(cropped_image, 0))flipped_image_summary \n= tf.summary.image('image flipped', tf.expand_dims(flipped_image, 0))rotated_image_summary \n= tf.summary.image('image rotated', tf.expand_dims(rotated_image, 0))grayed_image_summary \n= tf.summary.image('image grayed', tf.expand_dims(grayed_image, 0))merged \n= tf.summary.merge_all()with \ntf.Session() as sess:
\nsummary_writer = tf.summary.FileWriter('/tmp/tensorboard', \nsess.graph)
\nsummary_all = sess.run(merged)
\nsummary_writer.add_summary(summary_all, 0)
\nsummary_writer.close()运行该程序,会在 \n/tmp/tensorboard 目录下生成 summary,接着在命令行启动 tensorboard 服务:打开浏览器,输入 \n127.0.0.1:6006 就可以查看 tensorboard 页面了(Ubuntu 自带的 firefox 打开 tensorboard \n时不显示图像,可以更换为 Chrome 浏览器)。TensorBoard \n图像可视化效果利用 \ntensorboard 还可以查看图像直方图为了显示直方图,需要在代码中增加一行 \nsummary :histogram_summary \n= tf.summary.histogram('image hist', image0)完整代码如下:如果您觉得本文对您有帮助,请关注微信公众号,将来会有更多更好的文章推送! (二维码自动识别)","updated":"T02:50:56.000Z","canComment":false,"commentPermission":"anyone","commentCount":1,"collapsedCount":0,"likeCount":15,"state":"published","isLiked":false,"slug":"","isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-d8d49754cfbcc8a8534290e_r.jpg","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"深度学习(Deep Learning)"}],"adminClosedComment":false,"titleImageSize":{"width":480,"height":360},"href":"/api/posts/","excerptTitle":"","column":{"slug":"c_","name":"慢慢学TensorFlow"},"tipjarState":"inactivated","annotationAction":[],"sourceUrl":"","pageCommentsCount":1,"hasPublishingDraft":false,"snapshotUrl":"","publishedTime":"T10:50:56+08:00","url":"/p/","lastestLikers":[{"bio":"明天 你好","isFollowing":false,"hash":"d7c0cab95ecb0cb42c22fdf03b0e244a","uid":24,"isOrg":false,"slug":"xiao-dan-46-55","isFollowed":false,"description":"春日的花香,夏天的风","name":"咸咸","profileUrl":"/people/xiao-dan-46-55","avatar":{"id":"v2-5b3fad669c2cac","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"dff0c20aeddeedc9b755871a","uid":870600,"isOrg":false,"slug":"long-yue-ying-5","isFollowed":false,"description":"","name":"胧月影","profileUrl":"/people/long-yue-ying-5","avatar":{"id":"aa17c1bb770a7ff7bdec7dd56b451c88","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"2fb4433f0","uid":268160,"isOrg":false,"slug":"chai-yun-44-52","isFollowed":false,"description":"SJTU CS","name":"柴云","profileUrl":"/people/chai-yun-44-52","avatar":{"id":"de53ce28f696f3a614f42f812ceb6396","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"永远在学习","isFollowing":false,"hash":"dc81c2f9ec24d0faf75f90","uid":28,"isOrg":false,"slug":"hehehehefuzaixin","isFollowed":false,"description":"永远在学习","name":"1111","profileUrl":"/people/hehehehefuzaixin","avatar":{"id":"v2-419f33bfb234d8c18e43cce12f3b9fa6","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"","isFollowing":false,"hash":"ab7fd074e7a833c0d2f99b1d","uid":995800,"isOrg":false,"slug":"-59","isFollowed":false,"description":"","name":"StudierA","profileUrl":"/people/-59","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"注:文章转自《慢慢学TensorFlow》微信公众号图像是人们喜闻乐见的一种信息形式,“百闻不如一见”,有时一张图能胜千言万语。图像处理是利用计算机将数值化的图像进行一定(线性或非线性)变换获得更好效果的方法。Photoshop,美颜相机就是利用图像处理技…","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/50/v2-22a4e2d2dd8ac3e1ec75b9cce962cc8a_xl.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"深度学习(Deep Learning)"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"qq圈人","isFollowing":false,"hash":"47ad35a6f1d01b941a1e9e344d60a194","uid":437000,"isOrg":false,"slug":"dong-xiao-man-18","isFollowed":false,"description":"","name":"绿萝123","profileUrl":"/people/dong-xiao-man-18","avatar":{"id":"v2-4de0f89feb4fb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"c_","name":"慢慢学TensorFlow"},"content":"注这里的量化不是指“量化交易(Quantitative trade)”,而是 Quantization ,即离散化,注意是否走错片场。前言开发神经网络时最大的挑战是让它真正起作用,训练时一般希望速度越快越好,准确率越高越好。使用浮点是保持结果精确最简单的方式,GPU 拥有加速浮点算法的库,所以很自然地,不需要过多关注其他数值格式。最近,有很多神经网络模型投入实际应用。训练计算需求随研究者数目线性增长,但预测所需的周期与用户数目成正比。这意味着纯预测的效率成为迫在眉睫的问题。这就是量化神经网络的用武之地。该方法包括很多不同技巧,以相对 32 位浮点更紧凑的方式对数值进行存储和计算。本文关注 8 bit 量化,后续文章还会再讲。量化神经网络的可行性训练神经网络时,对权值做很多微小的改动,这些微小增量一般需要浮点精度才能正常工作(也有一些研究工作使用量化网络进行训练)。使用预训练的模型运行预测则不同。深度网络的奇妙特性是对输入噪声容忍度很高。如果你考虑识别照片中物体,网络能忽略所有 CCD 噪声,光照变化和其他不重要的差异,而把注意力放在更重要的相似性。该功能意味着网络可以把低精度计算作为另一种噪声源,在容纳更少信息的数值格式下仍然能产生准确的预测结果。量化神经网络的必要性神经网络模型可能占据大量磁盘空间,例如原始的 AlexNet (浮点格式)需要超过 200 MB。由于一个模型中常常有数百万连接,几乎所有空间都被神经元连接的权值所占据。况且这些权值都是有些微不同的浮点数,简单的压缩格式(如 zip)不能很好地压缩。它们分布在大量层中,每层权值都趋向于某个确定区间的正态分布,例如(-3.0, 6.0)。量化网络最初的动机是减小模型文件尺寸(用 8-bit 量化可以缩小到原来 25%),在模型载入后仍然转换回浮点数,这样你已有的浮点计算代码无需改动即可正常运行。具体方法是在网络权值保存为文件时,将每层最小值、最大值存储下来,然后将每个浮点数值采用 8-bit 整数表示(在最大值、最小值范围内空间线性划分 256 段,每段用一个唯一的 8-bit 整数表示在该段内的实数值)。例如,在 (-3.0, 6.0) 区间内,字节 0 表示 -3.0, 字节 255 表示 6.0, 以此类推,字节 128 表示 1.5。另一个量化的动机是降低预测过程的计算资源需求,这时需要将完整计算都采用 8-bit 实现。该方案实施也更加困难,因为需要修改所有计算代码,同时也有更大的潜在回报。读取 8-bit 数值只需要相对浮点数值 25% 内存带宽,你可以更好利用 caches,避免访存瓶颈。你也可以使用 SIMD 指令,在一个时钟周期内实现更多计算。一些情况下你还可以用 DSP 芯片加速 8-bit 计算。将计算移植到 8-bit 可以帮助你更快地运行模型,功耗更低(在移动设备上尤其重要)。它也打开了一扇通向大量不能高效运行浮点计算代码的系统的大门,让物联网世界大量应用成为可能。为什么不直接用低精度训练?有一些实验使用低位宽进行训练,但结果显示需要使用高于 8-bit 来处理反向传播梯度值。这使得实现训练异常复杂,从纯预测开始是合理的。我们也有很多训练好的浮点模型,用得多了自然十分了解,将它们直接转换格式是非常方便的。如何量化你的模型TensorFlow 在产品级别内在支持 8-bit 计算。它也有一个将用浮点训练好的模型转换为等效的利用量化算法进行预测的图。例如,你可以将最新 GoogLeNet 模型转换为 8-bit 计算:$ curl
-o /tmp/inceptionv3.tgz$ tar xzf /tmp/inceptionv3.tgz -C /tmp/$ cd ~/tensorflow-1.0.0-rc1/$ bazel build tensorflow/tools/quantization:quantize_graph$ bazel-bin/tensorflow/tools/quantization/quantize_graph \\--input=/tmp/classify_image_graph_def.pb \\--output_node_names=\"softmax\" \\--output=/tmp/quantized_graph.pb \\--mode=eightbit运行截图见下图所示:这样将会产生一个新模型 quantized_graph.pb,与原始模型运行相同计算,但内部使用 8-bit 计算,所有权值也做 8-bit 量化。如果你注意文件尺寸,会发现它只有原先模型的 1/4 ( 23MB vs 91 MB)。你仍然可以运行这个模型使用几乎相同输入和输出,并获得等价的结果。下面是例子:$ bazel build tensorflow/examples/label_image:label_image$ bazel-bin/tensorflow/examples/label_image/label_image \\--image=&input-image& \\--graph=/tmp/quantized_graph.pb \\--labels=/tmp/imagenet_synset_to_human_label_map.txt \\--input_width=299 \\--input_height=299 \\--input_mean=128 \\--input_std=128 \\--input_layer=\"Mul:0\" \\--output_layer=\"softmax:0\"用原始模型运行结果如图所示:你会看到新量化的图,输出与原始模型非常近似的结果。量化过程是怎样的TF 已经通过编写等价的预测时常用的 8-bit 版本运算符实现了量化计算,这些运算符包括卷积、矩阵乘、激活函数、下采样和拼接。转换脚本首先替换所有已知的运算符为等价的量化运算符。小的子图在输入和输出部分有转换函数实现浮点到 8-bit 的转换。以下是一个例子,展示了它们的模样。首先是原始的 Relu 运算符,具有浮点输入和输出:接下来是等价的转换后的子图,仍然为浮点输入和输出,但内部转换为 8-bit,这样所有计算都是以 8-bit 实现:最小和最大值运算符实际上是根据输入浮点值进行计算,之后送入 Quantize 运算符将输入张量转换为 8-bit。每个独立运算符转换完毕,下一步是去除不必要的转换。如果存在一串连续的浮点运算符,它们都以浮点张量传递结果,那么会存在大量相邻的 反量化/量化运算符。在该步检测以上情形,识别出彼此可以抵消,之后便删除这些不必要的步骤,如下图所示:应用到大规模模型,所有运算符都有量化版本,可以实现一张全部张量计算都以 8-bit 实现的图,无需转换回浮点。内容译自: 部分图片来源:扫描下面二维码关注此公众号! (二维码自动识别)","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T10:48:36+08:00","url":"/p/","title":"TensorFlow 1.0.0rc1上玩量化神经网络","summary":"注 这里的量化不是指“量化交易(Quantitative trade)”,而是 Quantization ,即离散化,注意是否走错片场。前言开发神经网络时最大的挑战是让它真正起作用,训练时一般希望速度越快越好,准确率越高越好。使用浮点是保持结果精确最简单的方式,GPU …","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":1,"likesCount":4},"next":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/50/v2-30f3d96bea59f4c195a1ab35c7b530f2_xl.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"深度学习(Deep Learning)"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"qq圈人","isFollowing":false,"hash":"47ad35a6f1d01b941a1e9e344d60a194","uid":437000,"isOrg":false,"slug":"dong-xiao-man-18","isFollowed":false,"description":"","name":"绿萝123","profileUrl":"/people/dong-xiao-man-18","avatar":{"id":"v2-4de0f89feb4fb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"c_","name":"慢慢学TensorFlow"},"content":"OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程;即,针对印刷体字符,采用光学的方式将纸质文档中的文字转换成为黑白点阵的图像文件,并通过识别软件将图像中的文字转换成文本格式,供文字处理软件进一步编辑加工的技术。如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题。近年来,随着深度学习技术的进步,对 OCR 正确率的提升起到积极促进的作用。一些成熟的产品级别 OCR 系统能同时识别汉字、字母、数字、特殊字符并进行版面恢复,可以应用于身份证实名认证中的人证识别、名片识别、印刷文本识别等具体场景。下面我们看如何利用 TensorFlow 实现英文字符识别,读者需要在机器上安装 TensorFlow 和 Keras,具体安装步骤可以参考上一篇文章《》。OCR 例程位于 keras/examples/image_ocr.py。为了运行该例程,需要安装以下两个包:# pip install cairocffi# pip install editdistance根据运行时报错情况,可能还需要安装以下包:# pip install matplotlib# pip install scipy# pip install numpy# pip install h5py这个例子使用卷积网络 + 递归网络 + CTC 对数损失函数来实现生成文本图像上的 OCR 功能。目前未验证是否真正学到了文本的通用形状,还是只能识别训练集里面的字体。起初,先识别 4 字母的单词。前 12 个 epoch,难度递增。使用 TextImageGenerator 类作为训练数据、测试数据生成器。该类也是 Keras 回调类。经过 20 个 epoch,将更长的序列作为输入,重新构建能处理宽图像的模型,重建单词列表,包括两个由空格分离的单词。1. 准备数据:原来的代码中数据下载部分有 bug,需要做如下修改。找到这两行:
fdir = os.path.dirname(get_file('wordlists.tgz',
origin='', untar=True))删掉,改为:
fdir = '/tmp/'从网盘(关注公众号,后台回复“”获得下载链接)下载 wordlists.tgz,解压到 /tmp/,包括这两个文件:wordlist_bi_clean.txt
wordlist_mono_clean.txt2. 运行训练:# python image_ocr.py训练过程如下:中间结果输出目录位于 examples/image_ocr/epoch 0:epoch 10:epoch 20:epoch 24:如果你觉得本文对你有帮助,请关注公众号,将来会有更多更好的文章推送! (二维码自动识别)","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T09:22:38+08:00","url":"/p/","title":"如何用 TensorFlow 实现 OCR","summary":"OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程;即,针对印刷体字符,采用光学的方式将纸质文档中的文字…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":1,"likesCount":5}},"annotationDetail":null,"commentsCount":1,"likesCount":15,"FULLINFO":true}},"User":{"dong-xiao-man-18":{"isFollowed":false,"name":"绿萝123","headline":"","avatarUrl":"/v2-4de0f89feb4fb_s.jpg","isFollowing":false,"type":"people","slug":"dong-xiao-man-18","bio":"qq圈人","hash":"47ad35a6f1d01b941a1e9e344d60a194","uid":437000,"isOrg":false,"description":"","profileUrl":"/people/dong-xiao-man-18","avatar":{"id":"v2-4de0f89feb4fb","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{},"columns":{"next":{},"c_":{"following":false,"canManage":false,"href":"/api/columns/c_","name":"慢慢学TensorFlow","creator":{"slug":"dong-xiao-man-18"},"url":"/c_","slug":"c_","avatar":{"id":"v2-d8a0e1fc7acee4e5c3b7c2d6","template":"/{id}_{size}.jpg"}}},"columnPosts":{},"columnSettings":{"colomnAuthor":[],"uploadAvatarDetails":"","contributeRequests":[],"contributeRequestsTotalCount":0,"inviteAuthor":""},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"drafts":{"draftsList":[],"next":{}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{}}3.1问题分析
为了评估N个鸡蛋中是否有圈养鸡蛋,我们利用卷积神经网络(CNN)让计算机学习圈养鸡蛋和土鸡蛋图片的特征,然后根据鸡蛋的图片将其分类。通过对图片的预处理,将其转化为32*32相同大小的图片。在神经网络加载数据之后,会将其转化为32*32*3的数组。然后通过卷积和池化等一系列操作提取出图片的特征。以达到对鸡蛋进行分类的目的。我们主要用Python语言在TensorFlow中构建卷积神经网络(CNN),让CNN学习圈养鸡蛋和土鸡蛋的特征。然后对比其多次测试分类的情况。综合评估N个鸡蛋是否有圈养鸡蛋。
3.2前期数据处理
3.2.1数据描述
因为神经网络需要固定输入的图片大小,所以,我们将所有图片调整为相同的大小。但是由于图片具有不同的长宽比,并且我们收集的图片数据中鸡蛋的占比率比较小,噪点较多,图片特征不明显。我们采用裁剪方式,将其背景去掉,使鸡蛋面积占图片面积超过50%。提高土鸡蛋和圈养鸡蛋的图片特征。优化数据集,让机器更好的学习两种鸡蛋的特征。最终,我们用程序将图片批量处理为32 * 32像素的尺寸,这在肉眼下较容易识别图片。如下图:
数据目录结构:
datasets目录有两个子文件夹Training和Testing用于存放训练和测试图片,训练过程模型保存在egg_model1目录下.。模型代码在egg根目录。整个egg文件夹已放在附件。
3.2.2加载数据方式
因为数据集比较小,因此可以直接将数据加载到RAM里面。加载完数据之后,并且通过Numpy将其转化成数组(矩阵)格式。下图是我们通过代码访问并显示数据集况:
说明:0表示圈养鸡蛋,1表示土鸡蛋
3.3模型建立
3.3.1模型描述
模型是基于TensorFlow建立的,因此我们先了解TensorFlow中的神经网络。
TensorFlow的执行图中封装了神经网络的架构。构建的图包含了操作(简称为Ops),比如 Add,Multiply,Reshape,..... 等等。这些操作在张量(多维数组)中对数据执行操作。
模型训练需要提取出图片的特征,即计算出图片数组的特征值。模型的输入层是一个一维向量。该向量由一个32*32*3的三维数组压平转化而得。神经层通过构建一个全连接池,该连接池有N个神经元,让每个神经元都连接到输入层,因此每个神经元接受32 * 32 * 3 = 3072个输入。并使用ReLU函数作为激活函数。下图较清晰地描述了模型思路:
ReLU激活函数:f(x) = max(0, x),如下:
y = xW + b
使用ReLU函数作为激活函数的优点是它可以模拟出了脑神经元接受信号更精确的激活模型,更快的进行特征学习,学习周期大大缩短。综合速率和效率更高。
3.3.2建立模型
1.设置占位符(Placeholder)用来放置图片和标签。
参数images_ph的维度是[None, 32, 32, 3],四个参数分别表示[批量大小,高度,宽度,通道]。批处理大小用None表示向模型中导入任意批量大小的数据。
images_ph=tf.placeholder(tf.float32, [None,32,32,3])
labels_ph = tf.placeholder(tf.int32, [None])
2.定义一个全连接层
logits=tf.contrib.layers.fully_connected(images_flat, 32, tf.nn.relu)
模型的输入是一个一维向量(images_flat)。全连接层的输出是一个长度是32的对数矢量,如:[0.3, 0, 0, 1.2, 2.1, 0.01, 0.4, ... ..., 0, 0]。矢量值越高,表示图片为该标签的可能性越高。
3.将连接层结果的最大值为预测值
predicted_labels = tf.argmax(logits, 1)
argmax函数使输出结果(logits)将是一个整数,范围是0和1。0表示圈养鸡蛋,1表示土鸡蛋。预测标签保存在predicted_labels列表中。
4.定义交叉熵损失函数
loss=tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits,labels_ph))
因为我们用Relu函数作为神经元的激活函数时,因此使用交叉熵代价函数来替代方差代价函数,以避免训练过程太慢。交叉熵代价函数是一个在分类任务中最常见的函数。它是两个概率向量之间的差的度量。TensorFlow中交叉熵函数表示为:sparse_softmax_cross_entropy_with_logits,利用交叉熵函数将标签和神经网络的输出转换成概率向量。然后通过reduce_mean函数来获得一个值,表示最终的损失值。
5.使用梯度下降训练
train=tf.train.AdamOptimizer(0.001).minimize(loss)
使用ADAM优化算法,它对每个权值都计算自适应的学习速率,收敛速度比一般的梯度下降法更快。
6.初始化所有的操作,将所有变量的值设置为零(或随机值)
init = tf.initialize_all_variables()
3.3.3开始训练模型
1.创建一个会话(Session)对象。
会话(Session)保存所有变量的值。模型中图(Gragh)保存的是方程y = xW + b,那么会话保存的是这些变量的实际值。
session = tf.Session()
2.初始化操作
session.run(init)
3.开始循环训练模型
for i in range(200):
_, loss_value = session.run([train, loss],
feed_dict={images_ph: images_a, labels_ph:
labels_a})
if i % 10 == 0:
print("Loss: ", loss_value)
在训练过程中,我们记录并且打印出损失函数的值,帮助我们监控训练的进度。将循环次数设置成了200,并且当循环次数满足10的倍数时,打印出损失值。最终的输出结果看起来像这样:
Loss: 164.604
Loss: 12.3638
Loss: 7.03638
Loss: 1.22729
Loss: 1.00379
3.4模型测试(检验)
1.随机取了10个图片进行分类,并且同时打印了标签结果和预测结果。
sample_indexes=random.sample(range(len(images32)), 10)
sample_images = [images32[i] for i in sample_indexes]
sample_labels = [labels[i] for i in sample_indexes]
# Run the "predicted_labels" op.
predicted = session.run(predicted_labels,
{images_ph: sample_images})print(sample_labels)print(predicted)
[0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1]
[0 1 1 0 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1]
2.结果可视化,编写一个可视化函数用来展示对比结果,展示效果如下:
从图中我们可以发现,我们的模型是可以正确运行的,但是从图中不能量化它的准确性。因为训练数据量比较小,我们测试分类的还是训练的图片。因此模型在未知数据集上面的效果如何,我们在测试集上面进行更好地评测。
3.5模型评估(优缺点和优化)
1.模型优点:
1.读取方式简单,直接读取数据图片所在目录文件夹。
2.通过将图片改成32*32像素相同大小,可以快速高效地提取出图片的特征,提高模型的学习效率和准确值。
3.利用一个全连接池的32神经元,多个特征提取,最后通过迭代训练找出特征最明显的情况确认可能性最高分类结果。
4.训练速度快,计算量较小。可以快速高效地训练并得到分类结果、
2.模型缺点:
1.当loss处于局部收敛时,会出现分类情况为全是圈养鸡蛋,分类无效。
2.训练过程中变量不能保存,每次测试过程中都需要训练,这使得模型应用性较差。因此我们需要在此基础上进行优化,使其保存在训练过程中的所有变量值,测试的时候直接读取训练的变量值,提高测试效率。
3.模型优化:
由于需要将变量保存起来,我们给模型增加两个卷积层构成卷积神经网络(CNN),我们在输入层和全连接层之间加入两次卷积和池化。模型结构如下图:
模型优化部分如下:
1.定义变量和卷积池化函数
#定义权值变量函数
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
#定义偏差变量 函数
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
2.第一个卷积层
W_conv1 = weight_variable([5, 5, 3, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(images_ph, W_conv1) + b_conv1)
参数为卷积核为5*5,图片RGB通道为3,输出为32
3.第一个池化层
h_pool1 = max_pool(h_conv1)
将卷积每一个通道的32个输出通过2*2池化得到32个16*16图片
4.第二个卷积层
W_conv2 = weight_variable([3, 3, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
参数为卷积核为3*3,图片RGB通道为3,输出为64
5.第二个池化层
h_pool2 = max_pool(h_conv2)
将卷积每一个通道的32个输出通过2*2池化得到64个8*8图片
6.第一个全连接池
W = weight_variable([8*8*64,16])
b = bias_variable([16])
h_pool2_flat = tf.reshape(h_pool2, [-1, 8*8*64])
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat, W) + b)
参数8*8*64为第二池化层输出的图片大小8*8以及数量64
7.第二个全连接池
logits = tf.contrib.layers.fully_connected(h_fc1,8, tf.nn.relu)
8.防止过拟合(dropout)
#用dropout防止logits过拟合
keep_prob = tf.placeholder("float")
logits1 = tf.nn.dropout(logits, keep_prob)
9.保存(Saver)和读取(Restore)
saver = tf.train.Saver()
#判断模型保存路径是否存在,不存在就创建
if not os.path.exists('egg_model/'):
os.mkdir('egg_model/')
session = tf.Session()
if os.path.exists('egg_model/checkpoint'): #判断模型是否存在
saver.restore(session, 'egg_model/model1.ckpt') #存在就从模型中恢复变量
init = tf.global_variables_initializer() #不存在就初始化变量
session.run(init)
for i in range(10):
train_value, loss_value = session.run([train, loss],
feed_dict={images_ph: images_a, labels_ph: labels_a,keep_prob:0.8})
if(i%2==0):
save_path = saver.save(session, 'egg_model/model1.ckpt') print("模型保存:%s 当前训练损失:%s"%(save_path, loss_value))
10.训练过程
下图是训练50次后随机抽取10张的预测结果:
可视化如图:
11.测试过程:
我们分为两个数据集合,一个用于训练,另一个用于测试。两个数据有所区别。用于测试图片数据鸡蛋面积的占图片面积百分比多样化,图片处理比训练数据更加随机化。所以,我们可以很容易的使用测试集来评估我们的训练模型。再让其训练1000次之后,让其分类测试数据集,先在测试集中随机抽二十张,分类效果如下:
测试全部图片:
为了确认当前训练情况是否有效。我们用一个评估部分的相关代码,加载测试集,然后计算预测正确性。代码如下:
# 测试全部图片.
predicted = session.run(predicted_labels,
feed_dict={images_ph: sample_images,keep_prob:0.8})
match_count = sum([int(y == y_)
for y, y_ in zip(sample_labels, predicted)])
accuracy = match_count / len(sample_labels)
print("正确数量:",match_count)
print("测试图片总数量:",len(sample_labels))
print("Accuracy: {:.3f}".format(accuracy))
结果如下所示:
在每次的运行中,模型在训练次数较小的情况下(1000次),准确性在0.50~0.70之间:
造成这个原因是模型是否落在局部最小值还是全局最小值。这也是简单的CNN模型无法避免的问题。那么当我们增加模型训练次数,扩大数据集更大时,模型训练的正确率是否将更高,又能达到多少呢。。如何提高结果的一致性?这个还需要增加收集数据量和训练时间,由于数据和时间有限,我们将下一次专题讨论。
写在最后:FOR Freedom 看看外边的世界,以及IT这一行,少不了去Google查资料,最后,安利一些速器代理。
加速器推荐
一枝红杏加速器
免费方案暂无,稳定高速
输入8折优惠码wh80,年付只需80元/年
心易加速器
最好用的外贸加速器
最低¥30/月
LoCo加速器
每天免费2小时
最低¥15/月
本文标签:
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关阅读:《》
相关BLOG:
原文地址:
网站的维护离不开大家的支持鼓励,捐赠让我更有动力走的更远:
本博客所有文章如无特别注明均为原创。作者: ,复制或转载请以超链接形式注明转自
。原文地址《》
邮箱(必填)
网址(选填)}

我要回帖

更多关于 emgucv图像处理函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信