一、实验要求
1.使用卷积神经网络实现图片分类,数据集为OxFlowers17;
二、实验环境
Anaconda2-4.3.1(Python2.7),tensorflow-cpu。
三、实验原理
3.1 数据读取
已知数据集是连续80个样本为一个分类,有17个类别,所以一共只有1360个样本,所以首先用一个函数把每一类的样本分到一个文件夹,文件夹的名字从0开始命名,接着进行数据的读取,由于本次实验使用的数据集比较小,因而没有划分出验证集,根据官网给出的划分数据集的方法,把验证集也划分给训练集,以丰富训练集,最后得到1020个训练样本和340个测试样本。
对应代码:loadData.py
# -*- coding: UTF-8 -*-
import os
import numpy as np
import scipy.io as sio
from PIL import Image
dir='../oxflower17/jpg/'
def to_categorical(y, nb_classes):
y = np.asarray(y, dtype='int32')
if not nb_classes:
nb_classes = np.max(y)+1
Y = np.zeros((1, nb_classes))
Y[0,y] = 1.
return Y
def build_class_directories(dir):
dir_id = 0
class_dir = os.path.join(dir, str(dir_id))
if not os.path.exists(class_dir):
os.mkdir(class_dir)
for i in range(1, 1361):
fname = "image_" + ("%.4i" % i) + ".jpg"
os.rename(os.path.join(dir, fname), os.path.join(class_dir, fname))
if i % 80 == 0 and dir_id < 16:
dir_id += 1
class_dir = os.path.join(dir, str(dir_id))
os.mkdir(class_dir)
def get_input(resize=[224,224]):
print 'Load data...'
getJPG = lambda filePath: np.array(Image.open(filePath).resize(resize))
dataSet=[];labels=[];choose=1
classes = os.listdir(dir)
for index, name in enumerate(classes):
class_path = dir+ name + "/"
if os.path.isdir(class_path):
for img_name in os.listdir(class_path):
img_path = class_path + img_name
img_raw = getJPG(img_path)
dataSet.append(img_raw)
y=to_categorical(int(name),17)
labels.append(y)
datasplits = sio.loadmat('../oxflower17/datasplits.mat')
keys = [x + str(choose) for x in ['val', 'trn', 'tst']]
train_set, vall_set, test_set = [set(list(datasplits[name][0])) for name in keys]
train_data, train_label,test_data ,test_label= [],[],[],[]
for i in range(len(labels)):
num = i + 1
if num in test_set:
test_data.append(dataSet[i])
test_label.extend(labels[i])
else:
train_data.append(dataSet[i])
train_label.extend(labels[i])
train_data = np.array(train_data, dtype='float32')
train_label = np.array(train_label, dtype='float32')
test_data = np.array(test_data, dtype='float32')
test_label = np.array(test_label, dtype='float32')
return train_data, train_label,test_data ,test_label
def batch_iter(data, batch_size, num_epochs, shuffle=True):
data = np.array(data)
data_size = len(data)
num_batches_per_epoch = int((len(data)-1)/batch_size) + 1
for epoch in range(num_epochs):
# Shuffle the data at each epoch
if shuffle:
shuffle_indices = np.random.permutation(np.arange(data_size))
shuffled_data = data[shuffle_indices]
else:
shuffled_data = data
for batch_num in range(num_batches_per_epoch):
start_index = batch_num * batch_size
end_index = min((batch_num + 1) * batch_size, data_size)
yield shuffled_data[start_index:end_index]
if __name__=='__main__':
#build_class_directories(os.path.join(dir))
train_data, train_label,test_data, test_label=get_input()
print len(train_data),len(test_data)
3.2 模型介绍
本次实验使用的是AlexNet模型,AlexNet共有八层,其前五层是卷积层,后三层是全连接层。最后一个全连接层的输出具有17个输出单元。
其中第一个卷积层