用Keras+TensorFlow,实现ImageNet数据集日常对象的识别

本文来自AI新媒体量子位(QbitAI)

在计算机视觉领域里,有3个最受欢迎且影响非常大的学术竞赛:ImageNet ILSVRC(大规模视觉识别挑战赛),PASCAL VOC(关于模式分析,统计建模和计算学习的研究)和微软COCO图像识别大赛。这些比赛大大地推动了在计算机视觉研究中的多项发明和创新,其中很多都是免费开源的。

博客Deep Learning Sandbox作者Greg Chu打算通过一篇文章,教你用Keras和TensorFlow,实现对ImageNet数据集中日常物体的识别。

量子位翻译了这篇文章:

你想识别什么?

看看ILSVRC竞赛中包含的物体对象。如果你要研究的物体对象是该列表1001个对象中的一个,运气真好,可以获得大量该类别图像数据!以下是这个数据集包含的部分类别:

椅子
汽车键盘箱子
婴儿床旗杆iPod播放器
轮船面包车项链
降落伞枕头桌子
钱包球拍步枪
校车萨克斯管足球
袜子舞台火炉
火把吸尘器自动售货机
眼镜红绿灯菜肴
盘子西兰花红酒
 表1 ImageNet ILSVRC的类别摘录

完整类别列表见:https://gist.github.com/gregchu/134677e041cd78639fea84e3e619415b

如果你研究的物体对象不在该列表中,或者像医学图像分析中具有多种差异较大的背景,遇到这些情况该怎么办?可以借助迁移学习(transfer learning)和微调(fine-tuning),我们以后再另外写文章讲。

图像识别

图像识别,或者说物体识别是什么?它回答了一个问题:“这张图像中描绘了哪几个物体对象?”如果你研究的是基于图像内容进行标记,确定盘子上的食物类型,对癌症患者或非癌症患者的医学图像进行分类,以及更多的实际应用,那么就能用到图像识别。

Keras和TensorFlow

Keras是一个高级神经网络库,能够作为一种简单好用的抽象层,接入到数值计算库TensorFlow中。另外,它可以通过其keras.applications模块获取在ILSVRC竞赛中获胜的多个卷积网络模型,如由Microsoft Research开发的ResNet50网络和由Google Research开发的InceptionV3网络,这一切都是免费和开源的。具体安装参照以下说明进行操作:

Keras安装:https://keras.io/#installation

TensorFlow安装:https://www.tensorflow.org/install/

实现过程

我们的最终目标是编写一个简单的python程序,只需要输入本地图像文件的路径或是图像的URL链接就能实现物体识别。

以下是输入非洲大象照片的示例:

1. python classify.py --image African_Bush_Elephant.jpg
2. python classify.py --image_url http://i.imgur.com/wpxMwsR.jpg

输入:

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

输出将如下所示:

640?wx_fmt=png&wxfrom=5&wx_lazy=1

 该图像最可能的前3种预测类别及其相应概率

预测功能

我们接下来要载入ResNet50网络模型。首先,要加载keras.preprocessingkeras.applications.resnet50模块,并使用在ImageNet ILSVRC比赛中已经训练好的权重。

想了解ResNet50的原理,可以阅读论文《基于深度残差网络的图像识别》。地址:https://arxiv.org/pdf/1512.03385.pdf

import numpy as np
from keras.preprocessing import image
from keras.applications.resnet50
import ResNet50, preprocess_input, decode_predictions model = ResNet50(weights='imagenet')

接下来定义一个预测函数:

def predict(model, img, target_size, top_n=3):
  """Run model prediction on image
  Args:
    model: keras model
    img: PIL format image
    target_size: (width, height) tuple
    top_n: # of top predictions to return
  Returns:
    list of predicted labels and their probabilities
  """
  if img.size != target_size:
    img = img.resize(target_size)
  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  x = preprocess_input(x)
  preds = model.predict(x)  
return decode_predictions(preds, top=top_n)[0]

在使用ResNet50网络结构时需要注意,输入大小target_size必须等于(224,224)。许多CNN网络结构具有固定的输入大小,ResNet50正是其中之一,作者将输入大小定为(224,224)

image.img_to_array:将PIL格式的图像转换为numpy数组。

np.expand_dims:将我们的(3,224,224)大小的图像转换为(1,3,224,224)。因为model.predict函数需要4维数组作为输入,其中第4维为每批预测图像的数量。这也就是说,我们可以一次性分类多个图像。

preprocess_input:使用训练数据集中的平均通道值对图像数据进行零值处理,即使得图像所有点的和为0。这是非常重要的步骤,如果跳过,将大大影响实际预测效果。这个步骤称为数据归一化。

model.predict:对我们的数据分批处理并返回预测值。

