簡體   English   中英

使用 TensorFlow-Keras API 進行數據增強

[英]Data Augmentation using TensorFlow-Keras API

以下代碼允許在每個 epoch 結束時將訓練集的圖像旋轉 90º。

from skimage.io import imread
from skimage.transform import resize, rotate
import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from keras.utils import Sequence 
from keras.models import Sequential
from keras.layers import Conv2D, Activation, Flatten, Dense

# Model architecture  (dummy)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(15, 15, 4)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# Data iterator 
class CIFAR10Sequence(Sequence):
    def __init__(self, filenames, labels, batch_size):
        self.filenames, self.labels = filenames, labels
        self.batch_size = batch_size
        self.angles = [0,90,180,270]
        self.current_angle_idx = 0

    # Method to loop throught the available angles
    def change_angle(self):
      self.current_angle_idx += 1
      if self.current_angle_idx >= len(self.angles):
        self.current_angle_idx = 0
  
    def __len__(self):
        return int(np.ceil(len(self.filenames) / float(self.batch_size)))

    # read, resize and rotate the image and return a batch of images
    def __getitem__(self, idx):
        angle = self.angles[self.current_angle_idx]
        print (f"Rotating Angle: {angle}")

        batch_x = self.filenames[idx * self.batch_size:(idx + 1) * self.batch_size]
        batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]
        return np.array([
            rotate(resize(imread(filename), (15, 15)), angle)
               for filename in batch_x]), np.array(batch_y)

# Custom call back to hook into on epoch end
class CustomCallback(keras.callbacks.Callback):
    def __init__(self, sequence):
      self.sequence = sequence

    # after end of each epoch change the rotation for next epoch
    def on_epoch_end(self, epoch, logs=None):
      self.sequence.change_angle()               


# Create data reader
sequence = CIFAR10Sequence(["f1.PNG"]*10, [0, 1]*5, 8)
# fit the model and hook in the custom call back
model.fit(sequence, epochs=10, callbacks=[CustomCallback(sequence)])

如何修改代碼以便在每個時期發生圖像的旋轉?

期望的輸出:

Epoch 1/10
Rotating Angle: 0
Rotating Angle: 90
Rotating Angle: 180
Rotating Angle: 270

Epoch 2/10
Rotating Angle: 0
Rotating Angle: 90
Rotating Angle: 180
Rotating Angle: 270

(...)

Epoch 10/10
Rotating Angle: 0
Rotating Angle: 90
Rotating Angle: 180
Rotating Angle: 270

換句話說,我如何編寫一個回調,該回調在一個時代的“結束”上運行,該回調改變了角度值並在同一時代繼續訓練(不更改到下一個)?

提前致謝

注意:代碼來源來自“mujjiga”。

由於您有一個自定義序列生成器,因此您可以創建一個在 epoch 開始或結束時運行的函數。 這是您可以放置​​代碼來修改圖像的地方。 文檔在[這里][1]

Epoch-level methods (training only)
on_epoch_begin(self, epoch, logs=None)
Called at the beginning of an epoch during training.

on_epoch_end(self, epoch, logs=None)
Called at the end of an epoch during training.


  [1]: https://keras.io/guides/writing_your_own_callbacks/

無需為此創建CustomCallback 最后,您希望在訓練期間進行擴充。

解決方案是以概率應用旋轉操作

# read, resize and rotate the image and return a batch of images
def __getitem__(self, idx):
    angle = self.angles[self.current_angle_idx]
    print(f"Rotating Angle: {angle}")
    batch_x = self.filenames[idx * self.batch_size:(idx + 1) * self.batch_size]
    batch_y = self.labels[idx * self.batch_size:(idx + 1) * self.batch_size]
    #These new lines (say we augment with probability > 0.5)
    #Number between 0 and 1
    images = []
    for filename in batch_x:
        probability = random.random()
        apply_rotate = probability > 0.5
        if apply_rotate:
            images.append(rotate(resize(imread(filename), (15, 15)), angle))
        else:
            images.append(resize(imread(filename), (15, 15)))
    return np.array(images), np.array(batch_y)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM