ошибка pytorch 'int' object has no attribute 'backward?

        import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim

    from PIL import Image
    import matplotlib.pyplot as plt

    import torchvision.transforms as transforms
    from torchvision.models import vgg19, VGG19_Weights

    import copy
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    torch.set_default_device(device)
    # Какого размера изображение мы хотим обрабатывать
    Insize = 256 if torch.cuda.is_available() else 128 #Если нет GPU делаем изображение поменьше

    loader = transforms.Compose([
        transforms.Resize(Insize), #маштабируем
        transforms.CenterCrop(Insize), #обрезаем края
        transforms.ToTensor()]) # преобразуем в нужный класс

    def image_loader(image_name):

        #загрузим и преобразуем картинку
        image = Image.open(image_name).convert('RGB')
        image = loader(image).unsqueeze(0)
        return image.to(device, torch.float)

    style_img = image_loader("Screenshot_3.png")
    content_img = image_loader("Screenshot_17.png")

    assert style_img.size() == content_img.size()

    unloader = transforms.ToPILImage()

    plt.ion()

    def imshow(tensor, title=None):
        image = tensor.cpu().clone()
        image = image.squeeze(0)
        image = unloader(image)
        plt.imshow(image)

        if title is not None:
            plt.title(title)
        plt.pause(0.001)

    plt.figure()
    imshow(style_img, title='Изображение"Стиль"')

    plt.figure()
    imshow(content_img, title='Изображение"Контент"')

    class ContentLoss(nn.Module):

        def __init__(self, target,):
            super(ContentLoss, self).__init__()
            self.target = target.detach()

        def forward(self, input):
            self.loss = F.mse_loss(input, self.target)
            return input

    def gram_matrix(input):
        a, b, c, d = input.size()
        features = input.view(a * b, c * d)
        G = torch.mm(features, features.t())
        return G.div(a * b * c * d)

    class StyleLoss(nn.Module):

        def __init__(self, target_feature):
            super(StyleLoss, self).__init__()
            self.target = gram_matrix(target_feature).detach()

        def forward(self, input):
            G = gram_matrix(input)
            self.loss = F.mse_loss(G, self.target)
            return input

    cnn = vgg19(weights=VGG19_Weights.DEFAULT).features.eval()

    cnn_normalization_mean = torch.tensor([0.485, 0.456, 0.406])
    cnn_normalization_std = torch.tensor([0.229, 0.224, 0.225])

    #упоковочный класс
    class Normalization(nn.Module):
        def __init__(self, mean, std):
            super(Normalization, self).__init__()
            self.mean = torch.tensor(mean).view(-1, 1, 1)
            self.std = torch.tensor(std).view(-1, 1, 1)
        def forward(self, img):
            return (img - self.mean) / self.std

    #название слоев, по которому бедем расчитывать рассхождение по контенту
    content_layers_default = ['conv_4']
    #название слоев, по которому бедем расчитывать рассхождение по стилю
    style_layers_default = ['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5']

    def get_style_model_and_losses(cnn, normalization_mean, normalization_std,
                                   style_img, content_img,
                                   content_layers=content_layers_default,
                                   style_layers=style_layers_default):

    #модуль чтобы нормализовать изображение
        normalization = Normalization(normalization_mean, normalization_std)
    #будем складывать меры расхождениялоссы) в удобные массивы
        content_losses = []
        style_losses = []
    # поскольку cnn является объектом типа nn.Sequential
    # создадим новый nn.Sequential куда мы по порядку положим
    # все модули, которые будут проводить вычисления в нейросети
        model = nn.Sequential(normalization)
        i = 0 #пройдемся по элементам в исходной нейросети и дадим им имена
        for layer in cnn.children():

           if isinstance(layer, nn.Conv2d):
                i += 1
                name = 'conv_{}'.format(i)
            elif isinstance(layer, nn.ReLU):
                name = 'relu_{}'.format(i)
                #чуть изменим параметры слоев активации
                # в исходной нейросети не работает с нашей реализацией сontent_losses и style_losses
                layer = nn.ReLU(inplace=False)
            elif isinstance(layer, nn.MaxPool2d):
                name = 'pool_{}'.format(i)
            elif isinstance(layer, nn.BatchNorm2d):
                name = 'bn_{}'.format(i)
            else:
                raise RuntimeError('Unrecognized layer: {}'.format(layer.__class__.__name__))
    #добавляем очередной модуль в нашу Sequential-модель
            model.add_module(name, layer)

        if name in content_layers:
            #а если к последнему слою нужно пристыковать контент-лосс, сделаем это
            target = model(content_img).detach()
            content_loss = ContentLoss(target)
            model.add_module("content_loss_{}".format(i), content_loss)
            content_losses.append(content_loss)

        if name in style_layers:
            #а если имя слоя в списке стиль-лоссов, добавим после  ннего соответсвующий лосс
            target_feature = model(style_img).detach()
            style_loss = StyleLoss(target_feature)
            model.add_module("style_loss_{}".format(i), style_loss)
            style_losses.append(style_loss)
    #все слои которые идут после последнего добавленного контент лосса или стиль лосса
    # нам будут не нужны, их можно отбросить
        for i in range(len(model) - 1, -1, -1):
            if isinstance(model[i], ContentLoss) or isinstance(model[i], StyleLoss):
                break
        model = model[:(i + 1)]
        return model, style_losses, content_losses

    #чтобы использовать исходную картинку, раскоментируйте:
    input_img = content_img.clone()

    #чтобы использовать шум
    #input_img = torch.randn(content_img.data.size())
    # add the original input image to the figure:\n",
    plt.figure()
    imshow(input_img, title='Входное изображение')


    def get_input_optimizer(input_img):
        optimizer = optim.LBFGS([input_img])
        return optimizer

    def run_style_transfer(cnn, normalization_mean, normalization_std,
                          content_img, style_img, input_img, num_steps=300,
                          style_weight=10000, content_weight=100):
        print('Построение модели переноса стиля')
        model, style_losses, content_losses = get_style_model_and_losses(cnn,
                                                                        normalization_mean, normalization_std, style_img, content_img)

        input_img.requires_grad_(True)
        model.eval()
        model.requires_grad_(False)
        optimizer = get_input_optimizer(input_img)

        print('Оптимизируем картинку')
        run = [0]
        while run[0] <= num_steps:

            def closure():

                # скорректируем значение сходного изображения",
                with torch.no_grad():
                    input_img.clamp_(0, 1)

                optimizer.zero_grad() # обнуляем градиенты
               model(input_img) # отправляем картинку в модель

                # посчитаем расхождение изображений по стилю и содержимому
                style_score = 0
                content_score = 0

                for sl in style_losses: style_score += sl.loss
                for cl in content_losses: content_score += cl.loss

                style_score *= style_weight # домножаем каждую компоновку лосса на заданный вес
                content_score *= content_weight

                loss = style_score + content_score
                # обратное значение распространения ошибки
                loss.backward()

                run[0] += 1
                if run[0] % 50 == 0:
                    print("run {}:".format(run))
                    print('Style Loss : {:4f} Content Loss: {:4f}'.format(
                        style_score.item(), content_score.item()))
                    print()
                return style_score + content_score

            optimizer.step(closure)

    # ВОЗРАЩАЕМ ИЗОБРАЖЕНИЕ
        with torch.no_grad():
            input_img.clamp_(0, 1)
        return input_img

    output = run_style_transfer(cnn,
                        cnn_normalization_mean, cnn_normalization_std,
                        content_img, style_img, input_img)

    plt.figure()
    imshow(output, title = 'Полученное изображение')
    #sphinx_gallery_thumbnail_number = 4
    plt.ioff()
    plt.show()'''

Ответы (0 шт):