AI

Bright Data를 활용한 PyTorch 기반 다중 모달 머신러닝 파이프라인

이 가이드는 PyTorch와 Bright Data를 사용하여 전자상거래 제품 이미지를 양호/불량으로 분류하는 모델을 단계별로 훈련하는 방법을 보여줍니다.
5 분 읽기
PyTorch with Bright Data

이 튜토리얼을 마치면 다음을 이해하게 됩니다:

  • PyTorch가 다중 모달 머신러닝 워크플로 구축에 탁월한 선택인 이유.
  • Bright Data가 제공하는 것과 같이 수백만 건의 레코드를 포함하는 데이터셋으로부터 신뢰할 수 있는 데이터의 신뢰할 수 있는 출처의 필요성.
  • PyTorch에서 Bright Data 데이터셋을 활용하여 다중 모달 프로세스에서 제품 이미지 분류를 위한 ML 모델을 미세 조정하는 방법.

자, 시작해 보겠습니다!

다중 모달 머신 러닝에 PyTorch를 사용하는 이유

데이터는 그로부터 도출되는 통찰력만큼만 가치가 있습니다. 기업에게 올바른 접근 방식으로 데이터를 활용하는 것은 더 현명한 의사 결정, 전략 개선, 고객 유지율 및 마케팅 성과 향상과 같은 결과로 이어질 수 있습니다.

현대 머신러닝은 평점이나 판매 실적 같은 구조화된 데이터뿐만 아니라 이미지, 텍스트, 심지어 동영상과 같은 비정형 데이터도 처리할 수 있게 합니다. 이는 다중 모달 통찰력의 문을 열어줍니다. 예를 들어, 리뷰 이미지와 텍스트를 결합하면 고객 참여를 유도하는 요인에 대한 풍부한 이해를 얻을 수 있습니다.

본 글은 딥 뉴럴 네트워크 구축 및 훈련에 널리 사용되는 파이썬 머신러닝 프레임워크인 PyTorch를 기반으로 합니다. 이 라이브러리는 이미지 분류, 자연어 처리, 다양한 데이터 유형을 함께 분석하는 복합 워크플로우 등 광범위한 작업을 지원합니다.

PyTorch의 일반적인 적용 사례는 다음과 같습니다:

  • 제품 이미지 품질 평가: 이미지가 시각적으로 매력적이고 고객 참여를 유도할 가능성이 있는지 자동으로 판단합니다.
  • 고객 감정 분석: 텍스트 리뷰에서 통찰력을 추출하여 사용자 의견과 만족도를 파악합니다.
  • 추천 시스템 구축: 텍스트와 이미지 특징을 결합하여 더 정확하고 개인화된 제품 제안을 생성합니다.
  • 다중 모달 데이터 예측 모델링: 시각적 정보와 텍스트 정보를 함께 활용하여 트렌드, 판매량 또는 고객 행동을 예측합니다.

기업을 위한 고품질 다중 모달 데이터 확보 방법

개발하는 머신 러닝 또는 AI 애플리케이션의 유형에 상관없이, 이러한 시스템은 훈련에 사용된 데이터만큼만 효과적이라는 점을 기억해야 합니다.

멀티모달 애플리케이션에서는 텍스트와 시각적 형식의 정보를 모두 수집해야 하기 때문에 데이터 소싱이 특히 어려울 수 있습니다. 바로 여기에서 Bright Data와 같은 신뢰할 수 있는 데이터 공급자가 필요합니다.

Bright Data는 스타트업부터 대기업까지 모든 규모의 기업을 위한 AI 및 머신러닝 지원 솔루션 제품군을 제공합니다:

  • 웹 스크레이퍼 API: 수백 개의 인기 웹사이트에서 구조화된 데이터에 대한 프로그래매틱 접근을 제공하여 대규모로 최신 웹 데이터를 자동 수집할 수 있게 합니다.
  • 데이터셋 마켓플레이스: 이미지, 텍스트, 구조화된 필드를 포함한 수십억 개의 항목으로 구성된 즉시 사용 가능한 다중 모달 데이터셋을 제공합니다.
  • 관리형 데이터 수집 서비스: 스크래핑 파이프라인 구축 및 유지 관리 없이도 팀이 데이터를 획득하고 유지할 수 있도록 지원하는 완전 관리형 엔터프라이즈급 솔루션입니다.
  • 데이터 어노테이션 서비스: NLP, 컴퓨터 비전, 음성 인식 작업을 위한 확장 가능하고 맞춤 설정 가능한 어노테이션 솔루션입니다.

