PyTorch Преобразование изображений с помощью gridsampler, странное поведение при оптимизации сетки - PullRequest
2 голосов
/ 03 июля 2019

Я пытаюсь получить преобразование по пикселям, чтобы подогнать одно изображение (+ фон) к результату. Фоновое изображение + Входное изображение должно быть преобразовано в желаемый результат

для достижения этой цели я использую гридсэмплер PyTorch и autograd для оптимизации сетки. Преобразованный вход будет добавлен к неизменному фону.


ToTensor = torchvision.transforms.ToTensor()
FromTensor = torchvision.transforms.ToPILImage()

backround= ToTensor(Image.open("backround.png"))
pic = ToTensor(Image.open("pic.png"))
goal = ToTensor(Image.open("goal.png"))

empty = empty.expand(1, 3, empty.size()[1], empty.size()[2])
pic = pic.expand(1, 3, pic.size()[1], pic.size()[2])
goal = goal.expand(1, 3, goal.size()[1], goal.size()[2])

def createIdentityGrid(w, h):
    grid = torch.zeros(1, w, h, 2);
    for x in range(w):
        for y in range(h):
            grid[0][x][y][1] = 2 / w * (0.5 + x) - 1
            grid[0][x][y][0] = 2 / h * (0.5 + y) - 1
    return grid

w = 256; h=256 #hardcoded imagesize

grid = createIdentityGrid(w, h)
grid.requires_grad = True

for i in range(300):
    goal_pred = torch.nn.functional.grid_sample(pic, grid)[0]
    goal_pred = (empty + 0.75 * goal_pred).clamp(min=0, max=1)
    out = goal_pred

    loss = (goal_pred - goal).pow(2).sum()
    loss.backward()

    with torch.no_grad():
        grid -= grid.grad * (1e-2)
        grid.grad.zero_()

FromTensor(out[0]).show()

это результат:

Это действительно простой пример работы с этим, но я наблюдаю странное поведение. Сетка только начинает меняться с одной стороны. Почему это так, и почему полная сетка не меняется мгновенно? Есть ли какая-то очевидная часть, которую я пропускаю?

1 Ответ

0 голосов
/ 05 июля 2019

enter image description here

from PIL import Image
import torch

ToTensor = torchvision.transforms.ToTensor()
FromTensor = torchvision.transforms.ToPILImage()

lr = 1
backround= ToTensor(Image.open(r"C:\Users\dj\Pictures\Saved Pictures\background.png"))
pic = ToTensor(Image.open(r"C:\Users\dj\Pictures\Saved Pictures\input.png"))
goal = ToTensor(Image.open(r"C:\Users\dj\Pictures\Saved Pictures\result.png"))

empty = backround.expand(1, 3, backround.size()[1], backround.size()[2])
pic = pic.expand(1, 3, pic.size()[1], pic.size()[2])
goal = goal.expand(1, 3, goal.size()[1], goal.size()[2])

def createIdentityGrid(w, h):
    grid = torch.zeros(1, w, h, 2);
    for x in range(w):
        for y in range(h):
            grid[0][x][y][1] = 2 / w * (0.5 + y) - 1
            grid[0][x][y][0] = 2 / h * (0.5 + x) - 1
    return grid

w = 256; h=256 #hardcoded imagesize

grid = createIdentityGrid(w, h)
grid.requires_grad = True

for i in range(9):
    goal_pred = torch.nn.functional.grid_sample(pic, grid, mode="bilinear")[0]
    goal_pred = F.relu(empty + 0.75 * goal_pred)
    out = goal_pred

    loss = (goal_pred - goal).pow(2).sum()
    loss.backward()

    with torch.no_grad():
        grid -= grid.grad * lr
        lr = lr/1.1 #learning rate a0-ing
        grid.grad.zero_()

FromTensor(out[0]).show()

Это действительно простой пример, но я наблюдаю странное поведение. Сетка только начинает меняться с одной стороны. Почему это так, и почему полная сетка не меняется мгновенно?

Я не знаю. Я только что повторил ваш пример, и для меня он идет снизу вверх.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...