Я пытаюсь выполнить Mixup Augmentation (подробности здесь ), но я получаю ошибку значения следующим образом:
ValueError: operands could not be broadcast together with shapes (47,128,128,3) (64,1,1,1)
Ниже приведено определение класса MixupImageDataGenerator, которое я использую:
class MixupImageDataGenerator():
def __init__(self, generator, directory, batch_size, img_height, img_width, alpha=0.2, subset=None):
"""Constructor for mixup image data generator.
Keyword Arguments:
alpha {float} -- Mixup beta distribution alpha parameter. (default: {0.2})
subset {str} -- 'training' or 'validation' if validation_split is specified in
`generator` (ImageDataGenerator).(default: {None})
"""
self.batch_index = 0
self.batch_size = 64
self.alpha = alpha
# First iterator yielding tuples of (x, y)
self.generator1 = generator.flow_from_directory(directory,
target_size=(
128, 128),
class_mode="categorical",
batch_size=64,
shuffle=True,
subset=subset)
# Second iterator yielding tuples of (x, y)
self.generator2 = generator.flow_from_directory(directory,
target_size=(
128, 128),
class_mode="categorical",
batch_size=64,
shuffle=True,
subset=subset)
# Number of images across all classes in image directory.
self.n = self.generator1.samples
def reset_index(self):
"""Reset the generator indexes array.
"""
self.generator1._set_index_array()
self.generator2._set_index_array()
def on_epoch_end(self):
self.reset_index()
def reset(self):
self.batch_index = 0
def __len__(self):
# round up
return (self.n + self.batch_size - 1) // self.batch_size
def get_steps_per_epoch(self):
"""Get number of steps per epoch based on batch size and
number of images.
Returns:
int -- steps per epoch.
"""
return self.n // self.batch_size
def __next__(self):
"""Get next batch input/output pair.
Returns:
tuple -- batch of input/output pair, (inputs, outputs).
"""
if self.batch_index == 0:
self.reset_index()
#my_list = []
current_index = (self.batch_index * self.batch_size) % self.n
#my_list.insert(0,current_index)
#print("current index" + str(current_index))
if self.n > current_index + self.batch_size:
self.batch_index += 1
else:
self.batch_index = 0
#print("batch_index" + str(self.batch_index))
# random sample the lambda value from beta distribution.
l = np.random.beta(self.alpha, self.alpha, self.batch_size)
print("l")
print(l.shape)
X_l = l.reshape(self.batch_size, 1, 1, 1)
print("X_l")
print(X_l.shape)
y_l = l.reshape(self.batch_size, 1)
print("y_l")
print(y_l.shape)
# Get a pair of inputs and outputs from two iterators.
X1, y1 = self.generator1.next()
print("X1, y1")
print(X1.shape, y1.shape)
X2, y2 = self.generator2.next()
print("X2, y2")
print(X2.shape, y2.shape)
# Perform the mixup.
X = X1 * X_l + X2 * (1 - X_l)
y = y1 * y_l + y2 * (1 - y_l)
print("X")
print(X.shape)
print("y")
print(y.shape)
print("my_list " + str(my_list))
return X, y
def __iter__(self):
while True:
yield next(self)
Ниже приведен мой код, по которому я вызываю класс Mixup и выполняю фактическое увеличение:
# Create training and validation generator.
train_generator = MixupImageDataGenerator(generator=input_datagen,
directory='data/train/',
batch_size=64,
img_height=128,
img_width=128,
subset='training')
validation_generator = input_datagen.flow_from_directory(directory = 'data/train/', target_size=(128, 128), color_mode='rgb', class_mode='categorical',batch_size=64,subset='validation', shuffle=True, seed=42)
print('training steps: ', train_generator.get_steps_per_epoch())
print('validation steps: ', validation_generator.samples // batch_size)
Вывод:
Found 3503 images belonging to 5 classes.
Found 3503 images belonging to 5 classes.
Found 1496 images belonging to 5 classes.
training steps: 54
validation steps: 23
Я инициировал обучениеи я показываю результаты 42-го шага.Все предыдущие шаги имели схожие результаты.
42/54 [======================>.......] - ETA: 11s - loss: 1.3245 - acc: 0.4565
current index 3392
batch_index 54
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
43/54 [======================>.......] - ETA: 10s - loss: 1.3227 - acc: 0.4557
current index 3456
batch_index 0
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(47, 128, 128, 3) (47, 5)
\n X2, y2
(47, 128, 128, 3) (47, 5)
44/54 [=======================>......] - ETA: 9s - loss: 1.3233 - acc: 0.4538 current index 0
batch_index 1
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
45/54 [========================>.....] - ETA: 8s - loss: 1.3214 - acc: 0.4549
current index 64
batch_index 2
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
46/54 [========================>.....] - ETA: 7s - loss: 1.3211 - acc: 0.4541
current index 128
batch_index 3
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
47/54 [=========================>....] - ETA: 6s - loss: 1.3193 - acc: 0.4561
current index 192
batch_index 4
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
.
.
.
.
.
53/54 [============================>.] - ETA: 0s - loss: 1.3072 - acc: 0.4608
current index 576
batch_index 10
\n l
(64,)
X_l
(64, 1, 1, 1)
y_l
(64, 1)
\n X1, y1
(64, 128, 128, 3) (64, 5)
\n X2, y2
(64, 128, 128, 3) (64, 5)
\n X
(64, 128, 128, 3)
y
(64, 5)
54/54 [==============================] - 53s 986ms/step - loss: 1.3058 - acc: 0.4606 - val_loss: 1.2556 - val_acc: 0.4749
Epoch 00001: val_acc improved from -inf to 0.47486, saving model to GoDL-NP_CE_NLS_ABC-MIXUP.h5
Epoch 2/3
После этого я получаю следующую ошибку:
ValueError: operands could not be broadcast together with shapes (47,128,128,3) (64,1,1,1)
Мои наблюдения
1) Все шаги, кроме шага 43, имеют следующие формы:
X1, y1 (64, 128, 128, 3) (64, 5)
X2, y2 (64, 128, 128, 3) (64, 5)
Но шаг 43 имеет следующую форму:
X1, y1 (47, 128, 128, 3) (47, 5)
X2, y2 (47, 128, 128, 3) (47, 5)
2) До начала первого шага обучения генератор данных, кажется, уже продвинулся вперед, о чем свидетельствует тот факт, что cuurent_index = 124 к моменту выполнения шага 1 времени.
3) Мне кажется, что для шага 43 доступны только 47 изображений, а не ожидаемые 64 (равны размеру пакета).Я говорю это потому, что для шага 47 current_index = 3456 и batch_index = 0.Общий размер обучающих образов = 3503. Таким образом, разница составляет 3503 - 3456 = 47. Для следующего шага текущий индекс = 0 и batch_index = 1.
Итак, я думаю, что мне нужно следующее:
- Как обеспечить одинаковое количество изображений для каждого шага?
- Как обеспечить синхронизацию генератора данных и обучения?