이러한 솔루션을 통해 연구원, 중소기업 및 대기업은 공개 웹 데이터를 효율적으로 수집하고 통합할 수 있습니다. 이를 활용하여 다중 모드 머신 러닝 워크플로우를 구동하고, 정교한 AI 모델을 훈련하고, 지능형 에이전트를 개발하고, 분석 및 비즈니스 인텔리전스 시스템을 구축할 수 있습니다.

Bright Data 데이터 세트를 사용한 PyTorch 기반 다중 모달 머신 러닝 분석 파이프라인 구축 방법

이 가이드 섹션에서는 텍스트 및 이미지 데이터가 모두 포함된 Bright Data의 “Amazon 제품” 데이터 세트로 머신 러닝 모델을 훈련하는 방법을 배웁니다.

온라인 제품을 판매하며 적절한 이미지로 제품을 선보이는 것의 중요성을 이해하고 있다고 가정하겠습니다. 목표는 PyTorch를 사용하여 전자상거래 제품 이미지와 해당 평가 정보를 기반으로 머신러닝 모델을 훈련하는 것입니다. 이 모델은 제품 이미지가 “좋은”지 “나쁜”지를 자동으로 평가하는 역할을 수행하게 됩니다.

이러한 다중 모달 머신러닝 워크플로우 덕분에 귀사는 제품 이미지가 고객을 유치하고 참여도를 높일 가능성을 프로그래밍 방식으로 평가할 수 있습니다.

참고: 이는 단순한 예시입니다. PyTorch와 Bright Data 데이터셋 및 데이터 피드를 함께 활용하면 다양한 다른 사용 사례와 시나리오를 커버할 수 있습니다.

아래 지침을 따르세요!

필수 조건

이 섹션을 따라가려면 다음이 설치되어 있어야 합니다:

또한 ResNet-18 모델과 미세 조정(fine-tuning) 작동 방식에 대한 이해는 다중 모달 PyTorch 이미지 분류 논리를 완전히 이해하는 데 도움이 될 것입니다.

1단계: JupyterLab 프로젝트 생성

다중 모달 데이터 작업 시 데이터셋을 시각화하는 것이 유용합니다. 따라서 JupyterLab은 개발 환경으로 탁월한 선택입니다. 이후 워크플로우가 개발되면 코드를 쉽게 생산 환경에 적용 가능한 머신러닝 파이프라인으로 전환할 수 있습니다.

전용 프로젝트 폴더를 생성하고 해당 폴더로 이동하여 시작합니다:

mkdir pytorch-brightdata-product-image-analysis
cd pytorch-brightdata-product-image-analysis

다음으로, 해당 폴더 내에서 가상 환경을 초기화합니다:

python -m venv .venv

macOS/Linux에서는 다음 명령어로 가상 환경을 활성화하세요:

source .venv/bin/activate

Windows에서는 다음 명령을 실행하세요:

.venvScriptsactivate

가상 환경이 활성화된 상태에서 jupyterlab 패키지를 통해 JupyterLab을 설치합니다:

pip install jupyterlab

다음 명령어로 JupyterLab 실행:

jupyter lab

브라우저에서 http://localhost:8888/lab/로 접속하면 JupyterLab 인터페이스가 열립니다. “Notebook” 섹션 아래의 “Python 3 (ipykernel)” 버튼을 클릭하여 새 노트북을 생성하세요:
Pressing the “Python 3 (ipykernel)” button

Untitled.ipynb 파일이 표시됩니다:
The new “Untitled.ipynb“ notebook
새 노트북에 “Bright Data + PyTorch”와 같은 이름을 지정하고 저장하세요.

완료! 이제 PyTorch를 통한 다중 모달 머신러닝 워크플로 개발을 위한 완벽한 Python 환경이 구축되었습니다.

2단계: 필수 종속성 설치 및 임포트

노트북에 다음 pip 명령어가 포함된 새 코드 셀을 추가하세요

!pip install pillow tqdm requests scikit-learn torch torchvision pandas

