提到机器学习, 深度学习这些, 大家都会立马想起 Python 但 R 的实力也不容小觑今天就用 R 来演示一个基于 TensorFlow 的图像识别的例子如果你想运行这些代码, 就必须先安装配置好 TensorFlow, 我是在 Linux 系统上面运行的如何配置 TensorFlow 尽量看看官方文档, 虽然是英文的, 但是最新的, 也是最准确的
废话不说, 直接来看代码, 在代码中我也做了详细的注释, 看起来应该不是很困难
- library(tensorflow) #加载 TensorFlow 包
- library(magrittr) #数据处理包, 可以使用管道函数
- slim= tf$contrib$slim #slim 是一个使构建, 训练, 评估神经网络变得简单的库
- # slim 提供了很多计算机视觉方面的著名模型(VGG, AlexNet 等), 我们不仅可以直接使用, 甚至能以各种方式进行扩展
- tf$reset_default_graph() #在每次运行中清除当前图形, 以避免变量重复 #Session 会话 张量的具体值和操作, 会话关闭时, 张量的任何具体值都会丢失
- images = tf$placeholder(tf$float32, shape(NULL, NULL, NULL, 3))# 创建占位符
- imgs_scaled = tf$image$resize_images(images, shape(224,224)) #设置图片大小# slim$conv2d 自带卷积功能 + 激励函数
- fc8 = slim$conv2d(imgs_scaled, 64, shape(3,3), scope='vgg_16/conv1/conv1_1') %>%
- slim$conv2d(64, shape(3,3), scope='vgg_16/conv1/conv1_2') %>%
- slim$max_pool2d( shape(2, 2), scope='vgg_16/pool1') %>% #池化操作
- slim$conv2d(128, shape(3,3), scope='vgg_16/conv2/conv2_1') %>%
- slim$conv2d(128, shape(3,3), scope='vgg_16/conv2/conv2_2') %>%
- slim$max_pool2d( shape(2, 2), scope='vgg_16/pool2') %>%
- slim$conv2d(256, shape(3,3), scope='vgg_16/conv3/conv3_1') %>%
- slim$conv2d(256, shape(3,3), scope='vgg_16/conv3/conv3_2') %>%
- slim$conv2d(256, shape(3,3), scope='vgg_16/conv3/conv3_3') %>%
- slim$max_pool2d(shape(2, 2), scope='vgg_16/pool3') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv4/conv4_1') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv4/conv4_2') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv4/conv4_3') %>%
- slim$max_pool2d(shape(2, 2), scope='vgg_16/pool4') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv5/conv5_1') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv5/conv5_2') %>%
- slim$conv2d(512, shape(3,3), scope='vgg_16/conv5/conv5_3') %>%
- slim$max_pool2d(shape(2, 2), scope='vgg_16/pool5') %>%
- slim$conv2d(4096, shape(7, 7), padding='VALID', scope='vgg_16/fc6') %>%
- slim$conv2d(4096, shape(1, 1), scope='vgg_16/fc7') %>%
- # Setting the activation_fn=NULL does not work, so we get a ReLU
- slim$conv2d(1000, shape(1, 1), scope='vgg_16/fc8') %>%
- tf$squeeze(shape(1, 2), name='vgg_16/fc8/squeezed')
- tf$summary$FileWriter('/tmp/dumm/vgg16', tf$get_default_graph())$close() #保存在 / tmp/dumm/vgg16 目录下
- restorer = tf$train$Saver() #创建一个 Saver 来管理模型中的所有变量
- sess = tf$Session()
- restorer$restore(sess, 'vgg_16.ckpt') #复原模型
- library(jpeg)
- img1<-readJPEG('caomei.jpg') #img1 的值在 0-1 之间
- d=dim(img1) #获取 img1 的维度
- imgs =array(255*img1,dim = c(1,d[1],d[2],d[3]))
- # 因为数值需要在 0 到 225 之间, 所以需要乘 225. 形成一个四维数组 #我们可以通过与存储在数组 imgs 中的图像的张量来对图像做预测
- fc8_vals=sess$run(fc8,dict(images=imgs))# 将 fc8 的张量存储在 fc8_vals 中
- fc8_vals[1:5]
- probs=exp(fc8_vals)/sum(exp(fc8_vals))
- # 按概率从高排序, 并取前五个
- idx=sort.int(fc8_vals,index.return = TRUE,decreasing = TRUE)$ix[1:5]
- # 读取图像分类文件
- library(readr)
- names = read_delim("imagenet_classes.txt", "\t", escape_double = FALSE, trim_ws = TRUE,col_names = FALSE)
- library(grid) #图片处理的一个包, 主要控制输出图形的大的外观和一些细节东西的排列
- g = rasterGrob(img1, interpolate=TRUE) #图形进行栅格化
- text = ""for (id in idx) {
- text = paste0(text, names[id,][[1]], "", round(probs[id],5),"\n")
- }
- #annotate 添加文本注释
- #annotation_custom 可以添加各种图形元素到 ggplot 图中
- library(ggplot2)
- ggplot(data.frame(d=1:3)) + annotation_custom(g) +
- annotate('text',x=0.05,y=0.05,label=text, size=7, hjust = 0, vjust=0, color='blue') + xlim(0,1) + ylim(0,1)
主要代码转自:
https://randomthoughtsonr.blogspot.com/2016/11/image-classification-in-r-using-trained.html
我在网上找的了一张草莓的图片, 使用该模型进行识别
识别结果如下图, 不过结果还挺准的是草莓的概率是 0.99999 不过有的情况下识别结果还是不太准的, 毕竟这个模型也是有限的
再来一张二哈 (英文名: Siberian husky, 取自百度百科) 的照片, 我专门在百度百科上面找了一张二哈比较霸气的照片在百度百科上面找的主要原因就是保证这张照片就是二哈
图片来自百度百科 词条西伯利亚雪橇犬
分析结果表明是二哈的可能性是 0.592. 基本上还是挺准的
也许就有人说 Siberian husky 和 husky, 有什么区别, 百度百科上面他们好像就是一个在维基百科查阅发现, Siberian husky 是 husky 的一个品种, husky 还包括了其他品种比如拉布拉多犬哈士奇, 我相信一些爱狗人士可能会董于是我在维基百科上面的 husky 词条找到了下面这张照片
图片来源 维基百科 词条 Husky
结果显示是 husky 的概率是 0.46234. 还是挺准的, 毕竟这只是一张侧脸照把这两张照片放在一块, 我觉得一般人都分不清楚
补充:
由于 TensorFlow 发展比较快, 如果看一些比较旧的资料, 比如两年前的资料, 在用最新的 TensorFlow 时, 输入有的 API 就会报错, 我在这跟大家分享几个 API 更新后的名字, 希望在用的时候能帮到大家
旧版本 | 新版本 |
---|---|
tf.mul | tf.multiply |
tf.sub | tf.subtract |
tf.neg | tf.negative |
tf.train.SummaryWriter | tf.summary.FileWriter |
程序中用到的 vgg16 模型以及 imagenet_classes.txt 我已经通过百度网盘分享给大家了, 在我的公众号跟着菜鸟一起学 R 语言后台回复 vgg16 即可获取下载链接
注:
作者: 王亨
公众号: 跟着菜鸟一起学 R 语言
来源: http://blog.csdn.net/wzgl__wh/article/details/79312839