图片分类常见处理流程
-
样本来源
- 竞赛官方提供
- 爬虫(selenium+urllib2+可以搜图的网站)
- 初始化webdrive,设置代理
- 初始urllib2 设置代理
- driver =webdrive.FireFox()
- 找到翻页按钮属性,模拟点击翻页
- 解析页面提取图片链接元素,保存图片
-
样本处理 归一化
-
模型建立
conv2->MaxPool->Conv2->Maxpool->Conv2->MaxPool->Flatten->Dense
随着卷积层叠加网络大小减小所以需要增加通道数
-
优化
- 样本太少,使用图片增强
- keras 自带翻转、斜切、缩放等功能
- 针对自己的样本可以自定义方法 例如opencv直方图均衡 图片去噪等
- 预训练模型
- 例如使用VGG模型,冻结网络参数层,在密集连接分类器前一层增加自定义层进行训练
- 同时可以冻结VGG模型部分层,解冻靠低端的层一起训练,模型微调
- 使用可分离的卷积层 参数更少且训练更快
- 样本太少,使用图片增强
from keras.applications import VGG16
path = '/mnt/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
conv_base = VGG16(weights=path,
include_top = False,
input_shape=(150, 150, 3))
model = Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(4, activation='softmax'))
#冻结层权重
conv_base.trainable = False
#图片增强
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size=(150, 150),
batch_size=10,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(validation_dir,
target_size=(150, 150),
batch_size=5,
class_mode='categorical')
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(lr=1e-4),
metrics=['acc'])
history1 = model.fit_generator(train_generator,
steps_per_epoch=13,
epochs=50,
validation_data=validation_generator,
validation_steps=4)
#使用可分离
model = Sequential()
model.add(layers.SeparableConv2D(32, (3,3), activation='relu', input_shape=(150, 150, 3)))
model.add(layers.SeparableConv2D(64, (3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.SeparableConv2D(64, (3,3), activation='relu'))
model.add(layers.SeparableConv2D(128, (3,3), activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.SeparableConv2D(64, (3,3), activation='relu'))
model.add(layers.SeparableConv2D(128, (3,3), activation='relu'))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(4,activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(lr=1e-4),
metrics=['acc'])
history2 = model.fit_generator(train_generator,
steps_per_epoch=13,
epochs=50,
validation_data=validation_generator,
validation_steps=4)