이 블록을 실행하여 필요한 모든 라이브러리를 설치하세요:

  • pillow: 이미지 로딩 및 처리를 위한 라이브러리입니다.
  • tqdm: 루프 진행률 표시를 위한 것으로, 데이터 로딩 및 훈련 추적에 유용합니다.
  • requests: HTTP 요청을 통해 URL에서 이미지를 다운로드하기 위한 라이브러리입니다.
  • scikit-learn: 데이터셋 분할을 위한 train_test_split 같은 도구 제공.
  • torch: 머신러닝 모델 구축 및 훈련을 위한 핵심 PyTorch 라이브러리.
  • torchvision: 데이터셋, 사전 훈련된 모델 및 이미지 변환 기능을 제공합니다.
  • pandas: CSV 파일과 같은 구조화된 데이터를 처리하고 데이터 조작을 용이하게 합니다.

다른 코드 셀에서 필요한 모든 모듈을 임포트하세요:

import os
import io
import json
import requests
from PIL import Image, ImageStat
from tqdm import tqdm
from sklearn.model_selection import train_test_split
import pandas as pd

import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, models
from tqdm import tqdm

from PIL import Image

훌륭합니다! 이 두 셀로 노트북이 Bright Data 다중 모달 데이터셋을 처리하고 PyTorch를 사용한 이미지 및 텍스트 처리를 수행할 준비가 완전히 되었습니다.

3단계: Bright Data 데이터셋 다운로드

이제 PyTorch 개발을 위한 노트북 설정이 완료되었으니, 이 워크플로의 가장 중요한 구성 요소인 입력 데이터를 가져올 차례입니다!

이 튜토리얼에서는 Bright Data에서 제공하는 여러 전자상거래 데이터셋 중 하나인 “Amazon products”데이터셋을 사용할 것입니다. 작성 시점 기준으로 해당 데이터셋은 3억 1,100만 개 이상의 항목을 포함하며, 각 항목은 87개의 데이터 필드를 가지고 있습니다. 각 상품에 대해 이러한 필드에는 이미지 URL, 리뷰 평점, 상품 ASIN 등 다양한 정보가 포함됩니다.

참고: Bright Data eCommerce Scraper를 사용하면 Amazon, eBay, Walmart 등 다양한 플랫폼에서 최신 구조화된 데이터를 수집할 수 있습니다.

시작하기 위해, 아직 Bright Data 계정이 없다면 계정을 생성하세요. 이미 계정이 있다면 로그인 후 계정의 “데이터셋 마켓플레이스” 페이지로 이동하세요:
The “Dataset marketplace” page on your Bright Data account

“가장 인기 있는” 항목 중에서 “Amazon products” 데이터셋을 선택하세요:
Selecting the “Amazon products” dataset

데이터셋 페이지로 이동합니다:
The “Amazon products” dataset
여기서 항목을 수동으로 필터링하거나 AI 기반 필터를 활용해 필요에 맞는 하위 집합을 생성할 수 있습니다. 해당 필터는 Filter API를 통해 프로그래밍 방식으로 적용할 수도 있으며, 이를 통해 특정 기준에 기반한 데이터셋 스냅샷을 생성할 수 있습니다.

이 튜토리얼에서는 다중 모드 머신러닝 워크플로를 시연하기 위한 소규모 샘플 데이터셋만 필요하므로 무료 샘플 데이터셋으로 충분합니다. 실제 운영 환경이나 기업용 워크플로를 구축하려면 특정 요구사항에 맞춰 구성된 전체 데이터셋을 다운로드해야 합니다.

샘플 데이터셋을 다운로드하려면 “Dataset sample” 드롭다운을 열고 “Download as CSV”를 선택하세요:
Selecting the “Download as CSV” option

Amazon products.csv라는 이름의 파일(1,000개 제품 포함, 약 7.3MB)을 받게 됩니다. 이 파일의 이름을 amazon_products.csv로 변경하고 프로젝트 폴더에 저장하세요:
The amazon_products.csv file analyzed in JupyterLab

사용 가능한 87개 필드 중 이 다중 모달 워크플로와 관련된 필드는 다음과 같습니다:

  • asin: 아마존의 고유 제품 식별자.
  • image_url: 제품의 메인 이미지 URL입니다.
  • images: 제품의 추가 이미지 URL을 포함하는 JSON 형식 배열.
  • rating: 1~5점 척도의 평균 고객 리뷰 평점.

