当前位置: 首页 > article >正文

T10 数据增强

文章目录

  • 一、准备环境和数据
    • 1.环境
    • 2. 数据
  • 二、数据增强(增加数据集中样本的多样性)
  • 三、将增强后的数据添加到模型中
  • 四、开始训练
  • 五、自定义增强函数
  • 六、一些增强函数

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:365天深度学习训练营-第10周:数据增强(训练营内部成员可读)
  • 🍖 原作者:K同学啊 | 接辅导、项目定制
  • 🚀 文章来源:K同学的学习圈子

本文说明了两种数据增强方式,以及如何自定义数据增强方式并将其放到我们代码当中,两种数据增强方式如下:
● 将数据增强模块嵌入model中
● 在Dataset数据集中进行数据增强

常用的tf增强函数在文末有说明

一、准备环境和数据

1.环境

import matplotlib.pyplot as plt
import numpy as np
import sys
from datetime import datetime
#隐藏警告
import warnings
warnings.filterwarnings('ignore')

from tensorflow.keras import layers
import tensorflow as tf

print("--------# 使用环境说明---------")
print("Today: ", datetime.today())
print("Python: " + sys.version)
print("Tensorflow: ", tf.__version__)

gpus = tf.config.list_physical_devices("GPU")
if gpus:
    tf.config.experimental.set_memory_growth(gpus[0], True)  #设置GPU显存用量按需使用
    tf.config.set_visible_devices([gpus[0]],"GPU")
    # 打印显卡信息,确认GPU可用
    print(gpus)
else:
    print("Use CPU")

在这里插入图片描述

2. 数据

使用上一课的数据集,即猫狗识别2的数据集。其次,原数据集中不包括测试集,所以使用tf.data.experimental.cardinality确定验证集中有多少批次的数据,然后将其中的 20% 移至测试集。

# 从本地路径读入图像数据
print("--------# 从本地路径读入图像数据---------")
data_dir   = "D:/jupyter notebook/DL-100-days/datasets/Cats&Dogs Data2/"
img_height = 224
img_width  = 224
batch_size = 32

# 划分训练集
print("--------# 划分训练集---------")
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.3,
    subset="training",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 划分验证集
print("--------# 划分验证集---------")
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.3,
    subset="validation",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 从验证集中划20%的数据用作测试集
