Я хотел бы добавить обратимый шум в набор данных MNIST для некоторых экспериментов.
Вот что я пытаюсь сделать:
import torchvision.transforms as transforms
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
from PIL import Image
import torchvision
def display_img(pixels, label = None):
plt.imshow(pixels, cmap = "gray")
if label:
plt.title("Label: %d" % label)
plt.axis("off")
plt.show()
class NoisyMNIST(torchvision.datasets.MNIST):
def __init__(self, root, train=True, transform=None, target_transform=None, download=False):
super(NoisyMNIST, self).__init__(root, train=train, transform=transform, target_transform=target_transform, download=download)
def __getitem__(self, index):
img, target = self.data[index], self.targets[index]
img = Image.fromarray(img.numpy(), mode = "L")
if self.transform is not None:
img = self.transform(img)
# add the noise
noise_level = 0.3
noise = self.generate_safe_random_tensor(img) * noise_level
noisy_img = img + noise
return noisy_img, noise, img, target
def generate_safe_random_tensor(self, img):
"""generates random noise for an image but limits the pixel values between -1 and 1"""
min_values = torch.clamp(-1 - img, max=0)
max_values = torch.clamp(1 - img, min=0)
return torch.rand(img.shape) * (max_values - min_values) + min_values
# Define transformations to apply to the data
transform = transforms.Compose([
transforms.ToTensor(), # Convert images to tensors
transforms.Normalize((0.1307,), (0.3081,)),
])
train_dataset = NoisyMNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = NoisyMNIST(root='./data', train=False, download=True, transform=transform)
np_noise = train_dataset[img_id][1]
np_data = train_dataset[img_id][0]
display_img(np_data_sub_noise, 4)
В идеале это дало бы мне обычный набор данных MNIST вместе с зашумленными изображениями MNIST и коллекцией добавленного шума. Учитывая это, я предполагал, что смогу вычесть шум из зашумленного изображения и вернуться к исходному изображению, но мои операции с изображением необратимы.
Будем очень признательны за любые указатели или фрагменты кода. Ниже приведены изображения, которые я сейчас получаю с помощью своего кода:
Исходное изображение:
С добавлением шума:
И с вычетом шума для изображения с шумом:
Не сохраняйте созданный вами шум.
Сохраните шум, который отличает чистый объект от шумного объекта. Эти значения вы можете смело вычесть.
Когда вы применяете шум к изображению, состоящему из целых чисел, вы получаете либо целочисленное переполнение/недополнение/зацикливание (200 + 200 = 400 = 144, мод. 256), либо насыщенность (200 + 200 = 255, обрезано). Это источник различий, которые вы видите.
«Эффективный» шум, который вы добавили (и вычислили путем вычитания), будет выглядеть странно. Если исходное изображение яркое, значения шума не могут быть очень положительными. В темных регионах шум не может быть очень негативным.
Возможно, вам захочется работать с числами, которые не обрезаны/насыщены. Поплавки — лучший кандидат для этого.
Также рассмотрите гамма-сжатие. Ваша сеть может узнать, что вы добавили синтетический шум. Он мог бы научиться отличать изображения с реальным шумом от изображений с искусственным шумом. (Предполагаемый гауссов) шум на реальных изображениях гамма-сжимается вместе с «сигналом». Если вы добавите (гауссов) шум к гамма-сжатому изображению, то в линейном пространстве шум перестанет быть гауссовским.
Помните, что сжатие изображений с потерями происходит с потерями. Поскольку вас, похоже, волнуют точные значения пикселей, вам следует использовать только сжатие без потерь.
Отличный ответ. Цените, что вы потратили время на объяснение подводных камней вместо того, чтобы просто предоставить работающий код. Сейчас я изменю свой код. Ваше здоровье!
Я бы предоставил некоторый код, если бы был достаточно знаком с torchvision: P Я судил о ситуации по картинкам. Ситуация происходит при обработке изображений в целом.
Если вы можете хранить шум, почему бы не сохранить оригинальные изображения? Или какой-то указатель на исходное изображение, хранящееся где-то.