이 필드들을 통해 다중 모달 PyTorch ML 워크플로우에서 시각적 데이터(이미지)와 구조화된 수치 데이터(평점)를 결합할 수 있습니다. 훌륭합니다! 이제 입력 데이터셋을 확보했습니다.

4단계: 제품 이미지 다운로드 및 라벨링 로직 정의

노트북으로 돌아가 이미지 다운로드 및 라벨링 기능을 추가하여 핵심 로직을 초기화하세요. 이 두 기능은 ML 이미지 분류 프로세스 구현의 기본 구성 요소로, 다음 단계를 수행합니다:

  1. Bright Data의 “Amazon products” 데이터셋에서 image_url, images 배열, rating, asin을 포함한 제품 데이터를 수집합니다.
  2. 각 제품 항목에 대한 이미지 URL을 추출하고 중복 제거합니다.
  3. 모든 URL에서 이미지를 다운로드하여 로컬에 저장합니다.
  4. 시각적 특징(흰색 배경, 해상도)과 리뷰 평점을 결합하여 이미지에 라벨을 지정합니다.
  5. 라벨링된 이미지를 사용하여 CNN(Convolutional Neural Network) 모델 훈련에 적합한 PyTorch 데이터셋을 준비합니다.
  6. 라벨링된 데이터셋을 사용하여 이미지 품질(“GOOD” 대 “BAD”)을 예측하도록 CNN을 미세 조정합니다.
  7. 테스트 세트에서 모델을 평가합니다.
  8. 모델을 사용하여 새로운 제품 이미지를 자동으로 평가합니다.

노트북의 새 코드 셀에 제품 이미지 다운로드 및 라벨링 함수를 작성하세요:

def download_image(url):
    # 이미지의 URL로 GET 요청 전송
    response = requests.get(url)

    # 응답 내용을 BytesIO 객체로 읽기
    image_bytes = io.BytesIO(response.content)

    # PIL로 이미지 열고 RGB 모드로 변환
    image = Image.open(image_bytes).convert("RGB")

    return image

def label_image(image, rating):
    # 이미지 너비와 높이 가져오기
    w, h = image.size

    # 테두리 밝기 분석을 위해 상단 10픽셀 잘라내기
    border = image.crop((0, 0, w, 10))

    # 테두리 통계값(평균) 계산
    stat = ImageStat.Stat(border)

    # RGB 채널별 평균 밝기 계산
    brightness = sum(stat.mean) / 3

    # 이미지가 흰색 배경을 가지는지 판단
    is_white_bg = brightness > 240

    # 이미지가 저해상도인지 판단 (최소 변 < 400px)
    is_low_res = min(image.size) < 400

    # 경험적 라벨: 흰색 배경이고 저해상도가 아니면 1=좋음, 그 외 0=나쁨
    heuristic_label = 1 if (is_white_bg and not is_low_res) else 0

    # 평가 점수가 없거나 0인 경우, 경험적 라벨만 사용
    if rating is None or rating == 0:
        return heuristic_label

    # 평가 점수를 0-1 범위로 정규화
    r = rating / 5

    # 극단적 평가 점수에 기반해 라벨을 조정하는 약한 감독 적용
    if heuristic_label == 1 and r < 0.5:   # 매우 낮은 평가 → 나쁨으로 표시
        return 0
    if heuristic_label == 0 and r > 0.9:   # 매우 높은 평가 → 좋음으로 표시
        return 1

    # 그 외의 경우, 휴리스틱 라벨 유지
    return heuristic_label

download_image() 함수는 단순히 지정된 URL에서 이미지를 다운로드하여 PIL Image 인스턴스로 반환합니다. 반면 label_image() 함수는 시각적 단서와 고객 평점 같은 텍스트/수치 데이터를 결합하여 제품 이미지에 대한 다중 모드 평가를 구현합니다.

label_image() 는 먼저 백색 배경과 충분한 해상도 확인 같은 휴리스틱을 적용해 초기 “양호” 또는 “불량” 라벨을 할당합니다. 그런 다음 평점이 존재할 경우 함수는 다음과 같이 라벨을 조정합니다:

  • 매우 낮은 평점은 시각적으로 양호한 이미지를 무효화합니다.
  • 우수한 평가는 외관이 나쁜 이미지를 구제합니다.

이 논리는 이미지가 좋아 보여도 낮은 평점은 유용하지 않음을 나타내므로 타당합니다. 반대로 우수한 평점은 품질이 낮은 이미지임에도 성공적인 이미지를 부각시킬 수 있습니다. 따라서 최종 라벨을 할당할 때 시각적 정보와 수치적 정보 모두를 고려합니다.