print("--------# 从验证集中划20%的数据用作测试集---------")
val_batches = tf.data.experimental.cardinality(val_ds)
test_ds     = val_ds.take(val_batches // 5)
val_ds      = val_ds.skip(val_batches // 5)

print('验证集的批次数: %d' % tf.data.experimental.cardinality(val_ds))
print('测试集的批次数: %d' % tf.data.experimental.cardinality(test_ds))

# 显示数据类别
print("--------# 显示数据类别---------")
class_names = train_ds.class_names
print(class_names)

print("--------# 归一化处理---------")
AUTOTUNE = tf.data.AUTOTUNE

def 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().prefetch(buffer_size=AUTOTUNE)
val_ds   = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

# 数据可视化
print("--------# 数据可视化---------")
plt.figure(figsize=(15, 10))  # 图形的宽为15高为10

for images, labels in train_ds.take(1):
    for i in range(8):
        
        ax = plt.subplot(5, 8, i + 1) 
        plt.imshow(images[i])
        plt.title(class_names[labels[i]])
        
        plt.axis("off")

在这里插入图片描述

二、数据增强(增加数据集中样本的多样性)

数据增强的常用方法包括(但不限于):随机平移、随机翻转、随机旋转、随机亮度、随机对比度,可以在Tf中文网的experimental/preprocessing类目下查看,也可以在Tf中文网的layers/类目下查看。

本文使用随机翻转随机旋转来进行增强:

tf.keras.layers.experimental.preprocessing.RandomFlip:水平和垂直随机翻转每个图像

tf.keras.layers.experimental.preprocessing.RandomRotation:随机旋转每个图像

# 第一个层表示进行随机的水平和垂直翻转,而第二个层表示按照 0.2 的弧度值进行随机旋转。
print("--------# 数据增强:随机翻转+随机旋转---------")
data_augmentation = tf.keras.Sequential([
  tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical"),
  tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
])

# Add the image to a batch.
print("--------# 添加图像到batch中---------")
# Q:这个i从哪来的??????
image = tf.expand_dims(images[i], 0)

print("--------# 显示增强后的图像---------")
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")
--------# 数据增强:随机翻转+随机旋转---------
--------# 添加图像到batch中---------
--------# 显示增强后的图像---------
WARNING:tensorflow:Using a while_loop for converting RngReadAndSkip cause there is no registered converter for this op.
WARNING:tensorflow:Using a while_loop for converting Bitcast cause there is no registered converter for this op.

在这里插入图片描述

三、将增强后的数据添加到模型中

两种方式:

  • (1)将其嵌入model中

优点是:

● 数据增强这块的工作可以得到GPU的加速(如果使用了GPU训练的话)

注意:只有在模型训练时(Model.fit)才会进行增强,在模型评估(Model.evaluate)以及预测(Model.predict)时并不会进行增强操作。

'''
model = tf.keras.Sequential([
  data_augmentation,
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
])
'''
"\nmodel = tf.keras.Sequential([\n  data_augmentation,\n  layers.Conv2D(16, 3, padding='same', activation='relu'),\n  layers.MaxPooling2D(),\n])\n"
  • (2)在Dataset数据集中进行数据增强
batch_size = 32
AUTOTUNE = tf.data.AUTOTUNE

def prepare(ds):
    ds = ds.map(lambda x, y: (data_augmentation(x, training=True), y), num_parallel_calls=AUTOTUNE)
    return ds

print("--------# 增强后的图像加到模型中---------")
train_ds = prepare(train_ds)

在这里插入图片描述

四、开始训练

# 设置模型
print("--------# 设置模型---------")
model = tf.keras.Sequential([
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(len(class_names))
])

# 设置编译参数
# ● 损失函数(loss):用于衡量模型在训练期间的准确率。
# ● 优化器(optimizer):决定模型如何根据其看到的数据和自身的损失函数进行更新。
# ● 评价函数(metrics):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
print("--------# 设置编译器参数---------")
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

print("--------# 开始训练---------")
epochs=20
history = model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=epochs
)

print("--------# 查看训练结果---------")
loss, acc = model.evaluate(test_ds)
print("Accuracy", acc)

在这里插入图片描述

五、自定义增强函数

print("--------# 自定义增强函数---------")
import random
# 这是大家可以自由发挥的一个地方
def aug_img(image):
    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

image = tf.expand_dims(images[3]*255, 0)
print("Min and max pixel values:", image.numpy().min(), image.numpy().max())

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.axis("off")
    
# Q: 将自定义增强函数应用到我们数据上呢?
# 请参考上文的 preprocess_image 函数,将 aug_img 函数嵌入到 preprocess_image 函数中,在数据预处理时完成数据增强就OK啦。

在这里插入图片描述
在这里插入图片描述

# 从本地路径读入图像数据
print("--------# 从本地路径读入图像数据---------")
data_dir   = "D:/jupyter notebook/DL-100-days/datasets/Cats&Dogs Data2/"
img_height = 224
img_width  = 224
batch_size = 32

# 划分训练集
print("--------# 划分训练集---------")
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.3,
    subset="training",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 划分验证集
print("--------# 划分验证集---------")
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    data_dir,
    validation_split=0.3,
    subset="validation",
    seed=12,
    image_size=(img_height, img_width),
    batch_size=batch_size)

