深度学习 Day10——T10数据增强

  • 🍨 本文为🔗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)

在这里插入图片描述

总结

通过本次的学习,学习到了几种图像增强调用方式,原文中增强方式均为增强数据替代原始数据加入训练集,本文加入将增强数据与原始数据一起合并作为样本的方法,本文中的增强方式加入案例,效果并没有很理想,跟数据集实际情况有关,可将本文提到的图像增强方式运用到其他案例中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/268186.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哪种单机版进销存软件好用且真正免费的?

——“哪种单机版进销存软件好用且真正免费的?” ——“免费可使用,但付费实现更大价值。” 作为相关行业的从业者,我十分理解很多小微企业/个体户生存不易,希望在进销存系统上节省成本,或者没有付费使用管理系统的习…

基于ssm应急资源管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本应急资源管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息…

JS的变量提升ES6基础

JS的变量提升&ES6基础 变量var关键字var声明作用域实例一实例二多个变量 变量提升 let关键字暂时性死区全局声明for循环中使用let const关键字 变量 ECMAScript变量时松散类型的,意思是变量可以用于保存任何类型的数据。 声明变量:var 、const、let …

软件测试面试八股文(答案解析+视频教程)

1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行,可以实现跨平台,客户端零维护,维护成本低,但是个性化能力低,响应速度较慢。 C/S响应速度快,安全性强,一般应用于局域网中&#xf…

外包干了3年,技术退步太明显了。。。。。

先说一下自己的情况,本科生生,18年通过校招进入武汉某软件公司,干了差不多3年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能…

Linux 高级管理,基于域名的虚拟Web主机

实验环境 某公司的网站服务器使用的公网IP地址为192.168.184.50并使用该IP地址注册了两个域名 www.bdqn1.com和www.jbit.com。服务器中已经安装好了 CentOS 7操作系统.并通过源码编译的 方式安装了Web服务器软件httpd-2.4.25.现需要对httpd服务进行配置.以支持同时运行这两个 W…

OpenHarmony 如何去除系统锁屏应用

前言 OpenHarmony源码版本:4.0release / 3.2 release 开发板:DAYU / rk3568 一、3.2版本去除锁屏应用 在源码根目录下:productdefine/common/inherit/rich.json 中删除screenlock_mgr组件的编译配置,在rich.json文件中搜索th…

智能时代:互联网+如何改变我们的生活与工作

引言 随着科技的不断进步和互联网的普及,我们正处在一个智能时代。这个时代被互联网所定义,它深刻地改变了我们的生活和工作方式。从社交互动到日常工作,智能时代的影响无处不在,给人们带来了前所未有的变革和机遇。 互联网的涌…

【基础知识】大数据概述

关键词—分布式 化整为零,再化零为整 大数据的定义 传统数据库处理起来困难的数据集。 发展历程 中国开源生态图谱2023 参考内容 中国开源生态图谱 2023.pdf 技术组件说明 数据集成 sqoop、dataX、flume 数据存储 hdfs、kafka 数据处理 mapreduce、hive…

leetcode:2367. 算术三元组的数目(python3解法)

难度&#xff1a;简单 给你一个下标从 0 开始、严格递增 的整数数组 nums 和一个正整数 diff 。如果满足下述全部条件&#xff0c;则三元组 (i, j, k) 就是一个 算术三元组 &#xff1a; i < j < k &#xff0c;nums[j] - nums[i] diff 且nums[k] - nums[j] diff 返回不…

告诉大家一款手机上就能使用的SSH工具

工欲善其事必先利其器&#xff0c;我们在日常工作中需要登录服务器。在Pc端工具比较丰富&#xff0c;如Xshell等。而在手机端有没有好用的ssh连接工具呢&#xff1f; 关于 flutter_server_box一个 Flutter 项目&#xff0c;它提供图表来显示 Linux 服务器状态和管理服务器的工…

C++ Qt开发:LineEdit单行输入组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍LineEdit单行输入框组件的常用方法及灵活运用…