그 점은 위험한가요? WebGPU와 EfficientNetV2로 실시간 피부 병변 분류기 만들기 🚀
Source: Dev.to
소개
헬스케어가 엣지로 이동하고 있습니다. 로컬 실행의 프라이버시와 네이티브 앱 수준의 속도를 갖춘 브라우저에서 의심스러운 피부 병변을 바로 스크리닝할 수 있다고 상상해 보세요. WebGPU API와 TensorFlow.js 덕분에 이제 EfficientNetV2와 같은 고성능 컴퓨터 비전 모델을 전례 없는 성능으로 실행할 수 있습니다.
이 튜토리얼에서는 피부 병변 분류를 위한 고성능 엣지 AI 애플리케이션을 구축하는 방법을 깊이 있게 살펴봅니다. 우리는 하드웨어 가속 추론을 위해 WebGPU를 활용하여 민감한 건강 데이터가 사용자의 장치를 떠나지 않도록 보장합니다. 브라우저에서 컴퓨터 비전을 마스터하고 싶거나 차세대 웹 그래픽 API가 딥러닝에 어떻게 활용될 수 있는지 보고 싶다면, 바로 여기입니다! 💻🥑
데이터 흐름도
graph TD
A[User Camera Stream] --> B[React Canvas Wrapper]
B --> C{WebGPU Supported?}
C -- Yes --> D[TF.js WebGPU Backend]
C -- No --> E[TF.js WebGL/CPU Fallback]
D --> F[EfficientNetV2 Inference]
F --> G[Probability Distribution]
G --> H[Medical Priority Assessment]
H --> I[UI Alert/Recommendation]
사전 요구 사항
- React 18+를 프런트엔드 구조에 사용합니다.
- TensorFlow.js (
@tensorflow/tfjs)와 WebGPU 확장. - 미세 조정된 EfficientNetV2 모델(
model.json형식으로 변환됨). - WebGPU를 지원하는 브라우저(Chrome 113+ 또는 Edge).
WebGPU 초기화
WebGPU는 WebGL의 후속 기술로, 훨씬 낮은 오버헤드와 GPU 연산 기능에 대한 더 나은 접근성을 제공합니다. TensorFlow.js에서 이를 초기화하는 것은 간단하지만 비동기 확인이 필요합니다.
import * as tf from '@tensorflow/tfjs';
import '@tensorflow/tfjs-backend-webgpu';
async function initializeAI() {
try {
// Attempt to set the backend to WebGPU
await tf.setBackend('webgpu');
await tf.ready();
console.log("🚀 Running on WebGPU: The future is here!");
} catch (e) {
console.warn("WebGPU not available, falling back to WebGL.");
await tf.setBackend('webgl');
}
}
모델 로드
EfficientNetV2는 최신 수준의 정확도를 제공하면서도 이전 모델들보다 훨씬 빠르고 작아 이 작업에 최적입니다. 우리는 ISIC(International Skin Imaging Collaboration) 데이터셋에 대해 미세 조정된 모델을 로드할 것입니다.
const MODEL_URL = '/models/efficientnet_v2_skin/model.json';
const useSkinClassifier = () => {
const [model, setModel] = React.useState(null);
React.useEffect(() => {
const loadModel = async () => {
const loadedModel = await tf.loadGraphModel(MODEL_URL);
// Warm up the model to avoid first‑inference lag
const dummyInput = tf.zeros([1, 224, 224, 3]);
loadedModel.predict(dummyInput);
setModel(loadedModel);
};
loadModel();
}, []);
return model;
};
예측 로직
핵심 로직은 비디오 프레임을 캡처하고, EfficientNetV2가 기대하는 입력인 224×224 크기로 리사이즈한 뒤, 픽셀 값을 정규화하는 것입니다.
const predict = async (videoElement, model) => {
if (!model || !videoElement) return;
const result = tf.tidy(() => {
// 1. Convert video frame to tensor
const img = tf.browser.fromPixels(videoElement);
// 2. Preprocess: Resize and Normalize to [-1, 1] or [0, 1]
const resized = tf.image.resizeBilinear(img, [224, 224]);
const offset = tf.scalar(127.5);
const normalized = resized.sub(offset).div(offset).expandDims(0);
// 3. Inference
return model.predict(normalized);
});
const probabilities = await result.data();
const topResult = getTopClass(probabilities);
// Clean up tensors
tf.dispose(result);
return topResult;
};
Production Considerations
프로토타입을 만드는 것은 쉽지만, 프로덕션 등급의 의료 스크리닝 도구를 만드는 것은 어렵습니다. 다음을 처리해야 합니다:
- 조명 변화
- 모션 블러
- 분포 외(OOD) 데이터(예: 사용자가 피부 병변 대신 개를 촬영할 때)
팁: 프로덕션 환경에서는 모델 양자화를 사용해 번들 크기를 줄이고, Web Workers를 활용해 UI 스레드를 부드럽게 유지하세요.
고위험 환경에서 AI를 배포하기 위한 고급 아키텍처 패턴을 찾고 있다면 WellAlly 블로그의 기술 심층 분석을 확인해 보세요. 여기에는 엔터프라이즈 규모 React 애플리케이션을 위한 TensorFlow 모델 최적화와 실시간 비전 파이프라인을 위한 복잡한 상태 관리에 대한 자료가 있습니다.
클래스 매핑 및 우선순위 평가
우리 시스템은 단순히 라벨을 제공하는 것이 아니라 “의료 우선순위”를 평가합니다. 우리는 멜라노마와 같은 클래스는 높은 우선순위로, 네비우스와 같은 클래스는 낮은 우선순위로 매핑합니다.
const CLASSES = {
0: { name: 'Actinic keratoses', priority: 'Medium' },
1: { name: 'Basal cell carcinoma', priority: 'High' },
2: { name: 'Benign keratosis', priority: 'Low' },
3: { name: 'Dermatofibroma', priority: 'Low' },
4: { name: 'Melanoma', priority: 'Urgent' },
5: { name: 'Melanocytic nevi', priority: 'Low' },
6: { name: 'Vascular lesions', priority: 'Medium' }
};
const getTopClass = (probs) => {
const maxIdx = probs.indexOf(Math.max(...probs));
return {
...CLASSES[maxIdx],
confidence: probs[maxIdx]
};
};
결론
우리는 로컬화된 하드웨어 가속 피부 병변 분류기를 성공적으로 구축했습니다. EfficientNetV2와 WebGPU를 사용함으로써 사용자가 “앱”을 다운로드할 필요 없이 거의 네이티브 수준의 성능을 달성합니다.
Note: AI 기반 스크리닝 도구는 전문 의료 진단을 대체하기 위한 것이 아니라 보조하기 위한 것입니다. UI에 항상 면책 조항을 포함하세요! 🩺
다음 단계는?
- 양자화(Int8 또는 Float16)를 구현해 보고 WebGPU 성능에 어떤 영향을 미치는지 확인해 보세요.
- WellAlly의 고급 가이드를 확인하여 이러한 유형의 애플리케이션을 확장하는 데 대한 더 많은 통찰을 얻으세요.
WebGPU를 이미 실험해 보셨나요? 아래에 댓글을 남겨 생각을 알려 주세요! 👇