import os
import pickle
import numpy as np
from keras import models
from keras import layers
from keras import optimizers
import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
# 将模型写入到文件
def writer_file(file, model):
f = open(file, "wb")
byte = pickle.dumps(model)
f.write(byte)
f.close()
# 读取模型文件
def read_file(file):
f = open(file, "rb")
my_byte = f.read()
f.close()
return pickle.loads(my_byte)
# 转化图片
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=120, # 迭代图片一批有120张
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=200, # 迭代图片一批有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
# 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.plot(range(1, len(history_dict["loss"])), val_loss, color='blue', ls="--", label="val_loss") # 实线
plt.plot(range(1, len(history_dict["val_loss"])), loss, color='blue', ls="-", label="loss") # 点
plt.plot(range(1, len(history_dict["accuracy"])), accuracy, color='red', ls="-", label="accuracy") # 点
plt.plot(range(1, len(history_dict["val_accuracy"])), val_accuracy, color='red', ls="--",
label="val_accuracy") # 实线
plt.xlabel("epochs")
plt.legend()
plt.show()
#
home = r"D:/data/train"
# 猫狗的训练图像
home_train = home + "/train/"
train_cats_dir = os.path.join(home_train, "cats")
train_dogs_dir = os.path.join(home_train, "dogs")
# 猫狗的校验图像
home_val = home + "/val/"
val_cats_dir = os.path.join(home_val, "cats")
val_dogs_dir = os.path.join(home_val, "dogs")
model = models.Sequential() # 创建神经网络
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) # 设置输入层为(150,150,3)的彩色图片,有64个网络节点
model.add(layers.MaxPool2D(2, 2)) # 将网络的输出内容聚合为之前的1/2
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Flatten()) # 铺平
model.add(layers.Dropout(0.1)) # 删除部分数据,防止过拟合
model.add(layers.Dense(512, activation='relu')) # 设置有512个节点的网络层
model.add(layers.Dense(1, activation='sigmoid')) # 设置一个节点的网络层使用sigmoid二分类
model.compile(optimizer=optimizers.RMSprop(lr=1e-4), loss='binary_crossentropy', metrics=['acc']) # 定义损失函数
# 创建迭代器
train_generator = rotate(home_train) # 训练集迭代器,下面有猫和狗的子目录,每一个目录都是一个标签
val_generator = format_pacture(home_val) # 验证集迭代器,不需要设置旋转所以不用调用rotate
# 训练并返回迭代次数的损失与精度集合
history = model.fit_generator( # 编译模型
train_generator, # 训练集迭代器
steps_per_epoch=100, # 设置一次迭代分成多少批次
epochs=2, # 设置迭代次数
validation_data=val_generator, # 验证集迭代器
validation_steps=50 # 验证一批数据量
)
# 输出损失与精度,找到最佳迭代次数,用于重新训练,并防止过拟合
print(history)
# 保存训练好的模型model
writer_file(r"D:\PyProjects\MyTest\卷积神经网络猫狗识别\model1", model) # 保存目录
# 读取之前保存的模型
model = read_file(r"D:\PyProjects\MyTest\卷积神经网络猫狗识别\identification")
pucture = format_pucture(r"C:\Users\admin\Desktop\pu\1.jpg", (150, 150, 3))
predict = model.predict(pucture)
print("识别的结果为:", predict) # 猫和狗被识别为[0,1]之间的数据,越靠近边缘,分类越精确
深度训练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查询训练过程