Keras实现猫狗分类

使用keras实现猫狗分类

简单CNN实现分类

使用keras要将需要的层、优化器等先进行定义。就如下,需要用到卷积层、池化层、激活函数、优化器等等。

from keras.models import Sequential
from keras.layers import Conv2D,MaxPool2D,Activation,Dropout,Flatten,Dense
from keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator,img_to_array,load_img

开始定义网络模型,要先再前面加Sequential(),先进行卷积的操作,卷积需要传入的参数是(图片的长、图片的宽、图片的通道数),再设置filters滤波器的个数(32)和大小(3*3),用samepadding的方法,可以理解为输入图像和输出图像的大小都相同,再进行一次卷积,再进行一次2x2的池化操作,随后再进行卷积和池化操作,最后用到flatten,就是打平,让数据成1维的,这里要定义一个dropout为0.5,就是一半的神经元不进行工作,因为是二分类问题,最后输出是两个,激活函数用到softmax。再定义优化器,在训练过程中以accuracy为指标计算准确率。

# 定义模型
model = Sequential()
model.add(Conv2D(input_shape=(150,150,3),filters=32,kernel_size=3,padding='same',activation='relu'))
model.add(Conv2D(filters=32,kernel_size=3,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2, strides=2))

model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))
model.add(Conv2D(filters=64,kernel_size=3,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2, strides=2))

model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu'))
model.add(Conv2D(filters=128,kernel_size=3,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2, strides=2))

model.add(Flatten())
model.add(Dense(64,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2,activation='softmax'))

# 定义优化器
adam = Adam(lr=1e-4)

# 定义优化器,代价函数,训练过程中计算准确率
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])

随后再对训练数据进行一系列数据增加的操作,因为本身图片就不是很多,可以通过一些旋转、平移这样的操作使训练的数据更多一点。而测试集就用训练就只用进行归一化操作就可以了。

train_datagen = ImageDataGenerator(
    rotation_range = 40,     # 随机旋转度数
    width_shift_range = 0.2, # 随机水平平移
    height_shift_range = 0.2,# 随机竖直平移
    rescale = 1/255,         # 数据归一化
    shear_range = 20,       # 随机错切变换
    zoom_range = 0.2,        # 随机放大
    horizontal_flip = True,  # 水平翻转
    fill_mode = 'nearest',   # 填充方式
) 
test_datagen = ImageDataGenerator(
    rescale = 1/255,         # 数据归一化
) 

随后生成训练数据和测试数据,定义路径,图片大小,批次。

batch_size = 32

# 生成训练数据
train_generator = train_datagen.flow_from_directory(
    'image/train',
    target_size=(150,150),
    batch_size=batch_size,
    )

# 测试数据
test_generator = test_datagen.flow_from_directory(
    'image/test',
    target_size=(150,150),
    batch_size=batch_size,
    )
Found 400 images belonging to 2 classes.
Found 200 images belonging to 2 classes.

训练集里面有400张图片,测试机有200张图片,都是分猫狗两类。

train_generator.class_indices
{'cat': 0, 'dog': 1}

猫的标签为0,狗的为1

开始训练,数据就为刚才定义的train_generator,训练几轮就等于训练集的数量除以批次大小再向上取整,训练三十个回合。验证的同理,并将模型保存。
注意要保存模型必须要先 pip install h5py

model.fit_generator(train_generator,steps_per_epoch=len(train_generator),epochs=30,validation_data=test_generator,validation_steps=len(test_generator))
model.save('model_cnn.h5')

开始测试,将保存的模型导入,再导入图片,定义标签。

from keras.models import load_model
import numpy as np

label = np.array(['cat','dog'])
# 载入模型
model = load_model('model_cnn.h5')

# 导入图片
image = load_img('image/test/cat/cat.1002.jpg')
image

Keras实现猫狗分类_第1张图片
对图片进行重置大小、归一化、再转成np.array类型,添加一个维度,放到网络中进行预测,得到结果。

image = image.resize((150,150))
image = img_to_array(image)
image = image/255
image = np.expand_dims(image,0)
print(label[model.predict_classes(image)])
['cat']

VGG16实现猫狗分类

再使用一个VGG16完成猫狗分类,还是用到将需要的包导入。

from keras.applications.vgg16 import VGG16
from keras.models import Sequential
from keras.layers import Conv2D,MaxPool2D,Activation,Dropout,Flatten,Dense
from keras.optimizers import SGD
from keras.preprocessing.image import ImageDataGenerator,img_to_array,load_img
import numpy as np

导入VGG16的模型,只是这里include_top是false,就是不会用到全连接,而且全连接上参数很多。

vgg16_model = VGG16(weights='imagenet',include_top=False, input_shape=(150,150,3))

既然用不到vgg的全连接,就只有自己写一个全连接,全连接就是将vgg16模型最后输出的维度的最后三个,不取第一个batch拿出来,打平,加上激活函数,dropout,最后网络还是二分类,再用softmax。我们的模型是采用vgg16的前面几层,和最后几层自己定义的全连接层。

# 搭建全连接层
top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16_model.output_shape[1:]))
top_model.add(Dense(256,activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(2,activation='softmax'))

model = Sequential()
model.add(vgg16_model)
model.add(top_model)

还是想刚才定义图像增加,然后生成训练数据和测试数据。

train_datagen = ImageDataGenerator(
    rotation_range = 40,     # 随机旋转度数
    width_shift_range = 0.2, # 随机水平平移
    height_shift_range = 0.2,# 随机竖直平移
    rescale = 1/255,         # 数据归一化
    shear_range = 20,       # 随机错切变换
    zoom_range = 0.2,        # 随机放大
    horizontal_flip = True,  # 水平翻转
    fill_mode = 'nearest',   # 填充方式
) 
test_datagen = ImageDataGenerator(
    rescale = 1/255,         # 数据归一化
) 
batch_size = 32

# 生成训练数据
train_generator = train_datagen.flow_from_directory(
    'image/train',
    target_size=(150,150),
    batch_size=batch_size,
    )

# 测试数据
test_generator = test_datagen.flow_from_directory(
    'image/test',
    target_size=(150,150),
    batch_size=batch_size,
    )

定义开始训练,训练的数据、训练的批次,要训练几轮。并保存模型

# 定义优化器,代价函数,训练过程中计算准确率
model.compile(optimizer=SGD(lr=1e-4,momentum=0.9),loss='categorical_crossentropy',metrics=['accuracy'])

model.fit_generator(train_generator,steps_per_epoch=len(train_generator),epochs=20,validation_data=test_generator,validation_steps=len(test_generator))
model.save('model_vgg16.h5')

进行测试,载入模型并导入图片

from keras.models import load_model
import numpy as np

label = np.array(['cat','dog'])
# 载入模型
model = load_model('model_vgg16.h5')

# 导入图片
image = load_img('image/test/cat/cat.1003.jpg')
image

Keras实现猫狗分类_第2张图片
对图片进行处理,让它可以放到网络中进行预测。

image = image.resize((150,150))
image = img_to_array(image)
image = image/255
image = np.expand_dims(image,0)
print(label[model.predict_classes(image)])

['cat']

你可能感兴趣的:(Keras实现猫狗分类)