使用 AugLy 打造端到端多模態資料擴增與對抗穩健性基準:涵蓋影像、文字、音訊與 PyTorch
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
相關文章
iPhone Duo 開賣兩週:DeepSeek、B 站補位,蘋果搬出 10 萬適配 App 撐場
11 月 9 日披露,中國市場 QQ、騰訊會議、DeepSeek、文心等社交 AI 應用,嗶哩嗶哩、起點、美圖秀秀等工具,以及京東、得物、支付寶等均已適配 iPhone Duo。遊戲側,米哈遊 11 月 5 日宣佈《絕區零》3.3.1 版起適配。
基元律動發佈NeoHorse-1.5-Flash Preview,開放限量內測
對照評測顯示,相較基座模型,新模型在Agents’ Last Exam上整體得分提高9.23分,在Natural Language to Repository評測上提高5.92分,物理科學任務提升超過20分,開發工具與測試、Web開發、安全認證與加密等方向亦有改善。
肯德基在日本翻車:AI 畫的商品圖,連冰塊都"染了色"
日本肯德基最近就栽在了這上面。據日媒 ITmedia 11 月 10 日報道,有網友發現,這家快餐巨頭在部分門店試售新品時,商品宣傳圖並非實拍,而是出自生成式 AI 之手,且這並非個別門店的疏忽,而是一次有意識的製作選擇。被 AI 染綠的冰塊露了餡此次試售的是"冰淇淋可樂飲品"和"冰淇淋哈密瓜汽水"兩款限定產品。
谷歌給 Gemini 裝"刪除鍵":AI 記住的隱私,現在你能看能改能刪
谷歌決定把這本賬攤開給你看。據 Android Authority 11 月 9 日披露,谷歌正為 Gemini 推出"記憶摘要"(Memory summary)功能,讓用戶能查看、編輯乃至刪除 AI 替自己留存的個人信息,把"它到底知道我什麼"的主動權交回手裡。
AI日報:騰訊AI遊戲陪伴Agent鵝次元內測;Anthropic發佈Claude Fable5.2;美團開源LongCat-2.5
你的遊戲“最強搭子”上線:騰訊首款AI遊戲陪伴Agent“鵝次元”內測開啟騰訊“鵝次元”切入遊戲陪伴細分場景,以實時屏幕感知與多模態交互形成差異化,首測覆蓋主流遊戲並聯動QQ跨端生態。其路徑體現了AI Agent從文本問答向視覺理解與擬人陪伴演進,但角色深度與長期粘性仍需觀察。
金雞百花首開 AI 單元:287 支團隊拼 72 小時極限創作
11 月 10 日,2026 中國金雞百花電影節"金雞電影 AI 單元·推介儀式"在福建廈門舉行。這個創辦於 1992 年、在全國各城市輪流舉辦的國家級電影節,此番首次設立電影 AI 單元,意在探索人工智能在影視創作裡的實際應用與落地,也給不同來路的創作者搭一個展示、切磋與交流的臺子。