TensorFlow.js를 사용한 예측 프리페칭

이 튜토리얼에서는 TensorFlow.js를 사용하여 리소스 예측 미리 가져오기를 수행하는 예제 웹 애플리케이션을 실행합니다. Angular 로 구축된 이 예제는 Google Merchandise Store에서 영감을 얻었지만 데이터나 구현 세부정보를 공유하지 않습니다.

이 예시에서는 사전 학습된 모델을 사용하여 예측합니다. 실제 시나리오에서는 웹 사이트의 분석을 사용하여 모델을 교육해야 합니다. TFX를 사용하여 이러한 학습을 ​​수행할 수 있습니다. 예측 프리페치를 위한 사용자 정의 모델 교육에 대해 자세히 알아보려면 이 블로그 게시물을 참조하세요.

예제 코드는 GitHub 에서 사용할 수 있습니다.

전제조건

이 튜토리얼을 완료하려면 개발 환경에 다음이 설치되어 있어야 합니다.

예제 설치

소스 코드를 가져오고 종속 항목을 설치합니다.

  1. tfjs-examples 저장소를 복제하거나 다운로드하세요.
  2. angular-predictive-prefetching/client 디렉터리로 변경하고 종속성을 설치합니다.

    cd tfjs-examples/angular-predictive-prefetching/client && yarn
    
  3. angular-predictive-prefetching/server 디렉토리로 변경하고 종속성을 설치합니다.

    cd ../server && yarn
    

예제 실행

서버와 클라이언트를 모두 시작합니다.

  1. 서버 시작: server 디렉터리에서 yarn start 실행합니다.

  2. 클라이언트를 시작합니다.

    1. 다른 터미널 창을 엽니다.
    2. tfjs-examples/angular-predictive-prefetching/client 로 변경합니다.
    3. 다음 명령을 실행하십시오.

      yarn build
      cd dist/merch-store
      npx serve -s .
      

      서비스 패키지를 설치하라는 메시지가 표시될 수 있습니다. 그렇다면 y를 입력하여 패키지를 설치하십시오.

  3. 브라우저에서 http://localhost:3000 으로 이동합니다. 모의 Google 상품 매장이 보일 것입니다.

DevTools로 탐색

Chrome DevTools를 사용하여 프리페칭이 어떻게 작동하는지 확인하세요.

  1. DevTools를 열고 Console 을 선택하세요.
  2. 앱을 준비하려면 애플리케이션의 몇 가지 다른 페이지로 이동하세요. 그런 다음 왼쪽 탐색에서 판매를 선택합니다. 다음과 같은 로그 출력이 표시됩니다.

    Navigating from: 'sale'
    'quickview' -> 0.381757915019989
    'apparel-unisex' -> 0.3150934875011444
    'store.html' -> 0.1957530975341797
    '' -> 0.052346792072057724
    'signin.html' -> 0.0007763378671370447
    

    이 출력은 귀하(사용자)가 다음에 방문할 페이지에 대한 예측을 보여줍니다. 애플리케이션은 이러한 예측을 기반으로 리소스를 가져옵니다.

  3. 가져오기 요청을 보려면 네트워크 를 선택하세요. 출력이 약간 복잡하지만 예측된 페이지에 대한 리소스 요청을 찾을 수 있습니다. 예를 들어, quickview 예측한 후 애플리케이션은 http://localhost:8000/api/merch/quickview 에 요청합니다.

예측 프리패치가 작동하는 방식

예시 앱은 사전 학습된 모델을 사용하여 사용자가 다음에 방문할 페이지를 예측합니다. 사용자가 새 페이지로 이동하면 앱은 모델을 쿼리한 다음 예측 페이지와 연결된 이미지를 미리 가져옵니다.

앱은 서비스 워커 에 대한 예측 프리페칭을 수행하므로 메인 스레드를 차단하지 않고 모델을 쿼리할 수 있습니다. 서비스 작업자는 사용자의 탐색 기록을 기반으로 향후 탐색을 예측하고 관련 제품 이미지를 미리 가져옵니다.

서비스 워커는 Angular 앱의 기본 파일인 main.ts 에 로드됩니다.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/prefetch.service-worker.js', { scope: '/' });
}

위의 코드 조각은 prefetch.service-worker.js 스크립트를 다운로드하여 백그라운드에서 실행합니다.

merch-display.comComponent.ts 에서 앱은 탐색 이벤트를 서비스 워커에게 전달합니다.

this.route.params.subscribe((routeParams) => {
  this.getMerch(routeParams.category);
  if (this._serviceWorker) {
    this._serviceWorker.postMessage({ page: routeParams.category });
  }
});

위 스니펫에서 앱은 URL 매개변수의 변경 사항을 감시합니다. 변경 시 스크립트는 페이지 카테고리를 서비스 워커에게 전달합니다.

서비스 작업자 스크립트 prefetch.service-worker.js 는 기본 스레드의 메시지를 처리하고 이를 기반으로 예측하며 관련 리소스를 미리 가져옵니다.

서비스 워커는 loadGraphModel 사용하여 사전 훈련된 모델을 로드합니다 .

const MODEL_URL = "/assets/model.json";

let model = null;
tf.loadGraphModel(MODEL_URL).then((m) => (model = m));

예측은 다음 함수 표현식 에서 발생합니다.

const predict = async (path, userId) => {
  if (!model) {
    return;
  }
  const page = pages.indexOf(path);
  const pageId = tf.tensor1d([parseInt(page)], "int32");

  const sessionIndex = tf.tensor1d([parseInt(userId)], "int32");

  const result = model.predict({
    cur_page: pageId,
    session_index: sessionIndex,
  });
  const values = result.dataSync();
  const orders = sortWithIndices(values).slice(0, 5);
  return orders;
};

그런 다음 prefetch 함수에 의해 predict 함수가 호출됩니다.

const prefetch = async (path, sessionId) => {
  const predictions = await predict(path, sessionId);
  const formattedPredictions = predictions
    .map(([a, b]) => `'${b}' -> ${a}`)
    .join("\n");
  console.log(`Navigating from: '${path}'`);
  console.log(formattedPredictions);
  const connectionSpeed = navigator.connection.effectiveType;
  const threshold = connectionSpeeds[connectionSpeed];
  const cache = await caches.open(ImageCache);
  predictions.forEach(async ([probability, category]) => {
    if (probability >= threshold) {
      const merchs = (await getMerchList(category)).map(getUrl);
      [...new Set(merchs)].forEach((url) => {
        const request = new Request(url, {
          mode: "no-cors",
        });
        fetch(request).then((response) => cache.put(request, response));
      });
    }
  });
};

먼저, prefetch 사용자가 다음에 방문할 페이지를 예측합니다. 그런 다음 예측을 반복합니다. 각 예측에 대해 연결 속도를 기준으로 확률이 특정 임계값을 초과하면 함수는 예측된 페이지에 대한 리소스를 가져옵니다. 다음 페이지 요청 전에 이러한 리소스를 가져오면 앱이 잠재적으로 콘텐츠를 더 빠르게 제공하고 더 나은 사용자 환경을 제공할 수 있습니다.

무엇 향후 계획

이 튜토리얼에서 예제 앱은 사전 학습된 모델을 사용하여 예측을 수행합니다. TFX를 사용하여 예측 미리 가져오기를 위한 모델을 학습시킬 수 있습니다. 자세한 내용은 기계 학습을 사용하여 웹페이지 미리 가져오기로 사이트 속도 향상을 참조하세요.