| |
| import torch |
| import torch.nn as nn |
| from torchvision.models import densenet121, DenseNet121_Weights |
|
|
| |
| DISEASE_LIST = [ |
| 'Atelectasis', 'Cardiomegaly', 'Consolidation', 'Edema', 'Effusion', |
| 'Emphysema', 'Fibrosis', 'Hernia', 'Infiltration', 'Mass', |
| 'Nodule', 'Pleural_Thickening', 'Pneumonia', 'Pneumothorax' |
| ] |
|
|
| |
| class CheXNet(nn.Module): |
| def __init__(self, num_classes=14): |
| super().__init__() |
| base_model = densenet121(weights=DenseNet121_Weights.IMAGENET1K_V1) |
| self.features = base_model.features |
| self.classifier = nn.Linear(base_model.classifier.in_features, num_classes) |
|
|
| def forward(self, x): |
| x = self.features(x) |
| x = nn.functional.adaptive_avg_pool2d(x, (1, 1)) |
| x = torch.flatten(x, 1) |
| return self.classifier(x) |
|
|
|
|
|
|
| from huggingface_hub import hf_hub_download |
| def load_model(device): |
| model_path = hf_hub_download(repo_id="cfgpp/danny_net", filename="dannynet.pth") |
| |
| |
| model = CheXNet(num_classes=14) |
| |
| |
| state_dict = torch.load(model_path, map_location=device) |
| model.load_state_dict(state_dict) |
| |
| model.to(device) |
| model.eval() |
| return model |
|
|
|
|
|
|
|
|
| def predict(model, img_tensor, device): |
| with torch.no_grad(): |
| output = model(img_tensor.unsqueeze(0).to(device)) |
| probs = torch.sigmoid(output[0]).cpu().numpy() |
| |
| |
| sorted_probs = sorted(zip(DISEASE_LIST, probs), key=lambda x: x[1], reverse=True) |
| return dict(sorted_probs) |
|
|
|
|
| import cv2 |
| import numpy as np |
| import torch |
|
|
| def generate_gradcam(model, input_tensor, target_class, device): |
| features = [] |
| gradients = [] |
|
|
| def forward_hook(module, input, output): |
| features.append(output.detach()) |
|
|
| def backward_hook(module, grad_input, grad_output): |
| gradients.append(grad_output[0].detach()) |
|
|
| last_conv_layer = model.features[-1] |
| forward_handle = last_conv_layer.register_forward_hook(forward_hook) |
| backward_handle = last_conv_layer.register_backward_hook(backward_hook) |
|
|
| model.zero_grad() |
| output = model(input_tensor.unsqueeze(0).to(device)) |
| class_score = output[0][target_class] |
| class_score.backward() |
|
|
| grads = gradients[0] |
| fmap = features[0] |
|
|
| weights = grads.mean(dim=[2, 3], keepdim=True) |
| cam = (weights * fmap).sum(dim=1).squeeze() |
| cam = torch.relu(cam).cpu().numpy() |
|
|
| cam = cam - cam.min() |
| cam = cam / cam.max() |
| cam = cv2.resize(cam, (224, 224)) |
|
|
| forward_handle.remove() |
| backward_handle.remove() |
|
|
| return cam |
|
|
|
|
|
|
|
|
|
|
|
|