본문 바로가기
AI2025년 5월 8일8분 읽기

TensorFlow.js 브라우저에서 머신러닝 모델 실행하기

YS
김영삼
조회 734

브라우저 ML의 장점

TensorFlow.js는 JavaScript로 머신러닝 모델을 학습하고 추론할 수 있는 라이브러리입니다. 브라우저에서 직접 모델을 실행하면 서버 왕복 지연이 없고, 사용자 데이터가 디바이스를 떠나지 않아 프라이버시를 보장하며, GPU 가속(WebGL/WebGPU)을 활용할 수 있습니다.

설치 및 백엔드 설정

// npm 설치
npm install @tensorflow/tfjs @tensorflow/tfjs-backend-webgl

// CDN 사용
// <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs"></script>

import * as tf from '@tensorflow/tfjs';

// 백엔드 설정 (성능 순: webgpu > webgl > wasm > cpu)
await tf.setBackend('webgl');
await tf.ready();
console.log('Backend:', tf.getBackend());

// WebGPU 사용 (Chrome 113+)
// import '@tensorflow/tfjs-backend-webgpu';
// await tf.setBackend('webgpu');

사전 학습 모델 사용

// 이미지 분류 - MobileNet
import * as mobilenet from '@tensorflow-models/mobilenet';

const model = await mobilenet.load({ version: 2, alpha: 1.0 });
const img = document.getElementById('image');
const predictions = await model.classify(img, 5);

console.log(predictions);
// [{ className: "golden retriever", probability: 0.92 }, ...]

// 객체 탐지 - COCO-SSD
import * as cocoSsd from '@tensorflow-models/coco-ssd';

const detector = await cocoSsd.load();
const detections = await detector.detect(img);
detections.forEach(det => {
  console.log(det.class, det.score, det.bbox);
  // "person" 0.95 [x, y, width, height]
});

실시간 웹캠 추론

async function startWebcamDetection() {
  const video = document.getElementById('webcam');
  const canvas = document.getElementById('overlay');
  const ctx = canvas.getContext('2d');

  // 웹캠 스트림 시작
  const stream = await navigator.mediaDevices.getUserMedia({
    video: { width: 640, height: 480 }
  });
  video.srcObject = stream;
  await video.play();

  const model = await cocoSsd.load({ base: 'lite_mobilenet_v2' });

  async function detectFrame() {
    const predictions = await model.detect(video);

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    predictions.forEach(pred => {
      const [x, y, w, h] = pred.bbox;
      ctx.strokeStyle = '#00ff00';
      ctx.lineWidth = 2;
      ctx.strokeRect(x, y, w, h);
      ctx.fillStyle = '#00ff00';
      ctx.font = '16px sans-serif';
      ctx.fillText(
        `${pred.class} (${(pred.score * 100).toFixed(1)}%)`,
        x, y - 5
      );
    });

    requestAnimationFrame(detectFrame);
  }

  detectFrame();
}

Python 모델을 TensorFlow.js로 변환

# Python에서 모델 저장
model.save('saved_model/my_model')

# TensorFlow.js 형식으로 변환
pip install tensorflowjs

# SavedModel -> TF.js
tensorflowjs_converter \
  --input_format=tf_saved_model \
  --output_format=tfjs_graph_model \
  --signature_name=serving_default \
  --saved_model_tags=serve \
  saved_model/my_model \
  web_model/

# Keras H5 -> TF.js
tensorflowjs_converter \
  --input_format=keras \
  --output_format=tfjs_layers_model \
  model.h5 \
  web_model/

# 양자화로 모델 크기 축소
tensorflowjs_converter \
  --input_format=tf_saved_model \
  --quantize_uint8 \
  saved_model/my_model \
  web_model_quantized/

변환된 모델 로드 및 추론

// Graph 모델 로드
const model = await tf.loadGraphModel('/web_model/model.json');

// 이미지 전처리 및 추론
function preprocessImage(imgElement) {
  return tf.tidy(() => {
    const tensor = tf.browser.fromPixels(imgElement)
      .resizeBilinear([224, 224])
      .toFloat()
      .div(255.0)
      .expandDims(0);
    return tensor;
  });
}

const input = preprocessImage(document.getElementById('photo'));
const output = model.predict(input);
const probabilities = await output.data();
input.dispose();
output.dispose();

성능 최적화

기법효과적용 방법
tf.tidy()메모리 누수 방지텐서 연산을 tidy 블록으로 감싸기
양자화 (uint8)모델 크기 75% 감소변환 시 --quantize_uint8
WebGL 프리워밍첫 추론 속도 개선더미 입력으로 사전 실행
모델 캐싱재방문 시 로딩 제거IndexedDB에 저장
WebWorkerUI 블로킹 방지추론을 워커 스레드에서 실행
  • 모바일 브라우저에서는 MobileNet, EfficientNet-Lite 같은 경량 모델을 사용하세요
  • tf.tidy()를 빠뜨리면 텐서가 누적되어 메모리 부족이 발생합니다
  • WebGPU 백엔드가 사용 가능하면 WebGL 대비 2-5배 성능 향상을 기대할 수 있습니다

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록