Skip to content

kitoku8706/skinseal-pythonAI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

33 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

์งˆ๋ณ‘์ง„๋‹จ AI ์„œ๋ฒ„

์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜ ์งˆ๋ณ‘ ์ง„๋‹จ์„ ์œ„ํ•œ Python AI ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. Flask ์›น ํ”„๋ ˆ์ž„์›Œํฌ์™€ PyTorch ๋”ฅ๋Ÿฌ๋‹ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿš€ ์ฃผ์š” ๊ธฐ๋Šฅ

  • ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ: ๋‹ค์–‘ํ•œ ์ด๋ฏธ์ง€ ํ˜•์‹ ์ง€์› (PNG, JPG, JPEG, GIF, BMP)
  • AI ์ง„๋‹จ: PyTorch ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•œ ์ž๋™ ์งˆ๋ณ‘ ์ง„๋‹จ
  • GradCAM ์‹œ๊ฐํ™”:
    • ์›๋ณธ ์ด๋ฏธ์ง€, ํžˆํŠธ๋งต, ์˜ค๋ฒ„๋ ˆ์ด ์ด๋ฏธ์ง€ ์ œ๊ณต
    • AI ํŒ๋‹จ ๊ทผ๊ฑฐ์˜ ์‹œ๊ฐ์  ์„ค๋ช…
    • Base64 ์ธ์ฝ”๋”ฉ์œผ๋กœ ์›น ์นœํ™”์  ์ „์†ก
  • REST API: JSON ํ˜•ํƒœ์˜ ์‘๋‹ต์„ ์ œ๊ณตํ•˜๋Š” RESTful API
  • ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ฆ‰์‹œ ์ง„๋‹จ ๊ฒฐ๊ณผ ์ œ๊ณต
  • ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ: ํฌ๊ด„์ ์ธ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐ ์‚ฌ์šฉ์ž ์นœํ™”์  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

skinseal-pythonAI/
โ”œโ”€โ”€ app.py                 # ๋ฉ”์ธ Flask ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (์™„์ „ ๊ธฐ๋Šฅ)
โ”œโ”€โ”€ app_simple.py          # ๊ฐ„๋‹จํ•œ Flask ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (ํ…Œ์ŠคํŠธ์šฉ)
โ”œโ”€โ”€ config.py              # ์„ค์ • ๊ด€๋ฆฌ
โ”œโ”€โ”€ utils.py               # ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค
โ”œโ”€โ”€ test_client.py         # API ํ…Œ์ŠคํŠธ ํด๋ผ์ด์–ธํŠธ
โ”œโ”€โ”€ test_gradcam_visual.py # GradCAM ์‹œ๊ฐํ™” ํ…Œ์ŠคํŠธ ํด๋ผ์ด์–ธํŠธ
โ”œโ”€โ”€ requirements.txt       # Python ์˜์กด์„ฑ ํŒจํ‚ค์ง€
โ”œโ”€โ”€ .env.example           # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์˜ˆ์‹œ ํŒŒ์ผ
โ”œโ”€โ”€ .gitignore            # Git ์ œ์™ธ ํŒŒ์ผ ๋ชฉ๋ก
โ”œโ”€โ”€ models/               # PyTorch ๋ชจ๋ธ ํŒŒ์ผ ์ €์žฅ์†Œ
โ”‚   โ””โ”€โ”€ README.md
โ”œโ”€โ”€ uploads/              # ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€ ์ž„์‹œ ์ €์žฅ์†Œ
โ”‚   โ””โ”€โ”€ README.md
โ””โ”€โ”€ .github/
    โ””โ”€โ”€ copilot-instructions.md

๐Ÿ”ง ์„ค์น˜ ๋ฐ ์„ค์ •

1. ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ

  • Python 3.8 ์ด์ƒ
  • ํ•„์š”ํ•œ Python ํŒจํ‚ค์ง€๋“ค (requirements.txt ์ฐธ์กฐ)

2. ์˜์กด์„ฑ ์„ค์น˜

pip install -r requirements.txt

3. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • (์„ ํƒ์‚ฌํ•ญ)

cp .env.example .env
# .env ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜์—ฌ ์„ค์ • ๊ฐ’๋“ค์„ ์กฐ์ •ํ•˜์„ธ์š”

4. ๋ชจ๋ธ ํŒŒ์ผ ๋ฐฐ์น˜

PyTorch ๋ชจ๋ธ ํŒŒ์ผ(20251006_212412_best_efficientnet.pth)์„ models/ ๋””๋ ‰ํ† ๋ฆฌ์— ๋ฐฐ์น˜ํ•˜์„ธ์š”.

๐Ÿš€ ์„œ๋ฒ„ ์‹คํ–‰

๋ฐฉ๋ฒ• 1: ์™„์ „ํ•œ AI ์„œ๋ฒ„ ์‹คํ–‰

python app.py

๋ฐฉ๋ฒ• 2: ๊ฐ„๋‹จํ•œ ํ…Œ์ŠคํŠธ ์„œ๋ฒ„ ์‹คํ–‰

python app_simple.py

์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋˜๋ฉด ๋‹ค์Œ ์ฃผ์†Œ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

๐Ÿ“ก API ์—”๋“œํฌ์ธํŠธ

1. ์„œ๋ฒ„ ์ƒํƒœ ํ™•์ธ

GET /

์‘๋‹ต ์˜ˆ์‹œ:

{
  "status": "healthy",
  "message": "์งˆ๋ณ‘์ง„๋‹จ AI ์„œ๋ฒ„๊ฐ€ ์ •์ƒ ์ž‘๋™ ์ค‘์ž…๋‹ˆ๋‹ค.",
  "model_loaded": true
}

2. ์งˆ๋ณ‘ ์ง„๋‹จ

POST /diagnose
Content-Type: multipart/form-data

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ:

  • image: ์ง„๋‹จํ•  ์ด๋ฏธ์ง€ ํŒŒ์ผ

์‘๋‹ต ์˜ˆ์‹œ:

{
  "results": [
    {
      "class": "์ •์ƒ",
      "probability": "95.20%"
    },
    {
      "class": "ํ”ผ๋ถ€์—ผ",
      "probability": "3.15%"
    }
  ]
}

3. GradCAM๊ณผ ํ•จ๊ป˜ ์ง„๋‹จ (์‹œ๊ฐํ™” ํฌํ•จ)

POST /api/diagnosis/{model_name}

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ:

  • file: ์ง„๋‹จํ•  ์ด๋ฏธ์ง€ ํŒŒ์ผ
  • userId: ์‚ฌ์šฉ์ž ID
  • gradcam: "true"๋กœ ์„ค์ •ํ•˜๋ฉด GradCAM ๊ฒฐ๊ณผ ํฌํ•จ
  • classIndex: (์„ ํƒ์‚ฌํ•ญ) ํŠน์ • ํด๋ž˜์Šค์— ๋Œ€ํ•œ GradCAM ์ƒ์„ฑ

์‘๋‹ต ์˜ˆ์‹œ:

{
  "results": [
    {
      "class": "ํ”ผ๋ถ€์—ผ",
      "probability": "87.30%"
    }
  ],
  "gradcam": {
    "targetIndex": 1,
    "score": 0.8730,
    "original_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    "heatmap_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
    "overlay_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."
  }
}

4. ์ „์šฉ GradCAM API

POST /api/diagnosis/{model_name}/gradcam

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ:

  • file: ์ง„๋‹จํ•  ์ด๋ฏธ์ง€ ํŒŒ์ผ
  • userId: ์‚ฌ์šฉ์ž ID
  • classIndex: (์„ ํƒ์‚ฌํ•ญ) ํŠน์ • ํด๋ž˜์Šค์— ๋Œ€ํ•œ GradCAM ์ƒ์„ฑ

์‘๋‹ต: ์œ„์™€ ๋™์ผํ•œ ํ˜•์‹์œผ๋กœ ํ•ญ์ƒ GradCAM ๊ฒฐ๊ณผ ํฌํ•จ

