datnguyentien204 commited on
Commit
8e0b903
1 Parent(s): b766711

Upload 338 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +14 -35
  2. 004f33259ee4aef671c2b95d54e4be68.png +0 -0
  3. Database/student_attendance.db +0 -0
  4. Database/test_db.py +24 -0
  5. Dockerfile +27 -0
  6. README.md +12 -10
  7. a.png +3 -0
  8. a.txt +30 -0
  9. app.py +74 -0
  10. cam_result.png +3 -0
  11. chestXray14/__init__.py +7 -0
  12. chestXray14/__pycache__/__init__.cpython-310.pyc +0 -0
  13. chestXray14/__pycache__/chestXray_utils.cpython-310.pyc +0 -0
  14. chestXray14/__pycache__/chexnet.cpython-310.pyc +0 -0
  15. chestXray14/__pycache__/constant.cpython-310.pyc +0 -0
  16. chestXray14/__pycache__/heatmap.cpython-310.pyc +0 -0
  17. chestXray14/__pycache__/layers.cpython-310.pyc +0 -0
  18. chestXray14/__pycache__/test.cpython-310.pyc +0 -0
  19. chestXray14/__pycache__/unet.cpython-310.pyc +0 -0
  20. chestXray14/cam_result.png +3 -0
  21. chestXray14/chestXray_utils.py +35 -0
  22. chestXray14/chexnet.py +67 -0
  23. chestXray14/constant.py +58 -0
  24. chestXray14/heatmap.py +38 -0
  25. chestXray14/layers.py +104 -0
  26. chestXray14/models/Model.ipynb +287 -0
  27. chestXray14/models/__pycache__/densenet.cpython-310.pyc +0 -0
  28. chestXray14/models/densenet.py +71 -0
  29. chestXray14/models/dpn.py +52 -0
  30. chestXray14/models/inception.py +91 -0
  31. chestXray14/models/nasnet.py +73 -0
  32. chestXray14/models/resnet.py +57 -0
  33. chestXray14/models/resnext.py +48 -0
  34. chestXray14/models/senet.py +61 -0
  35. chestXray14/segment_result.png +3 -0
  36. chestXray14/test.py +93 -0
  37. chestXray14/unet.h5 +3 -0
  38. chestXray14/unet.py +142 -0
  39. chexnet.h5 +3 -0
  40. config.yaml +38 -0
  41. face_recognition_dynamic.gif +3 -0
  42. faiss_index/index.faiss +0 -0
  43. faiss_index/index.pkl +0 -0
  44. image_to_3D/3d_model_requirements.txt +14 -0
  45. image_to_3D/__init__.py +12 -0
  46. image_to_3D/__pycache__/__init__.cpython-310.pyc +0 -0
  47. image_to_3D/__pycache__/__init__.cpython-39.pyc +0 -0
  48. image_to_3D/__pycache__/attention.cpython-310.pyc +0 -0
  49. image_to_3D/__pycache__/attention.cpython-39.pyc +0 -0
  50. image_to_3D/__pycache__/basic_transformer_block.cpython-310.pyc +0 -0
.gitattributes CHANGED
@@ -1,35 +1,14 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz 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
 
