RuntimeError: Output 0 of UnbindBackward is a view and is being modified inplace. This view is the output of a function that returns multiple views. Such functions do not allow the output views to be modified inplace. You should replace the inplace operation by an out-of-place one.
참고한 주소 링크 : https://sundryy.tistory.com/102
이미지를 저장하는 utils.save_image에서 에러가 나서, save image의 input인 이미지파일을 미리 복사해둔것으로 대체했더니 문제가 해결되었다.
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.init_size = opt.img_size // 4
self.l1 = nn.Sequential(nn.Linear(opt.latent_dim, 128*self.init_size**2))
self.conv_blocks0 = nn.Sequential(
nn.BatchNorm2d(128),
)
self.conv_blocks1 = nn.Sequential(
nn.Conv2d(128, 128, 3, stride=1, padding=1),
nn.BatchNorm2d(128, 0.8),
nn.LeakyReLU(0.2, inplace = True),
)
self.conv_blocks2 = nn.Sequential(
nn.Conv2d(128, 64, 3, stride=1, padding=1),
nn.BatchNorm2d(64, 0.8),
nn.LeakyReLU(0.2, inplace = True),
nn.Conv2d(64, opt.channels, 3, stride=1, padding=1),
nn.Tanh(),
nn.BatchNorm2d(opt.channels, affine=False)
)
def forward(self, z):
out = self.l1(z)
out = out.view(out.shape[0], 128, self.init_size, self.init_size)
img = self.conv_blocks0(out)
img = nn.functional.interpolate(img,scale_factor=2)
img = self.conv_blocks1(img)
img = nn.functional.interpolate(img,scale_factor=2)
img = self.conv_blocks2(img)
return img
generator = Generator().cuda()
teacher = torch.load(opt.teacher_dir + 'teacher').cuda()
teacher.eval()
criterion = torch.nn.CrossEntropyLoss().cuda()
teacher = nn.DataParallel(teacher)
generator = nn.DataParallel(generator)
def kdloss(y, teacher_scores):
p = F.log_softmax(y, dim=1)
q = F.softmax(teacher_scores, dim=1)
l_kl = F.kl_div(p, q, size_average=False) / y.shape[0]
return l_kl
if opt.dataset == 'MNIST':
# Configure data loader
net = LeNet5Half().cuda()
net = nn.DataParallel(net)
data_test = MNIST(opt.data,
train=False,
transform=transforms.Compose([
transforms.Resize((32, 32)),
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
]))
data_test_loader = DataLoader(data_test, batch_size=64, num_workers=1, shuffle=False)
# Optimizers
optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr_G)
optimizer_S = torch.optim.Adam(net.parameters(), lr=opt.lr_S)
if opt.dataset != 'MNIST':
transform_test = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])
if opt.dataset == 'cifar10':
net = resnet.ResNet18().cuda()
net = nn.DataParallel(net)
data_test = CIFAR10(opt.data,
train=False,
transform=transform_test)
if opt.dataset == 'cifar100':
net = resnet.ResNet18(num_classes=100).cuda()
net = nn.DataParallel(net)
data_test = CIFAR100(opt.data,
train=False,
transform=transform_test)
data_test_loader = DataLoader(data_test, batch_size=opt.batch_size, num_workers=0)
# Optimizers
optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr_G)
optimizer_S = torch.optim.SGD(net.parameters(), lr=opt.lr_S, momentum=0.9, weight_decay=5e-4)
def adjust_learning_rate(optimizer, epoch, learing_rate):
if epoch < 800:
lr = learing_rate
elif epoch < 1600:
lr = 0.1*learing_rate
else:
lr = 0.01*learing_rate
for param_group in optimizer.param_groups:
param_group['lr'] = lr
# ----------
# Training
# ----------
batches_done = 0
for epoch in range(opt.n_epochs):
total_correct = 0
avg_loss = 0.0
if opt.dataset != 'MNIST':
adjust_learning_rate(optimizer_S, epoch, opt.lr_S)
for i in range(120):
net.train()
z = Variable(torch.randn(opt.batch_size, opt.latent_dim)).cuda()
optimizer_G.zero_grad()
optimizer_S.zero_grad()
gen_imgs = generator(z) # batch x 3 x 32 x 32( B, C, H, W)
### ### ### ### ### ### ### ### ### ### 이미지 저장 ### ### ### ### ### ### ### ### ### ###
######### 에러나서 추가한 부분
gen_imgs_copy = gen_imgs.clone().detach()
# True - True
if i%10 ==0:
####################### 에러 나는 부분 ###########
utils.save_image( gen_imgs_copy,
f"{i}_generator.png",
nrow=10,
normalize=True,
scale_each=True)
# True - False
utils.save_image( gen_imgs_copy,
f"{i}_generator.png",
nrow=10,
normalize=True,
scale_each=False)
# False - True
utils.save_image( gen_imgs_copy,
f"{i}_generator.png",
nrow=10,
normalize =False,
scale_each=True)
# False - False
utils.save_image( gen_imgs_copy,
f"{i}_generator.png",
nrow=10,
normalize=False,
scale_each=False)
print(f"{i}_번째 이미지 저장 완료")
### ### ### ### ### ### ### ### ### ### 이미지 저장 ### ### ### ### ### ### ### ### ### ###
outputs_T, features_T = teacher(gen_imgs, out_feature=True)
pred = outputs_T.data.max(1)[1]
loss_activation = -features_T.abs().mean()
loss_one_hot = criterion(outputs_T,pred)
softmax_o_T = torch.nn.functional.softmax(outputs_T, dim = 1).mean(dim = 0)
loss_information_entropy = (softmax_o_T * torch.log10(softmax_o_T)).sum()
loss = loss_one_hot * opt.oh + loss_information_entropy * opt.ie + loss_activation * opt.a
loss_kd = kdloss(net(gen_imgs.detach()), outputs_T.detach())
loss += loss_kd
loss.backward()
optimizer_G.step()
optimizer_S.step()
if i == 1:
print ("[Epoch %d/%d] [loss_oh: %f] [loss_ie: %f] [loss_a: %f] [loss_kd: %f]" % (epoch, opt.n_epochs,loss_one_hot.item(), loss_information_entropy.item(), loss_activation.item(), loss_kd.item()))
with torch.no_grad():
for i, (images, labels) in enumerate(data_test_loader):
images = images.cuda()
labels = labels.cuda()
net.eval()
output = net(images)
avg_loss += criterion(output, labels).sum()
pred = output.data.max(1)[1]
total_correct += pred.eq(labels.data.view_as(pred)).sum()
avg_loss /= len(data_test)
print('Test Avg. Loss: %f, Accuracy: %f' % (avg_loss.data.item(), float(total_correct) / len(data_test)))
accr = round(float(total_correct) / len(data_test), 4)
if accr > accr_best:
torch.save(net,opt.output_dir + 'student')
accr_best = accr'Python > Error' 카테고리의 다른 글
| gpu 종류 확인하는 명령어 (0) | 2024.02.27 |
|---|---|
| 파일이 존재하는데 'No such file or directory' error가 날 때 (0) | 2023.10.13 |
| [error] Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same (0) | 2023.06.16 |