File size: 8,619 Bytes
477927e
08232dd
d718096
1e2fdae
08232dd
 
 
477927e
d718096
08232dd
 
 
1e2fdae
08232dd
 
 
d718096
08232dd
 
 
d718096
08232dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d718096
08232dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477927e
d718096
477927e
 
 
 
 
 
 
 
 
 
d718096
 
477927e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08232dd
d718096
 
 
08232dd
 
 
2c435d9
 
 
 
 
 
 
 
08232dd
 
 
 
 
 
 
 
 
 
477927e
 
08232dd
 
d718096
08232dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
from logging import PlaceHolder
import gradio as gr
import os, sys
import spaces
from npc_bert_models.gradio_demo import *
from npc_bert_models.mlm_module import NpcBertMLM
from npc_bert_models.cls_module import NpcBertCLS
from npc_bert_models.summary_module import NpcBertGPT2
from npc_bert_models.app_logger import get_logger
import json

class main_window():
    logger = get_logger('main', log_level='debug')
    def __init__(self):
        self.interface = None
        self.examples = json.load(open("examples.json", 'r'))
        self.logger.info(f"Created {__class__.__name__} instance.")
        
    def initialize(self):
        #! Initialize MLM
        self.logger.info("Loading MLM interface...")
        self.npc_mlm = NpcBertMLM()
        self.npc_mlm.load()
       
        with gr.Blocks() as self.mlm_interface:
            gr.Markdown("# Masked work prediction\n"
                        "Enter any sentence. Use the token `[MASK]` to see what the model predicts.\n"
                        "## Our examples:\n"
                        "|Input masked sequence|Ground-truth masked word|\n"
                        "|---------------------|------------------------|\n"
                        + "\n".join([f"|{a}|{b}|" for a, b in zip(self.examples['mlm-inp'], self.examples['mlm-inp-GT'])]))
            
            with gr.Row():
                with gr.Column():
                    inp = gr.Textbox("The tumor is confined in the [MASK].", label='mlm-inp')
                    btn = gr.Button("Run", variant='primary')
                    
                with gr.Column():
                    out = gr.Label(num_top_classes=5)
            

            gr.Examples(self.examples['mlm-inp'], inputs=inp, label='mlm-inp')
            btn.click(fn=self.npc_mlm.__call__, inputs=inp, outputs=out)
            inp.submit(fn=self.npc_mlm.__call__, inputs=inp, outputs=out)

        #! Initialize report classification
        self.logger.info("Loading BERTCLS interface...")
        self.npc_cls = NpcBertCLS()
        self.npc_cls.load()
        
        with gr.Blocks() as self.cls_interface:
            gr.Markdown("""
                        # Report discrimination
                        
                        In this example we explored how the fine-tuned BERT aids downstream task. We further trained it
                        to do a simple task of discriminating between reports written for non-NPC patients and NPC patients.
                        
                        # Disclaimer
                        
                        The examples are mock reports that is created with reference to authentic reports, they do not
                        represent any real patients. However, it was written to be an authentic representation of NPC or
                        patient under investigation for suspected NPC but with negative imaging findings.
                        """)
            
            with gr.Row():
                with gr.Column():
                    inp = gr.TextArea(placeholder="Use examples at the bottom to load example text reports.")
                    inf = gr.File(file_types=['.txt'], label="Report file (plaintext)", show_label=True, interactive=True)
                    inf.upload(fn=self._set_report_file_helper, inputs=inf, outputs=inp)
                    inf.change(fn=self._set_report_file_helper, inputs=inf, outputs=inp)
                    btn = gr.Button("Run", variant='primary')
                    

                with gr.Column():
                    out = gr.Label(num_top_classes=2)
                
            # gr.Examples(examples=list(self.examples['reports'].values()), inputs=inp)
            gr.Examples(examples="./report_examples", inputs=inf)
            btn.click(fn=self.npc_cls.__call__, inputs=inp, outputs=out)
            inp.submit(fn=self.npc_cls.__call__, inputs=inp, outputs=out)
        
        #! Initialize report conclusion generation
        self.logger.info("Loading Bert-GPT2 interface...")
        self.npc_summary = NpcBertGPT2()
        self.npc_summary.load()
        
        with gr.Blocks() as self.summary_interface:
            gr.Markdown("""
                        # Report conclusion generation
                        
                        In this example we explored how the fine-tunned BERT can aid summarizing the reported items and 
                        generates a conclusion, which includes providing stages of the written reports. 
                        
                        > On this cloud node withonly 2 cpu, it takes ~60 second for this task.
                        
                        # Disclaimer
                        
                        Again, similar to the last experiement, the examples we list here are mock reports that are created
                        with reference to authentic reports and they do not represent any real patients. We essentiall used
                        the same reports as the last tab, but cropped away the "conclusion" part which we trian the network 
                        to generate.
                        
                        """)
        
            with gr.Row():
                with gr.Column():
                    inp = gr.TextArea(placeholder="Use examples at the bottom to load example text reports.")
                    inf = gr.File(file_types=['.txt'], label="Report file (plaintext)", show_label=True, interactive=True)
                    inf.upload(fn=self._set_report_file_helper, inputs=inf, outputs=inp)
                    inf.change(fn=self._set_report_file_helper, inputs=inf, outputs=inp)
                    btn = gr.Button("Run", variant='primary')
                    

                with gr.Column():
                    out = gr.TextArea(placeholder="Conclusion is generated here", interactive=False)
        
            gr.Examples(examples="./report_examples_summary", inputs=inf)
            btn.click(fn=self.npc_summary.__call__, inputs=inp, outputs=out)
            inp.submit(fn=self.npc_summary.__call__, inputs=inp, outputs=out)
            
        #! Create tab interface
        with gr.Blocks() as self.interface:
            # Logo
            gr.HTML(open("./assets/header.html", 'r').read())
            
            gr.Markdown("""
                        # Introduction 
                        
                        This demo aims to showcase the potential of language models fine-tuned using a meticulously curated dataset of 
                        structured MRI radiology reports for the examination of nasopharyngeal carcinoma (NPC). Our team has a proven
                        track record in researching the role of AI for the early detection of NPC, having developed an AI system that 
                        achieves high sensitivity and specificity, both exceeding 90%. However, the explainability of the system remains 
                        a significant hurdle for clinical application. This challenge is not unique to our system but is pervasive in the 
                        development of AI for radiology. Therefore, in this pilot study, we investigate the capacity of language models 
                        to comprehend the context of the disease. Our aim is to explore the integration of language models into our 
                        existing system to enhance its explainability.
                        
                        # Affliations
                        
                        * Dr. M.Lun Wong, Dept. Imaging and Interventional Radiology. The Chinese University of Hong Kong
                        
                        # Disclaimer
                        
                        This software is provided as is and it is not a clinically validated software. The authors disclaim any responsibility
                        arising as a consequence from using this demo. 
                        """)
            tabs = gr.TabbedInterface([self.mlm_interface, self.cls_interface, self.summary_interface], 
                                      tab_names=["Masked Language Model", "Report classification", "Report conclusion generation"])     

    def lauch(self):
        self.interface.launch(allowed_paths=['assets'])
        pass
            
    def _set_report_file_helper(self, file_in):
        try:
            text = open(file_in, 'r').read()
            return text
        except:
            print(f"Cannot read file {file_in}")
            # Do nothing
            pass
        

if __name__ == '__main__':
    mw = main_window()
    mw.initialize()
    mw.lauch()