Me encuentro con un error de operación en el lugar cuando intento indexar una variable de hoja para actualizar los gradientes con la función de reducción personalizada. No puedo evitarlo. ¡Cualquier ayuda es muy apreciada!
import torch.nn as nn import torch import numpy as np from torch.autograd import Variable, Function # hyper parameters batch_size = 100 # batch size of images ld = 0.2 # sparse penalty lr = 0.1 # learning rate x = Variable(torch.from_numpy(np.random.normal(0,1,(batch_size,10,10))), requires_grad=False) # original # depends on size of the dictionary, number of atoms. D = Variable(torch.from_numpy(np.random.normal(0,1,(500,10,10))), requires_grad=True) # hx sparse representation ht = Variable(torch.from_numpy(np.random.normal(0,1,(batch_size,500,1,1))), requires_grad=True) # Dictionary loss function loss = nn.MSELoss() # customized shrink function to update gradient shrink_ht = lambda x: torch.stack([torch.sign(i)*torch.max(torch.abs(i)-lr*ld,0)[0] for i in x]) ### sparse reprsentation optimizer_ht single image. optimizer_ht = torch.optim.SGD([ht], lr=lr, momentum=0.9) # optimizer for sparse representation ## update for the batch for idx in range(len(x)): optimizer_ht.zero_grad() # clear up gradients loss_ht = 0.5*torch.norm((x[idx]-(D*ht[idx]).sum(dim=0)),p=2)**2 loss_ht.backward() # back propogation and calculate gradients optimizer_ht.step() # update parameters with gradients ht[idx] = shrink_ht(ht[idx]) # customized shrink function. RuntimeError Traceback (most recent call last) in () 15 loss_ht.backward() # back propogation and calculate gradients 16 optimizer_ht.step() # update parameters with gradients —> 17 ht[idx] = shrink_ht(ht[idx]) # customized shrink function. 18 19 /home/miniconda3/lib/python3.6/site-packages/torch/autograd/variable.py in setitem(self, key, value) 85 return MaskedFill.apply(self, key, value, True) 86 else: —> 87 return SetItem.apply(self, key, value) 88 89 def deepcopy(self, memo): RuntimeError: a leaf Variable that requires grad has been used in an in-place operation.Específicamente, esta línea de código a continuación parece dar error ya que indexa y actualiza la variable hoja al mismo tiempo.
ht[idx] = shrink_ht(ht[idx]) # customized shrink function.Gracias.
SW
Acabo de encontrar: para actualizar la variable, debe ser ht.data[idx] en lugar de ht[idx] . Podemos usar .data para acceder al tensor directamente.
El problema proviene del hecho de que ht requiere grad:
ht = Variable(torch.from_numpy(np.random.normal(0,1,(batch_size,500,1,1))), requires_grad=True)Y con las variables que requieren graduados, pytorch no le permite asignar valores a (porciones) de ellos. no puedes hacer:
ht[idx] = some_tensor Eso significa que deberá encontrar otra forma de hacer su función de reducción personalizada utilizando funciones integradas de pytorch como squeeze , unsqueeze , etc.
Otra opción es asignar sus rebanadas de shrink_ht(ht[idx]) a otra variable o tensor que no requiera graduaciones.
Usar ht.data[idx] está bien aquí, pero la nueva convención es usar explícitamente torch.no_grad() , como:
with torch.no_grad(): ht[idx] = shrink_ht(ht[idx]) Tenga en cuenta que no hay gradiente para esta operación en el lugar. En otras palabras, los gradientes solo retroceden a los valores shrunk de ht , no a los valores no unshrunk de ht .