Объект «GoogLeNet» не имеет атрибута «функции» - PullRequest
0 голосов
/ 03 октября 2019

Я пытаюсь использовать этот модуль (https://github.com/utkuozbulak/pytorch-cnn-visualizations), чтобы визуализировать то, на что смотрит сеть в моих изображениях, и я немного отредактировал его в соответствии со своими потребностями. Однако я получаю сообщение об ошибке и не могучтобы решить эту проблему. (AttributeError: у объекта 'GoogLeNet' нет атрибута 'features')

Изначально модуль использует сценарий misc_functions.py для обработки изображений (получить RGB, преобразовать в оттенки серого, изменить размер и т. д.). ), но поскольку сеть, которую я использовал, уже сделала это, я немного отредактировал модуль, чтобы он не использовал эти функции.

Ниже вы можете найти код, который я пытаюсь использовать, исеть, которую я использовал для обучения

"""
Created on Thu Oct 26 11:19:58 2017

@author: Utku Ozbulak - github.com/utkuozbulak
"""
import os
import time
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.optim as optim
from torch import nn
import torchvision
from torch.utils.data import DataLoader, random_split
from torchvision.datasets import ImageFolder
from torchvision import transforms
from torchvision import models
from PIL import Image

from misc_functions import save_gradient_images

class VanillaBackprop():
    """
        Produces gradients generated with vanilla back propagation from the image
    """
    def __init__(self, model):
        self.model = model
        self.gradients = None
        # Put model in evaluation mode
        self.model.eval()
        # Hook the first layer to get the gradient
        self.hook_layers()

    def hook_layers(self):
        def hook_function(module, grad_in, grad_out):
            self.gradients = grad_in[0]

        # Register hook to the first layer
        first_layer = list(self.model.features._modules.items())[0][1]
        first_layer.register_backward_hook(hook_function)

    def generate_gradients(self, input_image, target_class):
        # Forward
        model_output = self.model(input_image)
        # Zero grads
        self.model.zero_grad()
        # Target for backprop
        one_hot_output = torch.FloatTensor(1, model_output.size()[-1]).zero_()
        one_hot_output[0][target_class] = 1
        # Backward pass
        model_output.backward(gradient=one_hot_output)
        # Convert Pytorch variable to numpy array
        # [0] to get rid of the first channel (1,3,224,224)
        gradients_as_arr = self.gradients.data.numpy()[0]
        return gradients_as_arr

#Use simple pre-trained ResNet 
net = models.googlenet(pretrained=True)

#manually replace last layer for different num_classes (necessary for pretrained models)

net.fc = torch.nn.Linear(net.fc.in_features, 4)

#to gpu
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net = net.to(device)
net.load_state_dict(torch.load("/home/serce/scratch/titan_googlenet_epoch_100.pt")["model_state_dict"])
net.eval()

# dataLoader with transforms

tr = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    transforms.ToTensor()
])

ds = ImageFolder('/scratch/serce/chromatin_texture/dna_sir160-163_128/sted/', transform=tr)

def get_example_params(example_index):
    """
        Gets used variables for almost all visualizations, like the image, model etc.

    Args:
        example_index (int): Image id to use from examples

    returns:
        original_image (numpy arr): Original image read from the file
        prep_img (numpy_arr): Processed image
        target_class (int): Target class for the image
        file_name_to_export (string): File name to export the visualizations
        pretrained_model(Pytorch model): Model to use for the operations
    """
    # Pick one of the examples
    img_path = ds[example_index][0]
    target_class = ds[example_index][1]
    file_name_to_export = "example{}".format(example_index)
    # Read image
    original_image = img_path
    # Process image
    prep_img = original_image
    # Define model
    pretrained_model = net
    return (original_image,
            prep_img,
            target_class,
            file_name_to_export,
            pretrained_model)



if __name__ == '__main__':
    # Get params
    target_example = 0 
    (original_image, prep_img, target_class, file_name_to_export, pretrained_model) =\
        get_example_params(target_example)
    # Vanilla backprop
    VBP = VanillaBackprop(pretrained_model)
    # Generate gradients
    vanilla_grads = VBP.generate_gradients(prep_img, target_class)
    # Save colored gradients
    save_gradient_images(vanilla_grads, file_name_to_export + '_Vanilla_BP_color')
    # Convert to grayscale
    grayscale_vanilla_grads = vanilla_grads
    # Save grayscale gradients
    save_gradient_images(grayscale_vanilla_grads, file_name_to_export + '_Vanilla_BP_gray')
    print('Vanilla backprop completed')

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

1 Ответ

0 голосов
/ 04 октября 2019

Я проверил исходный код GoogleNet , предоставленный torchvision.models. У него нет атрибута с именем features. Я полагаю, вы находите VGG , который имеет features атрибутов. Если вы хотите извлечь функции, извлеченные из GoogleNet, вы можете написать оболочку.

Быстрый пример.

import torch
import torch.nn as nn
import torchvision.models as models

class FeatureExtractor(nn.Module):
    def __init__(self):
        super(FeatureExtractor, self).__init__()
        self.net = models.googlenet(pretrained=True)
        # If you treat GooLeNet as a fixed feature extractor, disable the gradients and save some memory
        for p in self.net.parameters():
            p.requires_grad = False
        # Define which layers you are going to extract
        self.features = nn.Sequential(*list(self.net.children())[:4])

    def forward(self, x):
        return self.features(x)

if __name__ == "__main__":
    fe = FeatureExtractor()
    noise = torch.randn(1, 3, 224, 224)
    feat = fe(noise)
    #print(feat)

...