亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

全部開發者教程

TensorFlow 入門教程

首頁 慕課教程 TensorFlow 入門教程 TensorFlow 入門教程 在 TensorFlow 之中進行數據增強

在 TensorFlow 之中進行數據增強

在我們之前的學習之中,我們所使用的數據都是進行一些 “簡單的處理”,比如正則化、歸一化、分批次等基本操作;這些操作都有一些特點,那就是在固定的數據集上進行處理,也就是說這些處理并不會改變數據的數量(甚至可能會減少數據的數量,比如數據篩選)。

那么這節課我們便來學習一下如何在 TensorFlow 之中數據增強,它可以增加數據量,從而可以使用更多樣的數據來訓練模型。

1. 什么是數據增強

關于數據增強,我們可以在 TensorFlow API 之中看到相關的定義:

A technique to increase the diversity of your training set by applying random (but realistic) transformations.

翻譯一下就是:

數據增強是一種通過應用隨機(但現實)的變換來增加訓練集的多樣性的技術。

簡單來說,通過數據增強,我們可以將一些已經存在的數據進行相應的變換(可以選擇將這些變換之后的數據增加到新的原來的數據集之中,也可以直接在原來的數據集上進行變換),從而實現數據種類多樣性的增加

數據增強常見于圖像領域,因此這節課我們會以圖像處理為例來解釋如何在 TensorFlow 之中進行數據增強。

對于圖片數據,常見的數據增強方式包括:

  • 隨機水平翻轉:
  • 隨機的裁剪;
  • 隨機調整明亮程度;
  • 其他方式等。

2. 如何在 TensorFlow 之中進行圖像數據增強

在 TensorFlow 之中進行圖像數據增強的方式主要有兩種:

  • 使用 tf.keras 的預處理層進行圖像數據增強;
  • 使用 tf.image 進行數據增強。

這兩種各有不同的特點,但是因為我們要采用 tf.keras 進行模型的構建,因此我們重點學習如何使用 tf.keras 的預處理層進行圖像數據增強。

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 的大小的裁剪框,在數據的中心進行裁剪。

以上介紹的是我們在數據增強處理之中使用的最多的增強方式,在接下來的學習之中,我們會以該方式為例進行程序的演示。

在使用的過程之中,我們只需要將這些數據增強的網絡層添加到網絡的最底層即可。

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 數據增強主要用在一些自定義的模型之中,從而可以實現數據增強的自定義化。

3. 使用 tf.keras 的預處理層進行數據增強的實例

在這里,我們仍然采用我們熟悉的貓狗分類的例子來進行程序的演示,我們的代碼和之前的代碼相同,只是我們新增加了兩個數據增強的處理層

    tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical",
                input_shape=(Height, Width ,3)),
    tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),

其中第一個層表示進行隨機的水平和垂直翻轉,而第二個層表示按照 0.2 的弧度值進行隨機旋轉。

整體的網絡程序為:


import tensorflow as tf
import os
import matplotlib.pyplot as plt

dataset_url = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
path_download = os.path.dirname(tf.keras.utils.get_file('cats_and_dogs.zip', origin=dataset_url, extract=True))
train_dataset_dir = path_download + '/cats_and_dogs_filtered/train'
valid_dataset_dir = path_download + '/cats_and_dogs_filtered/validation'

BATCH_SIZE = 64
TRAIN_NUM = 2000
VALID_NUM = 1000
EPOCHS = 15
Height = 128
Width = 128

train_image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
valid_image_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)

train_data_generator = train_image_generator.flow_from_directory(batch_size=BATCH_SIZE,
                              directory=train_dataset_dir,
                              shuffle=True,
                              target_size=(Height, Width),
                              class_mode='binary')
valid_data_generator = valid_image_generator.flow_from_directory(batch_size=BATCH_SIZE,
                              directory=valid_dataset_dir,
                              shuffle=True,
                              target_size=(Height, Width),
                              class_mode='binary')

model = tf.keras.models.Sequential([
    tf.keras.layers.experimental.preprocessing.RandomFlip("horizontal_and_vertical",
                input_shape=(Height, Width ,3)),
    tf.keras.layers.experimental.preprocessing.RandomRotation(0.2),
    tf.keras.layers.Conv2D(16, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(1)
])

model.compile(optimizer='adam',
       loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
       metrics=['accuracy'])
model.summary()

history = model.fit_generator(
    train_data_generator,
    steps_per_epoch=TRAIN_NUM // BATCH_SIZE,
    epochs=EPOCHS,
    validation_data=valid_data_generator,
    validation_steps=VALID_NUM // BATCH_SIZE)

acc = history.history['accuracy']
loss=history.history['loss']

val_acc = history.history['val_accuracy']
val_loss=history.history['val_loss']

epochs_ran = range(EPOCHS)

plt.plot(epochs_ran, acc, label='Train Acc')
plt.plot(epochs_ran, val_acc, label='Valid Acc')
plt.show()

plt.plot(epochs_ran, loss, label='Train Loss')
plt.plot(epochs_ran, val_loss, label='Valid Loss')
plt.show()

在訓練結束后,我們可以得到如下結果,而這個結果與我們之前的結果有了一個良好的提升,最高達到了 79% 的準確率,因此我們認為我們的數據增強起到了一定的作用。

Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
random_flip_1 (RandomFlip)   (None, 128, 128, 3)       0         
_________________________________________________________________
random_rotation_1 (RandomRot (None, 128, 128, 3)       0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 126, 126, 16)      448       
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 63, 63, 16)        0         
_________________________________________________________________
conv2d_7 (Conv2D)            (None, 61, 61, 32)        4640      
_________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 30, 30, 32)        0         
_________________________________________________________________
conv2d_8 (Conv2D)            (None, 28, 28, 64)        18496     
_________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 14, 14, 64)        0         
_________________________________________________________________
flatten_2 (Flatten)          (None, 12544)             0         
_________________________________________________________________
dense_4 (Dense)              (None, 512)               6423040   
_________________________________________________________________
dense_5 (Dense)              (None, 1)                 513       
=================================================================
Total params: 6,447,137
Trainable params: 6,447,137
Non-trainable params: 0
_________________________________________________________________
Epoch 1/15
31/31 [==============================] - 40s 1s/step - loss: 0.7372 - accuracy: 0.5052 - val_loss: 0.6700 - val_accuracy: 0.5583
......
Epoch 11/15
31/31 [==============================] - 41s 1s/step - loss: 0.5219 - accuracy: 0.8213 - val_loss: 0.5480 - val_accuracy: 0.7900
......

同時我們的程序還會輸出以下兩個圖片:

準確率變化曲線:

圖片描述

損失變化曲線:

圖片描述

4. 小結

通過這節課的學習,我們了解到了什么是數據增強,同時也明白了如何在 TensorFlow 之中進行數據增強(兩種不同的實現方式)。最后我們會很據以前的程序進行改進,得到了一個完整的程序示例。

avatat