멋지네요! 이제 데이터셋을 불러오고, 모든 이미지에 이 두 함수를 적용할 제품 항목을 준비할 시간입니다.

단계 #5: 데이터셋 로드 및 모든 이미지 다운로드 준비

amazon_products.csv 파일을 살펴보면 제품 이미지가 두 데이터 필드에 저장되어 있음을 확인할 수 있습니다:

  1. image_url: 주요 제품 이미지의 URL.
  2. images: 모든 추가 제품 이미지의 배열을 포함하는 JSON 형식의 문자열.

새 코드 블록에서 CSV를 로드하고 헬퍼 함수를 사용해 각 제품의 모든 이미지를 가져옵니다:

def extract_image_list(row):
    image_urls = []

    # 메인 image_url이 하나 있는지 확인하고, 존재하며 비어 있지 않으면 추가
    if isinstance(row.get("image_url"), str) and row["image_url"].strip():
        image_urls.append(row["image_url"].strip())

    # "images" 필드 확인 (JSON 문자열 또는 Python 리스트일 수 있음)
    images_field = row.get("images")

    if isinstance(images_field, str):
        # JSON 문자열을 Python 리스트로 디코딩
        decoded = json.loads(images_field)
        if isinstance(decoded, list):
            # 리스트의 모든 이미지를 image_urls에 추가
            image_urls.extend(decoded)

    # URL을 집합으로 변환한 후 다시 리스트로 변환하여 중복 제거
    return list(set(image_urls))

# Amazon 제품 CSV를 DataFrame으로 로드
df = pd.read_csv("amazon_products.csv")

# 필수 필드가 누락된 행 제거
df = df.dropna(subset=["asin", "image_url", "images", "rating"])

# 각 행에 extract_image_list 함수 적용하여 모든 고유 이미지 URL 목록 생성
df["all_image_urls"] = df.apply(extract_image_list, axis=1)

이제 가져온 데이터셋에는 all_image_urls라는 새 열이 생겼습니다. 여기에는 메인 이미지와 추가 이미지를 합친 중복 제거된 모든 이미지 URL 목록이 저장됩니다. 다음 단계에서는 이 필드에 접근하여 각 상품의 모든 이미지를 다운로드하고 처리할 것입니다!

단계 #6: 모든 이미지 다운로드 및 라벨링

셀에서 모든 제품 이미지를 로컬 images/ 폴더로 다운로드하고 라벨링하는 로직을 구현하세요:

# "images" 폴더가 존재하지 않으면 생성
os.makedirs("images", exist_ok=True)

# 다운로드 및 라벨링된 각 이미지의 메타데이터를 저장할 리스트 초기화
records = []

# 진행률 표시와 함께 DataFrame의 각 제품 행 반복
for idx, row in tqdm(df.iterrows(), total=len(df)):
    # 필요한 상품 데이터 필드 접근
    url_list = row["all_image_urls"]
    rating = float(row["rating"])
    asin = row.get("asin")

    # 해당 상품의 각 이미지 URL을 순회하며 다운로드 및 라벨링
    for i, url in enumerate(url_list):
        # 이미지 다운로드
        image = download_image(url)
        if image is None:
            continue

        # ASIN과 이미지 인덱스를 사용해 파일명 생성
        filename = f"{asin}_{i}.jpg"
        path = os.path.join("images", filename)

        # 다운로드한 이미지 디스크 저장
        image.save(path)

        # 다중 모달 정보를 사용하여 이미지에 레이블 지정
        label = label_image(image, rating)

        # 이 이미지의 관련 메타데이터 저장
        records.append({
            "asin": asin,
            "image_path": path,
            "image_url": url,
            "label": label
        })

# 레코드 목록을 DataFrame으로 변환하고 CSV 파일로 내보내기
labeled_df = pd.DataFrame(records)
labeled_df.to_csv("labeled_images.csv", index=False)

노트북에서 이 코드 블록을 실행하면 다운로드 프로세스가 시작됩니다. 2,500개 이상의 이미지를 다운로드해야 하므로 몇 분간 기다려 주세요.

완료 후 코드 셀의 출력에는 100%까지 진행률 표시줄이 나타납니다:
Note the progress bar to 100%

