def main(args): # Load the synset words file_name = 'synset_words.txt' classes = list() with open(file_name) as class_file: for line in class_file: classes.append(line.strip().split(' ', 1)[1].split(', ', 1)[0].replace( ' ', '_')) print('Loading a model...') model = torchvision.models.resnet152(pretrained=True) transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) print('\nGrad-CAM') gcam = GradCAM(model=model, target_layer='layer4.2', n_class=1000, cuda=args.cuda) gcam.load_image(args.image, transform) gcam.forward() for i in range(0, 5): gcam.backward(idx=gcam.idx[i]) cls_name = classes[gcam.idx[i]] output = gcam.generate() print('\t{:.5f}\t{}'.format(gcam.prob[i], cls_name)) gcam.save('results/{}_gcam.png'.format(cls_name), output) print('\nBackpropagation') bp = BackPropagation(model=model, target_layer='conv1', n_class=1000, cuda=args.cuda) bp.load_image(args.image, transform) bp.forward() for i in range(0, 5): bp.backward(idx=bp.idx[i]) cls_name = classes[bp.idx[i]] output = bp.generate() print('\t{:.5f}\t{}'.format(bp.prob[i], cls_name)) bp.save('results/{}_bp.png'.format(cls_name), output) print('\nGuided Backpropagation') gbp = GuidedBackPropagation(model=model, target_layer='conv1', n_class=1000, cuda=args.cuda) gbp.load_image(args.image, transform) gbp.forward() for i in range(0, 5): cls_idx = gcam.idx[i] cls_name = classes[cls_idx] gcam.backward(idx=cls_idx) output_gcam = gcam.generate() gbp.backward(idx=cls_idx) output_gbp = gbp.generate() output_gcam -= output_gcam.min() output_gcam /= output_gcam.max() output_gcam = cv2.resize(output_gcam, (224, 224)) output_gcam = cv2.cvtColor(output_gcam, cv2.COLOR_GRAY2BGR) output = output_gbp * output_gcam print('\t{:.5f}\t{}'.format(gbp.prob[i], cls_name)) gbp.save('results/{}_gbp.png'.format(cls_name), output_gbp) gbp.save('results/{}_ggcam.png'.format(cls_name), output)
def gradCAM(): # Chap 2 : Train Network print('\n[Chapter 2] : Operate gradCAM with trained network') # Phase 1 : Model Upload print('\n[Phase 1] : Model Weight Upload') use_gpu = torch.cuda.is_available() # upload labels data_dir = cf.test_dir trainset_dir = cf.data_base.split("/")[-1] + os.sep dsets = datasets.ImageFolder(data_dir, None) H = datasets.ImageFolder(cf.aug_base + '/train/') dset_classes = H.classes def softmax(x): return np.exp(x) / np.sum(np.exp(x), axis=0) # return np.exp(x) / np.sum(np.exp(x), axis=1) def getNetwork(opts): if (opts.net_type == 'alexnet'): file_name = 'alexnet' elif (opts.net_type == 'vggnet'): file_name = 'vgg-%s' % (opts.depth) elif (opts.net_type == 'resnet'): file_name = 'resnet-%s' % (opts.depth) else: print('[Error]: Network should be either [alexnet / vgget / resnet]') sys.exit(1) return file_name def random_crop(image, dim): if len(image.shape): W, H, D = image.shape w, h, d = dim else: W, H = image.shape w, h = dim[0], dim[1] left, top = np.random.randint(W - w + 1), np.random.randint(H - h + 1) return image[left:left + w, top:top + h], left, top # uploading the model print("| Loading checkpoint model for grad-CAM...") assert os.path.isdir('./path'), '[Error]: No checkpoint directory found!' assert os.path.isdir('./path/' + trainset_dir), '[Error]: There is no model weight to upload!' file_name = getNetwork(opts) checkpoint = torch.load('./path/' + trainset_dir + file_name + '.t7') model = checkpoint['model'] if use_gpu: model.cuda() cudnn.benchmark = True model.eval() sample_input = Variable(torch.randn(1, 3, 224, 224), volatile=False) if use_gpu: sampe_input = sample_input.cuda() def is_image(f): return f.endswith(".png") or f.endswith(".jpg") test_transform = transforms.Compose([ transforms.Resize(224), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(cf.mean, cf.std) ]) """ #@ Code for inference test img = Image.open(cf.image_path) if test_transform is not None: img = test_transform(img) inputs = img inputs = Variable(inputs, volatile=False, requires_grad=True) if use_gpu: inputs = inputs.cuda() inputs = inputs.view(1, inputs.size(0), inputs.size(1), inputs.size(2)) outputs = model(inputs) softmax_res = softmax(outputs.data.cpu().numpy()[0]) index,score = max(enumerate(softmax_res), key=operator.itemgetter(1)) print('| Uploading %s' %(cf.image_path.split("/")[-1])) print('| prediction = ' + dset_classes[index]) """ # @ Code for extracting a grad-CAM region for a given class gcam = GradCAM(list(model._modules.items())[0][1], cuda=use_gpu) # model=model._modules.items()[0][1], cuda=use_gpu) gbp = GuidedBackPropagation(model=list(model._modules.items())[0][1], cuda=use_gpu) # print(dset_classes) WBC_id = 5 # BHX class print("Checking Activated Regions for " + dset_classes[WBC_id] + "...") fileList = os.listdir('./samples/') i = 1 for f in fileList: file_name = './samples/' + f print("Opening " + file_name + "...") original_image = cv2.imread(file_name) resize_ratio = 224. / min(original_image.shape[0:2]) resized = cv2.resize(original_image, (0, 0), fx=resize_ratio, fy=resize_ratio) cropped, left, top = random_crop(resized, (224, 224, 3)) print(cropped.size) if test_transform is not None: img = test_transform(Image.fromarray(cropped, mode='RGB')) # center_cropped = original_image[16:240, 16:240, :] # expand the image based on the short side inputs = img inputs = Variable(inputs, requires_grad=True) if use_gpu: inputs = inputs.cuda() inputs = inputs.view(1, inputs.size(0), inputs.size(1), inputs.size(2)) probs, idx = gcam.forward(inputs) # probs, idx = gbp.forward(inputs) # Grad-CAM gcam.backward(idx=WBC_id) if opts.depth == 18: output = gcam.generate(target_layer='layer4.1') else: output = gcam.generate(target_layer='layer4.2') # a module name to be visualized (required) # Guided Back Propagation # gbp.backward(idx=WBC_id) # feature = gbp.generate(target_layer='conv1') # Guided Grad-CAM # output = np.multiply(feature, region) gcam.save('./results/%s.png' % str(i), output, cropped) cv2.imwrite('./results/map%s.png' % str(i), cropped) for j in range(3): print('\t{:5f}\t{}\n'.format(probs[j], dset_classes[idx[j]])) i += 1 """