Ошибка при запуске Convolutional Autoencoder RuntimeError: элемент 0 тензоров не требует grad и не имеет grad_fn - PullRequest
0 голосов
/ 03 ноября 2018

Я нуб и создаю модель в PyTorch впервые. Я пытаюсь создать сверточный автоэнкодер и получаю сообщение об ошибке во время работы модели. Код, который я использую:

class MyDataset(Dataset):
    def __init__(self, image_paths, target_paths, train=True):
        self.image_paths = image_paths
        self.target_paths = target_paths

    def transform(self, image, target):
        # Transform to tensor
        resize = transforms.Resize(size=(2350,1650))
        image = resize(image)
        target = resize(target)
        grayscale = transforms.Grayscale(1)
        image = grayscale(image)
        target = grayscale(target)
        image = TF.to_tensor(image)
        target = TF.to_tensor(target)
        return image, target

    def __getitem__(self, index):
        image = Image.open(self.image_paths[index])
        target = Image.open(self.target_paths[index])
        x, y = self.transform(image, target)
        return x, y

    def __len__(self):
        return len(self.image_paths)

traindata = MyDataset(image_paths=train_data, target_paths=target_data, train=True)
testdata = MyDataset(image_paths=test_data, target_paths=None, train=False)

train_loader = DataLoader(traindata, batch_size=1, shuffle=True, num_workers=4)
test_loader = DataLoader(testdata, batch_size=1, shuffle=False, num_workers=4)

class ConvolutionalAutoEncoder(nn.Module):
    def __init__(self):
        super(ConvolutionalAutoEncoder, self).__init__()
        self.encoder_block1 = nn.Sequential(
            nn.Conv2d(1, 64, 3, stride=1, padding=1),
            nn.ReLU(True),
            nn.Conv2d(64, 64, 3, stride=1, padding=1),
            nn.ReLU(True)
        )
        self.decoder_block1 = nn.Sequential(   
            nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1),
            nn.ReLU(True),
            nn.ConvTranspose2d(64, 64, 3, stride=1, padding=1),
            nn.ReLU(True)
         )
        self.decoder_block0 = nn.Sequential(  
            nn.ConvTranspose2d(64, 1, 3, stride=1, padding=1),
            nn.Sigmoid()
        )
    def forward(self, x):
        x1 = self.encoder_block1(x)
        y1 = self.decoder_block1(x1)
        y0 = self.decoder_block0(y1)
        return x

device = torch.device("cuda:2" if torch.cuda.is_available() else "cpu")
print(device)

model = ConvolutionalAutoEncoder().to(device)
# Loss and optimizer
learning_rate = 0.001
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

params = list(model.parameters())
print(len(params))
print(params[0].size())  # conv1's .weight

num_epochs = 30
total_step = len(train_loader)
for epoch in range(num_epochs):
    for batch_idx, data in enumerate(train_loader):
        inp, targ = data
        inp = inp.to(device)
        targ = targ.to(device)

        output = model(inp)
        loss = criterion(output, targ)

        model.zero_grad()
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()

        if (batch_idx+1) % 10 == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' 
                   .format(epoch+1, num_epochs, i+1, total_step, loss.item()))

Полная ошибка, которую я получаю:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-17-28fa0c94d845> in <module>
     13 
     14         model.zero_grad()
---> 15         loss.backward()
     16         optimizer.step()
     17 

~/anaconda3/envs/gautam_new/lib/python3.6/site-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)
     91                 products. Defaults to ``False``.
     92         """
---> 93         torch.autograd.backward(self, gradient, retain_graph, create_graph)
     94 
     95     def register_hook(self, hook):

~/anaconda3/envs/gautam_new/lib/python3.6/site-packages/torch/autograd/__init__.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)
     88     Variable._execution_engine.run_backward(
     89         tensors, grad_tensors, retain_graph, create_graph,
---> 90         allow_unreachable=True)  # allow_unreachable flag
     91 
     92 

RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

Пожалуйста, помогите. Кроме того, если возможно, также совет о том, как я могу сделать мою модель глубже. Я продолжаю получать ошибку CUDA из памяти.

Спасибо.

1 Ответ

0 голосов
/ 03 ноября 2018

Я не могу проверить вашу модель, но, учитывая сообщение об ошибке, имеет смысл, что причина вашей проблемы заключается в возвращаемом значении вашего forward.

В настоящее время вы возвращаете x, который является вашим фактическим входом , а не выходом :

def forward(self, x):
    x1 = self.encoder_block1(x)
    y1 = self.decoder_block1(x1)
    y0 = self.decoder_block0(y1)
    return x

Таким образом, чтобы вернуть вывод , вы можете изменить форму возвращаемого значения x на y0:

def forward(self, x):
    x1 = self.encoder_block1(x)
    y1 = self.decoder_block1(x1)
    y0 = self.decoder_block0(y1)
    return y0


О памяти:

Пожалуйста, не ставьте слишком много вопросов в одном вопросе. Представьте, что у вас есть три совершенно разные проблемы в одном вопросе, и есть три человека, каждый из которых может решить одну из ваших проблем, и у вас может получиться без ответа .
Поскольку ни один из них не может дать вам полный ответ на все эти проблемы.
Но если вы разделите свои проблемы на три вопроса, вы можете получить только три ответа, решая все ваши проблемы. Во многих случаях это также может улучшить вопрос, потому что можно быть более конкретным для проблемы, не написав целый роман в вопросе.
Конечно, если ваши проблемы очень связаны, вы можете поместить их в один вопрос, но это не Кажется, здесь дело не в этом.

Я полагаю, что у вашей forward функции все еще есть небольшой побочный эффект, приводящий к проблеме с памятью (дикое предположение - совсем не уверен в этом). Так что, если вам повезет, это может решить вашу проблему с памятью, но если нет, то вам определенно следует открыть новый вопрос об этом.

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