이제 프로젝트 디렉토리의 images/ 폴더에는 데이터셋에서 다운로드한 모든 제품 이미지가 포함됩니다:
Note the product images downloaded by the code cell
또한, 각 이미지의 라벨링 정보가 포함된 labeled_images.csv 파일이 로컬에 생성됩니다:
Note the labeling information in the “labeled_images.csv” file
훌륭합니다! 이제 다중 모달 프로세스에서 머신러닝 모델을 훈련하는 데 필요한 모든 로컬 이미지와 라벨링 정보를 확보하셨습니다.

7단계: 훈련 및 테스트 데이터셋 준비

라벨링 이미지 정보를 labeled_images.csv 파일에서 읽어들이고 이를 활용하여 머신러닝 모델 미세 조정에 사용할 훈련 및 테스트 데이터셋을 생성하는 새 블록을 추가하세요:

# 제품 이미지를 위한 커스텀 PyTorch Dataset 클래스 정의
class ProductImageDataset(Dataset):
    def __init__(self, df, transform=None):
        self.df = df
        self.transform = transform

    def __len__(self):
        # 데이터셋의 총 샘플 수 반환
        return len(self.df)

    def __getitem__(self, idx):
        # 지정된 인덱스의 이미지 경로와 레이블 가져오기
        path, label = self.df.iloc[idx]["image_path"], self.df.iloc[idx]["label"]
        # 이미지 로드 및 RGB 변환
        image = Image.open(path).convert("RGB")

        # 변환이 지정된 경우 적용 (예: 크기 조정, 텐서 변환)
        if self.transform:
            image = self.transform(image)

        # 이미지 텐서와 레이블을 torch 텐서로 반환
        return image, torch.tensor(label, dtype=torch.long)

# 라벨링된 이미지 CSV 로드
labeled_df = pd.read_csv("labeled_images.csv")

# 레이블 분포 균형을 유지하며 데이터셋을 훈련/테스트 세트로 분할
train_df, test_df = train_test_split(
    labeled_df,
    test_size=0.2,
    stratify=labeled_df["label"]
)

# 이미지 크기를 224x224로 조정하고 텐서로 변환하는 변환 정의
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
])

# 데이터셋 객체 초기화
train_ds = ProductImageDataset(train_df, transform)
test_ds = ProductImageDataset(test_df, transform)

# 배치 처리 및 셔플링을 위해 데이터셋을 DataLoader로 감쌈
train_dl = DataLoader(train_ds, batch_size=32, shuffle=True)
test_dl = DataLoader(test_ds, batch_size=32)

이 코드 조각은 PyTorch CNN 훈련을 위해 라벨링된 제품 이미지를 준비합니다. 이를 위해 사용자 정의 Dataset 을 정의하고 다음과 같은 이미지 변환을 적용합니다:

  1. transforms.Resize((224, 224)): 이미지를 224×224 크기로 재조정합니다. 이는 데이터셋 내 이미지가 서로 다른 해상도와 종횡비를 가지는 반면, CNN은 모든 입력 데이터가 동일한 고정 크기를 갖기를 기대하기 때문에 중요합니다.
  2. transforms.ToTensor(): PyTorch 모델은 원시 PIL 이미지보다 텐서를 기반으로 작동합니다. 이 변환은 각 이미지를 (채널, 높이, 너비) 형태의 정규화된 텐서로 변환하여 CNN과 호환되도록 합니다.

이러한 변환을 통해 모든 이미지의 크기와 형식이 표준화되어 모델이 불규칙한 입력 처리 대신 시각적 패턴 학습에 집중할 수 있습니다. 이후 데이터셋은 레이블 분포를 유지한 채 훈련 세트와 테스트 세트로 분할되며, DataLoader 객체로 래핑되어 이미지와 레이블로 구성된 데이터 배치를 생성합니다.

이 단계는 CNN이 올바르게 포맷된 데이터를 수신하도록 보장하여 효과적인 다중 모달 머신러닝 훈련의 기반을 마련합니다. 훌륭합니다!

단계 #8: 다중 모달 ML 모델 훈련

훈련 및 테스트 데이터셋이 준비되면, 다음 코드로 PyTorch에서 이미지 분류를 위한 CNN을 미세 조정합니다:

# 훈련용 디바이스 선택 (가능하면 GPU, 아니면 CPU)
device = "cuda" if torch.cuda.is_available() else "cpu"

