如果有朋友是第一次搭建模型,强烈建议看下我之前MNIST数据集的帖子!第一次搭建模型也尽量别选cifar-10!细节部分都在那篇中,本篇很多重复的细节部分不会再次强调!
MNIST数据集示例传送门:https://blog.csdn.net/q1163717378/article/details/103158410
cifar-10数据集下载:
https://pan.baidu.com/s/1aIL7PZ0lMmCrIueZ7YoA2g
提取码:wdp0
下载完后直接丢到.keras/datasets/中即可(一个文件夹,一个压缩文件)
需要导入的包:
import keras.utils as np_utils
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Conv2D, Activation, MaxPooling2D, Dropout, Flatten, Dense
# 这个包是关键!
from keras.preprocessing.image import ImageDataGenerator
定义超参数:
# 训练批次
batch_size = 32
# 总共有多少个类别
num_classes = 10
# 这里的迭代次数区别于MNIST数据集
epochs = 50
读取数据:
# 读取cifar-10数据集,第一次读取需要下载
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
数据预处理:
这里区别于MNIST数据集,因为cifar-10数据集中的每张图片大小为32x32,并且是彩图,所以通道数为3
x_train = x_train.reshape(-1, 32, 32, 3) / 255.
x_test = x_test.reshape(-1, 32, 32, 3) / 255.
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)
定义模型:
这里的模型与之前MNIST数据集的搭配方式略微不同
采用(2层卷积+1层池化)x2的搭配
还有一种搭配是(2层卷积+1层池化)x3,卷积核数量是32,64,256(和本篇的搭配很像,只不过多了一个大层而已)
这两种搭配方式适用于图像识别中的二分类或10分类,可以反复套用
另外,感觉这种卷积核跳跃式增长的模型还挺好用的,比如当前cifar-10,卷积核从32个一下子跳到了256,中间省略了64,128
model = Sequential()
model.add(Conv2D(32, 3, padding='same', batch_input_shape=(None, 32, 32, 3)))
model.add(Activation('relu'))
model.add(Conv2D(32, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(2))
model.add(Dropout(0.25))
model.add(Conv2D(128, 3, padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(128, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(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.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
图像数据增强:
图像增强基本适用于所有图像分类
# 定义一个ImageDataGenerator对象
datagen = ImageDataGenerator(
# 图片随机水平偏移幅度
width_shift_range=0.2,
# 图片随机垂直偏移幅度
height_shift_range=0.2,
# 图片随机垂直翻转
horizontal_flip=True
)
# 这一步可以理解为,获取x_train中的信息,也就是获取图片的信息
# 因为有些参数的设置可能会需要用到图片的信息。
# 我曾经尝试过去掉,然而对准确率的影响并不大,但以防万一,还是加上比较好
datagen.fit(x_train)
训练模型:
fit_generator():
flow():从训练集中随机抽取batch_size个数据,返回一个输出是元组的generator
model.fit_generator(generator=datagen.flow(x_train, y_train, batch_size=batch_size),
epochs=epochs,
steps_per_epoch=1024,
validation_data=(x_test, y_test),
validation_steps=10)
评估模型:
loss, accuracy = model.evaluate(x_test, y_test)
print('loss: ', loss)
print('accuracy: ', accuracy)
注:这里只迭代了50次,迭代200次的话有79%
测试集结果:
loss: 0.7385174388885498
accuracy: 0.7516000270843506
模型保存
model.save('model.h5')
完整代码:
import keras.utils as np_utils
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Conv2D, Activation, MaxPooling2D, Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator
batch_size = 32
num_classes = 10
epochs = 10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.reshape(-1, 32, 32, 3) / 255.
x_test = x_test.reshape(-1, 32, 32, 3) / 255.
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)
model = Sequential()
model.add(Conv2D(32, 3, padding='same', batch_input_shape=(None, 32, 32, 3)))
model.add(Activation('relu'))
model.add(Conv2D(32, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(2))
model.add(Dropout(0.25))
model.add(Conv2D(256, 3, padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(256, 3, padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(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.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 查看模型的网络结构,养成这个习惯会对建模理解得更深
model.summary()
datagen = ImageDataGenerator(
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True
)
datagen.fit(x_train)
model.fit_generator(generator=datagen.flow(x_train, y_train, batch_size=batch_size),
epochs=epochs,
steps_per_epoch=1024,
validation_data=(x_test, y_test),
validation_steps=10)
loss, accuracy = model.evaluate(x_test, y_test)
print('loss: ', loss)
print('accuracy: ', accuracy)
model.save('cifar10_model.h5')