Aumento de datos en PyTorch

Estoy un poco confundido sobre el aumento de datos realizado en PyTorch. Ahora, por lo que sé, cuando estamos realizando un aumento de datos, estamos GUARDANDO nuestro conjunto de datos original, y luego agregando otras versiones de este (Flipping, Recorte … etc). Pero eso no parece ocurrir en PyTorch. Por lo que entendí de las referencias, cuando usamos data.transforms en PyTorch, entonces las aplicamos una por una. Así por ejemplo:

 data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } 

Aquí, para el entrenamiento, primero (224,224) aleatoriamente la imagen y la redimensionamos a la forma (224,224) . Luego tomamos estas (224,224) imágenes y las (224,224) horizontalmente. Por lo tanto, nuestro conjunto de datos ahora contiene SOLO las imágenes volteadas horizontalmente, por lo que nuestras imágenes originales se pierden en este caso.

Estoy en lo cierto? ¿Es correcto este entendimiento? Si no, ¿dónde le decimos a PyTorch en este código anterior (tomado de la Documentación oficial) que guarde las imágenes originales y las redimensione a la forma esperada (224,224) ?

Gracias

Las operaciones de transforms se aplican a sus imágenes originales en cada generación de lotes. Por lo tanto, su conjunto de datos no se modifica, solo las imágenes de lote se copian y se transforman en cada iteración.

La confusión puede provenir del hecho de que a menudo, como en su ejemplo, las transforms se usan tanto para la preparación de los datos (redimensionamiento / recorte a las dimensiones esperadas, valores de normalización, etc.) y para el aumento de los datos (asignación aleatoria del tamaño / recorte, cambio aleatorio del imágenes, etc.).


Lo que hace tu data_transforms['train'] es:

  • Cambia el tamaño de la imagen proporcionada al azar y recórtala al azar para obtener un parche (224, 224)
  • Aplique o no un giro horizontal aleatorio a este parche, con una probabilidad de 50/50
  • Convertirlo en un Tensor
  • Normalice el Tensor resultante, dados los valores medios y de desviación que proporcionó

Lo que hace tu data_transforms['val'] es:

  • Cambia el tamaño de tu imagen a (256, 256)
  • Centro recorte la imagen redimensionada para obtener un parche (224, 224)
  • Convertirlo en un Tensor
  • Normalice el Tensor resultante, dados los valores medios y de desviación que proporcionó

(es decir, el cambio de tamaño / recorte aleatorio para los datos de entrenamiento se reemplaza por una operación fija para la validación, para tener resultados de validación confiables)


Si no quieres que tus imágenes de entrenamiento se inviertan horizontalmente con una probabilidad de 50/50, simplemente elimina las líneas de transforms.RandomHorizontalFlip() .

De manera similar, si desea que sus imágenes siempre se data_transforms['val'] al centro, reemplace transforms.RandomResizedCrop por transforms.Resize y transforms.CenterCrop , como se hizo para data_transforms['val'] .

Supongo que está preguntando si estas transformaciones de aumento de datos (por ejemplo, RandomHorizontalFlip) en realidad aumentan también el tamaño del conjunto de datos , o si se aplican a cada elemento en el conjunto de datos uno por uno y no se agrega al tamaño del conjunto de datos .

Al ejecutar el siguiente fragmento de código simple, podríamos observar que este último es verdadero , es decir, si tiene un conjunto de datos de 8 imágenes y crea un objeto de conjunto de datos de PyTorch para este conjunto de datos cuando recorre el conjunto de datos, se llama a las transformaciones en cada punto de datos. y se devuelve el punto de datos transformado. Así, por ejemplo, si tiene un giro aleatorio, algunos de los puntos de datos se devuelven como originales, otros se devuelven como volteados (por ejemplo, 4 volteados y 4 originales). En otras palabras, por una iteración a través de los elementos del conjunto de datos, obtiene 8 puntos de datos (algunos invertidos y otros no) . [Lo que está en desacuerdo con la comprensión convencional de boost el conjunto de datos (por ejemplo, en este caso tiene 16 puntos de datos en el conjunto de datos aumentado)]

 class experimental_dataset(Dataset): def __init__(self, data, transform): self.data = data self.transform = transform def __len__(self): return len(self.data.shape[0]) def __getitem__(self, idx): item = self.data[idx] item = self.transform(item) return item transform = transforms.Compose([ transforms.ToPILImage(), transforms.RandomHorizontalFlip(), transforms.ToTensor() ]) x = torch.rand(8, 1, 2, 2) print(x) dataset = experimental_dataset(x,transform) for item in dataset: print(item) 

Resultados: (Las pequeñas diferencias en los puntos flotantes se deben a la transformación de la imagen del pil y la parte posterior)

Conjunto de datos original simulado:

 tensor([[[[0.1872, 0.5518], [0.5733, 0.6593]]], [[[0.6570, 0.6487], [0.4415, 0.5883]]], [[[0.5682, 0.3294], [0.9346, 0.1243]]], [[[0.1829, 0.5607], [0.3661, 0.6277]]], [[[0.1201, 0.1574], [0.4224, 0.6146]]], [[[0.9301, 0.3369], [0.9210, 0.9616]]], [[[0.8567, 0.2297], [0.1789, 0.8954]]], [[[0.0068, 0.8932], [0.9971, 0.3548]]]]) 

conjunto de datos transformado:

 tensor([[[0.1843, 0.5490], [0.5725, 0.6588]]]) tensor([[[0.6549, 0.6471], [0.4392, 0.5882]]]) tensor([[[0.5647, 0.3255], [0.9333, 0.1216]]]) tensor([[[0.5569, 0.1804], [0.6275, 0.3647]]]) tensor([[[0.1569, 0.1176], [0.6118, 0.4196]]]) tensor([[[0.9294, 0.3333], [0.9176, 0.9608]]]) tensor([[[0.8549, 0.2275], [0.1765, 0.8941]]]) tensor([[[0.8902, 0.0039], [0.3529, 0.9961]]])