μ½˜ν…μΈ λ‘œ 이동

검색 둜직(opensearch)

Tip

πŸ’‘ 이 기술의 핡심은 ν…μŠ€νŠΈλ‘œ 이미지λ₯Ό 검색할 수 μžˆλ‹€λŠ” 것

전톡적인 이미지 검색은 λ©”νƒ€λ°μ΄ν„°λ‚˜ 파일 이름을 기반으둜 ν•˜μ§€λ§Œ,

μ‹œλ§¨ν‹± 검색은 이미지 자체의 λ‚΄μš©μ„ μ΄ν•΄ν•˜κ³  이λ₯Ό λ°”νƒ•μœΌλ‘œ μœ μ‚¬ν•œ 이미지λ₯Ό 검색할 수 μžˆλŠ” κΈ°λŠ₯을 λ§ν•©λ‹ˆλ‹€.

일반적으둜 μ΄λ ‡κ²Œ κ²€μƒ‰ν•΄μ„œ κ²°κ³Όλ₯Ό λ°›μœΌλ €λ©΄, λ‹¨μˆœ μƒν’ˆλͺ… 뿐만 μ•„λ‹ˆλΌ μƒν’ˆμ— λŒ€ν•œ μΆ”κ°€ 정보λ₯Ό μž…λ ₯ν•΄μ£Όμ–΄μ•Ό ν•  것이닀.

겨울, 검정색, 데이트룩 λ“±λ“±

ν•˜μ§€λ§Œ 이 κΈ°λŠ₯의 핡심은 μ–΄λ– ν•œ μΆ”κ°€ 정보λ₯Ό μž…λ ₯ν•˜μ§€ μ•Šκ³ λ„ λ”± 이미지 ν•˜λ‚˜λ§Œμ„ κ°€μ§€κ³  ν…μŠ€νŠΈλ₯Ό 검색할 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

이미지에 λŒ€ν•œ 정보(μΊ‘μ…˜)을 μΆ”μΆœν•  수 μžˆλŠ” λͺ¨λΈμ„ μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό ν™•λ³΄ν•©λ‹ˆλ‹€.

μ˜ˆμ‹œ μ‹œλ§¨ν‹± 검색어

  • 밝은 빨간색 λ―Έλ‹ˆ μ›ν”ΌμŠ€
  • μ–΄λ‘μš΄ νŒŒλž€μƒ‰ λ‘± μ›ν”ΌμŠ€
  • μ†Œλ§€κ°€ μ—†λŠ” λ…Έλž€μƒ‰ μ›ν”ΌμŠ€
  • 흰색 λ‘œμš°νƒ‘ μš΄λ™ν™”
  • κ°ˆμƒ‰ ν•˜μ΄νƒ‘ μš΄λ™ν™”
  • 여름에 μž…κΈ° 쒋은 톡기성 쒋은 흰색 ν‹°μ…”μΈ 

  • 격식 μžˆλŠ” νšŒμƒ‰ μŠ¬λž™μŠ€ λ°”μ§€

  • 발 νŽΈν•œ μ—¬μ„±μš© μš΄λ™ν™”
  • 방수 κΈ°λŠ₯이 있느 겨울 λΆ€μΈ 
  • κ³¨λ“œ 컬러의 λ―Έλ‹ˆλ©€ν•œ λ””μžμΈ 귀걸이
  • 데일리 룩에 μ–΄μšΈλ¦¬λŠ” 싀버 νŒ”μ°Œ

0. 기술 κ°œμš”ΒΆ


  1. μΊ‘μ…˜ μΆ”μΆœ
  2. μΊ‘μ…˜ μž„λ² λ”© & 검색어 μž„λ² λ”©
  3. κ΄€λ ¨ μƒν’ˆ 제곡

1. κ°­μ…˜ μΆ”μΆœΒΆ


λ¨Όμ €, μƒν’ˆμ„ 등둝할 λ•Œ λ„£λŠ” μƒν’ˆ μ΄λ―Έμ§€λ‘œλΆ€ν„° μžλ™μœΌλ‘œ κ°­μ…˜μ„ 생성

μ΄λŠ” μƒν’ˆμ˜ μ£Όμš” λ‚΄μš©μ„ μžμ—°μ–΄λ‘œ ν‘œν˜„ν•œ 것

