Hugging Face TextImage Augmentation パイプラインリリース
TL;DR
Hugging Face と Albumentations AI は、文書画像と埋め込まれたテキストを同時に変更する TextImage Augmentation パイプラインをリリースしました。これにより、現実的な合成データ生成と、限られた文書データセット上でのビジョン‑言語モデルの堅牢なファインチューニングが可能になります。
動機: 拡張はテキストを保持する必要がある
文書画像は密集したテキスト情報を含むため、従来の画像のみの拡張(例: リサイズ、ぼかし、背景変更)では OCR の性能が低下しがちです。ブログ記事では、このようなデータに対する効果的なデータ拡張は テキストの完全性を保ちつつ視覚的外観を多様化する 必要があると主張しています。この要件は、少量の文書コーパス上でビジョン‑言語モデル(VLM)をファインチューニングする際に特に重要で、テキストが欠落または破損すると学習が阻害されます。
はじめに: マルチモーダル拡張パイプライン
この新しいパイプラインは Albumentations AI と共同開発され、文書の拡張を マルチモーダル な問題として扱います。画像ピクセルとそれに対応するテキストアノテーションの両方に同時に変換を適用します。このアプローチは、テキストと画像の共同拡張が VLM の事前学習を改善すると仮定した過去の Hugging Face ブログ記事に基づいています。詳細なパラメータ仕様と使用例は Albumentations AI のウェブサイトに記載されています。
手法: バウンディングボックスからインペイントテキストへ
- Line Selection – バウンディングボックスの変更割合を制御する
fraction_rangeハイパーパラメータに基づき、文書の行をランダムに選択します。 - Text Augmentation – 選択された行に対して、いくつかの NLP スタイルの操作のうちの一つを適用します:
- Random Insertion(ストップワード挿入)
- Random Deletion(ランダム削除)
- Random Swap(ランダム入れ替え)
- Stopword Replacement(ストップワード置換)
- Image Update – 元のテキスト領域を黒く塗りつぶし、生成された新しいテキストでインペイントします。フォントサイズは
font_size_fraction_rangeを用いてバウンディングボックスの高さから算出されます。パイプラインは変更された画像と更新されたテキストメタデータの両方を返し、下流のトレーニングパイプラインが変換されたペアを利用できるようにします。
TextImage Augmentation の主な機能
1. 合成テキストオーバーレイ
任意の背景画像上に任意のテキストを描画し、完全に合成された文書サンプルを作成します。 これは OCR‑free 文書理解トランスフォーマーの SynthDOG のような手法に似ています。
2. 拡張テキストオーバーレイ
視覚的リアリズムを保ちつつテキストレベルの摂動を適用します。 サポートされている操作は次のとおりです:
- Random Deletion – ランダムに単語を削除します。
- Random Swapping – 行内の単語順序を入れ替えます。
- Stop‑word Insertion – 一般的なストップワード(例: "the", "and")を挿入します。
これらの拡張は任意の Albumentations 画像変換(例: カラージッター、アフィン変形)と組み合わせることができ、変換されたテキストは overlay_data フィールドを通じて取得できます。
Note: 以前のリポジトリバージョンには同義語置換が含まれていましたが、実行時間の大幅なオーバーヘッドのため削除されました。
インストール
pip install -U pillow
pip install albumentations
pip install nltk
import albumentations as A, cv2, json, nltk
from matplotlib import pyplot as plt
nltk.download('stopwords')
from nltk.corpus import stopwords
可視化ヘルパー
def visualize(image):
plt.figure(figsize=(20,15))
plt.axis('off')
plt.imshow(image)
文書データのロード
パイプラインは 行レベルのバウンディングボックス(正規化された Pascal VOC 形式)と対応するテキストを期待します。例として以下のデータセットがあります:
pixparse/idl-wdspixparse/pdfa-eng-wds
bgr_image = cv2.imread('examples/original/fkhy0236.tif')
image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB)
with open('examples/original/fkhy0236.json') as f:
labels = json.load(f)
font_path = '/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf'
visualize(image)
メタデータの準備では、正規化されたボックスを絶対座標に変換します:
def prepare_metadata(page, h, w):
meta = []
for txt, box in zip(page['text'], page['bbox']):
left, top, w_norm, h_norm = box
meta.append({
'bbox': [left, top, left + w_norm, top + h_norm],
'text': txt
})
return meta
page = labels['pages'][0]
metadata = prepare_metadata(page, *image.shape[:2])
テキスト拡張例
ランダム入れ替え
transform = A.Compose([
A.TextImage(font_path=font_path, p=1, augmentations=['swap'],
clear_bg=True, font_color='red',
fraction_range=(0.5,0.8),
font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])
ランダム削除
transform = A.Compose([
A.TextImage(font_path=font_path, p=1, augmentations=['deletion'],
clear_bg=True, font_color='red',
fraction_range=(0.5,0.8),
font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])
ランダム挿入(ストップワード挿入)
stops = stopwords.words('english')
transform = A.Compose([
A.TextImage(font_path=font_path, p=1, augmentations=['insertion'],
stopwords=stops, clear_bg=True, font_color='red',
fraction_range=(0.5,0.8),
font_size_fraction_range=(0.8,0.9))
])
out = transform(image=image, textimage_metadata=metadata)
visualize(out['image'])
他の Albumentations 変換との組み合わせ
複雑なパイプラインでは、PlanckianJitter(カラー バランス)や Affine(スケーリング/回転)などの画像レベル拡張とテキスト挿入を交互に適用できます:
transform_complex = A.Compose([
A.TextImage(font_path=font_path, p=1, augmentations=['insertion'],
stopwords=stops, clear_bg=True, font_color='red',
fraction_range=(0.5,0.8),
font_size_fraction_range=(0.8,0.9)),
A.PlanckianJitter(p=1),
A.Affine(p=1)
])
out = transform_complex(image=image, textimage_metadata=metadata)
visualize(out['image'])
変更されたテキストの抽出
overlay_data フィールドには、以下の情報を持つ辞書のリストが含まれます:
bbox_coords: 変更された領域のピクセル座標text: 新しい拡張テキストoriginal_text: 元の行bbox_index: 元メタデータリストのインデックスfont_color: 描画色
print(out['overlay_data'])
サンプル出力は、レイアウトを保ったまま入れ替えまたは挿入された単語を示します。
合成データ生成
既存の文書を摂動するだけでなく、パイプラインは 任意のテンプレート上に任意のテキストを描画 できます:
template = cv2.imread('template.png')
image_template = cv2.cvtColor(template, cv2.COLOR_BGR2RGB)
transform = A.Compose([
A.TextImage(font_path=font_path, p=1, clear_bg=True,
font_color='red', font_size_fraction_range=(0.5,0.7))
])
metadata = [
{'bbox':[0.1,0.4,0.5,0.48], 'text':'Some smart text goes here.'},
{'bbox':[0.1,0.5,0.5,0.58], 'text':'Hope you find it helpful.'}
]
out = transform(image=image_template, textimage_metadata=metadata)
visualize(out['image'])
この機能により、手動アノテーションなしで大量のラベル付き文書画像を作成できます。
結論
TextImage Augmentation ライブラリは、文書画像向けの統一されたマルチモーダル拡張ワークフローを提供します。古典的な NLP 摂動(ランダム挿入、削除、入れ替え、ストップワード置換)と Albumentations の強力な画像変換を組み合わせることで、実務者は多様で現実的なトレーニングデータを生成し、限られた文書コーパス上での VLM ファインチューニングを向上させることができます。詳細なパラメータドキュメントと例は Albumentations AI のサイトで入手可能です。
参考文献
- Kim, G., Hong, T., Yim, M., et al. OCR‑free Document Understanding Transformer, ECCV 2022.
インストール概要
pip install -U pillow albumentations nltk