Spaces:
Sleeping
Sleeping
resume.py
Browse files
app.py
ADDED
@@ -0,0 +1,303 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from PIL import Image
|
3 |
+
import numpy as np
|
4 |
+
|
5 |
+
#載入聊天機器人模型
|
6 |
+
from transformers import AutoTokenizer, AutoModelForCausalLM,TextIteratorStreamer
|
7 |
+
from threading import Thread
|
8 |
+
|
9 |
+
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
|
10 |
+
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
|
11 |
+
device = "cuda"
|
12 |
+
model.to(device)
|
13 |
+
def chat(message, history):
|
14 |
+
prompt = [
|
15 |
+
{"role": "system", "content": "You are a helpful assistant."},
|
16 |
+
]
|
17 |
+
for i in history:
|
18 |
+
prompt.append({"role": "user", "content": i[0]})
|
19 |
+
prompt.append({"role": "assisant", "content": i[1]})
|
20 |
+
prompt.append({"role": "user", "content": message})
|
21 |
+
|
22 |
+
messages = prompt
|
23 |
+
|
24 |
+
text = tokenizer.apply_chat_template(
|
25 |
+
messages,
|
26 |
+
tokenize=False,
|
27 |
+
add_generation_prompt=True
|
28 |
+
)
|
29 |
+
|
30 |
+
model_inputs = tokenizer([text], return_tensors="pt").to("cuda")
|
31 |
+
streamer = TextIteratorStreamer(tokenizer, timeout=10., skip_prompt=True, skip_special_tokens=True)
|
32 |
+
generate_kwargs = dict(
|
33 |
+
model_inputs,
|
34 |
+
streamer=streamer,
|
35 |
+
max_new_tokens=512,
|
36 |
+
do_sample=True,
|
37 |
+
top_p=0.95,
|
38 |
+
top_k=1000,
|
39 |
+
temperature=1.0,
|
40 |
+
)
|
41 |
+
t = Thread(target=model.generate, kwargs=generate_kwargs)
|
42 |
+
t.start()
|
43 |
+
partial_message = ""
|
44 |
+
for new_token in streamer:
|
45 |
+
partial_message += new_token
|
46 |
+
yield partial_message
|
47 |
+
|
48 |
+
avatar_images = ["https://cdn-icons-png.flaticon.com/128/3135/3135715.png",
|
49 |
+
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTIJYnfODgs7q_Q4k6RoUL592NBlSF7wUTEhT92lRyqc4HTunB-"]
|
50 |
+
|
51 |
+
custom_css = """
|
52 |
+
.gradio-container {background-color: #f0f0f0;padding-top: 0px !important;}
|
53 |
+
# .container {max-width: 100px; margin: 0; font-family: 'Arial', sans-serif;}
|
54 |
+
.header {background-color: #2c3e50; color: white; padding: 10px; text-align: center; border-radius: 10px 10px 0 0;margin-bottom: 0; /* Ensure no margin below header */}
|
55 |
+
.content {background-color: white; padding: 10px; border-radius: 0 0 10px 10px; margin: 0;margin-top: 0;}
|
56 |
+
.profile-pic {width: 150px; height: 150px; border-radius: 50%; margin: 20px auto; display: block;}
|
57 |
+
.skills {display: flex; justify-content: space-around; margin-top: 20px;margin-bottom: 20px;}
|
58 |
+
.skill {text-align: center; padding: 10px; background-color: #ecf0f1; border-radius: 5px;}
|
59 |
+
.cert-row {border-bottom: 1px solid #ddd; padding: 10px 0;}
|
60 |
+
.cert-header {background-color: #f2f2f2; font-weight: bold;}
|
61 |
+
|
62 |
+
/* footer styling */
|
63 |
+
.gradio-container footer {
|
64 |
+
display: none !important;
|
65 |
+
}
|
66 |
+
.custom-footer {
|
67 |
+
text-align: center;
|
68 |
+
padding: 0; /* 减小上下内边距 */
|
69 |
+
# line-height: 1.2; /* 减小行高 */
|
70 |
+
margin-top: 0; /* 减小与上方内容的间距 */
|
71 |
+
margin-bottom: 0; /* 减小与下方内容的间距 */
|
72 |
+
}
|
73 |
+
.custom-footer p {
|
74 |
+
margin: 0; /* 移除段落的默认外边距 */
|
75 |
+
}
|
76 |
+
|
77 |
+
"""
|
78 |
+
custom_footer = """
|
79 |
+
<div class="custom-footer">
|
80 |
+
<p>© 2024 Your Company Name. All rights reserved.</p>
|
81 |
+
</div>
|
82 |
+
"""
|
83 |
+
|
84 |
+
def load_image(image_path):
|
85 |
+
img = Image.open(image_path)
|
86 |
+
return np.array(img)
|
87 |
+
|
88 |
+
#讀取頭貼
|
89 |
+
image_path = "/content/drive/My Drive/個人資料/頭貼.jpg"
|
90 |
+
# profile_array = load_image(image_path)
|
91 |
+
|
92 |
+
#讀去證照圖片
|
93 |
+
import gradio as gr
|
94 |
+
|
95 |
+
|
96 |
+
with gr.Blocks(css=custom_css,title='我的履歷') as resume_app:# title可以修改页面标题
|
97 |
+
# with gr.Column():
|
98 |
+
gr.HTML("""
|
99 |
+
<div class="header">
|
100 |
+
<h1>巫宇哲的個人簡歷</h1>
|
101 |
+
<p>軟體工程師 | AI 愛好者 | 數據分析師</p>
|
102 |
+
</div>
|
103 |
+
""")
|
104 |
+
with gr.Tab("履歷資料",elem_classes="content"):
|
105 |
+
with gr.Row():
|
106 |
+
with gr.Column(scale=1):
|
107 |
+
gr.Image('履歷資料/頭貼.jpg', elem_classes="profile-pic")
|
108 |
+
gr.Markdown("""
|
109 |
+
<div style="text-align:center;">
|
110 |
+
<p style="margin-bottom: 0;">
|
111 |
+
📧 <a href="mailto:a0903153387@yahoo.com.tw" style="text-decoration: none; color: inherit;">a0903153387@yahoo.com.tw</a>
|
112 |
+
</p>
|
113 |
+
<p style="margin-bottom: 0;">
|
114 |
+
📱 <a href="tel:+1234567890" style="text-decoration: none; color: inherit;">0916-418068</a>
|
115 |
+
</p>
|
116 |
+
<p style="margin-bottom: 0; display: flex; align-items: center; justify-content: center;">
|
117 |
+
<img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" alt="GitHub" style="width:16px; height:16px; margin-right: 5px;">
|
118 |
+
<a href="https://github.com/3A732038" target="_blank" style="text-decoration: none; color: inherit;">github.com/3A732038</a>
|
119 |
+
</p>
|
120 |
+
</div>
|
121 |
+
""")
|
122 |
+
gr.Markdown("""
|
123 |
+
關於我
|
124 |
+
===
|
125 |
+
熱衷於探索 AI 技術的軟體工程師,擅長 Python 和機器學習。
|
126 |
+
熟悉各類開發工具與框架,並具備網站開發與資料庫使用經驗。喜歡將創新想法轉化為實際應用。
|
127 |
+
""")
|
128 |
+
gr.Markdown("""
|
129 |
+
|
130 |
+
技能
|
131 |
+
===
|
132 |
+
""")
|
133 |
+
with gr.Row(elem_classes="skills"):
|
134 |
+
for skill in ["Python", "深度學習", "Web 開發", "數據分析"]:
|
135 |
+
gr.Markdown(f"<div class='skill'>{skill}</div>")
|
136 |
+
with gr.Row():
|
137 |
+
with gr.Column(scale=2):
|
138 |
+
gr.Markdown("""
|
139 |
+
特殊經歷
|
140 |
+
===
|
141 |
+
""")
|
142 |
+
prove=['file/履歷資料/研討會證明.png','file/履歷資料/助教證明.jpg','file/履歷資料/專題名次.pdf']
|
143 |
+
name=['ICIM2024研討會: 提交的研究成果被接受,並在研討會上進行了發表。','碩二下學期擔任指導教授所開的類神經網路課程助教。','大學專題實務成果展競賽亞軍,技術類業界評選第一名。']
|
144 |
+
describe=['本研究基於研究所時期的成果,題為「基於情緒支持的對話:融合情緒感知和關鍵字識別的研究」。研究旨在通過聊天機器人為情緒困擾者提供陪伴,緩解其短期心理壓力。本文提出的模型結合情緒標籤和關鍵字識別技術,與其他基礎模型相比,能夠提供更精準的回復,從而更有效地支持用戶的情緒需求。<a href="file/履歷資料/巫宇哲_研討會.pdf" target="_blank">投稿內文連結</a>',
|
145 |
+
'主要協助老師指導學生實作部分。包括使用 WEKA 軟體教導學生快速構建和分析機器學習模型,並解釋模型結果的含義。後期則引導學生安裝 Python 環境,撰寫並執行機器學習模型的程式碼,幫助學生在未來能夠運用 AI 技術更有效地完成工作。' ,
|
146 |
+
'<i>專題名稱:熱影像結合人臉偵測暨網頁瀏覽系統。</i></br>為因應新冠疫情,無接觸體溫檢測需求激增,本專題開發了利用紅外線熱影像和後端資料庫蒐集,最終實現異地閱覽和確保體溫監測的安全與效率。<a href="file/履歷資料/專題文件.pdf" target="_blank">專題內文連結</a></br></br><b>我的貢獻:硬體設備組裝、人臉偵測和後端資料庫及視覺化</b>'
|
147 |
+
]
|
148 |
+
|
149 |
+
for i in range(len(name)):
|
150 |
+
gr.HTML(f"""
|
151 |
+
<div style="margin-bottom: 10px;">
|
152 |
+
<ui>
|
153 |
+
<li>
|
154 |
+
<p style="font-size: 1.3em; font-weight: bold;">{name[i]}</p>
|
155 |
+
<span style="font-size: 1.0em; font-weight: normal;">
|
156 |
+
<a href="{prove[i]}" target="_blank">點擊查看證明</a>
|
157 |
+
</span>
|
158 |
+
</li>
|
159 |
+
</ui>
|
160 |
+
</div>
|
161 |
+
 <strong>內容簡述:</strong> {describe[i]}
|
162 |
+
</br>
|
163 |
+
</br>
|
164 |
+
""")
|
165 |
+
with gr.Column(scale=1):
|
166 |
+
gr.HTML('''
|
167 |
+
<div style="font-size: 32px; font-weight: bold; color: #2c3e50; margin: 0; padding: 0;">
|
168 |
+
證照
|
169 |
+
</div>
|
170 |
+
<hr style="border: none; border-top: 2px solid #2c3e50; margin: 1% 0;">
|
171 |
+
''')
|
172 |
+
# Certificate table header
|
173 |
+
with gr.Row(elem_classes="cert-row cert-header"):
|
174 |
+
with gr.Column(scale=1, min_width=100):
|
175 |
+
gr.Markdown("### 證照名稱")
|
176 |
+
with gr.Column(scale=1, min_width=100):
|
177 |
+
gr.Markdown("### 證照機構")
|
178 |
+
with gr.Column(scale=2, min_width=200):
|
179 |
+
gr.Markdown("### 證照照片")
|
180 |
+
|
181 |
+
# Certificate data rows
|
182 |
+
certificates = [
|
183 |
+
("電腦硬體裝修丙級", "勞動部", "履歷資料/硬體裝修丙級.jpg"),
|
184 |
+
("電腦硬體裝修乙級", "勞動部", "履歷資料/硬體裝修乙級.jpg"),
|
185 |
+
("Database Administration Fundamentals", "微軟", "履歷資料/DAF.jpg"),
|
186 |
+
("Software Development Fundamentals", "微軟", "履歷資料/SDF.jpg"),
|
187 |
+
("Networking Fundamentals", "微軟", "履歷資料/NF.png"),
|
188 |
+
("CRM Merchandise Analyst", "微析科技", "履歷資料/crm.jpg"),
|
189 |
+
("Enterprise Resource Planning", "中華企業資源規劃學會", "履歷資料/erp.jpg"),
|
190 |
+
]
|
191 |
+
|
192 |
+
for cert_name, cert_org, cert_img in certificates:
|
193 |
+
with gr.Row(elem_classes="cert-row"):
|
194 |
+
with gr.Column(scale=1, min_width=100):
|
195 |
+
gr.Markdown(cert_name)
|
196 |
+
with gr.Column(scale=1, min_width=100):
|
197 |
+
gr.Markdown(cert_org)
|
198 |
+
with gr.Column(scale=2, min_width=200):
|
199 |
+
gr.Image(cert_img, height=100, show_label=False)
|
200 |
+
with gr.Tab("專案展示",elem_classes="content"):
|
201 |
+
with gr.Row():
|
202 |
+
with gr.Column(scale=1):
|
203 |
+
gr.Markdown("""
|
204 |
+
## 學生點名系統
|
205 |
+
<strong>動機與目的:</strong> 鑒於每次上課點名都是老師的一大負擔,開發了這個學生點名系統,旨在幫助老師更有效地進行點名。本專案使用 Laravel 開源 PHP Web 框架開發,主要功能包括:
|
206 |
+
<div style="display: flex;">
|
207 |
+
<div style="width: 20%;">
|
208 |
+
<b>老師功能</b>:
|
209 |
+
</br>
|
210 |
+
- 查看課表及點名記錄</br>
|
211 |
+
- 查看學生出缺席和請假狀況</br>
|
212 |
+
- 審核學生請假申請
|
213 |
+
</div>
|
214 |
+
<div style="width: 20%;">
|
215 |
+
<b>學生功能:</b>
|
216 |
+
</br>
|
217 |
+
- 查看課表及進行點名</br>
|
218 |
+
- 查看出缺席和請假記錄</br>
|
219 |
+
- 申請請假
|
220 |
+
</div>
|
221 |
+
</div>
|
222 |
+
</br>
|
223 |
+
下圖為學生點名系統的截圖:
|
224 |
+
""")
|
225 |
+
with gr.Row():
|
226 |
+
with gr.Column(scale=1):
|
227 |
+
gr.Markdown("""老師主頁課表封面""")
|
228 |
+
gr.Image('履歷資料/網頁1.jpg',container=False)#container 決定是否外面有框框
|
229 |
+
with gr.Column(scale=1):
|
230 |
+
gr.Markdown("""老師查看出缺席""")
|
231 |
+
gr.Image('履歷資料/網頁2.jpg',container=False)
|
232 |
+
gr.Markdown("""完整專案可參閱本github:<a href="https://github.com/WISD-2020/final02" target="_blank">學生點名系統專案</a>""")
|
233 |
+
gr.Markdown("""<hr style="border-top: 2px solid;border-color:#169bf2;">""")
|
234 |
+
gr.Markdown("""
|
235 |
+
## 氣管插管預測
|
236 |
+
<strong>動機與目的:</strong>為了協助醫生在執行插管時更精確地將氧氣管置入正確位置,我們利用影像分割技術(如 TransUnet、UNet++ 等)來實現該目標。最後,我們結合邊緣檢測與形態學技術,精確量化預測與實際的誤差,以提高插管的成功率並降低風險。
|
237 |
+
該成果如下展示:
|
238 |
+
""")
|
239 |
+
#提交要的範例後顯示對應該範例氣管插管真實和預測位置
|
240 |
+
def choice(input_idx,img):
|
241 |
+
if input_idx == "example_2":
|
242 |
+
return (gr.Image('履歷資料/EET_project/ex_2_pred.jpg', container=False,interactive=False,label='影像切割所預測出來的mask',visible=True,height=310),
|
243 |
+
gr.Image('履歷資料/EET_project/ex_2_label.jpg', container=False,interactive=False,label='真實氣管的mask位置',visible=True,height=310)
|
244 |
+
)
|
245 |
+
elif input_idx == "example_3":
|
246 |
+
return (gr.Image('履歷資料/EET_project/ex_3_pred.jpg', container=False,interactive=False,label='影像切割所預測出來的mask',visible=True,height=310),
|
247 |
+
gr.Image('履歷資料/EET_project/ex_3_label.jpg', container=False,interactive=False,label='真實氣管的mask位置',visible=True,height=310)
|
248 |
+
)
|
249 |
+
else:
|
250 |
+
return (gr.Image('履歷資料/EET_project/ex_1_pred.jpg', container=False,interactive=False,label='影像切割所預測出來的mask',visible=True,height=310),
|
251 |
+
gr.Image('履歷資料/EET_project/ex_1_label.jpg', container=False,interactive=False,label='真實氣管的mask位置',visible=True,height=310)
|
252 |
+
)
|
253 |
+
|
254 |
+
# 定義一個函數來根據 Dropdown 的選擇更新圖片
|
255 |
+
def update_image(choice):
|
256 |
+
# 根據選擇返回對應的圖片
|
257 |
+
if choice == "example_1":
|
258 |
+
return '履歷資料/EET_project/ex_1_init.jpg'
|
259 |
+
elif choice == "example_2":
|
260 |
+
return '履歷資料/EET_project/ex_2_init.jpg'
|
261 |
+
elif choice == "example_3":
|
262 |
+
return '履歷資料/EET_project/ex_3_init.jpg'
|
263 |
+
with gr.Row():
|
264 |
+
with gr.Column(scale=1):
|
265 |
+
dropdown = gr.Dropdown(["example_1", "example_2", "example_3"], label="Endotracheal Tube資料", info="氣管X-ray影像", value="example_1", interactive=True)
|
266 |
+
image = gr.Image('履歷資料/EET_project/ex_1_init.jpg', container=False,interactive=False)
|
267 |
+
# 當 Dropdown 值改變時更新 Image
|
268 |
+
dropdown.change(fn=update_image, inputs=dropdown, outputs=image)
|
269 |
+
gr.Interface(choice
|
270 |
+
,inputs=[dropdown,image]
|
271 |
+
,outputs=[gr.Image(visible=False),gr.Image(visible=False)],allow_flagging='never')
|
272 |
+
gr.HTML("""成果文件檔案:<a href="file/履歷資料/EET_project/EET_doc.pdf" target="_blank">EET成果文件檔</a>  完整專案可參閱本github:<a href="https://github.com/3A732038/hw2_M11123020" target="_blank">EET專案</a>""")
|
273 |
+
gr.Markdown("""<hr style="border-top: 2px solid;border-color:#169bf2;">""")
|
274 |
+
gr.Markdown("""
|
275 |
+
## 貨車車牌辨識
|
276 |
+
<strong>動機與目的:</strong>為了提高貨車進出倉庫的效率,我們建立一個車牌辨識系統,該系統基於深度學習技術,主要透過yolo來偵測車牌位置,再透過OCR技術來識別車牌號碼,最後將車牌號碼與倉庫數據庫進行比對,以確保進出貨物的準確性。
|
277 |
+
該成果如下影片展示:
|
278 |
+
""")
|
279 |
+
with gr.Row():
|
280 |
+
with gr.Column(scale=1):
|
281 |
+
gr.Video('履歷資料/貨車車牌/video_0001.mp4',label='原始貨車影片')
|
282 |
+
with gr.Column(scale=1):
|
283 |
+
gr.Video('履歷資料/貨車車牌/video_0001_result.mkv',label='車牌辨識影片')
|
284 |
+
gr.HTML("""成果文件檔案:<a href="file/履歷資料/貨車車牌/貨車車牌_doc.pdf" target="_blank">貨車車牌成果文件檔</a>  完整專案可參閱本github:<a href="https://github.com/3A732038/hw3_M11123020" target="_blank">貨車車牌辨識專案</a>""")
|
285 |
+
gr.Markdown("""<hr style="border-top: 2px solid;border-color:#169bf2;">""")
|
286 |
+
gr.Markdown("""
|
287 |
+
## 聊天機器人
|
288 |
+
""")
|
289 |
+
gr.Markdown("""
|
290 |
+
## 與我交談
|
291 |
+
歡迎使用下方的聊天機器人與我交流!
|
292 |
+
""")
|
293 |
+
gr.ChatInterface(
|
294 |
+
chat,
|
295 |
+
chatbot=gr.Chatbot(avatar_images=avatar_images),
|
296 |
+
textbox=gr.Textbox(placeholder="輸入你的訊息...", elem_id="textbox"),
|
297 |
+
submit_btn='送出',
|
298 |
+
clear_btn='清除',
|
299 |
+
retry_btn='重新送出',
|
300 |
+
undo_btn=None
|
301 |
+
)
|
302 |
+
# gr.HTML(custom_footer)
|
303 |
+
resume_app.launch(allowed_paths=['./'],favicon_path='履歷資料/android-chrome-512x512.png')
|