# torchvision에서 사전 훈련된 ResNet-18 모델 로드
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)

# 최종 완전 연결 레이어를 2개 클래스(GOOD/BAD) 출력으로 교체
model.fc = nn.Linear(model.fc.in_features, 2)

# 모델을 선택한 장치로 이동
model = model.to(device)

# 분류를 위한 손실 함수 정의
criterion = nn.CrossEntropyLoss()

# 작은 학습률로 최적화기 정의
opt = torch.optim.Adam(model.parameters(), lr=1e-4)

# 3에포크 동안 훈련 루프
for epoch in range(3):
    model.train()
    total_loss = 0

    # 이미지와 레이블 배치 반복
    for images, labels in tqdm(train_dl, desc=f"Epoch {epoch+1}"):
        images, labels = images.to(device), labels.to(device)

        opt.zero_grad()
        out = model(images)
        loss = criterion(out, labels)
        loss.backward()
        opt.step()

        total_loss += loss.item()

    # 에포크별 평균 손실 출력
    print(f"Epoch {epoch+1}: Average Loss={total_loss/len(train_dl):.4f}")

위 셀은 사전 훈련된 ResNet-18 CNN(18층 깊이의 컨볼루션 신경망)을 미세 조정합니다. 이 모델은 주로 이미지를 다양한 범주로 분류하는 데 사용됩니다.

이 경우 머신러닝 모델은 제품 이미지를 양품(good) 또는 불량품(bad)으로 분류합니다. ImageNet 가중치를 사용하면 수백만 개의 자연 이미지로부터 이미 학습된 특징을 활용하여 수렴 속도를 가속화할 수 있습니다. 그런 다음 최종 완전 연결층을 교체하여 두 클래스(“GOOD” 대 “BAD”, 의도된 대로)를 출력합니다.

루프 내에서 CrossEntropyLoss 인스턴스는 분류 오류를 측정하고, Adam 최적화기는 모델 가중치를 업데이트합니다. 각 에포크는 배치 단위로 반복되며, 전파(forward pass), 손실 계산, 역전파(backpropagation), 가중치 업데이트를 수행합니다.

코드 블록을 실행하면 다음과 같은 출력을 얻을 수 있습니다:

세 에포크 모두 성공적으로 완료되었음을 확인하세요. 최종 평균 손실은 0.0579로 상당히 낮으며 , 이는 모델이 잘 수렴하여 훈련 이미지를 높은 신뢰도로 구별하는 법을 학습했음을 나타냅니다.

자, 이제 끝났습니다! 방금 전자상거래 이미지 품질 구분을 위한 CNN을 미세 조정했습니다.

단계 #9: 모델 성능 평가

모델 성능을 검증하려면 평가 단계를 실행하세요:

# 평가용 모델 로드
model.eval()

# 처리된 이미지 추적
correct = 0
total = 0

# 훈련 데이터셋 대비 모델 평가
with torch.no_grad():
    for images, labels in test_dl:
        images, labels = images.to(device), labels.to(device)

        out = model(images)
        prediction = out.argmax(dim=1)
        correct += (prediction == labels).sum().item()
        total += len(labels)

# 결과 출력
print("테스트 정확도:", correct / total)

이것은 미세 조정된 모델이 이전에 본 적 없는 데이터(테스트 데이터셋)에 대해 얼마나 잘 일반화하는지 측정합니다. 구체적으로 추론을 통해 모델 평가를 수행합니다.

코드 셀은 먼저 모델을 평가 모드로 전환하고 속도 최적화와 일관된 동작 보장을 위해 기울기 추적을 비활성화합니다. 다음으로 루프가 테스트 데이터셋을 순회하며 모델의 예측값과 실제 레이블을 비교합니다. 마지막으로 총 정확도를 계산하여 훈련 세트 외부의 일반화 능력을 명확히 측정합니다.

결과는 다음과 같을 것입니다:

The result of the evaluation step
테스트 정확도 점수 0.924XXX는 미학습 테스트 데이터셋 내 제품 이미지 중 92.4% 이상을 “GOOD” 또는 “BAD”로 정확히 분류했음을 의미합니다.

이는 전자상거래 제품 이미지와 같은 실제 데이터에 대한 이진 분류에서 우수한 결과로 간주될 수 있습니다. 이는 모델이 단순히 훈련 데이터를 암기하는 것이 아니라 양호한 화질과 불량한 화질의 특징 차이를 성공적으로 학습했음을 강력히 시사합니다.

