上一节讲解了如何用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()
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') #添加左上角图例
1.因为该数据集没有提供测试集,因此我们直接测试训练集,仅仅只是为了验证程序的可行性,另外这里传入的同样是generator。
model.evaluate(train_data_gen)
模型测试成功。
2.模型预测。这里要注意的是传入的必须是四维图像,因为我们之前在训练时传入的图像就是四维。格式是(batch_size,图片高,图片宽,图片通道数),如果我们要测试单张图片只要增加一个维度batch_size并把值设为1就可以了。
model.predict(train_data_gen[0][0])
以上就是本节的内容,个人觉得通过keras自定义数据集会比tensorflow更方便一些,不过还是建议大家都掌握两种的使用方法。谢谢你们的观看和支持!