平平无奇CNN:使用CNN进行图像分类(对比机器学习(SIFT+Bag of Words模型+SVM多分类器)分类结果)
初始入门
首先我们使用官方的数据集CIFAR-10进行图像分类,关于CIFAR-10的具体介绍见CIFAR-10/CIFAR-100数据集解析
具体代码
直接可以运行
import keras
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
#10类的分类问题
num_classes = 10
model_name = 'cifar10.h5'
#加载训练集和测试集
# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
#归一化
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
#搭建网络
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.summary()
# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.001, decay=1e-6)
# train the model using RMSprop
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
hist = model.fit(x_train, y_train, epochs=10, shuffle=True)
model.save(model_name)
# 计算结果
loss, accuracy = model.evaluate(x_test, y_test)
print(loss, accuracy)
使用我们自己的数据集
可以看到上面例子中CIFAR-10替我们处理好了数据集,所以使用自己数据集时我们需要一个对于数据集处理的步骤
数据集简介
我们的数据集是一个15类,每类一百多张的灰度图像,分辨率为300x220左右
其中训练数据共2236张,测试数据共2196张
对数据集进行处理
在CIFAR-10中有一条操作
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
其中x_train的shape为(50000, 32, 32, 3),y_train的shape为(50000, 1)
x_test的shape为(10000, 32, 32, 3),y_test的shape为(10000, 1)。
x_train的意思是:其中有50000张图片 ,每张图片的分辨率为32x32,由于图片为彩色图像所以有RGB三通道。
y_train的意思是:有50000张图片,每张图片都标了从0~9的数,代表它们属于10类中的哪一类。
对于我们的数据要达到的是:
数据 | 格式 |
---|---|
x_train | (2236, 300, 220, 1) |
y_train | (2236,1) |
x_test | (2196, 300, 220, 1) |
y_test | (2196, 1) |
对数据集进行处理
import numpy as np
import os
import cv2 as cv
rootpath = './training/'
list = os.listdir(rootpath) #列出文件夹下所有的目录与文件
#设定图像宽高
imgwidth = 300
imgheight = 220
imgdata = []
imgtag = []
for i in range(len(list)):
#对于子目录进行处理
print(i)
currentpath = rootpath+list[i]
currentlist = os.listdir(currentpath)
for j in range(len(currentlist)):
#图像位置
imgpath = currentpath + "/" + currentlist[j]
#有后缀为db的文件
if currentlist[j][-3:] == "jpg":
#i为类目
imgtag.append(i)
#加载图像
img = cv.imread(imgpath,0)
img = cv.resize(img,(imgheight,imgwidth))
imgdata.append(img)
imgtag = np.array(imgtag)
imgdata = np.array(imgdata)
imgtag = imgtag.reshape(imgtag.shape[0],1)
#增加一维灰度维
imgdata = imgdata.reshape(imgdata.shape[0],imgdata.shape[1],imgdata.shape[2],1)
print(imgdata.shape,imgtag.shape)
#存储
np.save("./x_train.npy",imgdata)
np.save("./y_train.npy",imgtag)
更改rootpath为./testing/ 再跑一遍即可得到我们的数据集。
进行CNN训练
我们已经创建好了自己的数据集,在代码中load即可使用
import keras
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
import numpy as np
#15类分类
num_classes = 15
nppath = "./DataSet/"
#加载数据
x_train = np.load(nppath + "x_train.npy")
x_test = np.load(nppath + "x_test.npy")
y_train = np.load(nppath + "y_train.npy")
y_test = np.load(nppath + "y_test.npy")
x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.summary()
# 此优化器对本实验不适用
#opt = keras.optimizers.rmsprop(lr=0.001, decay=1e-6)
# train the model using RMSprop
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
hist = model.fit(x_train, y_train, epochs=100, shuffle=True)
model.save("./cnnmodel.h5")
# evaluate
loss, accuracy = model.evaluate(x_test, y_test)
print(loss, accuracy)
这样即可完成
迭代1000次之后,准确率为
对比笔者使用matlab编写的SIFT+BOG+SVM多分类器模型的准确率,最高可以达到81%
注:数据集和代码已经上传到我的github
参考:
用CNN实现cifar10图像分类模型
CIFAR-10/CIFAR-100数据集解析
使用Keras进行图像分类