使用 AugLy 打造端到端多模態資料擴增與對抗穩健性基準:涵蓋影像、文字、音訊與 PyTorch

2026年9月26日 07:22
站內 AI 整理稿

In this tutorial, we build a comprehensive multimodal augmentation and robustness workflow with AugLy for images, text, and audio.We start by addressing modern dependency compatibility issues and generating deterministic synthetic datasets so the experiments remain self-contained and reproducible.

We then explore AugLy’s functional and class-based APIs, metadata, and intensity tracking, probabilistic composition, bounding-box-aware transformations, and custom transforms.

We extend the workflow into practical robustness experiments by benchmarking perceptual-hash copy detection under image distortions and evaluating text classifiers against adversarial perturbations, Unicode obfuscation, sanitization, and adversarial training.

We also integrate audio augmentation, build a queryable metadata warehouse, and connect AugLy transformations directly to PyTorch datasets and DataLoaders, giving us an end-to-end view of augmentation as both a data-generation mechanism and a measurable robustness tool.

Copy CodeCopiedUse a different Browserimport subprocess, sys, importlib def sh(cmd): print(f"$ {cmd}") subprocess.run(cmd, shell=True, check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def need(mod): try: importlib.

importmodule(mod) return False except ImportError: return True if need("augly"): sh("apt-get -qq install -y libmagic1 > /dev/null 2>&1") sh(f'"{sys.executable}" -m pip install -q --no-deps augly') sh(f'"{sys.executable}" -m pip install -q "iopath>=0.1.8" "python-magic>=0.4.22" ' f'"regex>=2021.4.

4" "nlpaug==1.1.3"') import numpy as np from PIL import Image, ImageDraw, ImageFont, ImageFilter for name, builtin in (("float", float), ("int", int), ("bool", bool)): if not hasattr(np, name): setattr(np, name, builtin) def size(font, text): left, top, right, bottom = font.

getbbox(text) return (right, bottom) if not hasattr(ImageFont.FreeTypeFont, "getsize"): ImageFont.FreeTypeFont.getsize = lambda self, t, *a, **k: size(self, t) if not hasattr(ImageFont.

FreeTypeFont, "getsizemultiline"): def getsizemultiline(self, text, direction=None, spacing=4, features=None, language=None, strokewidth=0): lines = text.

split("\n") w = max((size(self, ln)[0] for ln in lines), default=0) h = sum(size(self, ln)[1] for ln in lines) + spacing (len(lines) - 1) return (w, h) ImageFont.FreeTypeFont.

getsizemultiline = getsizemultiline import os, io, json, math, random, string, textwrap, unicodedata, warnings from dataclasses import dataclass from typing import Any, Dict, List, Optional, Tuple import matplotlib.pyplot as plt import pandas as pd import augly.image as imaugs import augly.

text as textaugs import augly.utils as augutils from augly.image.transforms import BaseTransform as ImageBaseTransform warnings.filterwarnings("ignore") pd.setoption("display.width", 160) SEED = 1234 random.seed(SEED) np.random.seed(SEED) print("\n" + "=" 78) print("AugLy ready.

assets at:", augutils.ASSETSBASEDIR) print("image augs :", len([f for f in dir(imaugs) if f[0].islower()])) print("text augs :", len([f for f in dir(textaugs) if f[0].islower()])) print("=" 78 + "\n") def makeimage(idx: int, w: int = 320, h: int = 240) -> Tuple[Image.

Image, Tuple[int, int, int, int]]: """Procedurally generated 'photo' + a ground-truth bbox in pascalvoc format.""" rng = random.Random(SEED + idx) img = Image.new("RGB", (w, h), tuple(rng.randint(20, 90) for in range(3))) d = ImageDraw.Draw(img) for in range(70): x0, y0 = rng.randint(0, w), rng.

randint(0, h) d.line([x0, y0, x0 + rng.randint(-60, 60), y0 + rng.randint(-60, 60)], fill=tuple(rng.randint(60, 160) for in range(3)), width=rng.randint(1, 3)) ow, oh = rng.randint(70, 130), rng.randint(60, 110) ox, oy = rng.randint(10, w - ow - 10), rng.

randint(10, h - oh - 10) box = (ox, oy, ox + ow, oy + oh) colour = tuple(rng.randint(150, 255) for in range(3)) if idx % 3 == 0: d.ellipse(box, fill=colour, outline=(255, 255, 255), width=3) elif idx % 3 == 1: d.rectangle(box, fill=colour, outline=(255, 255, 255), width=3) else: d.

polygon([(ox + ow // 2, oy), (ox + ow, oy + oh), (ox, oy + oh)], fill=colour, outline=(255, 255, 255)) return img, box NIMAGES = 24 IMAGES, BOXES = zip([makeimage(i) for i in range(NIMAGES)]) IMAGES, BOXES = list(IMAGES), list(BOXES) DEMOIMG, DEMOBOX = IMAGES[0], BOXES[0] def maketextdataset(nperclass: int = 260): """Tiny sentiment corpus built from templates -> learnable but not trivial.

""" rng = random.

Random(SEED) posadj = ["excellent", "delightful", "superb", "charming", "brilliant", "flawless", "wonderful", "outstanding", "impressive", "lovely"] negadj = ["terrible", "awful", "dreadful", "disappointing", "clumsy", "broken", "miserable", "useless", "painful", "sloppy"] subj = ["the movie", "this restaurant", "the hotel room", "their support team", "the new phone", "the sequel", "this laptop", "the delivery service"] tailp = ["and I would recommend it to anyone", "worth every rupee", "I left completely satisfied", "easily the best of the year", "it exceeded all my expectations"] tailn = ["and I want a refund", "a total waste of money", "I left extremely frustrated", "easily the worst of the year", "it failed every expectation"] rows = [] for in range(nperclass): rows.

append((f"{rng.choice(subj)} was {rng.choice(posadj)} {rng.choice(tailp)}", 1)) rows.append((f"{rng.choice(subj)} was {rng.choice(negadj)} {rng.choice(tailn)}", 0)) rng.

shuffle(rows) return [r[0] for r in rows], [r[1] for r in rows] TEXTS, LABELS = maketextdataset() DEMOTEXT = "The quick brown fox jumps over the lazy dog near the river bank" def makeaudio(seconds: float = 2.0, sr: int = 16000) -> Tuple[np.

ndarray, int]: """A chirp + harmonics + a little noise = something you can actually hear change.""" t = np.linspace(0, seconds, int(sr seconds), endpoint=False) f = np.linspace(220, 880, t.size) sig = 0.5 np.sin(2 np.pi f t) + 0.2 np.sin(2 np.pi 2 f t) sig += 0.02 np.random.RandomState(SEED).

randn(t.size) env = np.minimum(1.0, np.minimum(t 8, (seconds - t) 8)) return (sig env).astype(np.float32), sr AUDIO, SR = makeaudio() def showgrid(pairs, cols=4, title="", figsizescale=2.9): """pairs: list of (caption, PIL.Image).""" rows = math.ceil(len(pairs) / cols) fig, axes = plt.

subplots(rows, cols, figsize=(cols figsizescale, rows figsizescale)) axes = np.atleast1d(axes).ravel() for ax, (cap, im) in zip(axes, pairs): ax.imshow(im) ax.settitle(cap, fontsize=8) ax.axis("off") for ax in axes[len(pairs):]: ax.axis("off") if title: fig.suptitle(title, fontsize=13, y=1.0) plt.

tightlayout() plt.show() def asstr(out) -> str: """AugLy text augs return str for str input in some transforms, list in others.""" return out[0] if isinstance(out, list) else out print("\n### §2 IMAGE AUGMENTATION + METADATA " + "#" * 38) functionalresult = imaugs.pixelization(DEMOIMG, ratio=0.

25) classresult = imaugs.Pixelization(ratio=0.25, p=1.0)(DEMOIMG) print("functional == class:", np.arrayequal(np.array(functionalresult), np.array(classresult))) IMAGEZOO = { "blur": lambda im, m: imaugs.blur(im, radius=3.0, metadata=m), "brightness": lambda im, m: imaugs.brightness(im, factor=1.

7, metadata=m), "colorjitter": lambda im, m: imaugs.colorjitter(im, brightnessfactor=1.3, contrastfactor=1.4, saturationfactor=1.6, metadata=m), "crop": lambda im, m: imaugs.crop(im, x1=.15, y1=.15, x2=.85, y2=.85, metadata=m), "encodingquality": lambda im, m: imaugs.

encodingquality(im, quality=8, metadata=m), "grayscale": lambda im, m: imaugs.grayscale(im, metadata=m), "hflip": lambda im, m: imaugs.hflip(im, metadata=m), "memeformat": lambda im, m: imaugs.memeformat(im, text="TOP TEXT", captionheight=90, metadata=m), "opacity": lambda im, m: imaugs.

opacity(im, level=0.45, metadata=m), "overlayemoji": lambda im, m: imaugs.overlayemoji(im, opacity=0.9, emojisize=0.35, metadata=m), "overlayscreenshot": lambda im, m: imaugs.overlayontoscreenshot(im, metadata=m), "overlaystripes": lambda im, m:

Related

相關文章

基元律動發佈NeoHorse-1.5-Flash Preview,開放限量內測

對照評測顯示,相較基座模型,新模型在Agents’ Last Exam上整體得分提高9.23分,在Natural Language to Repository評測上提高5.92分,物理科學任務提升超過20分,開發工具與測試、Web開發、安全認證與加密等方向亦有改善。

3 小時前7500

肯德基在日本翻車:AI 畫的商品圖,連冰塊都"染了色"

日本肯德基最近就栽在了這上面。據日媒 ITmedia 11 月 10 日報道,有網友發現,這家快餐巨頭在部分門店試售新品時,商品宣傳圖並非實拍,而是出自生成式 AI 之手,且這並非個別門店的疏忽,而是一次有意識的製作選擇。被 AI 染綠的冰塊露了餡此次試售的是"冰淇淋可樂飲品"和"冰淇淋哈密瓜汽水"兩款限定產品。

3 小時前7600

AI日報:騰訊AI遊戲陪伴Agent鵝次元內測;Anthropic發佈Claude Fable5.2;美團開源LongCat-2.5

你的遊戲“最強搭子”上線:騰訊首款AI遊戲陪伴Agent“鵝次元”內測開啟騰訊“鵝次元”切入遊戲陪伴細分場景,以實時屏幕感知與多模態交互形成差異化,首測覆蓋主流遊戲並聯動QQ跨端生態。其路徑體現了AI Agent從文本問答向視覺理解與擬人陪伴演進,但角色深度與長期粘性仍需觀察。

4 小時前4200