decode_predictions:采用与model.predict函数相同的编码标签,并从ImageNet ILSVRC集返回可读的标签。

keras.applications模块还提供4种结构:ResNet50、InceptionV3、VGG16、VGG19和XCeption,你可以用其中任何一种替换ResNet50。更多信息可以参考https://keras.io/applications/。

绘图

我们可以使用matplotlib函数库将预测结果做成柱状图,如下所示:

def plot_preds(image, preds):  
  """Displays image and the top-n predicted probabilities 
     in a bar graph  
  Args:    
    image: PIL image
    preds: list of predicted labels and their probabilities  
  """  
  #image
  plt.imshow(image)
  plt.axis('off')  #bar graph
  plt.figure()  
  order = list(reversed(range(len(preds))))  
  bar_preds = [pr[2] for pr in preds]
  labels = (pr[1] for pr in preds)
  plt.barh(order, bar_preds, alpha=0.5)
  plt.yticks(order, labels)
  plt.xlabel('Probability')
  plt.xlim(0, 1.01)
  plt.tight_layout()
  plt.show()

主体部分

为了实现以下从网络中加载图片的功能:

1. python classify.py --image African_Bush_Elephant.jpg
2. python classify.py --image_url http://i.imgur.com/wpxMwsR.jpg

我们将定义主函数如下:

if __name__=="__main__":
  a = argparse.ArgumentParser()
  a.add_argument("--image", 
help="path to image")  a.add_argument("--image_url",
help="url to image")  args = a.parse_args()
if args.image is None and args.image_url is None:    a.print_help()    sys.exit(1)
if args.image is not None:    img = Image.open(args.image)    print_preds(predict(model, img, target_size))
if args.image_url is not None:    response = requests.get(args.image_url)    img = Image.open(BytesIO(response.content))    print_preds(predict(model, img, target_size))

其中在写入image_url功能后,用python中的Requests库就能很容易地从URL链接中下载图像。

完工

将上述代码组合起来,你就创建了一个图像识别系统。项目的完整程序和示例图像请查看GitHub链接:

https://github.com/DeepLearningSandbox/DeepLearningSandbox/tree/master/image_recognition

本文作者:王新民
原文发布时间:2017-04-23 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TensorFlow 是 Google 开发的一个开源机器学习框架,特别适合深度学习任务,包括图像识别。WOC(Weakly Supervised Object Localization)数据集通常指的是弱监督对象定位的数据集,这意味着在标注数据中,每个图像可能只有类别标签而没有精确的边界框信息。这与完全监督的数据集(如 ImageNet)相比,训练起来更具挑战性,因为模型需要从有限的上下文线索中学习识别物体。 如果你想要使用 TensorFlow 对 WOC 数据集进行图像识别训练,首先你需要完成以下步骤: 1. **数据预处理**:下载并加载 WOC 数据集,可能需要对图像进行缩放、归一化等操作。你可以使用 `tensorflow_datasets` 库来简化这个过程。 ```python import tensorflow as tf import tensorflow_datasets as tfds # 加载数据集 dataset, info = tfds.load('woc', with_info=True) train_dataset, test_dataset = dataset['train'], dataset['test'] ``` 2. **数据增强**:为了提高模型的泛化能力,可以应用数据增强技术,如随机旋转、裁剪或翻转图像。 ```python data_augmentation = tf.keras.Sequential([ tf.keras.layers.RandomRotation(0.1), tf.keras.layers.RandomHorizontalFlip(), tf.keras.layers.RandomCrop((img_height, img_width), padding=8) ]) ``` 3. **构建模型**:通常选择预训练的卷积神经网络(如 VGG16、ResNet 或 EfficientNet)作为基础模型,然后在其上添加自定义分类层。 ```python base_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_height, img_width, 3)) x = base_model.output x = tf.keras.layers.GlobalAveragePooling2D()(x) output = tf.keras.layers.Dense(num_classes, activation='softmax')(x) model = tf.keras.Model(inputs=base_model.input, outputs=output) ``` 4. **迁移学习**:由于 WOC 是弱监督,可能不需要从头训练整个网络,而是进行微调(fine-tuning)。这通常涉及冻结基础层,只训练顶部的分类层。 ```python # 冻结基础模型 for layer in base_model.layers: layer.trainable = False # 编译模型 model.compile(optimizer=tf.keras.optimizers.Adam(), loss='sparse_categorical_crossentropy', metrics=['accuracy']) ``` 5. **训练和评估**:用数据集训练模型,并在测试集上评估性能。 ```python history = model.fit(train_dataset, epochs=num_epochs, validation_data=test_dataset) ``` 6. **结果分析**:查看训练历史 `history.history`,检查准确率和损失的变化,以及模型在验证集上的性能。 关于 WOC 的具体使用,可能会有额外的细节取决于该数据集的具体格式和要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值