import os
import numpy as np
from keras.models import Sequential, Model
from keras import layers
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.applications.vgg16 import VGG16
from keras.utils.np_utils import to_categorical
from scipy.misc import imread, imresize
import matplotlib.pyplot as plt
imgs = []
labels = []
img_shape =(150,150)
# image generator
files = os.listdir('data/test')
# read 1000 files for the generator
for img_file in files[:1000]:
img = imread('data/test/' + img_file).astype('float32')
img = imresize(img, img_shape)
imgs.append(img)
imgs = np.array(imgs)
train_gen = ImageDataGenerator(
# rescale = 1./255,
featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=True)
val_gen = ImageDataGenerator(
# rescale = 1./255,
featurewise_center=True,
featurewise_std_normalization=True)
train_gen.fit(imgs)
val_gen.fit(imgs)
# 4500 training images
train_iter = train_gen.flow_from_directory('data/train',class_mode='binary',
target_size=img_shape, batch_size=16)
# 501 validation images
val_iter = val_gen.flow_from_directory('data/val', class_mode='binary',
target_size=img_shape, batch_size=16)
'''
# image generator debug
for x_batch, y_batch in img_iter:
print(x_batch.shape)
print(y_batch.shape)
plt.imshow(x_batch[0])
plt.show()
'''
# finetune from the base model VGG16
base_model = VGG16(include_top=False, weights='imagenet', input_shape=(150, 150, 3))
base_model.summary()
out = base_model.layers[-1].output
out = layers.Flatten()(out)
out = layers.Dense(1024, activation='relu')(out)
# 因为前面输出的dense feature太多了,我们这里加入dropout layer来防止过拟合
out = layers.Dropout(0.5)(out)
out = layers.Dense(512, activation='relu')(out)
out = layers.Dropout(0.3)(out)
out = layers.Dense(1, activation='sigmoid')(out)
tuneModel = Model(inputs=base_model.input, outputs = out)
for layer in tuneModel.layers[:19]: # freeze the base model only use it as feature extractors
layer.trainable = False
tuneModel.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
history = tuneModel.fit_generator(
generator=train_iter,
steps_per_epoch=100,
epochs=100,
validation_data=val_iter,
validation_steps=32
)
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1,101)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'r', label='Validation acc')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.legend()
plt.show()
案例1
import time
from keras.applications.imagenet_utils import preprocess_input, decode_predictions
from keras.layers import Dropout, Flatten, Dense
from keras.layers.convolutional import Convolution2D,MaxPooling2D
from keras.models import Sequential
from keras.preprocessing import image
from keras import backend as K
K.set_image_data_format('channels_first')
import numpy as np
t0 = time.time()
height, width = 224, 224
img_path = 'cat.jpg'
img = image.load_img(img_path, target_size=(224, 224)) # 224×224
x = image.img_to_array(img) # 三维(3, 224,224)
x = np.expand_dims(x, axis=0) # 四维(1, 3,224, 224)
x = preprocess_input(x) # 预处理
print("训练样例:", x.shape)
print("取数据耗时: %.2f seconds ..." % (time.time() -t0))
print("开始建模CNN ...")
model = Sequential()
# Block 1, 2层
model.add(Convolution2D(64, 3, 3, activation='relu',
border_mode='same', input_shape=(3,height, width)))
model.add(Convolution2D(64, 3, 3, activation='relu',border_mode='same'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
# Block 2, 2层
model.add(Convolution2D(128, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(128, 3, 3, activation='relu',border_mode='same'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
# Block 3, 3层
model.add(Convolution2D(256, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(256, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(256, 3, 3, activation='relu',border_mode='same'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
# Block 4, 3层
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
# Block 5, 3层
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(Convolution2D(512, 3, 3, activation='relu',border_mode='same'))
model.add(MaxPooling2D((2, 2), strides=(2, 2)))
# Classification block, 全连接3层
model.add(Flatten())
model.add(Dense(2000, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2000, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1000, activation='softmax'))
model.load_weights('vgg16_weights_th_dim_ordering_th_kernels.h5')
print("建模CNN完成 ...")
y_pred = model.predict(x)
print('预测%s (类名, 语义概念, 预测概率) = %s' % (img_path,decode_predictions(y_pred))) #前五个
print('类预测:', decode_predictions(y_pred)[0][0][1])#概率最大类
print("耗时: %.2f seconds【徐海蛟博士】 ..." % (time.time() -t0))