- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊 | 接辅导、项目定制
文章目录
- 前言
- 一、我的环境
- 二、代码实现与执行结果
- 1.引入库
- 2.设置GPU(如果使用的是CPU可以忽略这步)
- 3.导入数据
- 4.查看数据
- 5.加载数据
- 6.再次检查数据
- 7.配置数据集
- 8.可视化数据
- 9.构建CNN网络模型
- 10.编译模型
- 11.训练模型
- 12.模型评估
- 三、知识点详解
- 1.图像增强
- 1.1TensorFlow 之中进行图像数据增强
- 1.1.1使用 tf.keras 的预处理层进行图像数据增强
- 1.1.2 使用 tf.image 进行数据增强
- 1.2自定义增强函数
- 1.3 图像增强数据与原始数据合并作为新样本
- 总结
前言
本文将采用CNN实现猫狗识别。简单讲述实现代码与执行结果,并浅谈涉及知识点。
关键字:图像增强
一、我的环境
- 电脑系统:Windows 11
- 语言环境:python 3.8.6
- 编译器:pycharm2020.2.3
- 深度学习环境:TensorFlow 2.10.1
- 显卡:NVIDIA GeForce RTX 4070
二、代码实现与执行结果
1.引入库
from PIL import Image
import numpy as np
from pathlib import Path
import tensorflow as tf
from tensorflow.keras import datasets, layers, models, regularizers
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras import layers, models, Input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout, BatchNormalization
from tqdm import tqdm
import tensorflow.keras.backend as K
import matplotlib.pyplot as plt
import warningswarnings.filterwarnings('ignore') # 忽略一些warning内容,无需打印
2.设置GPU(如果使用的是CPU可以忽略这步)
'''前期工作-设置GPU(如果使用的是CPU可以忽略这步)'''
# 检查GPU是否可用
print(tf.test.is_built_with_cuda())
gpus = tf.config.list_physical_devices("GPU")
print(gpus)
if gpus:gpu0 = gpus[0] # 如果有多个GPU,仅使用第0个GPUtf.config.experimental.set_memory_growth(gpu0, True) # 设置GPU显存用量按需使用tf.config.set_visible_devices([gpu0], "GPU")
执行结果
True
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
3.导入数据
数据链接: 猫狗数据
'''前期工作-导入数据'''
data_dir = r"D:\DeepLearning\data\CatDog"
data_dir = Path(data_dir)
4.查看数据
'''前期工作-查看数据'''
image_count = len(list(data_dir.glob('*/*.png')))
print("图片总数为:", image_count)
image_list = list(data_dir.glob('cat/*.png'))
image = Image.open(str(image_list[1]))
# 查看图像实例的属性
print(image.format, image.size, image.mode)
plt.imshow(image)
plt.show()
执行结果:
图片总数为: 3400
JPEG (512, 512) RGB
5.加载数据
'''数据预处理-加载数据'''
batch_size = 64
img_height = 224
img_width = 224
"""
关于image_dataset_from_directory()的详细介绍可以参考文章:https://mtyjkh.blog.csdn.net/article/details/117018789
"""
train_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="training",seed=12,image_size=(img_height, img_width),batch_size=batch_size)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(data_dir,validation_split=0.2,subset="validation",seed=12,image_size=(img_height, img_width),batch_size=batch_size)
# 我们可以通过class_names输出数据集的标签。标签将按字母顺序对应于目录名称。
class_names = train_ds.class_names
print(class_names)
运行结果:
Found 3400 files belonging to 2 classes.
Using 2720 files for training.
Found 3400 files belonging to 2 classes.
Using 680 files for validation.
['cat', 'dog']
6.再次检查数据
'''数据预处理-再次检查数据'''
# Image_batch是形状的张量(32,180,180,3)。这是一批形状180x180x3的32张图片(最后一维指的是彩色通道RGB)。
# Label_batch是形状(32,)的张量,这些标签对应32张图片
for image_batch, labels_batch in train_ds:print(image_batch.shape)print(labels_batch.shape)break
运行结果
(64, 224, 224, 3)
(64,)
7.配置数据集
AUTOTUNE = tf.data.AUTOTUNEdef preprocess_image(image, label):return (image / 255.0, label)# 归一化处理
train_ds = train_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
val_ds = val_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
test_ds = test_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
8.可视化数据
'''数据预处理-可视化数据'''
plt.figure(figsize=(18, 3))
for images, labels in train_ds.take(2):for i in range(8):ax = plt.subplot(1, 8, i + 1)plt.imshow(images[i].numpy().astype("uint8"))plt.title(class_names[labels[i]], fontsize=40)plt.axis("off")
# 显示图片
plt.show()
9.构建CNN网络模型
#VGG16
def VGG16(class_names, img_height, img_width):model = models.Sequential([# 1layers.Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same',input_shape=(img_height, img_width, 3)),layers.Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 2layers.Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 3layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 4layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 5layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# FClayers.Flatten(),layers.Dense(4096, activation='relu'),layers.Dense(4096, activation='relu'),layers.Dense(len(class_names), activation='softmax')])return model
model = VGG16(class_names, img_height, img_width)
model.summary()
网络结构结果如下:
Model: "sequential_1"
_________________________________________________________________Layer (type) Output Shape Param #
=================================================================conv2d (Conv2D) (None, 224, 224, 64) 1792 conv2d_1 (Conv2D) (None, 224, 224, 64) 36928 max_pooling2d (MaxPooling2D (None, 112, 112, 64) 0 ) conv2d_2 (Conv2D) (None, 112, 112, 128) 73856 conv2d_3 (Conv2D) (None, 112, 112, 128) 147584 max_pooling2d_1 (MaxPooling (None, 56, 56, 128) 0 2D) conv2d_4 (Conv2D) (None, 56, 56, 256) 295168 conv2d_5 (Conv2D) (None, 56, 56, 256) 590080 conv2d_6 (Conv2D) (None, 56, 56, 256) 590080 max_pooling2d_2 (MaxPooling (None, 28, 28, 256) 0 2D) conv2d_7 (Conv2D) (None, 28, 28, 512) 1180160 conv2d_8 (Conv2D) (None, 28, 28, 512) 2359808 conv2d_9 (Conv2D) (None, 28, 28, 512) 2359808 max_pooling2d_3 (MaxPooling (None, 14, 14, 512) 0 2D) conv2d_10 (Conv2D) (None, 14, 14, 512) 2359808 conv2d_11 (Conv2D) (None, 14, 14, 512) 2359808 conv2d_12 (Conv2D) (None, 14, 14, 512) 2359808 max_pooling2d_4 (MaxPooling (None, 7, 7, 512) 0 2D) flatten (Flatten) (None, 25088) 0 dense (Dense) (None, 4096) 102764544 dense_1 (Dense) (None, 4096) 16781312 dense_2 (Dense) (None, 2) 8194 =================================================================
Total params: 134,268,738
Trainable params: 134,268,738
Non-trainable params: 0
_________________________________________________________________
10.编译模型
'''编译模型'''
#设置初始学习率
initial_learning_rate = 1e-4
opt = tf.keras.optimizers.Adam(learning_rate=initial_learning_rate)
model.compile(optimizer=opt,loss='sparse_categorical_crossentropy',metrics=['accuracy'])
11.训练模型
'''训练模型'''
epochs = 10
history = model.fit(train_ds,validation_data=val_ds,epochs=epochs,shuffle=False
)
训练记录如下:
Epoch 1/1043/43 [==============================] - 42s 606ms/step - loss: 0.6830 - accuracy: 0.5511 - val_loss: 0.7328 - val_accuracy: 0.6630
Epoch 2/10
43/43 [==============================] - 17s 384ms/step - loss: 0.4927 - accuracy: 0.7614 - val_loss: 0.3283 - val_accuracy: 0.8714
Epoch 3/10
43/43 [==============================] - 17s 385ms/step - loss: 0.2113 - accuracy: 0.9165 - val_loss: 0.1986 - val_accuracy: 0.9221
Epoch 4/10
43/43 [==============================] - 17s 385ms/step - loss: 0.1173 - accuracy: 0.9555 - val_loss: 0.0977 - val_accuracy: 0.9620
Epoch 5/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0561 - accuracy: 0.9798 - val_loss: 0.0789 - val_accuracy: 0.9728
Epoch 6/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0483 - accuracy: 0.9816 - val_loss: 0.0578 - val_accuracy: 0.9783
Epoch 7/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0457 - accuracy: 0.9838 - val_loss: 0.0551 - val_accuracy: 0.9783
Epoch 8/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0372 - accuracy: 0.9875 - val_loss: 0.0985 - val_accuracy: 0.9692
Epoch 9/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0324 - accuracy: 0.9915 - val_loss: 0.0264 - val_accuracy: 0.9873
Epoch 10/10
43/43 [==============================] - 17s 385ms/step - loss: 0.0109 - accuracy: 0.9967 - val_loss: 0.0408 - val_accuracy: 0.9891
2/2 [==============================] - 0s 116ms/step - loss: 0.0615 - accuracy: 0.9922
Accuracy 0.9921875
12.模型评估
'''模型评估'''
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(len(loss))
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()loss, acc = model.evaluate(test_ds)
print("Accuracy", acc)
执行结果
2/2 [==============================] - 0s 116ms/step - loss: 0.0615 - accuracy: 0.9922
Accuracy 0.9921875
三、知识点详解
1.图像增强
在深度学习中,有的时候训练集不够多,或者某一类数据较少,或者为了防止过拟合,让模型更加鲁棒性,data augmentation是一个不错的选择。
通过数据增强,我们可以将一些已经存在的数据进行相应的变换(可以选择将这些变换之后的数据增加到新的原来的数据集之中,也可以直接在原来的数据集上进行变换),从而实现数据种类多样性的增加。
对于图片数据,常见的数据增强方式包括:
- 随机水平翻转:
- 随机的裁剪;
- 随机调整明亮程度;
- 其他方式等
1.1TensorFlow 之中进行图像数据增强
在 TensorFlow 之中进行图像数据增强的方式主要有两种:
- 使用 tf.keras 的预处理层进行图像数据增强;
- 使用 tf.image 进行数据增强。
1.1.1使用 tf.keras 的预处理层进行图像数据增强
使用 tf.keras 的预处理层进行图像数据增强要使用的最主要的 API 包括在一下包之中:
tf.keras.layers.experimental.preprocessing
在这个包之中,我们最常用的数据增强 API 包括:
tf.keras.layers.experimental.preprocessing.RandomFlip(mode)
: 将输入的图片进行随机翻转,一般我们会取 mode=“horizontal” ,因为这代表水平旋转;而 mode=“vertical” 则代表随机进行上下翻转;
tf.keras.layers.experimental.preprocessing.RandomRotation
§: 按照旋转角度(单位为弧度) p 将输入的图片进行随机的旋转;
tf.keras.layers.experimental.preprocessing.RandomContrast
§:按照 P 的概率将输入的图片进行随机的图像色相翻转;
tf.keras.layers.experimental.preprocessing.CenterCrop(height, width)
:使用 height * width 的大小的裁剪框,在数据的中心进行裁剪。
该API有两种使用方式:一个是将其嵌入model中,一个是在Dataset数据集中进行数据增强
方式一:嵌入model中
调用方式如下
# tf.keras.layers.experimental.preprocessing图像增强 第一个层表示进行随机的水平和垂直翻转,而第二个层表示按照 0.2 的弧度值进行随机旋转。
data_augmentation = tf.keras.Sequential([tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical",input_shape=(img_height, img_width, 3)),tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
])
model = tf.keras.Sequential([data_augmentation,layers.Conv2D(16, 3, padding='same', activation='relu'),layers.MaxPooling2D(),
])
# 图像增强 可视化效果图
for images, labels in train_ds.take(1):# Add the image to a batch.image = tf.expand_dims(images[0], 0)plt.figure(figsize=(8, 8))for i in range(9):augmented_image = data_augmentation(image)ax = plt.subplot(3, 3, i + 1)plt.imshow(augmented_image[0])plt.axis("off")plt.show()break
本文案例使用如下
data_augmentation = tf.keras.Sequential([tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical",input_shape=(img_height, img_width, 3)),tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
])
#方式一图像增强:tf.keras.layers.experimental.preprocessing方式实现的图像增强,嵌入模型中
#只有在模型训练时(Model.fit)才会进行增强,在模型评估(Model.evaluate)以及预测(Model.predict)时并不会进行增强操作
def VGG16_aug0(class_names, img_height, img_width):model = models.Sequential([data_augmentation,# 1layers.Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same',input_shape=(img_height, img_width, 3)),layers.Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 2layers.Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 3layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 4layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# 5layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'),layers.MaxPool2D(pool_size=(2, 2), strides=2),# FClayers.Flatten(),layers.Dense(4096, activation='relu'),layers.Dense(4096, activation='relu'),layers.Dense(len(class_names), activation='softmax')])return model
model = VGG16_aug0(class_names, img_height, img_width) # 方式一图像增强
model.summary()# 图像增强 可视化效果图
for images, labels in train_ds.take(1):# Add the image to a batch.image = tf.expand_dims(images[0], 0)plt.figure(figsize=(8, 8))for i in range(9):augmented_image = data_augmentation(image)ax = plt.subplot(3, 3, i + 1)plt.imshow(augmented_image[0])plt.axis("off")plt.show()break
方式二:在Dataset数据集中进行数据增强
本文案例使用如下
#方式二图像增强:tf.keras.layers.experimental.preprocessing方式实现的图像增强.在Dataset数据集中进行数据增强
AUTOTUNE = tf.data.AUTOTUNEdef prepare(ds):ds = ds.map(lambda x, y: (data_augmentation(x, training=True), y), num_parallel_calls=AUTOTUNE)return ds
train_ds1 = prepare(train_ds)'''训练模型'''
epochs = 20
history = model.fit(train_ds1,validation_data=val_ds,epochs=epochs
)
本文试验效果并不理想
1.1.2 使用 tf.image 进行数据增强
使用 tf.image 是 TensorFlow 最原生的一种增强方式,使用这种方式可以实现更多、更加个性化的数据增强。
其中包含的数据增强方式主要包括:
tf.image.flip_left_right (img)
:将图片进行水平翻转;
tf.image.rgb_to_grayscale (img)
:将 RGB 图像转化为灰度图像;
tf.image.adjust_saturation (image, f)
:将 image 图像按照 f 参数进行饱和度的调节;
tf.image.adjust_brightness (image, f)
:将 image 图像按照 f 参数进行亮度的调节;
tf.image.central_crop (image, central_fraction)
:按照 p 的比例进行图片的中心裁剪,比如如果 p 是 0.5 ,那么裁剪后的长、宽就是原来图像的一半;
tf.image.rot90 (image)
:将 image 图像逆时针旋转 90 度。
可以看到,很多的 tf.image 数据增强方式并不提供随机化选项,因此我们需要手动进行随机化。
也正是因为上述特性,tf.image 数据增强主要用在一些自定义的模型之中,从而可以实现数据增强的自定义化。
参考链接在 TensorFlow 之中进行数据增强
1.2自定义增强函数
import random
# 这是大家可以自由发挥的一个地方
def aug_img(image,label):seed = (random.randint(0, 9), 0)# 随机改变图像对比度stateless_random_brightness = tf.image.stateless_random_contrast(image, lower=0.1, upper=1.0, seed=seed)return stateless_random_brightness,label
train_ds2 = train_ds.map(aug_img, num_parallel_calls=AUTOTUNE)# 图像增强 可视化效果图
for images, labels in train_ds.take(1):# Add the image to a batch.image = tf.expand_dims(images[0], 0)plt.figure(figsize=(8, 8))for i in range(9):augmented_image = aug_img(image)ax = plt.subplot(3, 3, i + 1)# plt.imshow(augmented_image[0].numpy().astype("uint8"))plt.imshow(augmented_image[0][0])plt.axis("off")plt.show()break
效果也不是很理想,知道调用方法就行,针对不同案例实现图像增强
1.3 图像增强数据与原始数据合并作为新样本
操作步骤如下:
- 读取原始数据并图像增强
- 保存增强效果图
- 将原始数据与新生成的增强数据一起符号链接到新目录
读取原始数据并图像增强,保存增强效果图
from pathlib import Path
import cv2
import matplotlib.pyplot as plt
import warningswarnings.filterwarnings('ignore') # 忽略一些warning内容,无需打印
def saveaugimg(imgfile,newdir,prefix="aug_"):# cv2保存中文路径的图像imgFile = imgfile # 读取文件的路径img = cv2.imread(imgFile, flags=1) # flags=1 读取彩色图像(BGR)img1 = cv2.flip(img, 2) # 水平翻转img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)# plt.imshow(img2)# plt.show()saveFile = imgfile.replace(r"D:\DeepLearning\data\CatDog", newdir) # 带有中文的保存文件路径newname=prefix+str(Path(imgfile).name)saveFile = Path(saveFile).parent / newnamePath(saveFile).parent.mkdir(parents=True, exist_ok=True) # 创建新文件夹# cv2.imwrite(saveFile, img) # imwrite 不支持中文路径和文件名,读取失败,但不会报错!img_write = cv2.imencode(".jpg", img1)[1].tofile(saveFile)dirs=r"D:\DeepLearning\data\CatDog"
newdir = r"D:\DeepLearning\data\CatDog_aug"
for p in Path(dirs).rglob("*"):if p.is_file(): # 如果是文件imgfile=str(p)saveaugimg(imgfile, newdir)
将原始数据与新生成的增强数据一起符号链接到新目录
from pathlib import Path# 对目录dirs做符号链接
def createslinkbatfile(dirs, slinkdirs, batfile="slink.bat"):print(f"为{dirs}创建符号链接目录{slinkdirs}\n")# 创建符号链接目录Path(slinkdirs).mkdir(parents=True, exist_ok=True)# 创建bat文件,为了解决bat脚本中文输出乱码问题,# 我们需要在bat脚本开头添加chcp 65001来设置控制台编码格式为UTF-8。# 同时,我们还需要使用setlocal enabledelayedexpansion启用延迟变量扩展with open(batfile, 'a', encoding='utf-8') as file:file.write("@echo off\nchcp 65001\nsetlocal enabledelayedexpansion " + '\n')# 遍历目标目录下的文件夹及文件,创建符号链接cmd命令for p in Path(dirs).rglob("*"):slink = Path(str(p).replace(str(dirs), str(slinkdirs))) # 替换符号链接文件夹目录if p.is_dir(): # 目录符号链接command = f"mklink /d \"{slink}\" \"{str(p)}\""else: # 文件符号链接command = f"mklink \"{slink}\" \"{str(p)}\""# 将符号链接cmd命令写入bat文件with open(batfile, 'a', encoding='utf-8') as file:# 增加编码encoding='utf-8',解决中文乱码问题解决方法file.write(command + '\n')print(command)# 对目录dirs做符号链接,生成后右击bat文件,选用管理员身份运行Path("slink.bat").unlink(missing_ok=False)# 删除bat文件
dirs=r"D:\DeepLearning\data\CatDog"
newdirs = r"D:\DeepLearning\data\CatDog_aug"
slinkdirs = r"D:\DeepLearning\data\CatDog_all"
createslinkbatfile(dirs, slinkdirs)
createslinkbatfile(newdirs, slinkdirs)
部分bat内容同如下
@echo off
chcp 65001
setlocal enabledelayedexpansion
mklink /d "D:\DeepLearning\data\CatDog_all\cat" "D:\DeepLearning\data\CatDog\cat"
mklink /d "D:\DeepLearning\data\CatDog_all\dog" "D:\DeepLearning\data\CatDog\dog"
mklink "D:\DeepLearning\data\CatDog_all\cat\flickr_cat_000002.jpg" "D:\DeepLearning\data\CatDog\cat\flickr_cat_000002.jpg"
mklink "D:\DeepLearning\data\CatDog_all\cat\flickr_cat_000003.jpg" "D:\DeepLearning\data\CatDog\cat\flickr_cat_000003.jpg"
mklink "D:\DeepLearning\data\CatDog_all\cat\flickr_cat_000004.jpg" "D:\DeepLearning\data\CatDog\cat\flickr_cat_000004.jpg"
mklink "D:\DeepLearning\data\CatDog_all\cat\flickr_cat_000005.jpg" "D:\DeepLearning\data\CatDog\cat\flickr_cat_000005.jpg"
tf.keras.preprocessing.image_dataset_from_directory()传入新的文件夹目录
data_dir1 = r"D:\DeepLearning\data\CatDog_all" # 将自定义数据增强后的数据保存后,与原始数据一起合并加入样本中
data_dir = Path(data_dir1)
总结
通过本次的学习,学习到了几种图像增强调用方式,原文中增强方式均为增强数据替代原始数据加入训练集,本文加入将增强数据与原始数据一起合并作为样本的方法,本文中的增强方式加入案例,效果并没有很理想,跟数据集实际情况有关,可将本文提到的图像增强方式运用到其他案例中。