잘하셨습니다! 이제 미세 조정된 모델을 몇 개의 새 이미지에 적용하여 예상대로 작동하는지 확인해 보겠습니다.

10단계: ML 모델을 활용한 이미지 품질 예측

최적화된 모델이 예상대로 작동하는지 진정으로 검증하려면, 모델이 접해본 적 없는 이미지로 성능을 테스트해야 합니다. 이 모델은 모든 전자상거래 제품 이미지에 대해 작동하도록 훈련되었으므로, eBay, Walmart, Alibaba와 같은 플랫폼의 이미지나 자체 내부 제품 데이터베이스의 이미지로 테스트할 수 있습니다.

이 데모에서는 eBay에서 가져온 다음 두 제품 이미지로 모델을 테스트합니다:
The two test product images
이를 위해 전용 블록에 다음 코드를 추가합니다:

def predict_image_quality(img: Image.Image) -> str:
    # 모델을 평가 모드로 설정
    model.eval() 

    # 변환 적용 및 배치 차원 추가
    x = transform(img).unsqueeze(0).to(device) 

    with torch.no_grad():
        # 전파 수행, 예측된 클래스 인덱스 획득 및 스칼라로 추출
        prediction = model(x).argmax().item() 

    # 결과 문자열 반환
    return "GOOD" if prediction == 1 else "BAD"

# 테스트 이미지    
image_urls = ["https://i.ebayimg.com/images/g/N5kAAOSwTlplqFTa/s-l500.webp", "https://i.ebayimg.com/images/g/yUsAAOSweMJd67Jd/s-l1600.webp"]

# 이미지 URL 순회, 다운로드, 예측 및 표시
for image_url in image_urls:
    # HTTP 요청으로 이미지 콘텐츠 다운로드
    response = requests.get(image_url)
    image = Image.open(io.BytesIO(response.content)).convert("RGB") 

    # 예측 함수 호출
    quality = predict_image_quality(image) 

    # 모델 결과와 함께 노트북에 이미지 표시
    display(image) 
    print(image_url, "→", quality)

셀을 실행하면 다음과 같은 분류 결과를 확인할 수 있습니다:
The classification result on the first image
모델이 이미지를 “BAD”로 분류했음을 유의하십시오. 이는 정확한 결과입니다. 이미지가 시각적으로 저품질이고 흐릿하며 배경의 선명한 대비가 부족해 제품을 제대로 강조하지 못했기 때문입니다.

반면 두 번째 이미지에서는 다음과 같은 결과를 생성합니다:
The classification result on the second image
이번에는 “GOOD”으로 분류되었습니다. 시각적으로 매력적이고 선명하며 조명이 잘 되어 있고, 제품이 명확하게 드러나므로 설득력 있는 결과입니다.

자, 이제 완성되었습니다! Bright Data의 풍부한 데이터셋 덕분에 전자상거래 제품 데이터(이 경우 아마존 출처)를 추출했습니다. 이후 다중 모달 머신러닝 데이터 분석 접근법을 따라 PyTorch를 활용해 이미지 인식용 CNN을 미세 조정했습니다.

결론

이 블로그 포스트에서는 다중 모달 머신러닝 시스템을 구현하는 방법을 살펴보았습니다. 우리는 수억 개의 아마존 제품과 해당 이미지를 포함한 제품 데이터셋을 사용했습니다.

이 데이터를 Python 노트북 내 PyTorch 워크플로에 입력함으로써, 전자상거래 제품 이미지를 양호/불량으로 분류하는 CNN(컨볼루션 신경망)을 성공적으로 미세 조정했습니다.

이 프로젝트는 특히 전자 상거래를 목적으로 제품 표현에 대한 이미지 품질을 신속하게 평가할 방법을 찾고 있는 중소기업이나 대기업의 요구를 직접적으로 해결합니다.

Bright Data의 엔터프라이즈 데이터 서비스 없이는 이 모든 것이 불가능했을 것입니다. Bright Data는 Amazon, Walmart, LinkedIn, Zillow, Airbnb, Yahoo Finance 등 100개 이상의 도메인에서 데이터를 수집할 수 있도록 지원합니다.

Bright Data 계정에 지금 가입하여 데이터 솔루션을 무료로 테스트해 보세요!