原文:Image Classification in 5 Methods
作者:Shiyu Mou
翻译:何冰心
图像分类,顾名思义,是一个输入图像,输出对该图像内容分类的描述的问题。它是计算机视觉的核心,实际应用广泛。
图像分类的传统方法是特征描述及检测,这类传统方法可能对于一些简单的图像分类是有效的,但由于实际情况非常复杂,传统的分类方法不堪重负。现在,我们不再试图用代码来描述每一个图像类别,决定转而使用机器学习的方法处理图像分类问题。
目前,许多研究者使用CNN等深度学习模型进行图像分类;另外,经典的KNN和SVM算法也取得不错的结果。然而,我们似乎无法断言,哪种方法对于图像分来问题效果最佳。
本项目中,我们做了一些有意思的事情:
下面是具体实施细节。
在本项目中,用于实验的5种算法为KNN、SVM、BP神经网络、CNN以及迁移学习。我们采用如下三种方式进行实验
第一种方法:使用sklearn预处理数据以及实现KNN,SVM和BP神经网络。
第二种方法:基于TensorFlow构建CNN。使用TensorFlow得到计算图并在C++中实现,比Python更高效。
TensorFlow中使用到的的几个概念:占位符,变量,数学公式,成本计量,最优方法,CNN体系结构。
第三种方法:Retrain Inception V3。使用Retrain Inception V3 ,并利用迁移学习减少工作量。
我们得到pre-trained模型,移除原有顶层,训练新模型。然后分析在磁盘上的所有图像并计算它们的bottleneck值。脚本会运行4000次。每次运行都会从训练集中随机选取10个图像,找到它们的bottleneck值并注入最后一层得到预测结果。然后在反向传播过程中,根据预测结果和实际标签的比较结果去更新每层的权重。
实验中使用到的数据集是Oxford-IIIT Pet 数据集。其中有犬类25类,猫类12类。每类有200个图像。我们使用到该数据集中的10个类别的猫的数据,分别是[‘Sphynx’,’Siamese’,’Ragdoll’,’Persian’,’Maine-Coon’,’British-shorthair’,’Bombay’,’Birman’,’Bengal’,’Abyssinian’]。即,共有2000个图像,由于图像大小不一,我们调整大小统一为固定尺寸64X64或128X128。
本项目中,我们主要使用OpenCV预处理图像。一般通过变形、剪裁或亮化随机处理训练集。github
第一种方法:KNN,SVM,和BP神经网络
第一部分:使用sklearn预处理数据以及实现KNN,SVM和BP神经网络。在image_to_feature_vector函数中,我们设定尺寸128X128。经试验表明,图像尺寸越大,结果越精确,运行负担越大。最终我们决定使用128X128的尺寸。在extract_color_histogram函数中,设定每个通道的容器数量为32,32,32。对于数据集,使用3种数据集。第一个是具有400个图像,2个标签的子数据集。第二个是具有1000个图像,5个标签的子数据集。第三个是整个数据集,1997个图像,10个标签。
依据数据集,2个标签到10个标签不同,运行时间大约为3到5分钟不等。
第二种方法:基于TensorFlow构建CNN
由于在整个数据集中运行时间过长,我们在每个迭代中分批次处理。每批次一般有32个或64个图像。数据集分为1600个图像的训练集,400个图像的验证集,300个图像的测试集。
本方法中有大量的参数可调整。学习速率设定为1x10^-4;图像大小设定为64x64和128x128;然后是层和形状,然而有太多的参数可调整,我们依据经验并进行实验去得到最佳结果。
为了得到最佳的layers,我们进行实验。首先,参数如下:
# Convolutional Layer 1. filter_size1 = 5 num_filters1 = 64
# Convolutional Layer 2. filter_size2 = 5 num_filters2 = 64
# Convolutional Layer 3. filter_size3 = 5 num_filters3 = 128
# Fully-connected layer 1. fc1_size = 256
# Fully-connected layer 2. fc1_size = 256
我们使用了3个卷积层和2个全连接层,然而悲剧的是过度拟合。经过研究发现,对于该构造,我们的数据集过小,网络过于复杂。
最终,我们使用如下参数:
# Convolutional Layer 1. filter_size1 = 5 num_filters1 = 64
# Convolutional Layer 2. filter_size2 = 3 num_filters2 = 64
# Fully-connected layer 1. fc1_size = 128
# Number of neurons in fully-connected layer.
# Fully-connected layer 2. fc2_size = 128
# Number of neurons in fully-connected layer.
# Number of color channels for the images: 1 channel for gray-scale. num_channels = 3
我们只使用了2个卷积层和2个全连接层。依然不尽人意,经过4000次迭代,结果仍旧过拟合,不过好在测试结果10%优于前者。最终,经过5000次迭代,我们得到43%的精确度,运行时间是半小时以上。
PS:我们使用另一个数据集CIFAR-10进行了实验。
该数据集包含60000个32x32的彩色图像,分为10个类别,每个类别6000个图像。训练集50000个图像,测试集10000个图像。使用同样的网络结构,经过10个小时的训练,最终得到78%的精确度。
第三种方法:Retrain Inception V3
与以上方法相似,训练次数为4000,依据结果进行调整。学习速率依据每批次的图像数量进行调整。80%的数据用来训练,10%用来验证,10%用来测试。
第一种方法:KNN,SVM,和BP神经网络
在KNN中,Knn_raw_pixel和Knn_histo的精确度的值比较接近。在5类标签情况下,前者比后者要低,整体来说,原始像素表现更好。
在MLP分类器中,原始像素精确地要低于柱状图精确度。对于整个数据集(10个标签)来讲,原始像素精确度竟然低于随机猜想的精确度。
上面两种sklearn方法都没有得到非常好的性能。对于整个数据集,只有24%的精确度。实验结果证明,sklearn方法不能够有效进行图像分类。为了有效进行图像分类并且提高精确度,有必要使用深度学习的方法。
第二种方法:基于TensorFlow构建CNN
由于过拟合,我们无法得到好的实验结果。运行时间一般为半个小时,由于过拟合,我们认为,运行时间无法预估。通过与方法1比较,可以得出:即使CNN过拟合训练集,实验结果依旧优于方法1。
第三种方法:Retrain Inception V3
整个训练过程不超过10分钟,且我们得到了非常好的结果。事实证明,深度学习和迁移学习十分强大。
Demo:
基于以上实验比较,我们得出:
通过本次项目,我们得到了许多宝贵的经验,如下所示:
参考文献
1. CS231n Convolutional Neural Networks for Visual Recognition
2. TensorFlow Convolutional Neural Networks
3. How to Retrain Inception’s Final Layer for New Categories
4. k-NN classifier for image classification
5. Image Augmentation for Deep Learning With Keras
6. Convolutional Neural Network TensorFlow TutorialNote: The first method is performed by Ji Tong
https://github.com/JI-tong
Originally published at gist.github.com.