- keras是基于tensorflow的一个库,我们装好了tensorflow之后只需要
sudo pip install keras
即可完成keras的安装
- 我们使用的是一个图片训练集合,包含24种类型,对集合进行预处理:
import os
from PIL import Image
import numpy as np
def load_data():
data = np.empty((1028,200,200,3),dtype="float32")
#我们输入的训练数据是1028个200×200×3的图片
label = np.empty((1028),dtype="uint8")
#1028维的标签,对应一个0~23的整数
imgs = os.listdir("./bmp")
#os.listdir()可以读取当前文件夹目录下所有文件的名字,放到一个list中
del imgs[0]
#注意,在mac下读取时第一个文件名是'.DS_Store',将其删除
num = len(imgs)
for i in range(num): #一共1028张图,注意range函数从0开始
img = Image.open("./bmp/"+imgs[i]) #Image.open()读取图片,使用PIL下的Image
arr = np.asarray(img,dtype="float32") #将图片转化为一个200×200×3的张量
data[i,:,:,:] = arr #张量赋值给data[i]
label[i] = int((imgs[i].split('.')[0]).split('_')[1])
#"11027_07.wav.bmp"这是图片名称的格式,从中读取标签07
#将名称用‘.’分割成一个list,取第一个,然后再用‘_’分割取第二个,转化为整数作为标签
return data,label
- 加载数据
data, label = load_data() #当别的模型需要使用load_data()函数时,直接import的就行
label = np_utils.to_categorical(label, 24)
#label为0~23共24个类别,keras要求格式为binary class matrices,转化一下,直接调用keras提供的这个函数
#此时的label是1028×24维的,数字22对应[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]
- 分离训练集和数据集
from sklearn.cross_validation import train_test_split
#用到sklearn里面的一个库
x_train,x_test,y_train,y_test=train_test_split(data,label,random_state=33,test_size=0.1)
#x对应图片矩阵,y对应label,test集合占10%
- 建立CNN模型
model = Sequential()#生成一个model,后面的操作都是在此model的基础上
model.add(Convolution2D(4 ,5, 5, border_mode='valid' ,input_shape=(200,200,3)))
#4个卷积核,每个卷积核大小5*5。得到196×196。valid表示只卷积矩阵内部,图像会缩小
#与tensorflow不同的是,我们不需要显式的表示输入的通道数
model.add(Activation('tanh')) #激活函数
model.add(MaxPooling2D(pool_size=(2, 2)))#池化操作,得到98×98
model.add(Convolution2D(8, 5, 5, border_mode='valid'))
#8个卷积核,每个卷积核大小5*5。得到94×94
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))#池化操作,得到47×47
model.add(Convolution2D(16, 4, 4, border_mode='valid'))
#16个卷积核,每个卷积核大小3*3。得到44×44
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))#池化操作,得到22×22
model.add(Convolution2D(16, 3, 3, border_mode='valid'))
#16个卷积核,每个卷积核大小3*3。得到20×20
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))#池化操作,得到10×10
model.add(Convolution2D(32, 3, 3, border_mode='valid'))
#16个卷积核,每个卷积核大小3*3。得到8×8
model.add(Activation('tanh'))
model.add(MaxPooling2D(pool_size=(2, 2)))#池化操作,得到4×4
model.add(Flatten()) #压扁平准备全连接
model.add(Dense(512)) #标准一维全连接层。
model.add(Activation('tanh'))
#你还可以在model.add(Activation('tanh'))后加上dropout的技巧: model.add(Dropout(0.5))
model.add(Dense(24, init='normal')) #最后全连接到24个节点上
model.add(Activation('softmax')) #Softmax分类,输出是24类别
- 开始训练模型
sgd = SGD(lr=0.05, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
#交叉熵作为损失函数,SGD作为优化器,计算准确度
- 调用fit方法,就是一个训练过程
model.fit(x_train, y_train , batch_size=50 ,nb_epoch=10 , shuffle=True, verbose=1,validation_data=(x_test, y_test))
#训练的epoch数设为10,即训练10轮,batch_size为50每轮中每次训练用50个数据
#数据经过随机打乱shuffle=True。verbose=1,训练过程中输出的信息,0、1、2三种方式都可以,无关紧要。训练时每一个epoch都输出accuracy。
- 测试另外的数据
model.evaluate(x_test, y_test)#对另外的测试数据进行测试,输出loss和accuracy