# 从验证集中划20%的数据用作测试集
print("--------# 从验证集中划20%的数据用作测试集---------")
val_batches = tf.data.experimental.cardinality(val_ds)
test_ds     = val_ds.take(val_batches // 5)
val_ds      = val_ds.skip(val_batches // 5)

print('验证集的批次数: %d' % tf.data.experimental.cardinality(val_ds))
print('测试集的批次数: %d' % tf.data.experimental.cardinality(test_ds))

# 显示数据类别
print("--------# 显示数据类别---------")
class_names = train_ds.class_names
print(class_names)

print("--------# 归一化处理---------")
AUTOTUNE = tf.data.AUTOTUNE

print("--------# 将自定义增强函数应用到数据上---------")
def preprocess_image(aug_img,label):
    return (aug_img/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().prefetch(buffer_size=AUTOTUNE)
val_ds   = val_ds.cache().prefetch(buffer_size=AUTOTUNE)

# 数据可视化
print("--------# 数据可视化---------")
plt.figure(figsize=(15, 10))  # 图形的宽为15高为10

for images, labels in train_ds.take(1):
    for i in range(8):
        
        ax = plt.subplot(5, 8, i + 1) 
        plt.imshow(images[i])
        plt.title(class_names[labels[i]])
        
        plt.axis("off")
        
# 设置模型
print("--------# 设置模型---------")
model = tf.keras.Sequential([
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(len(class_names))
])

# 设置编译参数
# ● 损失函数(loss):用于衡量模型在训练期间的准确率。
# ● 优化器(optimizer):决定模型如何根据其看到的数据和自身的损失函数进行更新。
# ● 评价函数(metrics):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
print("--------# 设置编译器参数---------")
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

print("--------# 开始训练---------")
epochs=20
history = model.fit(
  train_ds,
  validation_data=val_ds,
  epochs=epochs
)

print("--------# 查看训练结果---------")
loss, acc = model.evaluate(test_ds)
print("Accuracy", acc)

使用自定义增强函数增强后的数据重新训练的结果:
在这里插入图片描述

六、一些增强函数

在这里插入图片描述
(1)随机亮度(RandomBrightness)

tf.keras.layers.RandomBrightness( factor, value_range=(0, 255), seed=None, **kwargs )

(2)随机对比度(RandomContrast)

tf.keras.layers.RandomContrast( factor, seed=None, **kwargs )

(3)随机裁剪(RandomCrop)

tf.keras.layers.RandomCrop( height, width, seed=None, **kwargs )

(4)随机翻转(RandomFlip)

tf.keras.layers.RandomFlip( mode=HORIZONTAL_AND_VERTICAL, seed=None, **kwargs )
(5)随机高度(RandomHeight)和随机宽度(RandomWidth)

tf.keras.layers.RandomHeight( factor, interpolation='bilinear', seed=None, **kwargs )

tf.keras.layers.RandomWidth( factor, interpolation='bilinear', seed=None, **kwargs )

(6)随机平移(RandomTranslation)

tf.keras.layers.RandomTranslation( height_factor, width_factor, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs )

(7)随机旋转(RandonRotation)

tf.keras.layers.RandomRotation( factor, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs )

(8)随机缩放(RandonZoom)

tf.keras.layers.RandomZoom( height_factor, width_factor=None, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs )


http://www.kler.cn/news/134336.html

相关文章:

  • 树莓派通过网线连接电脑(校园网也能连接),实现SSH连接
  • 深入解析具名导入es6规范中的具名导入是在做解构吗
  • C++二分查找算法:有序矩阵中的第 k 个最小数组和
  • 数据结构 堆
  • 配置iTerm2打开自动执行命令
  • 打开游戏提示xapofx1_5.dll丢失如何修复?xapofx1_5.dll缺失的修复教程分享
  • 从一到无穷大 #19 TagTree,倒排索引入手是否是优化时序数据库查询的通用方案?
  • 滚雪球学Java(09-5):Java中的赋值运算符,你真的掌握了吗?
  • mac 打不开 idea 或者 pycharm 的方法
  • JVM垃圾回收相关概念
  • V100 GPU服务器安装GPU驱动教程
  • C语言二叉树的建立和遍历
  • 【论文复现】DAE:《Annotating and Modeling Fine-grained Factuality in Summarization》
  • 云原生专栏丨基于服务网格的企业级灰度发布技术
  • Go语言常用命令详解(二)
  • 【手写数据库toadb】数据库planner的整体架构,以及逻辑查询树的设计与实现流程
  • 深度学习损失函数
  • 微信小程序手写table表格
  • DevToys:开发者的多功能瑞士军刀,让编程更高效!
  • python基础 | 类与继承
  • 小迪安全笔记(2)——web应用架构搭建漏洞HTTP数据包代理服务器
  • hive sql多表练习
  • 【原创】WeChat Server搭建
  • 【开源】基于Vue和SpringBoot的教学过程管理系统
  • 【C++】【Opencv】霍夫直线检测即cv::HoughLinesP()函数详解和示例
  • 深度学习:到底怎么理解embedding
  • 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】
  • 控制您的音乐、视频等媒体内容
  • 精通Nginx(15)-支持CORS
  • 基于单片机音乐弹奏播放DS1302万年历显示及源程序