예λ₯Ό λ“€μ–΄, μ‹ λ°œμ‚¬μ§„μ—μ„œ β€œλΉ¨κ°„ μ€„λ¬΄λŠ¬κ°€ μžˆλŠ” λŸ°λ‹ν™” ν•œ μΌ€λ ˆβ€ 와 같은 μΊ‘μ…˜μ„ 생성

μ˜μ–΄ μΊ‘μ…˜

The image shows a young man standing in front of a building with a sign that reads "Royles". He is wearing a beige button-down shirt and black trousers. He is holding a black jacket in his left hand and has a pair of glasses on his right wrist. He has short black hair and is looking off to the side with a serious expression on his face. The building behind him has a wooden facade and large windows.

ν•œκ΅­μ–΄ μΊ‘μ…˜

κ·Έ μ΄λ―Έμ§€λŠ” "Royles"라고 μ“°μ—¬μ§„ ν‘œμ§€νŒμ΄ μžˆλŠ” 건물 μ•žμ— μ„œ μžˆλŠ” μ Šμ€ λ‚¨μžλ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€. κ·ΈλŠ” 베이지색 λ²„νŠΌλ‹€μš΄ 셔츠와 검은색 λ°”μ§€λ₯Ό μž…κ³  μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŠ” 왼손에 검은색 μž¬ν‚·μ„ λ“€κ³  있고 였λ₯Έμͺ½ 손λͺ©μ— μ•ˆκ²½μ„ μ“°κ³  μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŠ” 짧은 검은 머리λ₯Ό κ°€μ§€κ³  있고 μ‹¬κ°ν•œ ν‘œμ •μœΌλ‘œ μ˜†μ„ 내렀닀보고 μžˆμŠ΅λ‹ˆλ‹€. 그의 뒀에 μžˆλŠ” 건물은 λ‚˜λ¬΄λ‘œ 된 μ •λ©΄κ³Ό 큰 창문을 κ°€μ§€κ³  μžˆμŠ΅λ‹ˆλ‹€.

2. ν•„μš”ν•œ μ •λ³΄λ§Œ μΆ”μΆœΒΆ


μœ„μ—μ„œ 보신 μΊ‘μ…˜ 데이터λ₯Ό λͺ¨λ‘ μ‡Όν•‘λͺ° λ°μ΄ν„°λ‘œ ν™œμš©λ  경우, λΆˆν•„μš”ν•œ 데이터가 ν¬ν•¨λ˜μ–΄ 검색 μ„±λŠ₯을 μ €ν•˜μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄, 도메인에 맞좘 핡심 ν‚€μ›Œλ“œλ§Œμ„ μΆ”μΆœν•˜κ³  μ€‘μš”λ„ 순으둜 데이터λ₯Ό μ €μž₯ν•˜λŠ” 방식을 μ±„νƒν•˜μ˜€μŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ 방식은 검색 정확도λ₯Ό 높이고 μ‹œμŠ€ν…œ μ„±λŠ₯을 μ΅œμ ν™”ν•˜λŠ” 데 도움이 λ©λ‹ˆλ‹€.

이미지 질의 λͺ¨λΈμ„ 톡해 ν•„μš”ν•œ μ •λ³΄λ§Œμ„ μΆ”μΆœν•˜λŠ” 방법을 μ‚¬μš©ν•©λ‹ˆλ‹€.

  1. μΉ΄ν…Œκ³ λ¦¬: μƒν’ˆμ˜ μ’…λ₯˜ (예: μ›ν”ΌμŠ€, μš΄λ™ν™”, μŠ¬λž™μŠ€ λ“±)
  2. 색상: μƒν’ˆμ˜ μ£Όμš” 색상 (예: 빨간색, νŒŒλž€μƒ‰, λ…Έλž€μƒ‰ λ“±)
  3. 성별: μƒν’ˆμ˜ λŒ€μƒ 성별 (예: μ—¬μ„±μš©, λ‚¨μ„±μš©)
  4. κ³„μ ˆ: μƒν’ˆμ΄ μ ν•©ν•œ κ³„μ ˆ (예: μ—¬λ¦„μ˜·, 겨울옷 λ“±)

