Environment configuration
Python 3.6
scikit-image 0.17.2
numpy 1.19.0
opencv-python 3.4.2.16
opencv-contrib-python 3.4.2.16
Program progress
Read training data
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip=True)
train_gen = train_datagen.flow_from_directory("data/train",
target_size = (240, 240),
batch_size = 8,
class_mode="categorical")
ImageDataGenerator
Data enhancement is possible;
reference link: Keras ImageDataGenerator
- rescale: normalize the value from 0 to 255 to a value between 0 and 1;
- rotation_range: Integer, the random rotation angle of the picture, the value is [0, 180], I think the default is generally counterclockwise;
- width_shift_range: floating-point number, a certain ratio, the range of random horizontal shift of the picture, the value is [0, 1];
- height_shift_range: floating-point number, a certain ratio, the amplitude of the random vertical translation of the picture, the value is [0, 1];
- shear_range: Floating point number, indicating the degree of (counterclockwise) shear transformation;
- zoom_range: floating point number, indicating the degree of random zooming, or a list of the form [lower, upper];
- horizontal_flip: Boolean value, random horizontal flip;
Automatically classify pictures according to folders:
flow_from_directory
It can be numbered according to folders and automatically classified;
view the training data in a batch, there are 8 pictures in a batch, temp[0] is the picture, temp[1] is the label; the
data range is 0 ~ 1: one-
hot encoding completed:
Load pre-trained models online
VGG = keras.applications.vgg16.VGG16(weights="imagenet", include_top=False, input_shape=[240, 240, 3])
Or load locally accessed files:
from keras.models import load_model
VGG = load_model("model/VGG_Pretrained.h5")
View model information:
Add a classifier at the end of the model
from keras.layers import Dense, Flatten
x = VGG.layers[-1].output
x = Flatten()(x)
x = Dense(64, activation="sigmoid")(x)
predictions=Dense(5, activation="softmax")(x)
model = keras.Model(inputs=VGG.inputs, outputs=predictions)
Add a classifier behind the model. Note that the number of neurons in the output layer must be the same as the label. Flatten must be added, otherwise the dense layer cannot accept matrix input; in
simple terms, two layers of neurons are added. The more troublesome is the original Connect the models;
for layer in model.layers[:-2]:
layer.trainable=False
Only train the last two layers;
Define optimizer
adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
model.compile(loss="categorical_crossentropy", optimizer=adam, metrics=["accuracy"])
Training model
model.fit_generator(train_gen, steps_per_epoch=12, epochs=10)
Save the trained model:
Load test data
import skimage.io as io
import skimage.transform as transform
img = io.imread("data/test/3.jpg")
img = img/255
img = transform.resize(img, output_shape=[240, 240])
print(img.shape)
plt.imshow(img)
start testing:
indices = {'紫葡萄': 0, '红苹果': 1, '绿葡萄': 2, '黄苹果': 3, '黄香蕉': 4}
output = model.predict(img.reshape([1, 240, 240, 3]))
print(output)
Output result
output_r has two numbers, which respectively indicate how many rows and how many columns the prediction result is:
Full source code
No redundant output information
# 完整版
import numpy as np
import keras
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.optimizers import Adam
from keras.utils.np_utils import to_categorical
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip=True)
train_gen = train_datagen.flow_from_directory("data/train",
target_size = (240, 240),
batch_size = 8,
class_mode="categorical")
# 从网上下载预先存取好的模型
VGG = keras.applications.vgg16.VGG16(weights="imagenet", include_top=False, input_shape=[240, 240, 3])
# 或者直接从本地导入
# from keras.models import load_model
# VGG = load_model("model/VGG_Pretrained.h5")
# 在原模型末尾加入分类器
from keras.layers import Dense, Flatten
x = VGG.layers[-1].output
x = Flatten()(x)
x = Dense(64, activation="sigmoid")(x)
predictions=Dense(5, activation="softmax")(x)
model = keras.Model(inputs=VGG.inputs, outputs=predictions)
# 设置为只需要训练最后新加入的两层神经元
for layer in model.layers[:-2]:
layer.trainable=False
# 定义优化器
adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
model.compile(loss="categorical_crossentropy", optimizer=adam, metrics=["accuracy"])
# 训练模型
model.fit_generator(train_gen, steps_per_epoch=12, epochs=10)
# 载入测试数据
import skimage.io as io
import skimage.transform as transform
img = io.imread("data/test/3.jpg")
img = img/255
img = transform.resize(img, output_shape=[240, 240])
# print(img.shape) # 查看图片信息
# plt.imshow(img)
# 结果展示
indices = {'紫葡萄': 0, '红苹果': 1, '绿葡萄': 2, '黄苹果': 3, '黄香蕉': 4}
output = model.predict(img.reshape([1, 240, 240, 3]))
# print(output)
# 使得结果更加清晰
output_r = np.where(output==np.max(output))
print(np.max(output_r[1])) # 表示预测结果的列编号