Tensorflow2.0学习(九) — 通过keras自定义图像数据集

上一节讲解了如何用tensorflow自带的函数自定义我们的数据集,那么这一节我将通过调用tensorflow2.0的高级API keras来分享另一种自定义数据集的方式,并且这种方式会更加易懂方便一些。

这一节我们准备处理的数据集为猫狗分类数据集,主要完成的是一个二分类任务。

一.自定义数据集的读取

1.导入相关的库。

from __future__ import absolute_import,division,print_function,unicode_literals
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator 
from tensorflow.keras import layers
import os
import numpy as np
import matplotlib.pyplot as plt

2.通过链接进行数据集下载并将数据路径保存到变量中。os.path.join的意思是将第一个路径和后面一个路径连接起来。

#改名为cats_and_dog.zip,extract的意思为提取解压
path_to_zip = tf.keras.utils.get_file('cats_and_dog.zip',origin=_URL,extract=True)
PATH = os.path.join(os.path.dirname(path_to_zip),'cats_and_dogs_filtered') #创建文件路径
PATH

 

3.创建数据的训练集和验证集路径。

train_dir = os.path.join(PATH,'train')
validation_dir = os.path.join(PATH,'validation')
train_cats_dir = os.path.join(train_dir,'cats')
train_dogs_dir = os.path.join(train_dir,'dogs')
validation_cats_dir = os.path.join(validation_dir,'cats')
validation_dogs_dir = os.path.join(validation_dir,'dogs')

4.查看猫和狗数据集的数量。

num_cats_tr = len(os.listdir(train_cats_dir))
num_dogs_tr = len(os.listdir(train_dogs_dir))
num_cats_val = len(os.listdir(validation_cats_dir))
num_dogs_val = len(os.listdir(validation_dogs_dir))
total_train = num_cats_tr+num_dogs_tr
total_val = num_cats_val+num_dogs_val
print(total_train)
print(total_val)

二.自定义数据集的加载和预处理

1.设置相关参数。

batch_size = 128 #batch数量
epochs = 5 #训练次数
IMG_HEIGHT = 150 #图片高
IMG_WIDTH = 150 #图片宽

2.创建ImageDataGenerator,这是keras提供的读入自定义数据集的方法,并且我们可以在这里面做数据的augmentation。那么这里蛮提一下为什么要做augmentation?这是一种减缓模型过拟合的方式,它包括了各种对数据集图像的操作,比如拉伸、旋转和缩放等等,这样就可以使我们的训练数据集数量变多,能够有效地减缓训练时的过拟合。那么在这里我们只对训练集进行augmentation操作,只有训练集的增加才能使模型训练时提取更多有用的图片特征,而验证集则就没有必要了。

train_image_generator = ImageDataGenerator(rescale=1./255, #归一化
                                           horizontal_flip=True, #图片翻转
                                           width_shift_range=.15, #宽变化
                                           height_shift_range=.15, #高变化
                                           rotation_range=45,#旋转45度
                                           zoom_range=0.5 #缩放0.5倍
                                              )
valiadation_image_generator = ImageDataGenerator(rescale=1./255) #验证集不进行augmentation处理

3.通过flow_from_directory函数将图片传入image_generator中。

train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=train_dir,#训练集路径
                                                           shuffle=True, #打乱图片顺序
                                                           target_size=(IMG_HEIGHT,IMG_WIDTH),#修改图片尺寸
                                                           class_mode='binary')

val_data_gen = valiadation_image_generator.flow_from_directory(batch_size=batch_size,
                                                             directory=validation_dir,#验证集路径
                                                             target_size=(IMG_HEIGHT,IMG_WIDTH), #修改图片尺寸
                                                             class_mode='binary')

到了这一步,我们的训练集、验证集部分就做好了。

4.定义一个显示图片的函数。

def plotImages(images_arr):
    fig,axes = plt.subplots(1,5,figsize=(20,20))
    axes = axes.flatten()
    for img,ax in zip(images_arr,axes):
        ax.imshow(img)
        ax.axis('off')
    plt.tight_layout()
    plt.show()

5.查看一张图片的变化效果。

augemted_images=[train_data_gen[0][0][0] for i in range(5)]
plotImages(augemted_images)

我们可以发现图片成功地被进行了各种处理。

三.模型的搭建

1.模型搭建。

model = tf.keras.models.Sequential([
    layers.Conv2D(16,3,padding='same',activation='relu',input_shape =(IMG_HEIGHT,IMG_WIDTH,3)), #16为filter个数 3为kernel_size 
    layers.MaxPooling2D(), 
    layers.Dropout(0.2), #防过拟合
    layers.Conv2D(32,3,padding='same',activation='relu'),
    layers.MaxPooling2D(),
    layers.Conv2D(64,3,padding='same',activation='relu'),
    layers.MaxPooling2D(),
    layers.Dropout(0.2),
    layers.Flatten(),
    layers.Dense(512,activation='relu'),
    layers.Dense(1,activation='sigmoid') #2分类,因此1个神经元
])

2.模型配置。因为是二值分类(猫和狗),因此选用binary_crossentropy作为损失函数。

model.compile(optimizer='adam',loss='binary_crossentropy',metrics=['accuracy'])

3.打印模型概要。

model.summary()

Tensorflow2.0学习(九) — 通过keras自定义图像数据集_第1张图片

四.模型的训练

1.之前我们是通过model.fit进行训练,但由于我们现在是将数据集传入generator当中,因此我们要将我们训练的函数改为model.fit_generator,为了节约时间我们这里把训练的batchsize步数减少到3。

history = model.fit_generator(
    train_data_gen, #训练集
    steps_per_epoch=3, #每个epoch训练batchsize的个数
    epochs=epochs,
    validation_data=val_data_gen,#验证集
    validation_steps=3,
)

2.定义显示曲线函数并显示loss曲线。

def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train]) #绘制训练数据的执行结果
    plt.plot(train_history.history[validation]) #绘制验证数据的执行结果
    plt.title('Train History') #图标题 
    plt.xlabel('epoch') #x轴标签
    plt.ylabel(train) #y轴标签
    plt.legend(['train','validation'],loc='upper left') #添加左上角图例

Tensorflow2.0学习(九) — 通过keras自定义图像数据集_第2张图片

五.模型的测试与预测

1.因为该数据集没有提供测试集,因此我们直接测试训练集,仅仅只是为了验证程序的可行性,另外这里传入的同样是generator。

model.evaluate(train_data_gen)

模型测试成功。

2.模型预测。这里要注意的是传入的必须是四维图像,因为我们之前在训练时传入的图像就是四维。格式是(batch_size,图片高,图片宽,图片通道数),如果我们要测试单张图片只要增加一个维度batch_size并把值设为1就可以了。

model.predict(train_data_gen[0][0])

 

以上就是本节的内容,个人觉得通过keras自定义数据集会比tensorflow更方便一些,不过还是建议大家都掌握两种的使用方法。谢谢你们的观看和支持!

 

你可能感兴趣的:(人工智能,Tensorflow2.0,深度学习)