Как создать метку класса для увеличения мозаики в классификации изображений?
Чтобы создать метку класса CutMix
или MixUp
расширение типа, мы можем использовать beta
такой как np.random.beta
или scipy.stats.beta
и сделать следующее для двух меток:
label = label_one*beta + (1-beta)*label_two
Но что, если у нас более двух изображений? В YoLo4 они попробовали интересное дополнение под названием Mosaic Augmentation для решения проблем с обнаружением объектов. В отличие от CutMix
или MixUp
, это расширение создает расширенные образцы с 4 изображениями. В случае обнаружения объекта, мы можем вычислить смещение каждого экземпляра со-ords и , таким образом , можно получить надлежащую землю правду, здесь . Но как мы можем это сделать только для случаев классификации изображений?
Вот стартер .
import tensorflow as tf
import matplotlib.pyplot as plt
import random
(train_images, train_labels), (test_images, test_labels) = \
tf.keras.datasets.cifar10.load_data()
train_images = train_images[:10,:,:]
train_labels = train_labels[:10]
train_images.shape, train_labels.shape
((10, 32, 32, 3), (10, 1))
Вот функция, которую мы написали для этого дополнения; (слишком уродливо с inner-outer
петлей! Пожалуйста, подскажите, сможем ли мы сделать это эффективно.)
def mosaicmix(image, label, DIM, minfrac=0.25, maxfrac=0.75):
'''
image, label : batches of samples
'''
xc, yc = np.random.randint(DIM * minfrac, DIM * maxfrac, (2,))
indices = np.random.permutation(int(image.shape[0]))
mosaic_image = np.zeros((DIM, DIM, 3), dtype=np.float32)
final_imgs = []
final_lbs = []
# Iterate over the full indices
for j in range(len(indices)):
# Take 4 sample for to create a mosaic sample randomly
rand4indices = [j] + random.sample(list(indices), 3)
# Make mosaic with 4 samples
for i in range(len(rand4indices)):
if i == 0: # top left
x1a, y1a, x2a, y2a = 0, 0, xc, yc
x1b, y1b, x2b, y2b = DIM - xc, DIM - yc, DIM, DIM # from bottom right
elif i == 1: # top right
x1a, y1a, x2a, y2a = xc, 0, DIM , yc
x1b, y1b, x2b, y2b = 0, DIM - yc, DIM - xc, DIM # from bottom left
elif i == 2: # bottom left
x1a, y1a, x2a, y2a = 0, yc, xc, DIM
x1b, y1b, x2b, y2b = DIM - xc, 0, DIM, DIM-yc # from top right
elif i == 3: # bottom right
x1a, y1a, x2a, y2a = xc, yc, DIM, DIM
x1b, y1b, x2b, y2b = 0, 0, DIM-xc, DIM-yc # from top left
# Copy-Paste
mosaic_image[y1a:y2a, x1a:x2a] = image[i,][y1b:y2b, x1b:x2b]
# Append the Mosiac samples
final_imgs.append(mosaic_image)
return final_imgs, label
Расширенные образцы, в настоящее время с неправильными метками.
data, label = mosaicmix(train_images, train_labels, 32)
plt.imshow(data[5]/255)

Однако вот еще несколько примеров, которые вас мотивируют. Данные взяты из конкурса листьев маниоки .
Однако, чтобы получить правильную метку из этого расширенного образца, мы попробовали что-то вроде этого, скажем, для каждого взаимодействия по пакетам внутри внешнего цикла и внутреннего цикла, если мы можем вычислить распределение 4 образцов, например, как каждый из них покрывает площадь внутри mosaic_image
, так что мы можем умножить каждую с вероятностью распределения a
.
# Iterate over the full indices
for j in range(len(indices)):
b = tf.random.uniform([],0,1) # this is beta dist with alpha=1.0
P = tf.cast( tf.random.uniform([],0,1)<=1.0, tf.int32)
for i in range(len(rand4indices)):
....
WIDTH = tf.cast( DIM * tf.math.sqrt(1-b),tf.int32) * P
a = tf.cast(WIDTH*WIDTH/DIM/DIM,tf.float32)
Ответы
Мы уже знаем , что в CutMix , λ
является поплавок число от бета - бета - распределения (а, а). Мы видели, когда α=1
это работает лучше всего. Теперь, если мы α==1
всегда допускаем, мы можем сказать, что λ
это выбрано из равномерного распределения. .
Мы можем λ
просто сказать, что это просто число с плавающей запятой, значение которого будет от 0 до 1.
Итак, только для 2 изображений, если мы используем λ
для 1-го изображения, мы можем вычислить оставшуюся неизвестную часть просто с помощью 1-λ
.
Но для 3 изображений, если мы используем λ
для 1-го изображения, мы не сможем вычислить другие 2 неизвестных из этого единственного λ
. Если мы действительно этого хотим, нам нужно 2 случайных числа для 3 изображений. Таким же образом мы можем сказать, что для n
количества изображений нам нужна n-1
числовая случайная величина. И во всех случаях суммирование должно быть 1
. (например, λ + (1-λ) == 1
). Если сумма не указана 1
, этикетка будет неправильной!
Для этой цели может оказаться полезным распределение Дирихле, поскольку оно помогает генерировать величины, сумма которых равна 1. Случайную величину с распределением Дирихле можно рассматривать как многомерное обобщение бета-распределения.
>>> np.random.dirichlet((1, 1), 1) # for 2 images. Equivalent to λ and (1-λ)
array([[0.92870347, 0.07129653]])
>>> np.random.dirichlet((1, 1, 1), 1) # for 3 images.
array([[0.38712673, 0.46132787, 0.1515454 ]])
>>> np.random.dirichlet((1, 1, 1, 1), 1) # for 4 images.
array([[0.59482542, 0.0185333 , 0.33322484, 0.05341645]])
В CutMix размер обрезанной части изображения зависит от λ
взвешивания соответствующих меток.


Таким образом, для нескольких λ
вам также необходимо рассчитать их соответствующим образом.
# let's say for 4 images
# I am not sure the proper way.
image_list = [4 images]
label_list = [4 label]
new_img = np.zeros((w, h))
beta_list = np.random.dirichlet((1, 1, 1, 1), 1)[0]
for idx, beta in enumerate(beta_list):
x0, y0, w, h = get_cropping_params(beta, full_img) # something like this
new_img[x0, y0, w, h] = image_list[idx][x0, y0, w, h]
label_list[idx] = label_list[idx] * beta
Другой способ взглянуть на эту проблему - рассмотреть разделительные линии как по ширине, так и по высоте. При построении мозаичного изображения цель состоит в том, чтобы объединить 4 изображения в одно изображение. Мы можем добиться этого, произвольно выбирая средние точки (обозначающие точки разделения) в каждом измерении. Это устраняет довольно сложное требование выборки 4 чисел в сумме до 1. Вместо этого теперь цель состоит в том, чтобы выбрать 2 независимых значения из равномерного распределения - гораздо более простая и интуитивно понятная альтернатива.
По сути, мы выбираем два значения:
w = np.random.uniform(0, 1)
h = np.random.uniform(0, 1)
Чтобы создать реалистичную мозаику, в которой каждое изображение имеет заметный вклад, мы можем выбрать значения из [0,25 0,75], а не из [0, 1]
Этих двух значений достаточно, чтобы параметризовать задачу мозаики. Каждое изображение в мозаике занимает области, охватываемые следующими координатами: Учтите, что изображение мозаики имеет размеры WxH, а средние точки каждого измерения представлены значениями w и h соответственно.
- вверху слева - от (0, 0) до (w, h)
- вверху справа - от (w, 0) до (W, h)
- внизу слева - от (0, h) до (w, H)
- внизу справа - от (w, h) до (W, H)
Отобранные средние точки также помогают в вычислении меток классов. Предположим, мы решили использовать область, занимаемую каждым изображением в мозаике, как соответствующий вклад в общую метку класса. Например, рассмотрим 4 изображения, принадлежащие 4 классам {0, 1, 2, 3}. Теперь предположим, что изображение «0» занимает верхний левый угол, «1» - верхний правый угол, «2» - нижний левый угол и «3» - нижний правый угол. Мы можем построить метку класса L следующим образом
вы можете просмотреть уравнение по этой ссылке