μ΄λŸ¬ν•œ 정보λ₯Ό μžλ™μœΌλ‘œ μΆ”μΆœν•  수 μžˆλ„λ‘ AI λͺ¨λΈμ„ μ„€μ •ν•˜λ©΄, λͺ¨λΈμ€ 이미지 μ•ˆμ˜ μƒν’ˆ 정보λ₯Ό μ •ν™•ν•˜κ²Œ λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μΆ”μΆœλœ 정보λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ 검색엔진 ν•„λ“œλ₯Ό κ΅¬μ„±ν•˜κ³ , μž„λ² λ”© 벑터λ₯Ό μƒμ„±ν•˜μ—¬ μ €μž₯ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ°©μ‹μœΌλ‘œ, 검색 쿼리에 λŒ€ν•œ 응닡 μ‹œ μž„λ² λ”© 벑터λ₯Ό ν™œμš©ν•˜μ—¬ 높은 μ •ν™•λ„μ˜ μ‹œλ§¨ν‹± 검색 κ²°κ³Όλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

3. 검색엔진 λž­ν‚Ή λͺ¨λΈ κ΅¬ν˜„ΒΆ


OpenSearchλ₯Ό ν™œμš©ν•œ 검색엔진 λž­ν‚Ή λͺ¨λΈ κ΅¬ν˜„

μ΄λ―Έμ§€μ—μ„œ μΆ”μΆœν•œ 정보λ₯Ό 효과적으둜 κ²€μƒ‰ν•˜κΈ° μœ„ν•΄ OpenSearchλ₯Ό ν™œμš©ν•œ μ‹œλ§¨ν‹± 검색 κΈ°λŠ₯을 κ΅¬ν˜„ν•©λ‹ˆλ‹€. μ‹œλ§¨ν‹± 검색은 λ‹¨μˆœν•œ ν‚€μ›Œλ“œ 맀칭을 λ„˜μ–΄, 검색어와 λ¬Έμ„œ κ°„μ˜ 의미적 μœ μ‚¬μ„±μ„ 기반으둜 κ²°κ³Όλ₯Ό μ œκ³΅ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ λž­ν‚Ή λͺ¨λΈμ„ μ‚¬μš©ν•˜μ—¬ 검색 결과의 정확성을 λ†’μž…λ‹ˆλ‹€.

3.1 OpenSearch μ„€μ •ΒΆ

λ¨Όμ €, OpenSearch ν΄λŸ¬μŠ€ν„°λ₯Ό κ΅¬μ„±ν•©λ‹ˆλ‹€.

  1. OpenSearch ν΄λŸ¬μŠ€ν„° ꡬ성: ν΄λŸ¬μŠ€ν„°λ₯Ό μ„€μ •ν•˜κ³  ν•„μš”ν•œ 인덱슀λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  2. 인덱슀 λ§€ν•‘ μ„€μ •: μΆ”μΆœλœ μΊ‘μ…˜ 정보λ₯Ό μ €μž₯ν•  인덱슀의 맀핑을 μ„€μ •ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 'category', 'color', 'gender', 'season' λ“±μ˜ ν•„λ“œλ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€.
PUT /fashion_items
{
  "mappings": {
    "properties": {
      "goodsNm": { "type": "text" },
      "category": { "type": "dense_vector", "dims": 768 },
      "color": { "type": "dense_vector", "dims": 768 },
      "gender": { "type": "dense_vector", "dims": 768 },
      "season": { "type": "dense_vector", "dims": 768 },
      "embedding": { "type": "dense_vector", "dims": 768 }
    }
  }
}

3.2 μž„λ² λ”© 벑터 생성 및 μ €μž₯ΒΆ

이미지 μΊ‘μ…˜μ„ 톡해 μΆ”μΆœλœ 정보λ₯Ό μž„λ² λ”© λ²‘ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ 사전 ν›ˆλ ¨λœ λͺ¨λΈ(BERT, CLIP λ“±)을 μ‚¬μš©ν•˜μ—¬ μΊ‘μ…˜μ„ λ²‘ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, CLIP λͺ¨λΈμ„ μ‚¬μš©ν•˜μ—¬ 이미지와 ν…μŠ€νŠΈ λͺ¨λ‘μ—μ„œ μž„λ² λ”©μ„ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€.

3.3 λž­ν‚Ή λͺ¨λΈ 적용¢