๐Ÿ“Š GradCAM ์‹œ๊ฐํ™” ์ดํ•ดํ•˜๊ธฐ

GradCAM(Gradient-weighted Class Activation Mapping)์€ AI ๋ชจ๋ธ์ด ์ด๋ฏธ์ง€์˜ ์–ด๋А ๋ถ€๋ถ„์„ ๋ณด๊ณ  ํŒ๋‹จ์„ ๋‚ด๋ ธ๋Š”์ง€ ์‹œ๊ฐ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

์‘๋‹ต ์ด๋ฏธ์ง€ ์„ค๋ช…

  1. original_base64: ์—…๋กœ๋“œํ•œ ์›๋ณธ ์ด๋ฏธ์ง€

    • ๋ถ„์„ ๋Œ€์ƒ์ด ๋œ ์›๋ž˜ ์ด๋ฏธ์ง€
  2. heatmap_base64: ์—ดํ™”์ƒ ๋งต (ํžˆํŠธ๋งต)

    • ๋นจ๊ฐ„์ƒ‰ ์˜์—ญ: AI๊ฐ€ ์ค‘์š”ํ•˜๊ฒŒ ๋ณธ ๋ถ€๋ถ„ (๋†’์€ ๊ด€์‹ฌ๋„)
    • ํŒŒ๋ž€์ƒ‰ ์˜์—ญ: AI๊ฐ€ ๋œ ์ค‘์š”ํ•˜๊ฒŒ ๋ณธ ๋ถ€๋ถ„ (๋‚ฎ์€ ๊ด€์‹ฌ๋„)
  3. overlay_base64: ์˜ค๋ฒ„๋ ˆ์ด ์ด๋ฏธ์ง€

    • ์›๋ณธ ์ด๋ฏธ์ง€ ์œ„์— ํžˆํŠธ๋งต์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ๊ฒน์นœ ๊ฒฐ๊ณผ
    • ์‹ค์ œ ๋ณ‘๋ณ€ ์œ„์น˜์™€ AI ํŒ๋‹จ ์˜์—ญ ๋น„๊ต ๊ฐ€๋Šฅ

ํด๋ผ์ด์–ธํŠธ ๊ตฌํ˜„ ์˜ˆ์ œ

import requests
import base64
from PIL import Image
from io import BytesIO

# GradCAM API ํ˜ธ์ถœ
response = requests.post('http://localhost:5000/api/diagnosis/efficientnet/gradcam', 
                        files={'file': ('image.jpg', open('image.jpg', 'rb'))},
                        data={'userId': 'user123'})

if response.status_code == 200:
    result = response.json()
    gradcam = result['gradcam']
    
    # Base64 ์ด๋ฏธ์ง€๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅ
    for img_type in ['original', 'heatmap', 'overlay']:
        b64_data = gradcam[f'{img_type}_base64']
        img_data = base64.b64decode(b64_data)
        
        with open(f'{img_type}.png', 'wb') as f:
            f.write(img_data)

5. ๋ชจ๋ธ ์ •๋ณด ์กฐํšŒ

GET /model/info

์‘๋‹ต ์˜ˆ์‹œ:

{
  "model_loaded": true,
  "device": "cpu",
  "model_path": "models/20251006_212412_best_efficientnet.pth"
}

๐Ÿงช ํ…Œ์ŠคํŠธ

๊ธฐ๋ณธ API ํ…Œ์ŠคํŠธ

python test_client.py

GradCAM ์‹œ๊ฐํ™” ํ…Œ์ŠคํŠธ

python test_gradcam_visual.py

์ด ํ…Œ์ŠคํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:

  • gradcam_results/diagnosis_original.png: ์›๋ณธ ์ด๋ฏธ์ง€
  • gradcam_results/diagnosis_heatmap.png: GradCAM ํžˆํŠธ๋งต
  • gradcam_results/diagnosis_overlay.png: ์›๋ณธ + ํžˆํŠธ๋งต ์˜ค๋ฒ„๋ ˆ์ด

