はじめに
OpenAIが Dev Day で発表したGPT-4-Vision-Previewは、画像処理と自然言語処理を組み合わせた最先端の技術です。
このモデルは、画像を理解し、その内容に基づいてテキスト情報を生成する能力を持っています。例えば、写真やイラストから物体を識別し、それに関連する説明や情報をテキストとして提供できます。この技術は、画像とテキストの間のギャップを橋渡しするものであり、多様な応用が可能です。
DROBEは、多様なファッション商品を取り扱うECサイトを運営しています。我々の挑戦の一つは、膨大な数の商品画像と説明文から、正確で有用なタグを抽出し、整理して保存しておく事です。このプロセスは従来、時間がかかり、人手に依存していましたが、GPT-4-Vision-Previewを導入する事でこの課題を解決できないかを検討しようと考えました。
DROBE の課題と GPT-4-Vision-Preview を試すモチベーション
ファッションの商品情報は多岐にわたりますが、特に検索や商品管理に重要な要素をあげると以下のようなものになります。
項目名 | 概要 | 対象カテゴリ |
---|---|---|
価格 | 共通 | |
サイズ | S, M, L など | 共通 |
季節 | SS, FW など | 共通 |
色 | 無彩色、中間色、など | 共通 |
テイスト | カジュアル、綺麗め、など | 共通 |
袖 | 半袖、長袖、など | トップス |
シルエット | ワイド、スリム、など | パンツ |
デザイン | ストレート、など | パンツ |
シルエット | タイト、フレア、など | スカート |
価格やサイズなどは商品に記載されているテキスト情報にたよるしかないですが、一方で色や袖などは画像を見る事で判断が可能になります。
テイストなどはテキストと画像を一緒に見る事で判断ができるようなものです。
GPTP-4-vision-preview を試すモチベーションは、テキストと画像を一緒に取り扱えるという事でファッションにおけるデータ構造化問題に対して有効な解決策になり得る可能性があると考えました。
ケーススタディ
以下にケーススタディの概要と結果を記載します。 利用した SDK は *1 openai-python v1.3.3 です
入力するデータ
入力としては以下のようなものを使います
説明文
■デザイン
上品な仕上がりで高見え効果抜群のオーバーサイズカーディガン
アクセントとなる大ぶりの配色ボタンがこなれ感をアップ。
前を閉じた状態、羽織の状態どちらでもスタイリングを確立してくれる万能アイテムです。
■素材
もっちりとした手触り。しっかりとした肉感を持ち合わせた素材。
やや硬めに仕上げ、シルエットを崩さずキープしてくれます。
ポケット: なし
裏地: なし
伸縮性: なし
透け感: なし
光沢感: なし
モデル身長:165cm/Mサイズ着用
素材
表地 ポリエステル:60% アクリル:40% 裏地 ポリエステル:100
メーカー公称の色
グリーン
こういった情報を入力として利用します。 今回は問題を難しくするため、 メーカー公称の色 を グリーン ではなく ブラックとし、画像とテキストに矛盾があるデータに対するモデルの挙動を確認します。
推論周辺部分のコード
画像は以下のようなコードで base64 にして投げる方式にしました
def image_url_to_base64(url, new_width): try: # URL から画像をダウンロード response = requests.get(url) response.raise_for_status() # PIL を使って画像を処理 with Image.open(io.BytesIO(response.content)) as image: # resize width, height = image.size aspect_ratio = height / width new_height = int(new_width * aspect_ratio) image = image.resize((new_width, new_height), Image.ANTIALIAS) print(f"resized to width:{new_width}, height:{new_height}") # バイト配列に変換 buffered = io.BytesIO() image_format = "PNG" image.save(buffered, format=image_format) img_byte = buffered.getvalue() # Base64 にエンコード img_base64 = base64.b64encode(img_byte).decode() # 正しいフォーマットでBase64データを返す return f"data:image/{image_format.lower()};base64,{img_base64}" except Exception as e: return f"Error: {str(e)}"
推論する部分のコードは以下です
def extract_tag(system_prompt, category, material, description, maker_color_name, image_url): base64_image = image_url_to_base64(image_url, 1000) prompt = f"{system_prompt}\n\nカテゴリは{category}です\n\n説明文は以下です\n{description}\n\n素材は以下です\n{material}\n\nメーカー公称のこのアイテムの色は{maker_color_name}です" response = client.chat.completions.create( model="gpt-4-vision-preview", messages=[ { "role": "user", "content": [ {"type": "text", "text": prompt}, { "type": "image_url", "image_url": { "url": f"{base64_image}", "detail": "low", }, } ], }, ], max_tokens=300 ) return response.choices[0].message.content
プロンプト
基本となるプロンプトは以下です。 extract_tag
関数の system_prompt
変数として入力します。
あなたはアパレルの商品管理エージェントです 与えられた説明文や画像から以下の情報を抽出してください color, occasion, sleeve_length で定義されている中の情報を取得できなければ空文字にしてください color - 無彩色 - 中間色 - 寒色 - 暖色 - その他 occasion - カジュアルマニッシュ - きれいめマニッシュ - カジュアルフェミニン - きれいめ - フェミニン - ニュートラル - その他 sleeve_length - ノースリーブ - フレンチ - 半袖 - 7分袖 - 長袖 結果は以下の json で返してください { "color": "", "occasion": "", "sleeve_length": "" }
これを基本形として、以下のように画像を優先する旨の指示や、タグを選択した理由を言語化してもらうバージョンのプロンプトも準備しました。
色に関しては、与えられるメーカー公称の色の名前と画像の両方から判断してください カテゴリとして与えられた商品に着目してください 画像と公称で矛盾がある場合は画像からの判断を優先してください
結果は以下の json で返してください { "color": "", "occasion": "", "sleeve_length": "" "reason_color": "" // colorタグを選んだ理由を記載してください "reason_occasion": "" // occasionタグを選んだ理由を記載してください "reason_sleeve_length": "" // sleeve_lengthタグを選んだ理由を記載してください }
実験結果
試行# | プロンプト | output |
---|---|---|
1 | 基本 | color: 無彩色 occasion: きれいめマニッシュ sleeve_length': 長袖 |
2 | 基本 + 画像優先の指示 + 理由の言語化 | color: 寒色 occasion: ニュートラル sleeve_length 長袖 reason_color: メーカー公称の色がブラックであるため無彩色と判断したが、画像で見ると緑のような寒色に見えるため、寒色とした。 reason_occasion: デザインから判断して、オーバーサイズカーディガンでありどちらのスタイリングにも適応可能なため、ニュートラルな装いに適していると考えられます。 reason_sleeve_length: モデルが着用しているカーディガンは長袖であることが明確なため |
この商品の期待結果は以下です
color: 寒色 occasion: ニュートラル sleeve_length: 長袖
期待結果との比較を踏まえると、画像と文章のどちらを優先するかを明確に指示しつつ、その判断結果を言語化してもらうという指示を出したパターンの方が良いという結果となりました。
今回取り組んだタスクは、画像とテキストの推論結果に基づいて最終判断を下す必要があります。これは、多段階の推論を要するタスクです。 このような多段階の推論を必要とするタスクにおいて、推論を促すようなプロンプトが性能を高めるというのはLLM を対象とした研究である *2 Large Language Models are Zero-Shot Reasoners で報告されています。
具体的には、「Let's think step by step.」というZero-shot Chain of Thought(CoT)プロンプトや、「Let's think about this logically.」などのプロンプトを使うことで多段階の推論が必要なタスクでの性能向上が確認されています。このようなプロンプトは、LLM の Zero-shot での推論能力を向上させる、推論を促すような(instructive)プロンプトとされています。
今回の reason
を述べさせるプロンプトも推論を促すようなプロンプトであり、それが VLM(Vision Language Model)での Zero-shot での推論能力の向上につながった可能性があると考えています。
とはいえこのような挙動がVLMでも起こるかはまだ十分に検証されていないように思えます。今後さらに論文のサーベイや手元のデータを使った実験によって調査を進めたいと思っています。
最後に、その他いくつかの商品を試した結果を載せておきます。
image | desc | material | maker_color_name | output |
---|---|---|---|---|
長袖ブラウスです。ほのかな光沢と滑らかな風合いの生地を使用。斜めに切り替えたペプラムがアイキャッチ。動きのある表情を演出します。ラウンドネックがすっきとした佇まい。ドロップショルダーが柔らかな雰囲気を演出します。バックネックの涙開きもポイント。ベーシックな無地デザインで、程よく抜け感のあるスタイリングが楽しめる一枚です。 フリル・ボートネック・ペプラム・長袖・パフスリーブ・ポリエステル・サテン・通勤・オフィス・オンオフ・休日・カジュアル・フェミニン・きれいめ・大人・上品 |
ポリエステル100% | ライトグリーン | color: 中間色 occasion: きれいめ sleeve_length: 長袖 reason_color: メーカー公称の色がライトグリーンで、画像もライトグリーンのような中間色に見えるため reason_occasion: 説明文に「オフィス」「オンオフ」「休日」「カジュアル」「フェミニン」「きれいめ」とあるが、上品なデザインと袖やペプラムのディテールから特に「きれいめ」に分類する reason_sleeve_length: 説明文に「長袖」とあるため |
|
ややゆったりとしたシルエットなので、腰まわりを自然にカバーできます◎ ナチュラル加工が施された、デイリーに着回ししやすい一枚です。 インディゴブルーカラーはシーズンやトレンドに左右されずにお召しいただけます。 ボタンとファスナーは金属のシルバーカラーを使用しています。 ■素材 柔らかい綿100%デニム素材を使用。 ナチュラルな加工を施しています。 ポケット: あり 裏地: なし 伸縮性: ややあり 透け感: なし 光沢感: なし モデル身長:cm/サイズ着用 |
綿100% | ネイビー系 | color: 寒色 silhouette: レギュラー detail: ストレート reason_color: 画像に写っているアイテムはインディゴブルーであり、寒色系に分類されるため。メーカー公称の色もネイビー系とのことで、これも寒色に分類される。 reason_silhouette: 説明文によるとややゆったりとしたシルエットなので、スリムでもワイドでもなく、中間にあたるレギュラーと判断。 reason_detail: 画像のパンツは裾にかけて広がりも狭くなりもせず、ストレートなシルエットが見て取れるため。 |
|
■デザイン ボディラインをタイト見せてくれる着痩せ効果抜群のタートルネックニット。 袖は手の甲が隠れる長さに仕上げ、フィンガーホールを施しました。 シャツやベストのインナーとしても◎もちろん1枚着としてもご着用いただけます。 何枚あっても重宝する万能ニットです。 ■素材 しっかりとした肉感でインナーのあたりの心配なし。 細畝のリブの編み地は伸縮性があり、タイトなシルエットながら柔らかな着用感です。 ポケット: なし 裏地: なし 伸縮性: あり 透け感: なし 光沢感: なし モデル身長:167cm/Mサイズ着用 |
レーヨン50%、ポリエステル29%、ナイロン21% | レッド | color: 暖色 occasion: きれいめマニッシュ sleeve_length: 長袖 reason_color: メーカー公称の色がレッドであり、画像にも赤色のトップスが確認できるため reason_occasion: タートルネックニットで着痩せ効果があり、シャツやベストのインナーとしても着用可能なため、きれいめマニッシュに分類 reason_sleeve_length: 袖が手の甲を隠す長さで、フィンガーホールが施されていることから長袖と判断 |
|
■デザイン リブハイネックがポイントのカットソープルオーバー。 ダンボール素材を使用しているので、ストレッチ性に優れ、軽やかな着心地がポイントです。 ボックスシルエットなので体のラインをひろいにくく、ゆったりと着ていただけます。 首元と袖口にはリブを使用しメリハリをプラスしています。 優しい印象を与える淡色展開です。 ■素材 膨らみのあるダンボールカットソー素材を使用。 表面が滑らかで、柔らかな風合いが特徴です。 ポケット: なし 透け感: なし 光沢感: なし |
本体:レーヨン74%、ナイロン17%、ポリウレタン9%、リブ:ポリエステル95%、ポリウレタン5% | ライトブルー | color: 中間色 occasion: カジュアルマニッシュ sleeve_length: 長袖 reason_color: メーカー公称の色がライトブルーであり、画像からもライトブルーに見えるため reason_occasion: ボックスシルエットで体のラインを拾いにくく、カジュアルながらもハイネックとリブがメリハリをつけており、マニッシュな印象を与えるため reason_sleeve_length: 袖口にリブが見え、袖自体が長いため |
|
■デザイン オーバーサイズの片畦メランジニット。 身頃から裾までストレートシルエットなので、腰回りもゆったりとしてお召しいただけます。 サイドスリットを入れることで、大きめサイズに抜け感を取り入れています。 お袖はややパフシルエットで女子感をプラス◎ ■素材 もちもちとした柔らかいメランジ糸を使用。 片畦で編み立てることで厚みをだし、暖かみのあるタッチです。 ポケット: なし 裏地: なし 透け感: なし 光沢感: なし |
アクリル65%、ポリエステル32%、ポリウレタン3% | カラシ | color: 暖色 occasion: カジュアルフェミニン sleeve_length: 長袖 reason_color: メーカー公称の色がカラシであり、画像においてもカラシ色、つまり暖色系の色が確認できるため reason_occasion: オーバーサイズでリラックス感がありながら、ややパフシルエットの袖が女性らしさを加えるデザインなのでカジュアルフェミニンに該当する reason_sleeve_length: 画像から見て手首まである袖であり、長袖に該当する |
おわりに
現在 (2023年11月時点) ではまだ rate limit が厳しく、数十万枚もあるような画像を分類するタスクへの本番投入はできません。 ただしこの問題は (OpenAI が落ち着けば) 早晩解決すると思いますので、その際にはいち早く作業を自動化できると考えています。
本取り組みを通じてこの技術が商品画像からの情報抽出とそれに基づくタグ付けにおいて高い性能を発揮する事がわかりました。 これにより、商品の特徴を瞬時に識別し、顧客が求める正確な情報を提供することが可能になります。 また、スタイルやトレンドをテキストデータとして解析し、顧客の好みや市場動向を予測することもできます。
ファッション業界は常に変化し、新しいスタイルやトレンドが絶え間なく生まれています。 GPT-4-Vision-Previewのようなマルチモーダルモデルは、これらの動きをリアルタイムで捉え、ビジネスの意思決定やマーケティング戦略を支援します。 この技術の柔軟性と適応性は、ファッション業界の持続的な革新と成長を支える鍵となると考えています。