Upload 7 files
Browse files- .streamlit/config.toml +2 -0
- Dockerfile +23 -0
- LICENSE +121 -0
- README.md +57 -3
- app.py +91 -0
- labels.txt +23 -0
- requirements.txt +4 -0
.streamlit/config.toml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
[global]
|
2 |
+
emailCapture = false
|
Dockerfile
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Используем официальный образ Python
|
2 |
+
FROM python:3.9-slim
|
3 |
+
|
4 |
+
# Обновляем систему и устанавливаем необходимые пакеты
|
5 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
6 |
+
build-essential \
|
7 |
+
&& rm -rf /var/lib/apt/lists/*
|
8 |
+
|
9 |
+
# Задаём рабочую директорию
|
10 |
+
WORKDIR /app
|
11 |
+
|
12 |
+
# Копируем файл зависимостей и устанавливаем их
|
13 |
+
COPY requirements.txt .
|
14 |
+
RUN pip install --no-cache-dir -r requirements.txt
|
15 |
+
|
16 |
+
# Копируем все файлы проекта
|
17 |
+
COPY . .
|
18 |
+
|
19 |
+
# Открываем порт Streamlit (по умолчанию 8501)
|
20 |
+
EXPOSE 8501
|
21 |
+
|
22 |
+
# Запускаем приложение
|
23 |
+
CMD ["streamlit", "run", "app.py", "--server.enableCORS", "false"]
|
LICENSE
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Creative Commons Legal Code
|
2 |
+
|
3 |
+
CC0 1.0 Universal
|
4 |
+
|
5 |
+
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
6 |
+
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
7 |
+
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
8 |
+
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
9 |
+
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
10 |
+
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
11 |
+
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
12 |
+
HEREUNDER.
|
13 |
+
|
14 |
+
Statement of Purpose
|
15 |
+
|
16 |
+
The laws of most jurisdictions throughout the world automatically confer
|
17 |
+
exclusive Copyright and Related Rights (defined below) upon the creator
|
18 |
+
and subsequent owner(s) (each and all, an "owner") of an original work of
|
19 |
+
authorship and/or a database (each, a "Work").
|
20 |
+
|
21 |
+
Certain owners wish to permanently relinquish those rights to a Work for
|
22 |
+
the purpose of contributing to a commons of creative, cultural and
|
23 |
+
scientific works ("Commons") that the public can reliably and without fear
|
24 |
+
of later claims of infringement build upon, modify, incorporate in other
|
25 |
+
works, reuse and redistribute as freely as possible in any form whatsoever
|
26 |
+
and for any purposes, including without limitation commercial purposes.
|
27 |
+
These owners may contribute to the Commons to promote the ideal of a free
|
28 |
+
culture and the further production of creative, cultural and scientific
|
29 |
+
works, or to gain reputation or greater distribution for their Work in
|
30 |
+
part through the use and efforts of others.
|
31 |
+
|
32 |
+
For these and/or other purposes and motivations, and without any
|
33 |
+
expectation of additional consideration or compensation, the person
|
34 |
+
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
35 |
+
is an owner of Copyright and Related Rights in the Work, voluntarily
|
36 |
+
elects to apply CC0 to the Work and publicly distribute the Work under its
|
37 |
+
terms, with knowledge of his or her Copyright and Related Rights in the
|
38 |
+
Work and the meaning and intended legal effect of CC0 on those rights.
|
39 |
+
|
40 |
+
1. Copyright and Related Rights. A Work made available under CC0 may be
|
41 |
+
protected by copyright and related or neighboring rights ("Copyright and
|
42 |
+
Related Rights"). Copyright and Related Rights include, but are not
|
43 |
+
limited to, the following:
|
44 |
+
|
45 |
+
i. the right to reproduce, adapt, distribute, perform, display,
|
46 |
+
communicate, and translate a Work;
|
47 |
+
ii. moral rights retained by the original author(s) and/or performer(s);
|
48 |
+
iii. publicity and privacy rights pertaining to a person's image or
|
49 |
+
likeness depicted in a Work;
|
50 |
+
iv. rights protecting against unfair competition in regards to a Work,
|
51 |
+
subject to the limitations in paragraph 4(a), below;
|
52 |
+
v. rights protecting the extraction, dissemination, use and reuse of data
|
53 |
+
in a Work;
|
54 |
+
vi. database rights (such as those arising under Directive 96/9/EC of the
|
55 |
+
European Parliament and of the Council of 11 March 1996 on the legal
|
56 |
+
protection of databases, and under any national implementation
|
57 |
+
thereof, including any amended or successor version of such
|
58 |
+
directive); and
|
59 |
+
vii. other similar, equivalent or corresponding rights throughout the
|
60 |
+
world based on applicable law or treaty, and any national
|
61 |
+
implementations thereof.
|
62 |
+
|
63 |
+
2. Waiver. To the greatest extent permitted by, but not in contravention
|
64 |
+
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
65 |
+
irrevocably and unconditionally waives, abandons, and surrenders all of
|
66 |
+
Affirmer's Copyright and Related Rights and associated claims and causes
|
67 |
+
of action, whether now known or unknown (including existing as well as
|
68 |
+
future claims and causes of action), in the Work (i) in all territories
|
69 |
+
worldwide, (ii) for the maximum duration provided by applicable law or
|
70 |
+
treaty (including future time extensions), (iii) in any current or future
|
71 |
+
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
72 |
+
including without limitation commercial, advertising or promotional
|
73 |
+
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
74 |
+
member of the public at large and to the detriment of Affirmer's heirs and
|
75 |
+
successors, fully intending that such Waiver shall not be subject to
|
76 |
+
revocation, rescission, cancellation, termination, or any other legal or
|
77 |
+
equitable action to disrupt the quiet enjoyment of the Work by the public
|
78 |
+
as contemplated by Affirmer's express Statement of Purpose.
|
79 |
+
|
80 |
+
3. Public License Fallback. Should any part of the Waiver for any reason
|
81 |
+
be judged legally invalid or ineffective under applicable law, then the
|
82 |
+
Waiver shall be preserved to the maximum extent permitted taking into
|
83 |
+
account Affirmer's express Statement of Purpose. In addition, to the
|
84 |
+
extent the Waiver is so judged Affirmer hereby grants to each affected
|
85 |
+
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
86 |
+
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
87 |
+
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
88 |
+
maximum duration provided by applicable law or treaty (including future
|
89 |
+
time extensions), (iii) in any current or future medium and for any number
|
90 |
+
of copies, and (iv) for any purpose whatsoever, including without
|
91 |
+
limitation commercial, advertising or promotional purposes (the
|
92 |
+
"License"). The License shall be deemed effective as of the date CC0 was
|
93 |
+
applied by Affirmer to the Work. Should any part of the License for any
|
94 |
+
reason be judged legally invalid or ineffective under applicable law, such
|
95 |
+
partial invalidity or ineffectiveness shall not invalidate the remainder
|
96 |
+
of the License, and in such case Affirmer hereby affirms that he or she
|
97 |
+
will not (i) exercise any of his or her remaining Copyright and Related
|
98 |
+
Rights in the Work or (ii) assert any associated claims and causes of
|
99 |
+
action with respect to the Work, in either case contrary to Affirmer's
|
100 |
+
express Statement of Purpose.
|
101 |
+
|
102 |
+
4. Limitations and Disclaimers.
|
103 |
+
|
104 |
+
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
105 |
+
surrendered, licensed or otherwise affected by this document.
|
106 |
+
b. Affirmer offers the Work as-is and makes no representations or
|
107 |
+
warranties of any kind concerning the Work, express, implied,
|
108 |
+
statutory or otherwise, including without limitation warranties of
|
109 |
+
title, merchantability, fitness for a particular purpose, non
|
110 |
+
infringement, or the absence of latent or other defects, accuracy, or
|
111 |
+
the present or absence of errors, whether or not discoverable, all to
|
112 |
+
the greatest extent permissible under applicable law.
|
113 |
+
c. Affirmer disclaims responsibility for clearing rights of other persons
|
114 |
+
that may apply to the Work or any use thereof, including without
|
115 |
+
limitation any person's Copyright and Related Rights in the Work.
|
116 |
+
Further, Affirmer disclaims responsibility for obtaining any necessary
|
117 |
+
consents, permissions or other rights required for any use of the
|
118 |
+
Work.
|
119 |
+
d. Affirmer understands and acknowledges that Creative Commons is not a
|
120 |
+
party to this document and has no duty or obligation with respect to
|
121 |
+
this CC0 or use of the Work.
|
README.md
CHANGED
@@ -1,3 +1,57 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Skin-ai
|
2 |
+
|
3 |
+
Skin-ai - это приложение на Streamlit для классификации кожных заболеваний с использованием обученной нейросети на PyTorch. Архитектуру использвовал ResNet-50 и обучил с разморозкой весов.
|
4 |
+
|
5 |
+
## Функционал
|
6 |
+
- Загрузка изображения кожи через веб-интерфейс
|
7 |
+
- Обнаружение и классификация заболевания
|
8 |
+
- Вывод предсказанного класса и уровня уверенности модели
|
9 |
+
|
10 |
+
### Датасет для обучения модели был взят отсюда
|
11 |
+
https://www.kaggle.com/datasets/pacificrm/skindiseasedataset
|
12 |
+
## Установка и запуск
|
13 |
+
|
14 |
+
### Локальный запуск
|
15 |
+
1. Клонируйте репозиторий:
|
16 |
+
```sh
|
17 |
+
git clone https://github.com/username/Skin-ai.git
|
18 |
+
cd Skin-ai
|
19 |
+
```
|
20 |
+
2. Установите зависимости:
|
21 |
+
```sh
|
22 |
+
pip install -r requirements.txt
|
23 |
+
```
|
24 |
+
3. Запустите приложение:
|
25 |
+
```sh
|
26 |
+
streamlit run app.py
|
27 |
+
```
|
28 |
+
|
29 |
+
### Запуск через Docker
|
30 |
+
1. Соберите Docker-образ:
|
31 |
+
```sh
|
32 |
+
docker build -t skin-ai .
|
33 |
+
```
|
34 |
+
2. Запустите контейнер:
|
35 |
+
```sh
|
36 |
+
docker run -p 8501:8501 skin-ai
|
37 |
+
```
|
38 |
+
3. Откройте в браузере:
|
39 |
+
```
|
40 |
+
http://localhost:8501
|
41 |
+
```
|
42 |
+
|
43 |
+
## Структура проекта
|
44 |
+
```
|
45 |
+
Skin-ai/
|
46 |
+
│── .github/workflows/ # GitHub Actions для CI/CD
|
47 |
+
│── .streamlit/ # Конфигурация Streamlit
|
48 |
+
│── Dockerfile # Файл для сборки Docker-образа
|
49 |
+
│── LICENSE # Лицензия проекта
|
50 |
+
│── README.md # Документация проекта
|
51 |
+
│── app.py # Основной код приложения
|
52 |
+
│── labels.txt # Файл с метками классов
|
53 |
+
│── requirements.txt # Список зависимостей
|
54 |
+
│── skin_disease_model_jit.pt # JIT-запакованная модель PyTorch
|
55 |
+
```
|
56 |
+
|
57 |
+
My telegram @eralyf
|
app.py
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import torch
|
3 |
+
from torchvision import transforms
|
4 |
+
from PIL import Image
|
5 |
+
import os
|
6 |
+
|
7 |
+
# Настройки страницы
|
8 |
+
st.set_page_config(
|
9 |
+
page_title="Классификация кожных заболеваний",
|
10 |
+
page_icon="🩺",
|
11 |
+
layout="centered",
|
12 |
+
initial_sidebar_state="collapsed"
|
13 |
+
)
|
14 |
+
|
15 |
+
# Заголовок
|
16 |
+
st.title("🩺 Классификация кожных заболеваний")
|
17 |
+
|
18 |
+
# Предупреждение
|
19 |
+
st.warning(
|
20 |
+
"⚠️ **Важно!** Данное приложение использует искусственный интеллект для анализа изображений, "
|
21 |
+
"но оно **не является медицинским инструментом**. Результаты предсказания могут быть неточными. "
|
22 |
+
"Для точной диагностики обратитесь к врачу-специалисту."
|
23 |
+
)
|
24 |
+
|
25 |
+
st.markdown("Загрузите изображение кожи, чтобы получить предсказание.")
|
26 |
+
|
27 |
+
# Ввод путей к модели и labels.txt
|
28 |
+
model_path = st.text_input("Введите путь к модели", "/home/eraly/Skin-ai/skin_disease_model_jit.pt")
|
29 |
+
labels_path = st.text_input("Введите путь к файлу labels.txt", "/home/eraly/Skin-ai/labels.txt")
|
30 |
+
|
31 |
+
# Проверка наличия модели
|
32 |
+
if not os.path.exists(model_path):
|
33 |
+
st.error(f"Модель не найдена: {model_path}")
|
34 |
+
st.stop()
|
35 |
+
|
36 |
+
# Загрузка модели
|
37 |
+
model = torch.jit.load(model_path, map_location=torch.device('cpu'))
|
38 |
+
model.eval()
|
39 |
+
|
40 |
+
# Проверка наличия labels.txt
|
41 |
+
if not os.path.exists(labels_path):
|
42 |
+
st.error("Файл меток (labels.txt) не найден.")
|
43 |
+
st.stop()
|
44 |
+
|
45 |
+
with open(labels_path, "r") as f:
|
46 |
+
labels = [line.strip() for line in f.readlines()]
|
47 |
+
|
48 |
+
# Предобработка изображений
|
49 |
+
preprocess = transforms.Compose([
|
50 |
+
transforms.Resize((224, 224)),
|
51 |
+
transforms.ToTensor(),
|
52 |
+
transforms.Normalize(mean=[0.485, 0.456, 0.406],
|
53 |
+
std=[0.229, 0.224, 0.225]),
|
54 |
+
])
|
55 |
+
|
56 |
+
# Загрузка изображения
|
57 |
+
uploaded_file = st.file_uploader("Выберите изображение", type=["jpg", "jpeg", "png"], key="file_uploader")
|
58 |
+
|
59 |
+
if uploaded_file is not None:
|
60 |
+
image = Image.open(uploaded_file).convert("RGB") # Принудительно переводим в RGB
|
61 |
+
st.image(image, caption="Загруженное изображение", use_container_width=True)
|
62 |
+
|
63 |
+
# Отображение прогресса загрузки
|
64 |
+
progress_bar = st.progress(0)
|
65 |
+
for i in range(100):
|
66 |
+
progress_bar.progress(i + 1)
|
67 |
+
|
68 |
+
# Предсказание
|
69 |
+
try:
|
70 |
+
with st.spinner("Модель обрабатывает изображение..."):
|
71 |
+
image_tensor = preprocess(image).unsqueeze(0)
|
72 |
+
with torch.no_grad():
|
73 |
+
output = model(image_tensor)
|
74 |
+
|
75 |
+
scores = torch.nn.functional.softmax(output[0], dim=0)
|
76 |
+
max_score_index = torch.argmax(scores).item()
|
77 |
+
predicted_class = labels[max_score_index]
|
78 |
+
confidence = scores[max_score_index].item()
|
79 |
+
|
80 |
+
# Вывод результата
|
81 |
+
st.markdown(f"""
|
82 |
+
### 🏥 Результат анализа:
|
83 |
+
- **Результат:** `{predicted_class}`
|
84 |
+
- **Вероятность результата:** `{confidence:.2f}`
|
85 |
+
""")
|
86 |
+
except Exception as e:
|
87 |
+
st.error(f"Ошибка при классификации: {e}")
|
88 |
+
|
89 |
+
else:
|
90 |
+
st.info("Пожалуйста, загрузите изображение.")
|
91 |
+
|
labels.txt
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Acne - Акне (угревая сыпь)
|
2 |
+
Actinic Keratosis - Актинический кератоз
|
3 |
+
Benign Tumors - Доброкачественные опухоли
|
4 |
+
Bullous - Буллезные заболевания
|
5 |
+
Candidiasis - Кандидоз
|
6 |
+
Drug Eruption - Лекарственная сыпь
|
7 |
+
Eczema - Экзема
|
8 |
+
Infestations/Bites - Паразитарные инфекции / укусы
|
9 |
+
Lichen - Лишай
|
10 |
+
Lupus - Волчанка
|
11 |
+
Moles - Родинки
|
12 |
+
Psoriasis - Псориаз
|
13 |
+
Rosacea - Розацеа (розовые угри)
|
14 |
+
Seborrheic Keratoses - Себорейный кератоз
|
15 |
+
Skin Cancer - Рак кожи
|
16 |
+
Sun/Sunlight Damage - Повреждение кожи солнцем
|
17 |
+
Tinea - Грибковые инфекции кожи (Тинея)
|
18 |
+
Unknown/Normal - Неизвестно / Норма
|
19 |
+
Vascular Tumors - Сосудистые опухоли
|
20 |
+
Vasculitis - Васкулит
|
21 |
+
Vitiligo - Витилиго
|
22 |
+
Warts - Бородавки
|
23 |
+
|
requirements.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
torch==1.13.0
|
2 |
+
torchvision==0.14.0
|
3 |
+
pillow==9.5.0
|
4 |
+
streamlit==1.26.0
|