1
+ *.h5 filter=lfs diff=lfs merge=lfs -text
2
+ a.png filter=lfs diff=lfs merge=lfs -text
3
+ cam_result.png filter=lfs diff=lfs merge=lfs -text
4
+ face_recognition_dynamic.gif filter=lfs diff=lfs merge=lfs -text
5
+ medicalDocuments/chan-doan-va-dieu-tri-benh-phoi-tac-nghen-man-tinh-copd-2018.pdf filter=lfs diff=lfs merge=lfs -text
6
+ model.ckpt filter=lfs diff=lfs merge=lfs -text
7
+ pages/images/segment_result.png filter=lfs diff=lfs merge=lfs -text
8
+ pages/output_yolov9/temp_image.png filter=lfs diff=lfs merge=lfs -text
9
+ segment_result.png filter=lfs diff=lfs merge=lfs -text
10
+ temp_image_3d.stl filter=lfs diff=lfs merge=lfs -text
11
+ temp_image.png filter=lfs diff=lfs merge=lfs -text
12
+ visualize_x3d/Eiffel_tower_sample.stl filter=lfs diff=lfs merge=lfs -text
13
+ yolov9/figure/multitask.png filter=lfs diff=lfs merge=lfs -text
14
+ yolov9/yolov9_vinbigData.pt filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
004f33259ee4aef671c2b95d54e4be68.png ADDED
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()
Dockerfile ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.8.9
2
+
3
+ WORKDIR /app
4
+
5
+ COPY ./requirements.txt /app/requirements.txt
6
+ COPY ./packages.txt /app/packages.txt
7
+
8
+ RUN apt-get update && xargs -r -a /app/packages.txt apt-get install -y && rm -rf /var/lib/apt/lists/*
9
+ RUN pip3 install --no-cache-dir -r /app/requirements.txt
10
+
11
+ # User
12
+ RUN useradd -m -u 1000 user
13
+ USER user
14
+ ENV HOME /home/user
15
+ ENV PATH $HOME/.local/bin:$PATH
16
+
17
+ WORKDIR $HOME
18
+ RUN mkdir app
19
+ WORKDIR $HOME/app
20
+ COPY . $HOME/app
21
+
22
+ EXPOSE 8501
23
+ CMD streamlit run app.py \
24
+ --server.headless true \
25
+ --server.enableCORS false \
26
+ --server.enableXsrfProtection false \
27
+ --server.fileWatcherType none
README.md CHANGED
@@ -1,10 +1,12 @@
1
- ---
2
- title: KN2024DockerFinal
3
- emoji: 🐨
4
- colorFrom: green
5
- colorTo: purple
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
+ ---
2
+ title: KN 2024 Final
3
+ emoji: 📊
4
+ colorFrom: indigo
5
+ colorTo: gray
6
+ sdk: streamlit
7
+ sdk_version: 1.38.0
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
a.png ADDED

Git LFS Details

  • SHA256: 9b89d0e21fabb41f407098f0ae402f2d232391e38f7a90c771d5a9bd090610ed
  • Pointer size: 132 Bytes
  • Size of remote file: 2.92 MB
a.txt ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Folder PATH listing for volume Data2
2
+ Volume serial number is 6AB0-11CA
3
+ E:.
4
+ +---chestXray14
5
+ � +---imges
6
+ � +---models
7
+ � � +---__pycache__
8
+ � +---__pycache__
9
+ +---image_to_3D
10
+ � +---tsr
11
+ � � +---models
12
+ � � � +---tokenizers
13
+ � � � � +---__pycache__
14
+ � � � +---transformer
15
+ � � � � +---__pycache__
16
+ � � � +---__pycache__
17
+ � � +---__pycache__
18
+ � +---__pycache__
19
+ +---pages
20
+ � +---images
21
+ +---resources_img
22
+ +---visualize_x3d
23
+ � +---__pycache__
24
+ +---youtube-streamlit-image-grid
25
+ +---data
26
+ +---images
27
+ +---cea_FaZellweger-90A-01-2
28
+ � +---.ipynb_checkpoints
29
+ +---cjbg_fbg0006
30
+ +---csg_1276
app.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import subprocess
3
+ import time
4
+ import streamlit as st
5
+
6
+ # Install torchmcubes from GitHub
7
+ st.set_page_config(layout='wide')
8
+
9
+ with st.spinner('Lung Cancer is in force...'):
10
+ time.sleep(1.8)
11
+
12
+ col_1, col_2 = st.columns([2.6, 5])
13
+
14
+ with col_1:
15
+ st.image(f'resources_img/vita.jpg', caption='Hệ thống chẩn đoán bệnh phổi sử dụng trí tuệ nhân tạo')
16
+
17
+ with col_2:
18
+ st.markdown("<h1 style='text-align: center;'>HƯỚNG DẪN SỬ DỤNG</h1>", unsafe_allow_html=True)
19
+ st.info('**1.Chức năng Scan**')
20
+ st.write("Để sử dụng tính năng Scan, bạn hãy chọn mục **🔬 Scan** trên thanh chức năng bên trái của màn hình.")
21
+ st.image('./resources_img/guide1.jpg', caption='Hình 1: Hướng dẫn sử dụng tiện ích Scan ảnh phổi (1)')
22
+ st.write("Tiếp đến, ở phía dưới bên trái màn hình có phần **Upload your scan**, tại đây, bạn có thể chọn đầu vào tiện ích Scan. "
23
+ "Đầu vào được cho phép gồm: **Ảnh**, được thể hiện trong kí hiệu (1) của hình 2 dưới đây.")
24
+ st.image('./resources_img/guide2.png', caption='Hình 2: Hướng dẫn sử dụng tiện ích Scan ảnh phổi (2)')
25
+ st.write("Đường bao màu (tím) trong hình 2 được sử dụng để tải lên ảnh Scan phổi của bệnh nhân, khi tải lên thành công ảnh sẽ hiển thị ở phần đường bao màu (xanh lá cây)")
26
+ st.write("Nếu còn chưa hiểu cách sử dụng, hãy chọn '**Hướng dẫn**' trong hộp đánh dấu màu (cam) của hình 2. Trong phần này sẽ mô tả các bước có thể làm việc với phần mềm.")
27
+
28
+ st.info('**2. Phân loại các loại bệnh phổi**')
29
+ st.write("Để sử dụng chức năng phân loại các loại bệnh phổi, bạn hãy chọn vào mục '**⭐ Thoracic Classification**' trên thanh chức năng phía bên trái màn hình. ")
30
+ st.image('./resources_img/guide3.png', caption='Hình 3: Hướng dẫn sử dụng chức năng phân loại các loại bệnh phổi')
31
+ st.write("Tiếp đến, ở phía dưới bên trái màn hình có phần **Upload your scan**, tại đây, bạn có thể chọn đầu vào tiện ích Scan. "
32
+ "Đầu vào được cho phép gồm: **Ảnh**, được thể hiện trong kí hiệu (1) của hình 2 dưới đây.")
33
+ st.write("Sau khi duyệt và chọn ảnh cần hiển thị. Nó sẽ hiển thị hiển thị cho chúng ta ảnh ở góc trái màn hình.")
34
+ st.image('./resources_img/guide3_1.png', caption='Hình 3.1: Các chức năng phân loại các loại bệnh phổi')
35
+
36
+ st.write("**2.1. Dự đoán bệnh phổi**")
37
+ st.write("Trong giao diện chức năng. Sẽ có 5 chức năng để bạn làm việc bao gồm **Predict All Scans** (1), **Cam Visualization(2), **Segmenation Visualization for Lung** (3), **View Report** (4), **Download Report** (5).")
38
+ st.write("_**Lưu ý: Phải chọn Predict All Scan trước khi dùng các chức năng khác**_")
39
+ st.write("Bước tiếp theo, bạn cần chọn Predict All Scans. Sau khi chọn **Predict All Scans**, hệ thống sẽ tự động tính toán và lấy các kết quả đầu ra.")
40
+ st.image('./resources_img/guide4.png', caption='Hình 4: Hướng dẫn sử dụng dự đoán bệnh phổi')
41
+ st.write("Sau khi chương trình chạy thành công, nó sẽ hiện thông báo màu xanh để chúng ta biết" )
42
+
43
+ st.write("**2.2. CAM Visualization**")
44
+ st.write("Để xem ảnh CAM( Class Activation Map), bạn chọn chức năng **CAM Visualization**")
45
+ st.write("Sau đó bạn có thể lướt xuống dưới để xem ảnh")
46
+ st.image('./resources_img/guide5.png', caption='Hình 5: Hướng dẫn sử dụng chức năng Sửa thông tin định danh')
47
+ st.write("Bạn có thể phóng to và thu nhỏ ảnh bằng cách di chuột vào ảnh và cuộn chuột")
48
+
49
+ st.write("**2.3. Segmentation Visualization for Lung**")
50
+ st.write("Để xem ảnh Segmentation, bạn chọn chức năng **Segmentation Visualization for Lung**")
51
+ st.write("Sau đó bạn có thể lướt xuống dưới để xem ảnh")
52
+ st.image('./resources_img/guide6.png', caption='Hình 6: Hướng dẫn sử dụng chức năng Segmentation Visualization for Lung')
53
+ st.write("Bạn có thể phóng to và thu nhỏ ảnh bằng cách di chuột vào ảnh và cuộn chuột")
54
+
55
+ st.write("**2.4. Xem báo cáo**")
56
+ st.write("Để xem ảnh báo cáo về khả năng nhiễm bệnh, bạn chọn chức năng **View Report**")
57
+ st.write("Sau đó bạn có thể lướt xuống dưới để xem bảng thông tin về khả năng nhiễm bệnh.")
58
+ st.image('./resources_img/guide7.png',
59
+ caption='Hình 7: Hướng dẫn sử dụng chức năng xem báo cáo')
60
+
61
+ st.write("**2.5. Tải báo cáo**")
62
+ st.write("Để tải báo cáo dưới dạng PDF về khả năng nhiễm bệnh, bạn chọn chức năng **View Report**")
63
+ st.write("Sau đó bạn có thể lướt xuống dưới để điền một số trường thông tin liên quan tới bệnh nhân. Sau đó chọn Submit báo cáo sẽ tự tải về máy dưới dạng PDF")
64
+ st.image('./resources_img/guide8.png',
65
+ caption='Hình 7: Hướng dẫn sử dụng chức năng tải và in báo cáo')
66
+
67
+ st.info('**4. Chức năng x3D Lung Viewer**')
68
+ st.write("There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration "
69
+ "in some form, by injected humour, or randomised words which don't look even slightly believable. If you are"
70
+ " going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the"
71
+ " middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, "
72
+ "making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined "
73
+ "with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem "
74
+ "Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.")
cam_result.png ADDED

Git LFS Details

  • SHA256: 28032e2ce7fa4a87184941c074597ac7d2422592973c3b5cf927e33da0702f6e
  • Pointer size: 132 Bytes
  • Size of remote file: 7 MB
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

Git LFS Details

  • SHA256: b023fcd2c5b2dcb172e44f1b9dcef7b32a1a171820e6c2aa49a1ee200a3062a9
  • Pointer size: 130 Bytes
  • Size of remote file: 71.8 kB
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

Git LFS Details

  • SHA256: 84f24b51f16a7358c5f353173945a536a585c270a894245fe9331b7c4cd1868f
  • Pointer size: 130 Bytes
  • Size of remote file: 38.1 kB
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
chexnet.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8d8e4e04574c0044faff5630f942ac873681be8914ba4968b6b2070362b1a340
3
+ size 28360928
config.yaml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cond_image_size: 512
2
+
3
+ image_tokenizer_cls: tsr.models.tokenizers.image.DINOSingleImageTokenizer
4
+ image_tokenizer:
5
+ pretrained_model_name_or_path: "facebook/dino-vitb16"
6
+
7
+ tokenizer_cls: tsr.models.tokenizers.triplane.Triplane1DTokenizer
8
+ tokenizer:
9
+ plane_size: 32
10
+ num_channels: 1024
11
+
12
+ backbone_cls: tsr.models.transformer.transformer_1d.Transformer1D
13
+ backbone:
14
+ in_channels: ${tokenizer.num_channels}
15
+ num_attention_heads: 16
16
+ attention_head_dim: 64
17
+ num_layers: 16
18
+ cross_attention_dim: 768
19
+
20
+ post_processor_cls: tsr.models.network_utils.TriplaneUpsampleNetwork
21
+ post_processor:
22
+ in_channels: 1024
23
+ out_channels: 40
24
+
25
+ decoder_cls: tsr.models.network_utils.NeRFMLP
26
+ decoder:
27
+ in_channels: 120 # 3 * 40
28
+ n_neurons: 64
29
+ n_hidden_layers: 9
30
+ activation: silu
31
+
32
+ renderer_cls: tsr.models.nerf_renderer.TriplaneNeRFRenderer
33
+ renderer:
34
+ radius: 0.87 # slightly larger than 0.5 * sqrt(3)
35
+ feature_reduction: concat
36
+ density_activation: exp
37
+ density_bias: -1.0
38
+ num_samples_per_ray: 128
face_recognition_dynamic.gif ADDED

Git LFS Details

  • SHA256: 78aa9bb0fcfe9dd9c4270295ff09e5bf7ed63550617d91cd50f010160a781425
  • Pointer size: 132 Bytes
  • Size of remote file: 4.03 MB
faiss_index/index.faiss ADDED
Binary file (98.3 kB). View file
 
faiss_index/index.pkl ADDED
Binary file (395 kB). View file
 
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