文章目录

  • 获取数据
  • 图片预处理
  • 构建神经网络
  • 输入神经网络
  • 模型参数的优化


该项目旨在教会机器识别马和人的图像

深度学习中train_loader需要什么头文件 train_datagen_tensorflow


获取数据

训练数据集:horse-or-human 测试数据集:validation-horse-or-human

图片预处理

当图片数据过大,且图片的尺寸不一致时,就需要对图片进行预处理操作,将其裁剪成规定大小的图片,然后再生成器中要指定每个批次中要训练的图片的数量。代码如下:

from tensorflow.keras.preprocessing.image import ImageDataGenerator

#创建两个数据生成器,指定scaling范围0-1
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)

#指定训练数据文件夹
train_generator = train_datagen.flow_from_directory(
        'F:\\ML_Data\\horse-or-human\\train', #训练数据所在文件夹
        target_size=(300,300),       #指定输出尺寸
        batch_size=32,               #单次传递给程序用以训练的参数个数
        class_mode='binary')         #指定二分类

#指定测试数据文件夹
validation_generator = validation_datagen.flow_from_directory(
        'F:\\ML_Data\\horse-or-human\\validation', #训练数据所在文件夹
        target_size=(300,300),       #指定输出尺寸
        batch_size=32,               #单次传递给程序用以训练的参数个数
        class_mode='binary')         #指定二分类

构建神经网络

import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
model = tf.keras.models.Sequential([
    #第一个卷积
    tf.keras.layers.Conv2D(16,(3,3),activation='relu',input_shape=(300,300,3)), #300x300和三字节颜色
    tf.keras.layers.MaxPooling2D(2,2),
    #第二个卷积
    tf.keras.layers.Conv2D(32,(3,3),activation='relu'), 
    tf.keras.layers.MaxPooling2D(2,2),
    #第三个卷积
    tf.keras.layers.Conv2D(64,(3,3),activation='relu'), 
    tf.keras.layers.MaxPooling2D(2,2),
    #展开输入神经网络
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512,activation='relu'), #512个神经元
    tf.keras.layers.Dense(1,activation='sigmoid') #1个神经元输出,0代表马,1代表人
])
model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])

输入神经网络

history = model.fit(
        train_generator, #输入数据
        epochs = 15,     #训练轮数
        verbose = 1,     #日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每个epoch输出一行记录
        validation_data = validation_generator, #指定的验证集
        validation_steps = 8 #表示将一个epoch的训练集数据分为多少个batch
)

运行结果:

深度学习中train_loader需要什么头文件 train_datagen_tensorflow_02

模型参数的优化

这里相信大家跟我都有一个问题,我们怎么知道设定多少个过滤器、卷积层重复循环多少遍、定义多少个神经元?如何确定这些参数才能达到最好的效果。

这里我们可以调用Hyperband库和HyperParameters库来让机器自己判断如何定义这些参数合适。其实就是在一个区间内循环跑好几遍,选结果最优的参数然后将其保存下来。

# 人马识别项目参数优化
from tensorflow.keras.preprocessing.image import ImageDataGenerator

#创建两个数据生成器,指定scaling范围0-1
train_datagen = ImageDataGenerator(rescale=1/255)
validation_datagen = ImageDataGenerator(rescale=1/255)

#指定训练数据文件夹
train_generator = train_datagen.flow_from_directory(
        'F:\\ML_Data\\horse-or-human\\train', #训练数据所在文件夹
        target_size=(150,150),       #指定输出尺寸
        batch_size=32,               #单次传递给程序用以训练的参数个数
        class_mode='binary')         #指定二分类

#指定测试数据文件夹
validation_generator = validation_datagen.flow_from_directory(
        'F:\\ML_Data\\horse-or-human\\validation', #训练数据所在文件夹
        target_size=(150,150),       #指定输出尺寸
        batch_size=32,               #单次传递给程序用以训练的参数个数
        class_mode='binary')         #指定二分类

import tensorflow as tf
from tensorflow.keras.optimizers import RMSprop
#调用调参库
from kerastuner.tuners import Hyperband 
from kerastuner.engine.hyperparameters import HyperParameters

hp = HyperParameters()
def build_model(hp):
    model = tf.keras.models.Sequential()
    # 寻找最优过滤器个数
    model.add(tf.keras.layers.Conv2D(hp.Choice('num_filters_layer0',values=[16,64],default=16),(3,3),activation='relu',input_shape=(150,150,3)))
    model.add(tf.keras.layers.MaxPooling2D(2,2))
    # 寻找最优卷积层处理遍数
    for i in range (hp.Int("num_conv_layers",1,3)):
        # 寻找每一层最优过滤器个数
        model.add(tf.keras.layers.Conv2D(hp.Choice(f'num_filters_layer{i+1}',values=[16,64],default=16),(3,3),activation='relu'))
        model.add(tf.keras.layers.MaxPooling2D(2,2))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(hp.Int("hidden_units",128,512,step=32),activation='relu')) # 在[128,512]区间中每次递增32,寻找最优神经元个数
    model.add(tf.keras.layers.Dense(1,activation='sigmoid'))
    model.compile(loss='binary_crossentropy',optimizer=RMSprop(lr=0.001),metrics=['acc'])
    return model

tuner = Hyperband(
    build_model,
    objective='val_acc',
    max_epochs=15,
    directory='horse_human_params',
    hyperparameters=hp,
    project_name='my_horse_human_project'
)
tuner.search(train_generator,epochs=10,validation_data=validation_generator)
#model.fit(train_generator,epochs=10,validation_data=validation_generator)
best_hps = tuner.get_best_hyperparameters(1)[0]
print(best_hps.values) #查看最优参数

运行结果:

深度学习中train_loader需要什么头文件 train_datagen_机器学习_03


由此可见,第一个卷积层设置16个过滤器,之后再重复3次。每次过滤器个数分别为16,64,64.神经元个数为384。但缺点是运行时间太长了,这里花了59m19s才跑出循环。

呜呜呜,运行上面结果时f’num_filters_layer{i+1}'忘了+1。这导致两个layer0重合了,所以在运行结果里大家只看见三层layer,最开始那层被覆盖了。跑一次太久了运行结果图就不做更正了。

我们运用算出的最优参数构建模型看看。

model = tuner.hypermodel.build(best_hps) # 按照算出的最优参数构建模型
model.summary() # 查看模型详情

运行结果:

深度学习中train_loader需要什么头文件 train_datagen_数据_04