Acne ์ „์šฉ ๋ชจ๋ธ ํ…Œ์ŠคํŠธ

python test_acne_client.py

๐Ÿ”ง ์„ค์ • ์˜ต์…˜

config.py ํŒŒ์ผ์—์„œ ๋‹ค์Œ ์„ค์ •๋“ค์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • MAX_CONTENT_LENGTH: ์—…๋กœ๋“œ ํŒŒ์ผ ์ตœ๋Œ€ ํฌ๊ธฐ (๊ธฐ๋ณธ: 16MB)
  • MODEL_PATH: PyTorch ๋ชจ๋ธ ํŒŒ์ผ ๊ฒฝ๋กœ
  • ALLOWED_EXTENSIONS: ํ—ˆ์šฉ๋œ ์ด๋ฏธ์ง€ ํŒŒ์ผ ํ™•์žฅ์ž
  • IMAGE_SIZE: ๋ชจ๋ธ ์ž…๋ ฅ ์ด๋ฏธ์ง€ ํฌ๊ธฐ (๊ธฐ๋ณธ: 224x224)

๐Ÿ“‹ ์ง€์›๋˜๋Š” ์ง„๋‹จ ํด๋ž˜์Šค

ํ˜„์žฌ ๋ชจ๋ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ”ผ๋ถ€ ์งˆํ™˜์„ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค:

  • ์ •์ƒ (Class ID: 0)
  • ํ”ผ๋ถ€์—ผ (Class ID: 1)
  • ์Šต์ง„ (Class ID: 2)
  • ๊ฑด์„  (Class ID: 3)
  • ๊ธฐํƒ€ ํ”ผ๋ถ€์งˆํ™˜ (Class ID: 4)

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ

  1. ์˜๋ฃŒ์šฉ ์ฃผ์˜: ์ด ์‹œ์Šคํ…œ์€ ์˜๋ฃŒ ์ „๋ฌธ๊ฐ€์˜ ์ง„๋‹จ์„ ๋Œ€์ฒดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ๊ฐœ๋ฐœ ์„œ๋ฒ„: Flask ๋‚ด์žฅ ์„œ๋ฒ„๋Š” ๊ฐœ๋ฐœ์šฉ์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” Gunicorn, uWSGI ๋“ฑ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.
  3. ๋ชจ๋ธ ํŒŒ์ผ: ์šฉ๋Ÿ‰์ด ํฐ ๋ชจ๋ธ ํŒŒ์ผ์€ Git์— ์ปค๋ฐ‹ํ•˜์ง€ ๋งˆ์„ธ์š”.
  4. ๋ณด์•ˆ: ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์ ์ ˆํ•œ ์ธ์ฆ ๋ฐ ๋ณด์•ˆ ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

๐Ÿ”ง ๊ฐœ๋ฐœ ํ™˜๊ฒฝ

VS Code์—์„œ ๊ฐœ๋ฐœํ•  ๋•Œ:

  1. Python ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ์„ค์น˜
  2. Pylance ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ์„ค์น˜
  3. ํ„ฐ๋ฏธ๋„์—์„œ python app.py ์‹คํ–‰ ๋˜๋Š” VS Code ์ž‘์—… ์‚ฌ์šฉ

๐Ÿ“ ๋ผ์ด์„ ์Šค

์ด ํ”„๋กœ์ ํŠธ๋Š” ์˜๋ฃŒ AI ์—ฐ๊ตฌ ๋ฐ ๊ฐœ๋ฐœ ๋ชฉ์ ์œผ๋กœ ์ œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค ๊ธฐ์—ฌ

๋ฒ„๊ทธ ๋ฆฌํฌํŠธ, ๊ธฐ๋Šฅ ์ œ์•ˆ, ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!


๊ฐœ๋ฐœ์ž: SkinSeal AI Team
๋ฒ„์ „: 1.0.0
๋งˆ์ง€๋ง‰ ์—…๋ฐ์ดํŠธ: 2025๋…„ 10์›” 6์ผ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages