python版本3.6.12
数据集目录
安装依赖
pip3 install tensorflow==2.4.1 -i https://pypi.tuna.tsinghua.edu.cn/simple --default-timeout=10000
pip3 install numpy==1.19.4 -i https://pypi.tuna.tsinghua.edu.cn/simple --default-timeout=10000
pip3 install SciPy -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install keras -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
根据训练集训练模型代码
import os
from keras import models
from keras import layers
from keras.models import load_model
from keras.preprocessing.image import ImageDataGenerator
# 注意安装SciPy pip3 install SciPy -i https://pypi.tuna.tsinghua.edu.cn/simple
# 转化图片
def format_pacture(file_dir):
datagen = ImageDataGenerator(rescale=1. / 255) # 图像的三维张量转为[0,1]之间
generator = datagen.flow_from_directory(
file_dir,
target_size=(150, 150), # 转化图像大小为150*150
batch_size=50, # 迭代图片一批有5张
class_mode='binary' # 训练时使用了binary_crossentropy,所以这里使用2进制标签
)
return generator
# 转化图片
def rotate(file_dir):
datagen = ImageDataGenerator(
rescale=1. / 255, # 图像的三维张量转为[0,1]之间
rotation_range=40, # 图像的旋转范围为[0,40]度
width_shift_range=0.2, # 图像左右平移比例,最大为1
height_shift_range=0.2, # 图像上下平移比例,最大为1
shear_range=0.2, # 随机错切变换角度
zoom_range=0.2, # 图像随机缩放范围
horizontal_flip=True # 是否随机将一半图像水平翻转
)
generator = datagen.flow_from_directory(
file_dir,
target_size=(150, 150), # 转化图像大小为150*150
batch_size=120, # 迭代图片一批有120张
class_mode='binary' # 训练时使用了binary_crossentropy,所以这里使用2进制标签
)
return generator
# 识别测试的时候先修改图像尺寸,并将图片设置为[0,1]之间的数值,神经网络善于处理这样的数据,训练的时候也是用的这个范围
def format_pucture(file_path, shape):
from keras.preprocessing import image
img = image.load_img(file_path, target_size=shape)
array = image.img_to_array(img)
array = array.reshape((1,) + shape) / 255
return array
# 数据根目录
home = "C:/Users/Administrator/Desktop/data/keras"
# 猫狗的训练图像
home_train = home + "/train/"
train_cats_dir = os.path.join(home_train, "cat")
train_dogs_dir = os.path.join(home_train, "dog")
# 猫狗的校验图像
home_val = home + "/test/"
val_cats_dir = os.path.join(home_val, "cat")
val_dogs_dir = os.path.join(home_val, "dog")
# model = load_model("./model/identification") # 读取之前保存的模型,迁移训练不用设置网路结构
model = models.Sequential()
model.add(layers.Conv2D(256, (3, 3), activation='relu', input_shape=(150, 150, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(256)) # 设置有256个节点的网络层
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.2)) # 丢弃0.2的数据
model.add(layers.Dense(128)) # 设置有128个节点的网络层
model.add(layers.BatchNormalization())
model.add(layers.Activation('relu'))
model.add(layers.Dropout(0.2)) # 丢弃0.2的数据
model.add(layers.Dense(1, activation='sigmoid')) # 设置一个节点的网络层使用sigmoid二分类
# optimizer优化器选择 adam/rmsprop 损失函数选择 binary_crossentropy 二进制交叉熵用于二分类问题中,categorical_crossentropy分类交叉熵适用于多分类问题中
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc']) # 定义损失函数
# 创建迭代器
train_generator = rotate(home_train) # 训练集迭代器,下面有猫和狗的子目录,每一个目录都是一个标签
val_generator = format_pacture(home_val) # 验证集迭代器,不需要设置旋转所以不用调用rotate
early_stop = EarlyStopping(monitor='val_loss', patience=13)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', patience=7, mode='auto', factor=0.2)
callbacks = [early_stop, reduce_lr]
# 训练并返回迭代次数的损失与精度集合,validation_steps * 验证集迭代器一批数据 = 验证集总数据;steps_per_epoch * 训练集迭代器有一批数据 = 训练集总数
history = model.fit( # 编译模型
x=train_generator, # 训练集迭代器
steps_per_epoch=220, # 设置一次迭代分成多少批次
epochs=100, # 设置迭代次数
validation_data=val_generator, # 验证集迭代器
validation_steps=30, # 验证一批数据量
callbacks=callbacks
)
# 输出损失与精度,找到最佳迭代次数,用于重新训练,并防止过拟合
print("训练历史信息\n", history.history)
# 保存训练好的模型model
model.save("./model/identification") # 保存目录
# 读取之前保存的模型
model = load_model("./model/identification")
picture = format_pucture("C:/Users/Administrator/Desktop/data/keras/test/dog/1.jpg", (150, 150, 3))
predict = model.predict(picture)
print("识别的结果为:", predict) # 猫和狗被识别为[0,1]之间的数据,越靠近边缘,分类越精确
训练完成支持检查训练情况
import matplotlib.pyplot as plt
# web 展示
def show(history_dict):
loss = history_dict["loss"]
accuracy = history_dict["acc"]
# 验证曲线众坐标
val_loss = history_dict["val_loss"]
val_accuracy = history_dict["val_acc"]
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
# 两条曲线的横坐标
plt.plot(range(0, len(history_dict["val_loss"])), loss, color='blue', ls="--", label="训练损失") # 点
plt.plot(range(0, len(history_dict["acc"])), accuracy, color='blue', ls="-", label="训练精度") # 点
plt.plot(range(0, len(history_dict["loss"])), val_loss, color='red', ls="--", label="校验损失") # 实线
plt.plot(range(0, len(history_dict["val_acc"])), val_accuracy, color='red', ls="-", label="校验精度") # 实线
plt.xlabel("epochs")
plt.legend()
plt.show()
# 将训练输出的结果写入data
data = {'loss': [0.6951414942741394, 0.6912084221839905, 0.6917884349822998],
'acc': [0.5249999761581421, 0.5416666865348816, 0.5166666507720947],
'val_loss': [0.7002933025360107, 0.6949335932731628, 0.6938526630401611],
'val_acc': [0.5027999877929688, 0.4991999864578247, 0.49639999866485596]}
show(data)
深度训练web可视化
代码中嵌入callbacks回调值,用于保存训练日志
log = r"C:\log_dir"
import keras
callbacks = [
keras.callbacks.TensorBoard(
log_dir=log,
histogram_freq=1,
embeddings_freq=1
)
]
# 训练并返回迭代次数的损失与精度集合
history = model.fit_generator( # 编译模型
train_generator, # 训练集迭代器
steps_per_epoch=500, # 设置一次迭代分成多少批次
epochs=100, # 设置迭代次数
validation_data=val_generator, # 验证集迭代器
validation_steps=500, # 验证一批数据量
callbacks=callbacks
)
1.创建日志目录log 启动python训练程序
2.启动tensorboard,并指定日志目录位置
tensorboard --logdir=C:\log_dir
3.访问localhost:6006查询训练过程