검색 μš”μ²­μ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©μžμ˜ 쿼리λ₯Ό μž„λ² λ”© λ²‘ν„°λ‘œ λ³€ν™˜ν•œ ν›„, OpenSearch의 k-NN 검색 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ—¬ μœ μ‚¬ν•œ ν•­λͺ©μ„ μ°ΎμŠ΅λ‹ˆλ‹€. λž­ν‚Ή λͺ¨λΈμ„ 톡해 검색 결과의 μˆœμœ„λ₯Ό μ •ν•˜μ—¬, κ°€μž₯ 관련성이 높은 κ²°κ³Όλ₯Ό μƒμœ„μ— λ…ΈμΆœμ‹œν‚΅λ‹ˆλ‹€.

  1. μ‚¬μš©μž 쿼리 μž„λ² λ”©: μ‚¬μš©μžμ˜ ν…μŠ€νŠΈ 쿼리λ₯Ό μž„λ² λ”© λ²‘ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.
  2. k-NN 검색 μˆ˜ν–‰: OpenSearch의 k-NN 검색을 톡해 μœ μ‚¬ν•œ ν•­λͺ©μ„ κ²€μƒ‰ν•©λ‹ˆλ‹€.
  3. λž­ν‚Ή λͺ¨λΈ 적용: 검색 결과에 λž­ν‚Ή λͺ¨λΈμ„ μ μš©ν•˜μ—¬ μˆœμœ„λ₯Ό λ§€κΉλ‹ˆλ‹€.
query = "밝은 빨간색 λ―Έλ‹ˆ μ›ν”ΌμŠ€"
query_embedding = model.get_text_features(query).squeeze().tolist()

search_query = {
  "query": {
    "bool": {
      "should": [
        {
          "knn": {
            "category": {
              "vector": query_embedding,
              "k": 10
            }
          }
        },
        {
          "knn": {
            "color": {
              "vector": query_embedding,
              "k": 10
            }
          }
        },
        {
          "knn": {
            "gender": {
              "vector": query_embedding,
              "k": 10
            }
          }
        },
        {
          "knn": {
            "season": {
              "vector": query_embedding,
              "k": 10
            }
          }
        },
        {
          "knn": {
            "embedding": {
              "vector": query_embedding,
              "k": 10
            }
          }
        }
      ]
    }
  },
  "rescore": {
    "window_size": 50,
    "query_weight": 0.7,
    "rescore_query_weight": 1.2,
    "rescore_query": {
      "rank_feature": {
        "field": "popularity",
        "factor": 1.2
      }
    }
  }
}

response = opensearch.search(index="fashion_items", body=search_query)

3.4 검색 κ²°κ³Ό 제곡¢

검색 κ²°κ³ΌλŠ” μ‚¬μš©μžμ—κ²Œ κ°€μž₯ 관련성이 높은 ν•­λͺ©λΆ€ν„° μˆœμ„œλŒ€λ‘œ μ œκ³΅λ©λ‹ˆλ‹€. OpenSearch의 λž­ν‚Ή λͺ¨λΈμ„ 톡해 μœ μ‚¬μ„±μ„ κΈ°μ€€μœΌλ‘œ κ²°κ³Όλ₯Ό μ •λ ¬ν•˜μ—¬ μ œκ³΅ν•©λ‹ˆλ‹€.

이와 같은 λ°©μ‹μœΌλ‘œ OpenSearch와 μž„λ² λ”© 벑터λ₯Ό ν™œμš©ν•œ μ‹œλ§¨ν‹± 검색을 κ΅¬ν˜„ν•˜λ©΄, μ‚¬μš©μžμ—κ²Œ λ”μš± μ •ν™•ν•˜κ³  μœ μ˜λ―Έν•œ 검색 κ²°κ³Όλ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 μ‚¬μš©μž κ²½ν—˜μ„ 크게 ν–₯μƒμ‹œν‚¬ 수 있으며, μ‡Όν•‘λͺ°μ—μ„œ μ›ν•˜λŠ” μƒν’ˆμ„ λΉ λ₯΄κ³  μ •ν™•ν•˜κ²Œ 찾을 수 있게 λ©λ‹ˆλ‹€.ΒΆ

κ΄€λ ¨ κΈ€