Spaces:
Sleeping
Sleeping
datnguyentien204
commited on
Commit
•
fa7fa68
1
Parent(s):
5a339d7
Upload 171 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +4 -0
- Database/student_attendance.db +0 -0
- Database/test_db.py +24 -0
- chestXray14/__init__.py +7 -0
- chestXray14/__pycache__/__init__.cpython-310.pyc +0 -0
- chestXray14/__pycache__/chestXray_utils.cpython-310.pyc +0 -0
- chestXray14/__pycache__/chexnet.cpython-310.pyc +0 -0
- chestXray14/__pycache__/constant.cpython-310.pyc +0 -0
- chestXray14/__pycache__/heatmap.cpython-310.pyc +0 -0
- chestXray14/__pycache__/layers.cpython-310.pyc +0 -0
- chestXray14/__pycache__/test.cpython-310.pyc +0 -0
- chestXray14/__pycache__/unet.cpython-310.pyc +0 -0
- chestXray14/cam_result.png +0 -0
- chestXray14/chestXray_utils.py +35 -0
- chestXray14/chexnet.py +67 -0
- chestXray14/constant.py +58 -0
- chestXray14/heatmap.py +38 -0
- chestXray14/layers.py +104 -0
- chestXray14/models/Model.ipynb +287 -0
- chestXray14/models/__pycache__/densenet.cpython-310.pyc +0 -0
- chestXray14/models/densenet.py +71 -0
- chestXray14/models/dpn.py +52 -0
- chestXray14/models/inception.py +91 -0
- chestXray14/models/nasnet.py +73 -0
- chestXray14/models/resnet.py +57 -0
- chestXray14/models/resnext.py +48 -0
- chestXray14/models/senet.py +61 -0
- chestXray14/segment_result.png +0 -0
- chestXray14/test.py +93 -0
- chestXray14/unet.h5 +3 -0
- chestXray14/unet.py +142 -0
- faiss_index/index.faiss +0 -0
- faiss_index/index.pkl +3 -0
- image_to_3D/3d_model_requirements.txt +14 -0
- image_to_3D/__init__.py +12 -0
- image_to_3D/__pycache__/__init__.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/__init__.cpython-39.pyc +0 -0
- image_to_3D/__pycache__/attention.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/attention.cpython-39.pyc +0 -0
- image_to_3D/__pycache__/basic_transformer_block.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/image.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/isosurface.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/nerf_renderer.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/network_utils.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/rotate.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/run.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/transformer_1d.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/triplane.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/ui.cpython-310.pyc +0 -0
- image_to_3D/__pycache__/x3D_utils.cpython-310.pyc +0 -0
.gitattributes
CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
medicalDocuments/chan-doan-va-dieu-tri-benh-phoi-tac-nghen-man-tinh-copd-2018.pdf filter=lfs diff=lfs merge=lfs -text
|
37 |
+
pages/images/cam_result.png filter=lfs diff=lfs merge=lfs -text
|
38 |
+
pages/images/segment_result.png filter=lfs diff=lfs merge=lfs -text
|
39 |
+
pages/output_yolov9/temp_image.png filter=lfs diff=lfs merge=lfs -text
|
Database/student_attendance.db
ADDED
Binary file (20.5 kB). View file
|
|
Database/test_db.py
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sqlite3
|
2 |
+
|
3 |
+
# Đường dẫn đến file cơ sở dữ liệu
|
4 |
+
db_path = 'student_attendance.db'
|
5 |
+
|
6 |
+
# Kết nối tới cơ sở dữ liệu
|
7 |
+
conn = sqlite3.connect(db_path)
|
8 |
+
|
9 |
+
# Tạo con trỏ để thực hiện các truy vấn SQL
|
10 |
+
cursor = conn.cursor()
|
11 |
+
|
12 |
+
# Thực hiện truy vấn SQL, ví dụ để lấy tất cả các bảng trong cơ sở dữ liệu
|
13 |
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
14 |
+
|
15 |
+
# Lấy kết quả
|
16 |
+
tables = cursor.fetchall()
|
17 |
+
|
18 |
+
# In danh sách các bảng
|
19 |
+
print("Danh sách các bảng trong cơ sở dữ liệu:")
|
20 |
+
for table in tables:
|
21 |
+
print(table[0])
|
22 |
+
|
23 |
+
# Đóng kết nối khi không còn sử dụng
|
24 |
+
conn.close()
|
chestXray14/__init__.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from test import *
|
2 |
+
from chexnet import *
|
3 |
+
from constant import *
|
4 |
+
from heatmap import *
|
5 |
+
from unet import *
|
6 |
+
from chestXray_utils import *
|
7 |
+
from layers import *
|
chestXray14/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (279 Bytes). View file
|
|
chestXray14/__pycache__/chestXray_utils.cpython-310.pyc
ADDED
Binary file (1.4 kB). View file
|
|
chestXray14/__pycache__/chexnet.cpython-310.pyc
ADDED
Binary file (2.42 kB). View file
|
|
chestXray14/__pycache__/constant.cpython-310.pyc
ADDED
Binary file (1.62 kB). View file
|
|
chestXray14/__pycache__/heatmap.cpython-310.pyc
ADDED
Binary file (1.54 kB). View file
|
|
chestXray14/__pycache__/layers.cpython-310.pyc
ADDED
Binary file (2.84 kB). View file
|
|
chestXray14/__pycache__/test.cpython-310.pyc
ADDED
Binary file (2.61 kB). View file
|
|
chestXray14/__pycache__/unet.cpython-310.pyc
ADDED
Binary file (5.83 kB). View file
|
|
chestXray14/cam_result.png
ADDED
chestXray14/chestXray_utils.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
from skimage import color, morphology
|
4 |
+
from constant import PATH, TRAIN_CSV, VAL_CSV, TEST_CSV
|
5 |
+
|
6 |
+
def get_chestxray_from_csv():
|
7 |
+
result = []
|
8 |
+
for f in [PATH/TRAIN_CSV, PATH/VAL_CSV, PATH/TEST_CSV]:
|
9 |
+
df = pd.read_csv(f, sep=' ', header=None)
|
10 |
+
images = df.iloc[:, 0].values
|
11 |
+
labels = df.iloc[:, 1:].values
|
12 |
+
result.append((images, labels))
|
13 |
+
return result
|
14 |
+
|
15 |
+
def sigmoid_np(x):
|
16 |
+
return 1. / (1. + np.exp(-x))
|
17 |
+
|
18 |
+
def blend_segmentation(image, mask, gt_mask=None, boundary=False, alpha=1):
|
19 |
+
image = np.array(image) # Convert PIL Image to NumPy array
|
20 |
+
w, h = image.shape[1], image.shape[0]
|
21 |
+
color_mask = np.zeros((h, w, 3)) # PIL Image
|
22 |
+
if boundary: mask = morphology.dilation(mask, morphology.disk(3)) - mask
|
23 |
+
color_mask[mask==1] = [1, 0, 0] # RGB
|
24 |
+
|
25 |
+
if gt_mask is not None:
|
26 |
+
gt_boundary = morphology.dilation(gt_mask, morphology.disk(3)) - gt_mask
|
27 |
+
color_mask[gt_boundary==1] = [0, 1, 0] # RGB
|
28 |
+
|
29 |
+
image_hsv = color.rgb2hsv(image)
|
30 |
+
color_mask_hsv = color.rgb2hsv(color_mask)
|
31 |
+
|
32 |
+
image_hsv[..., 0] = color_mask_hsv[..., 0]
|
33 |
+
image_hsv[..., 1] = color_mask_hsv[..., 1] * alpha
|
34 |
+
|
35 |
+
return color.hsv2rgb(image_hsv)
|
chestXray14/chexnet.py
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch.nn as nn
|
2 |
+
import pretrainedmodels
|
3 |
+
from torchvision.models import densenet121
|
4 |
+
from layers import Flatten
|
5 |
+
import torch
|
6 |
+
import torchvision.transforms as transforms
|
7 |
+
from pathlib import Path
|
8 |
+
from constant import IMAGENET_MEAN, IMAGENET_STD
|
9 |
+
import os
|
10 |
+
import sys
|
11 |
+
|
12 |
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
13 |
+
yolov9 = os.path.join(script_dir, '..', 'chestXray14')
|
14 |
+
sys.path.append(yolov9)
|
15 |
+
|
16 |
+
class ChexNet(nn.Module):
|
17 |
+
tfm = transforms.Compose([
|
18 |
+
transforms.Resize((224, 224)),
|
19 |
+
transforms.ToTensor(),
|
20 |
+
transforms.Normalize(IMAGENET_MEAN, IMAGENET_STD)
|
21 |
+
])
|
22 |
+
|
23 |
+
def __init__(self, trained=False, model_name='20180525-222635'):
|
24 |
+
super().__init__()
|
25 |
+
# chexnet.parameters() is freezed except head
|
26 |
+
if trained:
|
27 |
+
self.load_model(model_name)
|
28 |
+
else:
|
29 |
+
self.load_pretrained()
|
30 |
+
|
31 |
+
def load_model(self, model_name):
|
32 |
+
self.backbone = densenet121(False).features
|
33 |
+
self.head = nn.Sequential(
|
34 |
+
nn.AdaptiveAvgPool2d(1),
|
35 |
+
Flatten(),
|
36 |
+
nn.Linear(1024, 14)
|
37 |
+
)
|
38 |
+
path = Path('chestX-ray-14')
|
39 |
+
state_dict = torch.load('chexnet.h5')
|
40 |
+
self.load_state_dict(state_dict)
|
41 |
+
|
42 |
+
def load_pretrained(self, torch=False):
|
43 |
+
if torch:
|
44 |
+
self.backbone = densenet121(True).features
|
45 |
+
else:
|
46 |
+
self.backbone = pretrainedmodels.__dict__['densenet121']().features
|
47 |
+
|
48 |
+
self.head = nn.Sequential(
|
49 |
+
nn.AdaptiveAvgPool2d(1),
|
50 |
+
Flatten(),
|
51 |
+
nn.Linear(1024, 14)
|
52 |
+
)
|
53 |
+
|
54 |
+
def forward(self, x):
|
55 |
+
return self.head(self.backbone(x))
|
56 |
+
|
57 |
+
def predict(self, image):
|
58 |
+
"""
|
59 |
+
input: PIL image (w, h, c)
|
60 |
+
output: prob np.array
|
61 |
+
"""
|
62 |
+
image_tensor = self.tfm(image).unsqueeze(0) # Add batch dimension
|
63 |
+
image_tensor = image_tensor.to(next(self.parameters()).device) # Move to the same device as the model
|
64 |
+
with torch.no_grad():
|
65 |
+
py = torch.sigmoid(self(image_tensor))
|
66 |
+
prob = py.cpu().numpy()[0]
|
67 |
+
return prob
|
chestXray14/constant.py
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from pathlib import Path
|
3 |
+
import numpy as np
|
4 |
+
|
5 |
+
|
6 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
7 |
+
ROOT = os.path.abspath(os.path.join(current_dir, os.path.pardir))
|
8 |
+
|
9 |
+
N_CLASSES = 14
|
10 |
+
CLASS_NAMES = ['Atelectasis', 'Cardiomegaly', 'Effusion', 'Infiltration', 'Mass', 'Nodule', 'Pneumonia',
|
11 |
+
'Pneumothorax', 'Consolidation', 'Edema', 'Emphysema',
|
12 |
+
'Fibrosis', 'Pleural Thickening', 'Hernia']
|
13 |
+
|
14 |
+
IMAGENET_MEAN = np.array([0.485, 0.456, 0.406])
|
15 |
+
IMAGENET_STD = np.array([0.229, 0.224, 0.225])
|
16 |
+
|
17 |
+
PATH = Path('/home/dattran/data/xray-thesis/chestX-ray14')
|
18 |
+
ATTENTION_DN = 'tmp/attention'
|
19 |
+
IMAGE_DN = 'images'
|
20 |
+
TRAIN_CSV = 'train.csv'
|
21 |
+
VAL_CSV = 'val.csv'
|
22 |
+
TEST_CSV = 'test.csv'
|
23 |
+
|
24 |
+
"""
|
25 |
+
Below may not need any more
|
26 |
+
"""
|
27 |
+
# EPOCHS = 2# 100
|
28 |
+
# # BATCHES = 500 # 500
|
29 |
+
# BATCHSIZE = 32
|
30 |
+
# VALIDATE_EVERY_N_EPOCHS = 5
|
31 |
+
SCALE_FACTOR = .875
|
32 |
+
DATA_DIR = '/mnt/data/xray-thesis/data/chestX-ray14/images/'
|
33 |
+
PERCENTAGE = 0.01 # percentage of data use for quick run
|
34 |
+
TEST_AGUMENTED = False
|
35 |
+
DISEASE_THRESHOLD = 0.5
|
36 |
+
|
37 |
+
MODEL_DIR = '/mnt/data/xray-thesis/models'
|
38 |
+
LOG_DIR = 'mnt/data/xray-thesis/logs'
|
39 |
+
CSV_DIR = '%s/csv' % ROOT
|
40 |
+
STAT_DIR = '%s/stats' % ROOT
|
41 |
+
|
42 |
+
# chexnet file
|
43 |
+
CHEXNET_MODEL_NAME = '%s/chexnet_densenet.pth.tar' % MODEL_DIR
|
44 |
+
CHEXNET_TRAIN_CSV = '%s/chexnet_train_list.csv' % CSV_DIR
|
45 |
+
CHEXNET_VAL_CSV = '%s/chexnet_val_list.csv' % CSV_DIR
|
46 |
+
CHEXNET_TEST_CSV = '%s/chexnet_test_list.csv' % CSV_DIR
|
47 |
+
TRAIN_CSV = '%s/train_list.csv' % CSV_DIR
|
48 |
+
VAL_CSV = '%s/val_list.csv' % CSV_DIR
|
49 |
+
TEST_CSV = '%s/test_list.csv' % CSV_DIR
|
50 |
+
|
51 |
+
# different model
|
52 |
+
DENSENET121_DIR = '%s/densenet121' % MODEL_DIR
|
53 |
+
|
54 |
+
# stat
|
55 |
+
TRAIN_STAT = '%s/train.csv' % STAT_DIR
|
56 |
+
TEST_STAT = '%s/test.csv' % STAT_DIR
|
57 |
+
|
58 |
+
PREPROCESS = False
|
chestXray14/heatmap.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
import numpy as np
|
3 |
+
import cv2
|
4 |
+
from chexnet import ChexNet
|
5 |
+
from layers import SaveFeature
|
6 |
+
from constant import CLASS_NAMES
|
7 |
+
|
8 |
+
|
9 |
+
class HeatmapGenerator:
|
10 |
+
|
11 |
+
# def __init__(self, model_name='20180429-130928', mode=None):
|
12 |
+
def __init__(self, chexnet, mode=None):
|
13 |
+
self.chexnet = chexnet
|
14 |
+
self.sf = SaveFeature(chexnet.backbone)
|
15 |
+
self.weight = list(list(self.chexnet.head.children())[-1].parameters())[0]
|
16 |
+
self.mapping = self.cam if mode == 'cam' else self.default
|
17 |
+
|
18 |
+
def cam(self, pred_y):
|
19 |
+
heatmap = self.sf.features[0].permute(1, 2, 0).detach().numpy() @ self.weight[pred_y].detach().numpy()
|
20 |
+
return heatmap
|
21 |
+
|
22 |
+
# def default(self, pred_ys):
|
23 |
+
# return torch.max(torch.abs(self.sf.features), dim=1)[0]
|
24 |
+
|
25 |
+
def generate(self, image):
|
26 |
+
prob = self.chexnet.predict(image)
|
27 |
+
w, h = image.size
|
28 |
+
return self.from_prob(prob, w, h)
|
29 |
+
|
30 |
+
def from_prob(self, prob, w, h):
|
31 |
+
pred_y = np.argmax(prob)
|
32 |
+
heatmap = self.mapping(pred_y)
|
33 |
+
|
34 |
+
heatmap = heatmap - np.min(heatmap)
|
35 |
+
heatmap = heatmap / np.max(heatmap)
|
36 |
+
heatmap = cv2.resize(heatmap, (w, h))
|
37 |
+
|
38 |
+
return heatmap, CLASS_NAMES[pred_y]
|
chestXray14/layers.py
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from torch import nn
|
2 |
+
import torch
|
3 |
+
import torch.nn.functional as F
|
4 |
+
import numpy as np
|
5 |
+
|
6 |
+
|
7 |
+
class Flatten(nn.Module):
|
8 |
+
def forward(self, x):
|
9 |
+
x = x.view(x.size()[0], -1)
|
10 |
+
return x
|
11 |
+
|
12 |
+
class LSEPool2d(nn.Module):
|
13 |
+
|
14 |
+
def __init__(self, r=3):
|
15 |
+
super().__init__()
|
16 |
+
self.r =r
|
17 |
+
|
18 |
+
def forward(self, x):
|
19 |
+
s = x.size()[3] # x: bs*2048*7*7
|
20 |
+
r = self.r
|
21 |
+
x_max = F.adaptive_max_pool2d(x, 1) # x_max: bs*2048*1*1
|
22 |
+
p = ((1/r) * torch.log((1 / (s*s)) * torch.exp(r*(x - x_max)).sum(3).sum(2)))
|
23 |
+
x_max = x_max.view(x.size(0), -1) # bs*2048
|
24 |
+
return x_max+p
|
25 |
+
|
26 |
+
|
27 |
+
class WeightedBCEWithLogitsLoss(nn.Module):
|
28 |
+
|
29 |
+
def __init__(self):
|
30 |
+
super().__init__()
|
31 |
+
|
32 |
+
def forward(self, input, target):
|
33 |
+
w = self.get_weight(input, target)
|
34 |
+
return F.binary_cross_entropy_with_logits(input, target, w, reduction='mean')
|
35 |
+
|
36 |
+
def get_weight(self, input, target):
|
37 |
+
y = target.cpu().data.numpy()
|
38 |
+
y_hat = input.cpu().data.numpy()
|
39 |
+
P = np.count_nonzero(y == 1)
|
40 |
+
N = np.count_nonzero(y == 0)
|
41 |
+
beta_p = (P + N) / (P + 1) # may not contain disease
|
42 |
+
beta_n = (P + N) / N
|
43 |
+
w = np.empty(y.shape)
|
44 |
+
w[y==0] = beta_n
|
45 |
+
w[y==1] = beta_p
|
46 |
+
w = torch.FloatTensor(w).cuda()
|
47 |
+
return w
|
48 |
+
|
49 |
+
class SaveFeature:
|
50 |
+
features = None
|
51 |
+
|
52 |
+
def __init__(self, m):
|
53 |
+
self.hook = m.register_forward_hook(self.hook_fn)
|
54 |
+
|
55 |
+
def hook_fn(self, module, input, output):
|
56 |
+
self.features = output
|
57 |
+
|
58 |
+
def remove(self):
|
59 |
+
self.hook.remove()
|
60 |
+
|
61 |
+
# class FocalLoss(WeightedBCELoss):
|
62 |
+
|
63 |
+
# def __init__(self, theta=2):
|
64 |
+
# super().__init__()
|
65 |
+
# self.theta = theta
|
66 |
+
|
67 |
+
# def forward(self, input, target):
|
68 |
+
# # pt = target*input + (1-target)*(1-input)
|
69 |
+
# # target *= (1-pt)**self.theta
|
70 |
+
# w = self.get_weight(input, target)
|
71 |
+
# return F.binary_cross_entropy_with_logits(input, target, w)
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
# class FocalLoss(nn.Module):
|
76 |
+
# def __init__(self, gamma=0, alpha=None, size_average=True):
|
77 |
+
# super(FocalLoss, self).__init__()
|
78 |
+
# self.gamma = gamma
|
79 |
+
# self.alpha = alpha
|
80 |
+
# if isinstance(alpha,(float,int,long)): self.alpha = torch.Tensor([alpha,1-alpha])
|
81 |
+
# if isinstance(alpha,list): self.alpha = torch.Tensor(alpha)
|
82 |
+
# self.size_average = size_average
|
83 |
+
|
84 |
+
# def forward(self, input, target):
|
85 |
+
# if input.dim()>2:
|
86 |
+
# input = input.view(input.size(0),input.size(1),-1) # N,C,H,W => N,C,H*W
|
87 |
+
# input = input.transpose(1,2) # N,C,H*W => N,H*W,C
|
88 |
+
# input = input.contiguous().view(-1,input.size(2)) # N,H*W,C => N*H*W,C
|
89 |
+
# target = target.view(-1,1)
|
90 |
+
|
91 |
+
# logpt = F.log_softmax(input)
|
92 |
+
# logpt = logpt.gather(1,target)
|
93 |
+
# logpt = logpt.view(-1)
|
94 |
+
# pt = Variable(logpt.data.exp())
|
95 |
+
|
96 |
+
# if self.alpha is not None:
|
97 |
+
# if self.alpha.type()!=input.data.type():
|
98 |
+
# self.alpha = self.alpha.type_as(input.data)
|
99 |
+
# at = self.alpha.gather(0,target.data.view(-1))
|
100 |
+
# logpt = logpt * Variable(at)
|
101 |
+
|
102 |
+
# loss = -1 * (1-pt)**self.gamma * logpt
|
103 |
+
# if self.size_average: return loss.mean()
|
104 |
+
# else: return loss.sum()
|
chestXray14/models/Model.ipynb
ADDED
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 2,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [],
|
8 |
+
"source": [
|
9 |
+
"import torchvision\n",
|
10 |
+
"import pretrainedmodels\n",
|
11 |
+
"import torch\n",
|
12 |
+
"import pretrainedmodels.utils as utils\n",
|
13 |
+
"import torchvision.transforms as transforms\n",
|
14 |
+
"import torchvision.models as models\n",
|
15 |
+
"import torch.nn as nn\n",
|
16 |
+
"import torch.nn.functional as F\n",
|
17 |
+
"from PIL import Image\n",
|
18 |
+
"from collections import OrderedDict"
|
19 |
+
]
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"cell_type": "code",
|
23 |
+
"execution_count": 3,
|
24 |
+
"metadata": {},
|
25 |
+
"outputs": [
|
26 |
+
{
|
27 |
+
"name": "stdout",
|
28 |
+
"output_type": "stream",
|
29 |
+
"text": [
|
30 |
+
"{'imagenet': {'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth', 'input_space': 'RGB', 'input_size': [3, 331, 331], 'input_range': [0, 1], 'mean': [0.5, 0.5, 0.5], 'std': [0.5, 0.5, 0.5], 'num_classes': 1000}, 'imagenet+background': {'url': 'http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth', 'input_space': 'RGB', 'input_size': [3, 331, 331], 'input_range': [0, 1], 'mean': [0.5, 0.5, 0.5], 'std': [0.5, 0.5, 0.5], 'num_classes': 1001}}\n"
|
31 |
+
]
|
32 |
+
},
|
33 |
+
{
|
34 |
+
"name": "stderr",
|
35 |
+
"output_type": "stream",
|
36 |
+
"text": [
|
37 |
+
"Downloading: \"http://data.lip6.fr/cadene/pretrainedmodels/nasnetalarge-a1897284.pth\" to /home/dattran/.torch/models/nasnetalarge-a1897284.pth\n",
|
38 |
+
"100%|██████████| 356056626/356056626 [07:27<00:00, 795221.08it/s] \n"
|
39 |
+
]
|
40 |
+
}
|
41 |
+
],
|
42 |
+
"source": [
|
43 |
+
"print(pretrainedmodels.pretrained_settings['nasnetalarge'])\n",
|
44 |
+
"model = pretrainedmodels.__dict__['nasnetalarge'](num_classes=1000, pretrained='imagenet')"
|
45 |
+
]
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"cell_type": "code",
|
49 |
+
"execution_count": 21,
|
50 |
+
"metadata": {},
|
51 |
+
"outputs": [
|
52 |
+
{
|
53 |
+
"data": {
|
54 |
+
"text/plain": [
|
55 |
+
"Variable containing:\n",
|
56 |
+
"( 0 , 0 ,.,.) = \n",
|
57 |
+
" 0.1121 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
58 |
+
" 0.4418 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
59 |
+
" 0.0000 0.0000 0.0000 ... 0.8554 0.0000 0.0000\n",
|
60 |
+
" ... ⋱ ... \n",
|
61 |
+
" 0.0000 0.5682 0.5166 ... 0.0301 0.0000 0.0000\n",
|
62 |
+
" 0.0000 0.0921 0.2531 ... 2.0754 0.4212 0.0000\n",
|
63 |
+
" 0.0000 0.0000 0.0000 ... 1.8003 0.5220 0.0000\n",
|
64 |
+
"\n",
|
65 |
+
"( 0 , 1 ,.,.) = \n",
|
66 |
+
" 0.1536 0.1211 0.0000 ... 1.3220 0.1388 0.0000\n",
|
67 |
+
" 0.4111 0.2736 0.1038 ... 0.7770 0.0000 0.0000\n",
|
68 |
+
" 0.0000 0.0000 0.0000 ... 1.5591 0.0000 0.0000\n",
|
69 |
+
" ... ⋱ ... \n",
|
70 |
+
" 0.0000 0.0000 0.3120 ... 0.0000 0.0000 0.0000\n",
|
71 |
+
" 1.2059 0.9648 0.7537 ... 0.0000 0.0000 0.0000\n",
|
72 |
+
" 1.8497 0.5725 0.0000 ... 0.0000 0.0000 0.0000\n",
|
73 |
+
"\n",
|
74 |
+
"( 0 , 2 ,.,.) = \n",
|
75 |
+
" 0.3311 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
76 |
+
" 0.0000 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
77 |
+
" 0.3876 0.2232 0.1740 ... 0.0000 0.0000 0.0000\n",
|
78 |
+
" ... ⋱ ... \n",
|
79 |
+
" 0.0000 0.0000 0.3968 ... 0.0000 0.2945 0.0000\n",
|
80 |
+
" 0.4885 0.8537 1.2278 ... 0.2380 0.6205 1.0980\n",
|
81 |
+
" 2.1136 1.3682 1.5039 ... 0.9723 0.9817 0.0760\n",
|
82 |
+
" ... \n",
|
83 |
+
"\n",
|
84 |
+
"( 0 ,1533,.,.) = \n",
|
85 |
+
" 0.8787 0.9274 0.5682 ... 0.4111 0.5084 0.5470\n",
|
86 |
+
" 0.5436 0.6317 0.5634 ... 0.5417 0.3694 0.4478\n",
|
87 |
+
" 0.0000 0.3396 0.5478 ... 0.8584 0.5552 0.5867\n",
|
88 |
+
" ... ⋱ ... \n",
|
89 |
+
" 0.0000 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
90 |
+
" 0.4349 0.2017 0.0000 ... 0.0000 0.0000 0.0000\n",
|
91 |
+
" 0.3743 0.3398 0.0000 ... 0.0000 0.0000 0.0000\n",
|
92 |
+
"\n",
|
93 |
+
"( 0 ,1534,.,.) = \n",
|
94 |
+
" 0.1190 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
95 |
+
" 0.0259 0.0000 0.0000 ... 0.3597 0.0000 0.0000\n",
|
96 |
+
" 0.0000 0.0000 0.0000 ... 1.4928 0.0000 0.0000\n",
|
97 |
+
" ... ⋱ ... \n",
|
98 |
+
" 0.0000 0.0000 0.0000 ... 1.4441 1.2858 0.6525\n",
|
99 |
+
" 0.0000 0.1889 0.5281 ... 0.7508 0.9813 0.5251\n",
|
100 |
+
" 0.0000 0.9832 1.3777 ... 0.0639 0.2403 0.0000\n",
|
101 |
+
"\n",
|
102 |
+
"( 0 ,1535,.,.) = \n",
|
103 |
+
" 0.0000 0.1068 0.3845 ... 0.0000 0.0000 0.0000\n",
|
104 |
+
" 0.0000 0.2751 0.7059 ... 0.0000 0.0000 0.0000\n",
|
105 |
+
" 0.0000 0.0711 0.4025 ... 1.2069 1.4548 1.1041\n",
|
106 |
+
" ... ⋱ ... \n",
|
107 |
+
" 0.0000 0.0000 0.0000 ... 0.7915 0.3439 0.1936\n",
|
108 |
+
" 0.0000 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
109 |
+
" 0.0275 0.0000 0.0000 ... 0.0000 0.0000 0.0000\n",
|
110 |
+
"[torch.FloatTensor of size 1x1536x8x8]"
|
111 |
+
]
|
112 |
+
},
|
113 |
+
"execution_count": 21,
|
114 |
+
"metadata": {},
|
115 |
+
"output_type": "execute_result"
|
116 |
+
}
|
117 |
+
],
|
118 |
+
"source": [
|
119 |
+
"load_img = utils.LoadImage()\n",
|
120 |
+
"# transformations depending on the model\n",
|
121 |
+
"# rescale, center crop, normalize, and others (ex: ToBGR, ToRange255)\n",
|
122 |
+
"tf_img = utils.TransformImage(model) \n",
|
123 |
+
"\n",
|
124 |
+
"path_img = '/home/dattran/data/xray/00000013_029.png'\n",
|
125 |
+
"\n",
|
126 |
+
"input_img = load_img(path_img)\n",
|
127 |
+
"input_tensor = tf_img(input_img) # 3x400x225 -> 3x299x299 size may differ\n",
|
128 |
+
"input_tensor = input_tensor.unsqueeze(0) # 3x299x299 -> 1x3x299x299\n",
|
129 |
+
"input = torch.autograd.Variable(input_tensor,\n",
|
130 |
+
" requires_grad=False)\n",
|
131 |
+
"model.features(input)"
|
132 |
+
]
|
133 |
+
},
|
134 |
+
{
|
135 |
+
"cell_type": "code",
|
136 |
+
"execution_count": 23,
|
137 |
+
"metadata": {},
|
138 |
+
"outputs": [
|
139 |
+
{
|
140 |
+
"data": {
|
141 |
+
"text/plain": [
|
142 |
+
"\u001B[0;31mInit signature:\u001B[0m \u001B[0mtorch\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnn\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mMaxPool2d\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mkernel_size\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mstride\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;32mNone\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mpadding\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdilation\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;36m1\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mreturn_indices\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;32mFalse\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mceil_mode\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;32mFalse\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n",
|
143 |
+
"\u001B[0;31mDocstring:\u001B[0m \n",
|
144 |
+
"Applies a 2D max pooling over an input signal composed of several input\n",
|
145 |
+
"planes.\n",
|
146 |
+
"\n",
|
147 |
+
"In the simplest case, the output value of the layer with input size :math:`(N, C, H, W)`,\n",
|
148 |
+
"output :math:`(N, C, H_{out}, W_{out})` and :attr:`kernel_size` :math:`(kH, kW)`\n",
|
149 |
+
"can be precisely described as:\n",
|
150 |
+
"\n",
|
151 |
+
".. math::\n",
|
152 |
+
"\n",
|
153 |
+
" \\begin{array}{ll}\n",
|
154 |
+
" out(N_i, C_j, h, w) = \\max_{{m}=0}^{kH-1} \\max_{{n}=0}^{kW-1}\n",
|
155 |
+
" input(N_i, C_j, stride[0] * h + m, stride[1] * w + n)\n",
|
156 |
+
" \\end{array}\n",
|
157 |
+
"\n",
|
158 |
+
"| If :attr:`padding` is non-zero, then the input is implicitly zero-padded on both sides\n",
|
159 |
+
" for :attr:`padding` number of points\n",
|
160 |
+
"| :attr:`dilation` controls the spacing between the kernel points. It is harder to describe,\n",
|
161 |
+
" but this `link`_ has a nice visualization of what :attr:`dilation` does.\n",
|
162 |
+
"\n",
|
163 |
+
"The parameters :attr:`kernel_size`, :attr:`stride`, :attr:`padding`, :attr:`dilation` can either be:\n",
|
164 |
+
"\n",
|
165 |
+
" - a single ``int`` -- in which case the same value is used for the height and width dimension\n",
|
166 |
+
" - a ``tuple`` of two ints -- in which case, the first `int` is used for the height dimension,\n",
|
167 |
+
" and the second `int` for the width dimension\n",
|
168 |
+
"\n",
|
169 |
+
"Args:\n",
|
170 |
+
" kernel_size: the size of the window to take a max over\n",
|
171 |
+
" stride: the stride of the window. Default value is :attr:`kernel_size`\n",
|
172 |
+
" padding: implicit zero padding to be added on both sides\n",
|
173 |
+
" dilation: a parameter that controls the stride of elements in the window\n",
|
174 |
+
" return_indices: if ``True``, will return the max indices along with the outputs.\n",
|
175 |
+
" Useful when Unpooling later\n",
|
176 |
+
" ceil_mode: when True, will use `ceil` instead of `floor` to compute the output shape\n",
|
177 |
+
"\n",
|
178 |
+
"Shape:\n",
|
179 |
+
" - Input: :math:`(N, C, H_{in}, W_{in})`\n",
|
180 |
+
" - Output: :math:`(N, C, H_{out}, W_{out})` where\n",
|
181 |
+
" :math:`H_{out} = floor((H_{in} + 2 * padding[0] - dilation[0] * (kernel\\_size[0] - 1) - 1) / stride[0] + 1)`\n",
|
182 |
+
" :math:`W_{out} = floor((W_{in} + 2 * padding[1] - dilation[1] * (kernel\\_size[1] - 1) - 1) / stride[1] + 1)`\n",
|
183 |
+
"\n",
|
184 |
+
"Examples::\n",
|
185 |
+
"\n",
|
186 |
+
" >>> # pool of square window of size=3, stride=2\n",
|
187 |
+
" >>> m = nn.MaxPool2d(3, stride=2)\n",
|
188 |
+
" >>> # pool of non-square window\n",
|
189 |
+
" >>> m = nn.MaxPool2d((3, 2), stride=(2, 1))\n",
|
190 |
+
" >>> input = autograd.Variable(torch.randn(20, 16, 50, 32))\n",
|
191 |
+
" >>> output = m(input)\n",
|
192 |
+
"\n",
|
193 |
+
".. _link:\n",
|
194 |
+
" https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md\n",
|
195 |
+
"\u001B[0;31mFile:\u001B[0m ~/miniconda2/envs/dat/lib/python3.6/site-packages/torch/nn/modules/pooling.py\n",
|
196 |
+
"\u001B[0;31mType:\u001B[0m type\n"
|
197 |
+
]
|
198 |
+
},
|
199 |
+
"metadata": {},
|
200 |
+
"output_type": "display_data"
|
201 |
+
}
|
202 |
+
],
|
203 |
+
"source": [
|
204 |
+
"torch.nn.MaxPool2d?"
|
205 |
+
]
|
206 |
+
},
|
207 |
+
{
|
208 |
+
"cell_type": "code",
|
209 |
+
"execution_count": 5,
|
210 |
+
"metadata": {},
|
211 |
+
"outputs": [],
|
212 |
+
"source": [
|
213 |
+
"from pretrainedmodels.models.dpn import adaptive_avgmax_pool2d"
|
214 |
+
]
|
215 |
+
},
|
216 |
+
{
|
217 |
+
"cell_type": "code",
|
218 |
+
"execution_count": 9,
|
219 |
+
"metadata": {},
|
220 |
+
"outputs": [
|
221 |
+
{
|
222 |
+
"data": {
|
223 |
+
"text/plain": [
|
224 |
+
"1000"
|
225 |
+
]
|
226 |
+
},
|
227 |
+
"execution_count": 9,
|
228 |
+
"metadata": {},
|
229 |
+
"output_type": "execute_result"
|
230 |
+
}
|
231 |
+
],
|
232 |
+
"source": [
|
233 |
+
"x = nn.Conv2d(1000, 14,kernel_size=1, bias=True)\n",
|
234 |
+
"x.in_channels"
|
235 |
+
]
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"cell_type": "code",
|
239 |
+
"execution_count": 15,
|
240 |
+
"metadata": {},
|
241 |
+
"outputs": [
|
242 |
+
{
|
243 |
+
"data": {
|
244 |
+
"text/plain": [
|
245 |
+
"False"
|
246 |
+
]
|
247 |
+
},
|
248 |
+
"execution_count": 15,
|
249 |
+
"metadata": {},
|
250 |
+
"output_type": "execute_result"
|
251 |
+
}
|
252 |
+
],
|
253 |
+
"source": [
|
254 |
+
"model.eval()\n",
|
255 |
+
"model.training"
|
256 |
+
]
|
257 |
+
},
|
258 |
+
{
|
259 |
+
"cell_type": "code",
|
260 |
+
"execution_count": null,
|
261 |
+
"metadata": {},
|
262 |
+
"outputs": [],
|
263 |
+
"source": []
|
264 |
+
}
|
265 |
+
],
|
266 |
+
"metadata": {
|
267 |
+
"kernelspec": {
|
268 |
+
"display_name": "Python 3",
|
269 |
+
"language": "python",
|
270 |
+
"name": "python3"
|
271 |
+
},
|
272 |
+
"language_info": {
|
273 |
+
"codemirror_mode": {
|
274 |
+
"name": "ipython",
|
275 |
+
"version": 3
|
276 |
+
},
|
277 |
+
"file_extension": ".py",
|
278 |
+
"mimetype": "text/x-python",
|
279 |
+
"name": "python",
|
280 |
+
"nbconvert_exporter": "python",
|
281 |
+
"pygments_lexer": "ipython3",
|
282 |
+
"version": "3.6.4"
|
283 |
+
}
|
284 |
+
},
|
285 |
+
"nbformat": 4,
|
286 |
+
"nbformat_minor": 2
|
287 |
+
}
|
chestXray14/models/__pycache__/densenet.cpython-310.pyc
ADDED
Binary file (2.12 kB). View file
|
|
chestXray14/models/densenet.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
import torch
|
6 |
+
from constant import SCALE_FACTOR
|
7 |
+
import math
|
8 |
+
import pdb
|
9 |
+
|
10 |
+
class DenseNet(nn.Module):
|
11 |
+
|
12 |
+
def __init__(self, variant):
|
13 |
+
super(DenseNet, self).__init__()
|
14 |
+
assert variant in ['densenet121', 'densenet161', 'densenet201']
|
15 |
+
|
16 |
+
# load retrain model
|
17 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
18 |
+
self.features = model.features
|
19 |
+
num_ftrs = model.last_linear.in_features
|
20 |
+
self.classifier = nn.Sequential(
|
21 |
+
nn.Linear(num_ftrs, 14),
|
22 |
+
nn.Sigmoid()
|
23 |
+
)
|
24 |
+
# TODO: BCELoss with logit for numeric stable
|
25 |
+
# self.classifier = nn.Linear(num_ftrs, 14)
|
26 |
+
|
27 |
+
# load other info
|
28 |
+
self.mean = model.mean
|
29 |
+
self.std = model.std
|
30 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
31 |
+
self.input_range = model.input_range
|
32 |
+
self.input_space = model.input_space
|
33 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
34 |
+
|
35 |
+
def forward(self, x, **kwargs):
|
36 |
+
x = self.features(x) # 1x1024x7x7
|
37 |
+
s = x.size()[3] # 7 if input image is 224x224, 16 if input image is 512x512
|
38 |
+
x = F.relu(x, inplace=True) # 1x1024x7x7
|
39 |
+
|
40 |
+
pooling = kwargs['pooling']
|
41 |
+
if pooling == 'MAX':
|
42 |
+
x = F.max_pool2d(x, kernel_size=s, stride=1)
|
43 |
+
x = x.view(x.size(0), -1) # 1x1024
|
44 |
+
elif pooling == 'AVG':
|
45 |
+
x = F.avg_pool2d(x, kernel_size=s, stride=1) # 1x1024x1x1
|
46 |
+
x = x.view(x.size(0), -1) # 1x1024
|
47 |
+
elif pooling == 'LSE':
|
48 |
+
r = kwargs.lse_r
|
49 |
+
x_max = F.max_pool2d(x, kernel_size=s, stride=1)
|
50 |
+
p = ((1/r) * torch.log((1 / (s*s)) * torch.exp(r*(x - x_max)).sum(3).sum(2)))
|
51 |
+
x_max = x_max.view(x.size(0), -1)
|
52 |
+
x = x_max + p
|
53 |
+
else:
|
54 |
+
raise ValueError('Invalid pooling')
|
55 |
+
|
56 |
+
x = self.classifier(x) # 1x1000
|
57 |
+
return x
|
58 |
+
|
59 |
+
def extract(self, x):
|
60 |
+
return self.features(x)
|
61 |
+
|
62 |
+
# def count_params(self):
|
63 |
+
# return sum(p.numel() for p in self.parameters() if p.requires_grad)
|
64 |
+
|
65 |
+
def build(variant):
|
66 |
+
net = DenseNet(variant).cuda()
|
67 |
+
return net
|
68 |
+
|
69 |
+
architect='densenet'
|
70 |
+
|
71 |
+
|
chestXray14/models/dpn.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from constant import SCALE_FACTOR
|
6 |
+
import math
|
7 |
+
from pretrainedmodels.models.dpn import adaptive_avgmax_pool2d
|
8 |
+
|
9 |
+
class DPN(nn.Module):
|
10 |
+
|
11 |
+
def __init__(self, variant):
|
12 |
+
super(DPN, self).__init__()
|
13 |
+
assert variant in ['dpn68', 'dpn68b', 'dpn92', 'dpn98', 'dpn131', 'dpn107']
|
14 |
+
|
15 |
+
# load retrain model
|
16 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
17 |
+
self.features = model.features
|
18 |
+
num_ftrs = model.classifier.in_channels
|
19 |
+
self.classifier = nn.Sequential(
|
20 |
+
nn.Conv2d(num_ftrs, 14, kernel_size=1, bias=True), # something wrong here abt dimension
|
21 |
+
nn.Sigmoid()
|
22 |
+
)
|
23 |
+
|
24 |
+
# load other info
|
25 |
+
self.mean = model.mean
|
26 |
+
self.std = model.std
|
27 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
28 |
+
self.input_range = model.input_range
|
29 |
+
self.input_space = model.input_space
|
30 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
31 |
+
|
32 |
+
def forward(self, x):
|
33 |
+
x = self.features(x) # 1x1024x7x7
|
34 |
+
if not self.training and self.test_time_tool:
|
35 |
+
x = F.avg_pool2d(x, kernel_size=7, stride=1)
|
36 |
+
x = self.classifier(x)
|
37 |
+
x = adaptive_avgmax_pool2d(out, pool_type='avgmax') # something wrong here abt dimension
|
38 |
+
else:
|
39 |
+
x = adaptive_avgmax_pool2d(x, pool_type='avg')
|
40 |
+
x = self.classifier(x)
|
41 |
+
return x
|
42 |
+
|
43 |
+
def extract(self, x):
|
44 |
+
return self.features(x)
|
45 |
+
|
46 |
+
def build(variant):
|
47 |
+
net = DPN(variant).cuda()
|
48 |
+
return net
|
49 |
+
|
50 |
+
architect='dpn'
|
51 |
+
|
52 |
+
|
chestXray14/models/inception.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from collections import OrderedDict
|
6 |
+
from constant import SCALE_FACTOR
|
7 |
+
import math
|
8 |
+
|
9 |
+
class InceptionNet(nn.Module):
|
10 |
+
|
11 |
+
def __init__(self, variant):
|
12 |
+
super(InceptionNet, self).__init__()
|
13 |
+
assert variant in ['inceptionv4', 'inceptionv3', 'inceptionresnetv2']
|
14 |
+
|
15 |
+
# load pretrain model
|
16 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
17 |
+
self.features = _get_features(model, variant)
|
18 |
+
num_ftrs = model.last_linear.in_features
|
19 |
+
self.classifier = nn.Sequential(
|
20 |
+
nn.Linear(num_ftrs, 14),
|
21 |
+
nn.Sigmoid()
|
22 |
+
)
|
23 |
+
|
24 |
+
# load other info
|
25 |
+
self.mean = model.mean
|
26 |
+
self.std = model.std
|
27 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
28 |
+
self.input_range = model.input_range
|
29 |
+
self.input_space = model.input_space
|
30 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
31 |
+
|
32 |
+
def forward(self, x):
|
33 |
+
x = self.features(x) # 1x1536x8x8
|
34 |
+
s = x.size()[3] # 8 if input image is 224x224
|
35 |
+
x = F.avg_pool2d(x, kernel_size=s, count_include_pad=False) # 1x1536x1x1, same for inceptionv4 and inceptionresnetv2
|
36 |
+
x = x.view(x.size(0), -1) # 1x1536
|
37 |
+
x = self.classifier(x) # 1x1000
|
38 |
+
return x
|
39 |
+
|
40 |
+
def extract(self, x):
|
41 |
+
return self.features(x) # 1x1536x8x8
|
42 |
+
|
43 |
+
def build(variant):
|
44 |
+
net = InceptionNet(variant).cuda()
|
45 |
+
return net
|
46 |
+
|
47 |
+
def _get_features(model, variant):
|
48 |
+
if variant == 'inceptionv4':
|
49 |
+
features = model.features
|
50 |
+
elif variant == 'inceptionv3':
|
51 |
+
# TODO: Take a look on this
|
52 |
+
features = nn.Sequential(OrderedDict([
|
53 |
+
('Conv2d_1a_3x3', model.Conv2d_1a_3x3),
|
54 |
+
('Conv2d_2a_3x3', model.Conv2d_2a_3x3),
|
55 |
+
('Conv2d_2b_3x3', model.Conv2d_2b_3x3),
|
56 |
+
('max_pool2d_1', torch.nn.MaxPool2d(3, stride=2)),
|
57 |
+
('Conv2d_3b_1x1', model.Conv2d_3b_1x1),
|
58 |
+
('Conv2d_4a_3x3', model.Conv2d_4a_3x3),
|
59 |
+
('max_pool2d_2', torch.nn.MaxPool2d(3, stride=2)),
|
60 |
+
('Mixed_5b', model.Mixed_5b),
|
61 |
+
('Mixed_5c', model.Mixed_5c),
|
62 |
+
('Mixed_5d', model.Mixed_5d),
|
63 |
+
('Mixed_6a', model.Mixed_6a),
|
64 |
+
('Mixed_6b', model.Mixed_6b),
|
65 |
+
('Mixed_6c', model.Mixed_6c),
|
66 |
+
('Mixed_6d', model.Mixed_6b),
|
67 |
+
# ('Mixed_6c', model.Mixed_6c),
|
68 |
+
]))
|
69 |
+
elif variant == 'inceptionresnetv2':
|
70 |
+
features = nn.Sequential(OrderedDict([
|
71 |
+
('conv2d_1a', model.conv2d_1a),
|
72 |
+
('conv2d_2a', model.conv2d_2a),
|
73 |
+
('conv2d_2b', model.conv2d_2b),
|
74 |
+
('maxpool_3a', model.maxpool_3a),
|
75 |
+
('conv2d_3b', model.conv2d_3b),
|
76 |
+
('conv2d_4a', model.conv2d_4a),
|
77 |
+
('maxpool_5a', model.maxpool_5a),
|
78 |
+
('mixed_5b', model.mixed_5b),
|
79 |
+
('repeat', model.repeat),
|
80 |
+
('mixed_6a', model.mixed_6a),
|
81 |
+
('repeat_1', model.repeat_1),
|
82 |
+
('mixed_7a', model.mixed_7a),
|
83 |
+
('repeat_2', model.repeat_2),
|
84 |
+
('block8', model.block8),
|
85 |
+
('conv2d_7b', model.conv2d_7b)
|
86 |
+
]))
|
87 |
+
else:
|
88 |
+
raise "Unknown variant"
|
89 |
+
return features
|
90 |
+
|
91 |
+
architect='inception'
|
chestXray14/models/nasnet.py
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from collections import OrderedDict
|
6 |
+
|
7 |
+
class Nasnet(nn.Module):
|
8 |
+
|
9 |
+
def __init__(self, variant):
|
10 |
+
super(Nasnet, self).__init__()
|
11 |
+
assert variant in ['nasnetalarge']
|
12 |
+
|
13 |
+
# load retrain model
|
14 |
+
self.model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
15 |
+
# self.features = nn.Sequential(OrderedDict([
|
16 |
+
# ('conv0', model.conv0),
|
17 |
+
# ('cell_stem_0', model.cell_stem_0),
|
18 |
+
# ('cell_stem_1', model.cell_stem_1),
|
19 |
+
# ('cell_0', model.cell_0),
|
20 |
+
# ('cell_1', model.cell_1),
|
21 |
+
# ('cell_2', model.cell_2),
|
22 |
+
# ('cell_3', model.cell_3),
|
23 |
+
# ('cell_4', model.cell_4),
|
24 |
+
# ('cell_5', model.cell_5),
|
25 |
+
# ('reduction_cell_0', model.reduction_cell_0),
|
26 |
+
# ('cell_6', model.cell_6),
|
27 |
+
# ('cell_7', model.cell_7),
|
28 |
+
# ('cell_8', model.cell_8),
|
29 |
+
# ('cell_9', model.cell_9),
|
30 |
+
# ('cell_10', model.cell_10),
|
31 |
+
# ('cell_11', model.cell_11),
|
32 |
+
# ('reduction_cell_1', model.reduction_cell_1),
|
33 |
+
# ('cell_12', model.cell_6),
|
34 |
+
# ('cell_13', model.cell_7),
|
35 |
+
# ('cell_14', model.cell_8),
|
36 |
+
# ('cell_15', model.cell_9),
|
37 |
+
# ('cell_16', model.cell_10),
|
38 |
+
# ('cell_17', model.cell_11)
|
39 |
+
|
40 |
+
# ]))
|
41 |
+
num_ftrs = self.model.last_linear.in_features
|
42 |
+
self.model.last_linear = nn.Sequential(
|
43 |
+
nn.Linear(num_ftrs, 14),
|
44 |
+
nn.Sigmoid()
|
45 |
+
)
|
46 |
+
|
47 |
+
# load other info
|
48 |
+
# load other info
|
49 |
+
self.mean = self.model.mean
|
50 |
+
self.std = self.model.std
|
51 |
+
self.input_size = self.model.input_size[1] # assume every input is a square image
|
52 |
+
self.input_range = self.model.input_range
|
53 |
+
self.input_space = self.model.input_space
|
54 |
+
self.resize_size = 354 # as in pretrainmodels repo
|
55 |
+
|
56 |
+
def forward(self, x):
|
57 |
+
# x = self.features(x)
|
58 |
+
# x = F.avg_pool2d(x, kernel_size=11, stride=1, padding=0)
|
59 |
+
# x = x.view(x.size(0), -1)
|
60 |
+
# x = x.dropout(training=self.training)
|
61 |
+
# x = self.classifier(x) # 1x1000
|
62 |
+
# return x
|
63 |
+
return self.model.forward(x)
|
64 |
+
|
65 |
+
def extract(self, x):
|
66 |
+
# return self.features(x)
|
67 |
+
return self.model.features(x)
|
68 |
+
|
69 |
+
def build(variant):
|
70 |
+
net = Nasnet(variant).cuda()
|
71 |
+
return net
|
72 |
+
|
73 |
+
architect='nasnet'
|
chestXray14/models/resnet.py
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from collections import OrderedDict
|
6 |
+
from constant import SCALE_FACTOR
|
7 |
+
import math
|
8 |
+
|
9 |
+
class Resnet(nn.Module):
|
10 |
+
|
11 |
+
def __init__(self, variant):
|
12 |
+
super(Resnet, self).__init__()
|
13 |
+
assert variant in ['resnet50', 'resnet101', 'resnet152']
|
14 |
+
|
15 |
+
# load retrain model
|
16 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
17 |
+
self.features = nn.Sequential(OrderedDict([
|
18 |
+
('conv1', model.conv1),
|
19 |
+
('bn1', model.bn1),
|
20 |
+
('relu', model.relu),
|
21 |
+
('maxpool', model.maxpool),
|
22 |
+
('layer1', model.layer1),
|
23 |
+
('layer2', model.layer2),
|
24 |
+
('layer3', model.layer3),
|
25 |
+
('layer4', model.layer4)
|
26 |
+
]))
|
27 |
+
num_ftrs = model.last_linear.in_features
|
28 |
+
self.classifier = nn.Sequential(
|
29 |
+
nn.Linear(num_ftrs, 14),
|
30 |
+
nn.Sigmoid()
|
31 |
+
)
|
32 |
+
|
33 |
+
# load other info
|
34 |
+
# load other info
|
35 |
+
self.mean = model.mean
|
36 |
+
self.std = model.std
|
37 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
38 |
+
self.input_range = model.input_range
|
39 |
+
self.input_space = model.input_space
|
40 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
41 |
+
|
42 |
+
def forward(self, x):
|
43 |
+
x = self.features(x) # 1x2048x7x7
|
44 |
+
s = x.size()[3] # 7 if input image is 224x224, 16 if input image is 512x512
|
45 |
+
x = F.avg_pool2d(x, kernel_size=s, stride=1) # 1x2048x1x1
|
46 |
+
x = x.view(x.size(0), -1) # 1x2048
|
47 |
+
x = self.classifier(x) # 1x1000
|
48 |
+
return x
|
49 |
+
|
50 |
+
def extract(self, x):
|
51 |
+
return self.features(x)
|
52 |
+
|
53 |
+
def build(variant):
|
54 |
+
net = Resnet(variant).cuda()
|
55 |
+
return net
|
56 |
+
|
57 |
+
architect='resnet'
|
chestXray14/models/resnext.py
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from constant import SCALE_FACTOR
|
6 |
+
import math
|
7 |
+
|
8 |
+
class Resnext(nn.Module):
|
9 |
+
|
10 |
+
def __init__(self, variant):
|
11 |
+
super(Resnext, self).__init__()
|
12 |
+
assert variant in ['resnext101_32x4d', 'resnext101_64x4d']
|
13 |
+
|
14 |
+
# load retrain model
|
15 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
16 |
+
self.features = model.features
|
17 |
+
num_ftrs = model.last_linear.in_features
|
18 |
+
self.classifier = nn.Sequential(
|
19 |
+
nn.Linear(num_ftrs, 14),
|
20 |
+
nn.Sigmoid()
|
21 |
+
)
|
22 |
+
|
23 |
+
# load other info
|
24 |
+
self.mean = model.mean
|
25 |
+
self.std = model.std
|
26 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
27 |
+
self.input_range = model.input_range
|
28 |
+
self.input_space = model.input_space
|
29 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
30 |
+
|
31 |
+
def forward(self, x):
|
32 |
+
x = self.features(x) #
|
33 |
+
s = x.size()[3] # 7 if input image is 224x224, 16 if input image is 512x512
|
34 |
+
x = F.avg_pool2d(x, kernel_size=(7, 7), stride=(1, 1)) # 1x1024x1x1
|
35 |
+
x = x.view(x.size(0), -1) # 1x1024
|
36 |
+
x = self.classifier(x) # 1x1000
|
37 |
+
return x
|
38 |
+
|
39 |
+
def extract(self, x):
|
40 |
+
return self.features(x)
|
41 |
+
|
42 |
+
def build(variant):
|
43 |
+
net = Resnext(variant).cuda()
|
44 |
+
return net
|
45 |
+
|
46 |
+
architect='resnext'
|
47 |
+
|
48 |
+
|
chestXray14/models/senet.py
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torchvision
|
2 |
+
import torch.nn as nn
|
3 |
+
import pretrainedmodels
|
4 |
+
import torch.nn.functional as F
|
5 |
+
from collections import OrderedDict
|
6 |
+
from constant import SCALE_FACTOR
|
7 |
+
import math
|
8 |
+
|
9 |
+
class Resnet(nn.Module):
|
10 |
+
|
11 |
+
def __init__(self, variant):
|
12 |
+
super(Resnet, self).__init__()
|
13 |
+
assert variant in ['senet154', 'se_resnext101_32x4d', 'se_resnext50_32x4d', 'se_resnet152', 'se_resnet101', 'se_resnet50']
|
14 |
+
|
15 |
+
# load retrain model
|
16 |
+
model = pretrainedmodels.__dict__[variant](num_classes=1000, pretrained='imagenet')
|
17 |
+
self.features = nn.Sequential(OrderedDict([
|
18 |
+
('layer0', model.layer0),
|
19 |
+
('layer1', model.layer1),
|
20 |
+
('layer2', model.layer2),
|
21 |
+
('layer3', model.layer3),
|
22 |
+
('layer4', model.layer4)
|
23 |
+
]))
|
24 |
+
'''
|
25 |
+
Dropout
|
26 |
+
- For SENet154: 0.2
|
27 |
+
- For SE-ResNet models: None
|
28 |
+
- For SE-ResNeXt models: None
|
29 |
+
'''
|
30 |
+
self.dropout = model.dropout
|
31 |
+
num_ftrs = model.last_linear.in_features
|
32 |
+
self.classifier = nn.Sequential(
|
33 |
+
nn.Linear(num_ftrs, 14),
|
34 |
+
nn.Sigmoid()
|
35 |
+
)
|
36 |
+
|
37 |
+
# load other info
|
38 |
+
# load other info
|
39 |
+
self.mean = model.mean
|
40 |
+
self.std = model.std
|
41 |
+
self.input_size = model.input_size[1] # assume every input is a square image
|
42 |
+
self.input_range = model.input_range
|
43 |
+
self.input_space = model.input_space
|
44 |
+
self.resize_size = int(math.floor(self.input_size / SCALE_FACTOR))
|
45 |
+
|
46 |
+
def forward(self, x):
|
47 |
+
x = self.features(x) # 1x2048x7x7
|
48 |
+
s = x.size()[3] # 7 if input image is 224x224, 16 if input image is 512x512
|
49 |
+
x = F.avg_pool2d(x, kernel_size=s, stride=1) # 1x2048x1x1
|
50 |
+
x = x.view(x.size(0), -1) # 1x2048
|
51 |
+
x = self.classifier(x) # 1x1000
|
52 |
+
return x
|
53 |
+
|
54 |
+
def extract(self, x):
|
55 |
+
return self.features(x)
|
56 |
+
|
57 |
+
def build(variant):
|
58 |
+
net = Resnet(variant).cuda()
|
59 |
+
return net
|
60 |
+
|
61 |
+
architect='senet'
|
chestXray14/segment_result.png
ADDED
chestXray14/test.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import numpy as np
|
3 |
+
import matplotlib.pyplot as plt
|
4 |
+
import cv2
|
5 |
+
import os
|
6 |
+
|
7 |
+
from chexnet import ChexNet
|
8 |
+
from unet import Unet
|
9 |
+
from heatmap import HeatmapGenerator
|
10 |
+
from constant import IMAGENET_MEAN, IMAGENET_STD, CLASS_NAMES
|
11 |
+
|
12 |
+
import sys
|
13 |
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
14 |
+
imgto3d_path = os.path.join(script_dir, '.')
|
15 |
+
sys.path.append(imgto3d_path)
|
16 |
+
|
17 |
+
from chestXray_utils import blend_segmentation
|
18 |
+
import torch
|
19 |
+
import pandas as pd
|
20 |
+
|
21 |
+
|
22 |
+
output_dir = "pages/images"
|
23 |
+
os.makedirs(output_dir, exist_ok=True)
|
24 |
+
|
25 |
+
unet_model = '20190211-101020'
|
26 |
+
chexnet_model = '20180429-130928'
|
27 |
+
DISEASES = np.array(CLASS_NAMES)
|
28 |
+
|
29 |
+
|
30 |
+
# Initialize models
|
31 |
+
unet = Unet(trained=True, model_name=unet_model)
|
32 |
+
chexnet = ChexNet(trained=True, model_name=chexnet_model)
|
33 |
+
heatmap_generator = HeatmapGenerator(chexnet, mode='cam')
|
34 |
+
unet.eval()
|
35 |
+
chexnet.eval()
|
36 |
+
|
37 |
+
|
38 |
+
def process_image(image_path):
|
39 |
+
image = Image.open(image_path).convert('RGB')
|
40 |
+
|
41 |
+
# Run through net
|
42 |
+
(t, l, b, r), mask = unet.segment(image)
|
43 |
+
cropped_image = image.crop((l, t, r, b))
|
44 |
+
prob = chexnet.predict(cropped_image)
|
45 |
+
|
46 |
+
# Save segmentation result
|
47 |
+
blended = blend_segmentation(image, mask)
|
48 |
+
blended = (blended - blended.min()) / (blended.max() - blended.min()) # Normalize to [0, 1]
|
49 |
+
blended = (blended * 255).astype(np.uint8) # Convert to 0-255 range for cv2
|
50 |
+
cv2.rectangle(blended, (l, t), (r, b), (255, 0, 0), 5) # Color in BGR format for cv2
|
51 |
+
segment_result_path = os.path.join(output_dir, 'segment_result.png')
|
52 |
+
plt.imsave(segment_result_path, blended)
|
53 |
+
|
54 |
+
# Save CAM result
|
55 |
+
w, h = cropped_image.size
|
56 |
+
heatmap, _ = heatmap_generator.from_prob(prob, w, h)
|
57 |
+
|
58 |
+
# Resize the heatmap to match the original image dimensions
|
59 |
+
heatmap_resized = cv2.resize(heatmap, (image.width, image.height))
|
60 |
+
heatmap_resized = np.repeat(heatmap_resized[:, :, np.newaxis], 3, axis=2) # Ensure it has 3 channels
|
61 |
+
|
62 |
+
heatmap_resized = ((heatmap_resized - heatmap_resized.min()) * (
|
63 |
+
1 / (heatmap_resized.max() - heatmap_resized.min())) * 255).astype(np.uint8)
|
64 |
+
|
65 |
+
cam = cv2.applyColorMap(heatmap_resized, cv2.COLORMAP_JET)
|
66 |
+
cam = cv2.resize(cam, (image.width, image.height)) # Ensure cam has same dimensions as image
|
67 |
+
cam = cv2.addWeighted(cam, 0.4, np.array(image), 0.6, 0) # Combine heatmap with the original image
|
68 |
+
cam_result_path = os.path.join(output_dir, 'cam_result.png')
|
69 |
+
print("a",cam_result_path)
|
70 |
+
cv2.imwrite(cam_result_path, cam)
|
71 |
+
|
72 |
+
# Top-10 diseases
|
73 |
+
idx = np.argsort(-prob)
|
74 |
+
top_prob = prob[idx[:10]]
|
75 |
+
top_prob = [f'{x:.3}' for x in top_prob]
|
76 |
+
top_disease = DISEASES[idx[:10]]
|
77 |
+
prediction = dict(zip(top_disease, top_prob))
|
78 |
+
|
79 |
+
result = {'result': prediction}
|
80 |
+
df = pd.DataFrame(result['result'].items(), columns=['Disease', 'Probability'])
|
81 |
+
output_file = 'prediction_results.csv'
|
82 |
+
output_file_path = os.path.join(output_dir, output_file)
|
83 |
+
df.to_csv(output_file_path, index=False)
|
84 |
+
|
85 |
+
return result, segment_result_path, cam_result_path
|
86 |
+
|
87 |
+
|
88 |
+
# if __name__ == '__main__':
|
89 |
+
# image_path = r'E:\NLP\KN2024\chestX-ray-14\src\fibrosis.jpg' # Replace with your image path
|
90 |
+
# result, segment_result_path, cam_result_path = process_image(image_path)
|
91 |
+
# print("Prediction Results:", result)
|
92 |
+
# print(f"Segmentation Result Saved to: {segment_result_path}")
|
93 |
+
# print(f"CAM Result Saved to: {cam_result_path}")
|
chestXray14/unet.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a1768ae75ce08bc7cb1d338e26648887e5c4d79ff0b97ab89831789666ac0ed6
|
3 |
+
size 264784168
|
chestXray14/unet.py
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch.nn as nn
|
2 |
+
import torch.nn.functional as F
|
3 |
+
import torch
|
4 |
+
from layers import SaveFeature
|
5 |
+
import pretrainedmodels
|
6 |
+
from torchvision.models import resnet34, resnet50, resnet101, resnet152
|
7 |
+
from pathlib import Path
|
8 |
+
from torchvision.models.resnet import conv3x3, BasicBlock, Bottleneck
|
9 |
+
import skimage
|
10 |
+
from scipy import ndimage
|
11 |
+
import numpy as np
|
12 |
+
import torchvision.transforms as transforms
|
13 |
+
import cv2
|
14 |
+
from constant import IMAGENET_MEAN, IMAGENET_STD
|
15 |
+
|
16 |
+
device="cuda" if torch.cuda.is_available() else "cpu"
|
17 |
+
class UpBlock(nn.Module):
|
18 |
+
expansion = 1
|
19 |
+
|
20 |
+
def __init__(self, inplanes, planes, expansion=1):
|
21 |
+
super().__init__()
|
22 |
+
inplanes = inplanes * expansion
|
23 |
+
planes = planes * expansion
|
24 |
+
self.upconv = nn.ConvTranspose2d(inplanes, planes, 2, 2, 0)
|
25 |
+
self.bn1 = nn.BatchNorm2d(planes)
|
26 |
+
self.relu = nn.ReLU(inplace=True)
|
27 |
+
self.conv1 = conv3x3(inplanes, planes)
|
28 |
+
self.bn2 = nn.BatchNorm2d(planes)
|
29 |
+
|
30 |
+
def forward(self, u, x):
|
31 |
+
up = self.relu(self.bn1(self.upconv(u)))
|
32 |
+
out = torch.cat([x, up], dim=1) # cat along channel
|
33 |
+
out = self.relu(self.bn2(self.conv1(out)))
|
34 |
+
return out
|
35 |
+
|
36 |
+
class UpLayer(nn.Module):
|
37 |
+
|
38 |
+
def __init__(self, block, inplanes, planes, blocks):
|
39 |
+
super().__init__()
|
40 |
+
self.up = UpBlock(inplanes, planes, block.expansion)
|
41 |
+
layers = [block(planes * block.expansion, planes) for _ in range(1, blocks)]
|
42 |
+
self.conv = nn.Sequential(*layers)
|
43 |
+
|
44 |
+
def forward(self, u, x):
|
45 |
+
x = self.up(u, x)
|
46 |
+
x = self.conv(x)
|
47 |
+
return x
|
48 |
+
|
49 |
+
from pathlib import Path
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
class Unet(nn.Module):
|
54 |
+
tfm = transforms.Compose([
|
55 |
+
transforms.Resize((256, 256)),
|
56 |
+
transforms.ToTensor(),
|
57 |
+
transforms.Normalize(IMAGENET_MEAN, IMAGENET_STD)
|
58 |
+
])
|
59 |
+
|
60 |
+
def __init__(self, trained=False, model_name=None):
|
61 |
+
super().__init__()
|
62 |
+
self.layers = [3, 4, 6]
|
63 |
+
self.block = Bottleneck
|
64 |
+
if trained:
|
65 |
+
assert model_name is not None
|
66 |
+
self.load_model(model_name)
|
67 |
+
else:
|
68 |
+
self.load_pretrained()
|
69 |
+
|
70 |
+
def cut_model(self, model, cut):
|
71 |
+
return list(model.children())[:cut]
|
72 |
+
|
73 |
+
def load_model(self, model_name):
|
74 |
+
resnet = resnet50(False)
|
75 |
+
self.backbone = nn.Sequential(*self.cut_model(resnet, 8))
|
76 |
+
self.init_head()
|
77 |
+
|
78 |
+
model_path = Path(__file__).parent / 'unet.h5'
|
79 |
+
state_dict = torch.load(model_path, map_location=torch.device(device))
|
80 |
+
self.load_state_dict(state_dict)
|
81 |
+
|
82 |
+
def load_pretrained(self, torch=False):
|
83 |
+
if torch:
|
84 |
+
resnet = resnet50(True)
|
85 |
+
else:
|
86 |
+
resnet = pretrainedmodels.__dict__['resnet50']()
|
87 |
+
self.backbone = nn.Sequential(*self.cut_model(resnet, 8))
|
88 |
+
self.init_head()
|
89 |
+
|
90 |
+
def init_head(self):
|
91 |
+
self.sfs = [SaveFeature(self.backbone[i]) for i in [2, 4, 5, 6]]
|
92 |
+
self.up_layer1 = UpLayer(self.block, 512, 256, self.layers[-1])
|
93 |
+
self.up_layer2 = UpLayer(self.block, 256, 128, self.layers[-2])
|
94 |
+
self.up_layer3 = UpLayer(self.block, 128, 64, self.layers[-3])
|
95 |
+
|
96 |
+
self.map = conv3x3(64 * self.block.expansion, 64) # 64e -> 64
|
97 |
+
self.conv = conv3x3(128, 64)
|
98 |
+
self.bn_conv = nn.BatchNorm2d(64)
|
99 |
+
self.up_conv = nn.ConvTranspose2d(64, 1, 2, 2, 0)
|
100 |
+
self.bn_up = nn.BatchNorm2d(1)
|
101 |
+
|
102 |
+
def forward(self, x):
|
103 |
+
x = F.relu(self.backbone(x))
|
104 |
+
x = self.up_layer1(x, self.sfs[3].features)
|
105 |
+
x = self.up_layer2(x, self.sfs[2].features)
|
106 |
+
x = self.up_layer3(x, self.sfs[1].features)
|
107 |
+
x = self.map(x)
|
108 |
+
x = F.interpolate(x, scale_factor=2)
|
109 |
+
x = torch.cat([self.sfs[0].features, x], dim=1)
|
110 |
+
x = F.relu(self.bn_conv(self.conv(x)))
|
111 |
+
x = F.relu(self.bn_up(self.up_conv(x)))
|
112 |
+
return x
|
113 |
+
|
114 |
+
def close(self):
|
115 |
+
for sf in self.sfs:
|
116 |
+
sf.remove()
|
117 |
+
|
118 |
+
def segment(self, image):
|
119 |
+
"""
|
120 |
+
image: cropped CXR PIL Image (h, w, 3)
|
121 |
+
"""
|
122 |
+
kernel = np.ones((10, 10))
|
123 |
+
iw, ih = image.size
|
124 |
+
|
125 |
+
image_tensor = self.tfm(image).unsqueeze(0).to(next(self.parameters()).device)
|
126 |
+
with torch.no_grad():
|
127 |
+
py = torch.sigmoid(self(image_tensor))
|
128 |
+
py = (py[0].cpu() > 0.5).type(torch.FloatTensor) # 1, 256, 256
|
129 |
+
|
130 |
+
mask = py[0].numpy()
|
131 |
+
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
132 |
+
mask = cv2.resize(mask, (iw, ih))
|
133 |
+
slice_y, slice_x = ndimage.find_objects(mask, 1)[0]
|
134 |
+
h, w = slice_y.stop - slice_y.start, slice_x.stop - slice_x.start
|
135 |
+
|
136 |
+
nw, nh = int(w / .875), int(h / .875)
|
137 |
+
dw, dh = (nw - w) // 2, (nh - h) // 2
|
138 |
+
t = max(slice_y.start - dh, 0)
|
139 |
+
l = max(slice_x.start - dw, 0)
|
140 |
+
b = min(slice_y.stop + dh, ih)
|
141 |
+
r = min(slice_x.stop + dw, iw)
|
142 |
+
return (t, l, b, r), mask
|
faiss_index/index.faiss
ADDED
Binary file (98.3 kB). View file
|
|
faiss_index/index.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:5bbbcdb2dfcd7004d6dff916b1523d07fb41ffcf5d8d27b80e6208789f043f90
|
3 |
+
size 394942
|
image_to_3D/3d_model_requirements.txt
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
omegaconf==2.3.0
|
2 |
+
Pillow==10.1.0
|
3 |
+
einops==0.7.0
|
4 |
+
git+https://github.com/tatsy/torchmcubes.git
|
5 |
+
transformers==4.35.0
|
6 |
+
trimesh==4.0.5
|
7 |
+
rembg
|
8 |
+
huggingface-hub
|
9 |
+
imageio[ffmpeg]
|
10 |
+
gradio
|
11 |
+
xatlas==0.0.9
|
12 |
+
moderngl==5.10.0
|
13 |
+
torch==2.0.0
|
14 |
+
setuptools==68.2.0
|
image_to_3D/__init__.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from attention import *
|
2 |
+
from basic_transformer_block import *
|
3 |
+
from image import *
|
4 |
+
from isosurface import *
|
5 |
+
from nerf_renderer import *
|
6 |
+
from network_utils import *
|
7 |
+
from rotate import *
|
8 |
+
from run import *
|
9 |
+
from transformer_1d import *
|
10 |
+
from triplane import *
|
11 |
+
from ui import *
|
12 |
+
from x3D_utils import *
|
image_to_3D/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (403 Bytes). View file
|
|
image_to_3D/__pycache__/__init__.cpython-39.pyc
ADDED
Binary file (397 Bytes). View file
|
|
image_to_3D/__pycache__/attention.cpython-310.pyc
ADDED
Binary file (15.3 kB). View file
|
|
image_to_3D/__pycache__/attention.cpython-39.pyc
ADDED
Binary file (15.1 kB). View file
|
|
image_to_3D/__pycache__/basic_transformer_block.cpython-310.pyc
ADDED
Binary file (9.59 kB). View file
|
|
image_to_3D/__pycache__/image.cpython-310.pyc
ADDED
Binary file (2.52 kB). View file
|
|
image_to_3D/__pycache__/isosurface.cpython-310.pyc
ADDED
Binary file (2.23 kB). View file
|
|
image_to_3D/__pycache__/nerf_renderer.cpython-310.pyc
ADDED
Binary file (5.29 kB). View file
|
|
image_to_3D/__pycache__/network_utils.cpython-310.pyc
ADDED
Binary file (3.4 kB). View file
|
|
image_to_3D/__pycache__/rotate.cpython-310.pyc
ADDED
Binary file (1.2 kB). View file
|
|
image_to_3D/__pycache__/run.cpython-310.pyc
ADDED
Binary file (3.65 kB). View file
|
|
image_to_3D/__pycache__/transformer_1d.cpython-310.pyc
ADDED
Binary file (4.85 kB). View file
|
|
image_to_3D/__pycache__/triplane.cpython-310.pyc
ADDED
Binary file (1.74 kB). View file
|
|
image_to_3D/__pycache__/ui.cpython-310.pyc
ADDED
Binary file (765 Bytes). View file
|
|
image_to_3D/__pycache__/x3D_utils.cpython-310.pyc
ADDED
Binary file (13.5 kB). View file
|
|