Biểu diễn Đa phương thức¶
Các biểu diễn đa phương thức kết nối thị giác, ngôn ngữ và âm thanh vào các không gian embedding chia sẻ. File này bao quát các chiến lược fusion, CLIP, ALIGN, SigLIP, các hàm mất mát đối chọi (InfoNCE, NT-Xent), phân lớp zero-shot, và đánh giá truy xuất.
-
Hãy tưởng tượng bạn đang ngồi trong một quán cà phê. Bạn thấy một tách cà phê đang bốc khói trên bàn, nghe tiếng gốm sứ lanh canh, ngửi thấy mùi hạt cà phê rang, và cảm nhận hơi ấm tỏa ra từ tách. Không riêng cảm giác nào nói cho bạn mọi thứ: não bạn hợp nhất các tín hiệu này thành một tri giác thống nhất về \"tách cà phê nóng\". Học đa phương thức (multimodal learning) làm điều tương tự cho máy móc: nó kết hợp thông tin từ nhiều phương thức (thị giác, ngôn ngữ, âm thanh và các phương thức khác) để xây dựng các biểu diễn phong phú và bền vững hơn so với bất kỳ phương thức đơn lẻ nào.
-
Một phương thức (modality) là một kênh thông tin riêng biệt. Trong học máy, các phương thức phổ biến nhất là ảnh (lưới pixel), văn bản (chuỗi token), âm thanh (dạng sóng hoặc spectrogram, như trong Chương 9), video (chuỗi các frame), và dữ liệu có cấu trúc (bảng, đồ thị). Mỗi phương thức có cấu trúc thống kê riêng: ảnh là mạch lạc về không gian, văn bản là tuần tự và rời rạc, âm thanh là theo thời gian và liên tục. Thách thức của học đa phương thức là kết nối các kiểu dữ liệu khác biệt về căn bản này.
-
Tại sao phải bận tâm kết hợp các phương thức? Bởi vì chúng cung cấp thông tin bổ sung cho nhau. Một bức ảnh về một chú chó cho bạn biết về giống và màu lông nhưng không nói tên nó. Một chú thích như \"chú golden retriever Max của tôi\" cho bạn biết tên và giống nhưng không phải tư thế chính xác. Cùng nhau, ảnh và văn bản cho bức tranh đầy đủ hơn so với từng cái riêng lẻ. Sự bổ sung này là động lực cốt lõi: các mô hình đa phương thức có thể trả lời câu hỏi, sinh nội dung, và đưa ra quyết định mà không mô hình đơn phương thức nào làm được.
Các chiến lược Fusion¶
-
Hãy nghĩ về một dự án nhóm. Bạn có thể kết hợp ý tưởng theo hai cách: mọi người cùng làm việc trong cùng một phòng ngay từ đầu (chia sẻ các ghi chú và bản nháp thô), hoặc mỗi người viết phần của mình độc lập rồi bạn hợp nhất các tài liệu cuối cùng. Đây tương ứng với fusion sớm (early fusion) và fusion muộn (late fusion) trong học đa phương thức.
-
Fusion sớm (còn gọi là fusion cấp đặc trưng) nối hoặc trộn các đặc trưng thô hoặc cấp thấp từ các phương thức khác nhau trước khi có bất kỳ xử lý đáng kể nào. Ví dụ, bạn có thể nối các đặc trưng pixel của ảnh với các embedding token của văn bản và đưa chuỗi kết hợp vào một transformer duy nhất. Mô hình có thể học các tương tác xuyên phương thức tinh vi ngay từ đầu, nhưng không gian đầu vào lớn và mô hình phải học cách xử lý đồng thời các kiểu dữ liệu rất khác nhau.
-
Một cách hình thức, cho trước các vector đặc trưng \(x_{\text{img}} \in \mathbb{R}^{d_1}\) và \(x_{\text{txt}} \in \mathbb{R}^{d_2}\) từ hai phương thức, fusion sớm đơn giản là nối chúng:
-
Vector được nối này sau đó được xử lý bởi một mạng chia sẻ. Ưu điểm là mô hình có thể khám phá các tương quan xuyên phương thức ở mọi lớp. Nhược điểm là chi phí tính toán và khó khăn trong việc căn chỉnh các kiểu đặc trưng rất khác nhau (giá trị pixel dày đặc so với chỉ số token thưa).
-
Fusion muộn (còn gọi là fusion cấp quyết định) xử lý mỗi phương thức độc lập qua bộ mã hóa riêng, tạo ra một biểu diễn cấp cao hoặc thậm chí một dự đoán cuối cùng cho mỗi cái. Các đầu ra này sau đó được kết hợp, thường bằng cách trung bình các điểm số, bỏ phiếu, hoặc một lớp kết hợp có học. Fusion muộn đơn giản hơn và cho phép tái sử dụng các mô hình đơn phương thức đã tiền huấn luyện sẵn có, nhưng không thể nắm bắt các tương tác xuyên phương thức cấp thấp vì các phương thức không bao giờ \"nhìn thấy\" đặc trưng thô của nhau.
-
Cho trước các dự đoán đặc thù theo phương thức \(\hat{y}_1\) và \(\hat{y}_2\), một quy tắc fusion muộn đơn giản là:
-
trong đó \(\alpha \in [0, 1]\) là trọng số trộn được học hoặc tinh chỉnh thủ công.
-
Fusion giữa (middle fusion, còn gọi là fusion trung gian) là giải pháp trung dung thực dụng được hầu hết các hệ thống hiện đại sử dụng. Mỗi phương thức trước tiên được xử lý bởi bộ mã hóa riêng (trích xuất các đặc trưng đặc thù theo phương thức), sau đó các biểu diễn đã mã hóa được kết hợp giữa chừng trong mạng, thường qua các lớp cross-attention. Điều này cho phép mỗi bộ mã hóa chuyên biệt hóa vào phương thức của nó trong khi vẫn cho phép các tương tác xuyên phương thức phong phú. Flamingo, LLaVA, và hầu hết các mô hình thị giác-ngôn ngữ (file 02) dùng fusion giữa.
- Việc lựa chọn giữa các chiến lược fusion phụ thuộc vào tính sẵn có của dữ liệu, ngân sách tính toán, và tác vụ. Fusion sớm mạnh mẽ nhưng tốn dữ liệu. Fusion muộn rẻ nhưng hạn chế. Fusion giữa với cross-attention đã trở thành cách tiếp cận thống trị trong các mô hình đa phương thức quy mô lớn vì nó cân bằng giữa tính biểu đạt và tính mô-đun.
Không gian Embedding chung¶
-
Hãy tưởng tượng một trình dịch tự động có thể nhận bất kỳ câu nào bằng bất kỳ ngôn ngữ nào và ánh xạ nó đến cùng một điểm trong một \"không gian ý nghĩa\" chia sẻ. Câu \"a dog on a beach\" bằng tiếng Anh, Pháp, hay Nhật đều sẽ nằm cùng một tọa độ. Không gian embedding chung (joint embedding space) làm chính xác điều này, nhưng xuyên các phương thức: một ảnh chú chó trên bãi biển và văn bản \"a dog on a beach\" nên được ánh xạ đến các điểm gần nhau trong cùng một không gian vector.
-
Một cách hình thức, ta học hai hàm mã hóa: \(f_\theta : \mathcal{X}_1 \to \mathbb{R}^d\) cho phương thức 1 (ví dụ ảnh) và \(g_\phi : \mathcal{X}_2 \to \mathbb{R}^d\) cho phương thức 2 (ví dụ văn bản). Cả hai đều ánh xạ đầu vào của chúng vào cùng không gian \(d\) chiều. Mục tiêu huấn luyện đảm bảo rằng các cặp \((x_1, x_2)\) khớp ngữ nghĩa có các embedding \(f_\theta(x_1)\) và \(g_\phi(x_2)\) gần nhau (độ tương đồng cosine cao), trong khi các cặp không khớp thì xa nhau.
-
Đây là sự tổng quát trực tiếp của các không gian embedding từ (word embedding) từ Chương 7. Hãy nhớ rằng Word2Vec và GloVe đặt các từ đồng nghĩa gần nhau trong một không gian vector. Các không gian embedding chung mở rộng ý tưởng này xuyên các phương thức: thay vì độ tương đồng từ-với-từ, ta đo độ tương đồng ảnh-với-văn bản, âm thanh-với-văn bản, hoặc thậm chí ảnh-với-âm thanh.
-
Metric tương đồng hầu như luôn là độ tương đồng cosine (Chương 1):
- Bằng cách chuẩn hóa \(L_2\) tất cả các embedding lên siêu cầu đơn vị, độ tương đồng cosine thu gọn thành một tích vô hướng đơn giản \(u \cdot v\), cực kỳ hiệu quả để tính toán và có thể được tăng tốc với các thư viện tìm láng giềng gần xấp xỉ.
- Sức mạnh của một không gian embedding chung là nó cho phép truyền zero-shot (zero-shot transfer). Một khi bạn đã căn chỉnh các embedding ảnh và văn bản, bạn có thể phân lớp ảnh vào các hạng mục chưa từng được huấn luyện: chỉ cần nhúng tên hạng mục thành văn bản và tìm embedding văn bản nào gần nhất với embedding ảnh. Không cần tinh chỉnh đặc thù theo tác vụ. Đây là hiểu biết then chốt đằng sau CLIP và các hệ thống kế thừa nó.
Học đối chọi cho căn chỉnh đa phương thức¶
-
Hãy nghĩ về một bài tập trên lớp nơi học sinh được phát các cặp ảnh và chú thích đã xáo trộn, và được yêu cầu ghép mỗi ảnh với chú thích đúng của nó. Để làm tốt việc này, bạn cần hiểu cả nội dung hình ảnh và ngôn ngữ, và biết chúng liên quan thế nào. Học đối chọi (contrastive learning) huấn luyện các mô hình theo đúng cách đó: cho trước một batch các cặp (ảnh, văn bản), mô hình phải tìm ra ảnh nào đi với văn bản nào.
-
Như ta đã thấy ở Chương 8 (file 04), học đối chọi trong thiết lập đơn phương thức (SimCLR, MoCo) kéo các view tăng cường của cùng một ảnh lại gần nhau và đẩy các view của các ảnh khác xa nhau. Học đối chọi đa phương thức thay thế \"các view tăng cường\" bằng \"các phương thức khớp\": một ảnh và chú thích của nó là cặp dương (positive); ảnh được ghép với bất kỳ chú thích nào khác trong batch là cặp âm (negative).
CLIP¶
-
CLIP (Contrastive Language-Image Pre-training, Radford et al., 2021) là mô hình nền tảng cho học đối chọi đa phương thức. Nó huấn luyện một bộ mã hóa ảnh (một ViT hoặc ResNet, Chương 8) và một bộ mã hóa văn bản (một transformer, Chương 7) kết hợp trên 400 triệu cặp (ảnh, văn bản) được thu thập từ internet.
-
Cho một batch gồm \(N\) cặp ảnh-văn bản, CLIP tính ma trận \(N \times N\) các độ tương đồng cosine giữa tất cả các embedding ảnh và tất cả các embedding văn bản. Các phần tử trên đường chéo là các cặp khớp (dương); tất cả các phần tử ngoài đường chéo là không khớp (âm). Hàm mất mát huấn luyện đẩy các phần tử đường chéo lên cao và các phần tử ngoài đường chéo xuống thấp.
-
Mất mát là một cross-entropy đối xứng. Với ảnh \(i\) được ghép với văn bản \(j = i\), mất mát ảnh-đến-văn bản là:
- và mất mát văn bản-đến-ảnh là như nhau với vai trò đảo ngược:
- Tổng mất mát CLIP là trung bình cộng:
- Ở đây \(\tau\) là một tham số nhiệt độ (temperature) có học (khởi tạo tại \(\tau = 0.07\)). Nhiệt độ kiểm soát độ sắc của phân bố softmax: \(\tau\) thấp làm mô hình tập trung hơn vào kết quả khớp gần nhất, \(\tau\) cao trải xác suất đều hơn. CLIP học \(\tau\) kết hợp với trọng số mô hình thay vì coi nó như một siêu tham số cố định.
-
Bộ mã hóa ảnh của CLIP thường là một ViT-L/14 (một Vision Transformer lớn với các patch 14x14, Chương 8 file 04). Bộ mã hóa văn bản là một transformer 12 lớp với mặt nạ nhân quả (giống GPT, Chương 7 file 04). Cả hai bộ mã hóa đều chiếu đầu ra của chúng vào một không gian 512 hoặc 768 chiều chia sẻ qua một phép chiếu tuyến tính có học, theo sau là chuẩn hóa \(L_2\).
-
Thuộc tính đáng chú ý nhất của CLIP là phân lớp ảnh zero-shot. Để phân lớp một ảnh vào một trong \(K\) hạng mục, bạn tạo \(K\) prompt văn bản như \"a photo of a {class name}\", nhúng mỗi prompt bằng bộ mã hóa văn bản, nhúng ảnh bằng bộ mã hóa ảnh, và chọn hạng mục có embedding văn bản có độ tương đồng cosine cao nhất với embedding ảnh. Trên ImageNet, CLIP đạt độ chính xác cạnh tranh mà không hề nhìn thấy một ví dụ huấn luyện ImageNet nào.
ALIGN¶
- ALIGN (Jia et al., 2021) mở rộng cách tiếp cận của CLIP lên một tập dữ liệu lớn hơn và nhiễu hơn: 1,8 tỷ cặp ảnh-văn bản với lọc tối thiểu. Trong khi CLIP lọc dữ liệu cẩn thận, ALIGN cho thấy quy mô có thể bù đắp cho nhiễu. ALIGN sử dụng một bộ mã hóa ảnh EfficientNet và một bộ mã hóa văn bản BERT, và huấn luyện với cùng hàm mất mát đối chọi. Kết luận then chốt là với đủ dữ liệu, bạn không cần làm sạch dữ liệu tốn kém: mục tiêu đối chọi tự nhiên giảm trọng số của các cặp nhiễu vì chúng tạo ra các gradient không nhất quán.
SigLIP¶
-
SigLIP (Sigmoid Loss for Language-Image Pre-training, Zhai et al., 2023) thay thế hàm mất mát đối chọi dựa trên softmax của CLIP bằng một hàm mất mát sigmoid đơn giản hơn. Thay vì coi ma trận tương đồng \(N \times N\) như một bài toán phân lớp (mỗi hàng là một softmax qua các cột), SigLIP coi mỗi phần tử độc lập như một phân lớp nhị phân: cặp (ảnh, văn bản) này có khớp hay không?
-
Mất mát SigLIP cho một cặp \((i, j)\) đơn lẻ là:
-
trong đó \(y_{ij} = 1\) nếu \(i = j\) (khớp) và \(y_{ij} = 0\) nếu ngược lại, và \(\sigma\) là hàm sigmoid.
-
Ưu điểm quan trọng của SigLIP là nó loại bỏ nhu cầu chuẩn hóa softmax toàn cục trên toàn bộ batch. Trong CLIP, mẫu số softmax đòi hỏi thu thập tất cả các embedding trên mọi thiết bị, đây là một nút thắt giao tiếp trong huấn luyện phân tán. Mất mát sigmoid trên từng cặp của SigLIP có thể được tính cục bộ, cho phép mở rộng hiệu quả hơn lên các batch rất lớn. SigLIP đạt chất lượng tương đương CLIP với chi phí huấn luyện thấp hơn.
Các hàm mất mát đối chọi chi tiết¶
- Các hàm mất mát dùng trong học đối chọi chia sẻ một cấu trúc chung: tất cả đều cố gắng làm cho điểm tương đồng của các cặp dương cao hơn của các cặp âm, với một khái niệm \"biên\" (margin) hoặc \"nhiệt độ\" (temperature) kiểm soát mô hình đẩy mạnh như thế nào. Hãy formal hóa các biến thể chính.
InfoNCE¶
- InfoNCE (Noise-Contrastive Estimation, van den Oord et al., 2018) là nền tảng lý thuyết đằng sau mất mát của CLIP. Cho một truy vấn \(q\), một khóa dương \(k^+\), và \(K\) khóa âm \(\{k_1^-, \ldots, k_K^-\}\), mất mát là:
- Đây là một bài toán phân lớp \((K+1)\)-way: xác định phần tử dương trong số \(K+1\) ứng viên. InfoNCE là một cận dưới của thông tin tương hỗ giữa truy vấn và khóa dương, điều này giải thích tại sao tối đa hóa nó sẽ căn chỉnh các biểu diễn của các đầu vào khớp ngữ nghĩa. Cận này thắt lại khi số lượng âm \(K\) tăng, giải thích tại sao các phương pháp đối chọi có lợi từ các kích thước batch lớn.
NT-Xent¶
- NT-Xent (Normalised Temperature-scaled Cross-Entropy, Chen et al., 2020) là mất mát được dùng trong SimCLR (Chương 8 file 04) và về cơ bản là InfoNCE được áp dụng đối xứng trong một batch. Với một batch gồm \(N\) cặp, \(2N\) view tăng cường tạo ra \(2N - 2\) âm cho mỗi neo (tất cả các view trừ chính nó và phần tử dương của nó). Mất mát cho một cặp dương \((i, j)\) là:
- NT-Xent và InfoNCE là cùng một công thức toán học; tên khác nhau vì chúng được giới thiệu trong các bối cảnh khác nhau (thị giác tự giám sát so với lý thuyết học biểu diễn).
Vai trò của Nhiệt độ¶
-
Nhiệt độ \(\tau\) là một trong những siêu tham số quan trọng nhất trong học đối chọi. Để xây dựng trực giác, hãy nghĩ về nhiệt độ theo nghĩa vật lý: ở nhiệt độ cao, các phân tử chuyển động ngẫu nhiên (softmax phẳng, tất cả các âm đều có vẻ tệ như nhau); ở nhiệt độ thấp, các phân tử sắp xếp vào các cấu trúc cứng (softmax nhọn, chỉ các âm khó nhất mới quan trọng).
-
Một cách hình thức, khi \(\tau \to 0\), softmax tiến tới một argmax cứng chỉ chọn âm khó nhất duy nhất. Khi \(\tau \to \infty\), tất cả các âm đóng góp như nhau. Trong thực tế, \(\tau \in [0.01, 0.1]\) hoạt động tốt cho các embedding đã chuẩn hóa. Nhiệt độ quá thấp gây bất ổn huấn luyện (gradient trở nên rất lớn đối với các âm khó); nhiệt độ quá cao làm mất mát không nhạy với các vi phạm.
-
CLIP khởi tạo \(\tau = 0.07\) và học nó như một vô hướng tham số hóa bằng log \(\tau = \exp(t)\), trong đó \(t\) được cập nhật bởi hạ gradient cùng với trọng số mô hình. Điều này cho phép mô hình tự động điều chỉnh độ khó của bài toán đối chọi trong quá trình huấn luyện.
Mất mát Triple và các lựa chọn thay thế dựa trên biên¶
- Trước khi InfoNCE thống trị, mất mát triple (triplet loss) là chuẩn cho học metric. Cho một neo \(a\), một dương \(p\), và một âm \(n\):
-
trong đó \(m\) là một biên đảm bảo phần tử dương gần hơn phần tử âm ít nhất là \(m\). Mất mát triple hoạt động trên từng triple thay vì từng batch, làm cho nó kém hiệu quả về mẫu hơn InfoNCE. Nó cũng nhạy cảm với chiến lược khai thác: các âm ngẫu nhiên thường quá dễ (mất mát bằng 0), do đó khai thác âm khó (hard negative mining, chọn kết quả không khớp gần nhất) hoặc khai thác bán khó (semi-hard mining, chọn các âm nằm trong biên) là rất quan trọng.
-
InfoNCE thực hiện ngầm việc khai thác âm khó trên toàn bộ batch, đây là một lý do nó vượt trội so với mất mát triple ở quy mô lớn. Việc chuẩn hóa softmax trong InfoNCE tự động tăng trọng số cho các âm khó (những cái có độ tương đồng cao với neo), cung cấp một chương trình giảng dạy tự nhiên mà không cần khai thác tường minh.
Truy xuất ảnh-văn bản và phân lớp Zero-Shot¶
-
Một khi bạn có một không gian embedding chung đã huấn luyện, bạn có thể thực hiện truy xuất ảnh-văn bản (image-text retrieval): cho một truy vấn ảnh, tìm các văn bản liên quan nhất từ một cơ sở dữ liệu (truy xuất ảnh-đến-văn bản), hoặc cho một truy vấn văn bản, tìm các ảnh liên quan nhất (truy xuất văn bản-đến-ảnh). Đây đơn giản chỉ là một tìm kiếm láng giềng gần trong không gian embedding chia sẻ.
-
Hãy tưởng tượng một thủ thư có thể so sánh ngay lập tức bất kỳ bức ảnh nào với bất kỳ chú thích nào trong một danh mục hàng triệu mục. Họ không cần hiểu trước mọi hạng mục có thể; họ chỉ đo xem mỗi bức ảnh \"gần\" với mỗi chú thích đến mức nào. Đây là cách các mô hình kiểu CLIP thực hiện truy xuất và phân lớp zero-shot.
-
Phân lớp zero-shot là một trường hợp đặc biệt của truy xuất văn bản-đến-ảnh. Cho \(K\) tên hạng mục, bạn xây dựng các prompt văn bản \(\{t_1, \ldots, t_K\}\) (ví dụ \"a photo of a cat\", \"a photo of a dog\") và nhúng chúng. Với một ảnh mới \(x\), hạng mục được dự đoán là:
-
Hiểu biết then chốt là bộ mã hóa văn bản hoạt động như một đầu phân lớp linh hoạt. Thay vì huấn luyện một lớp tuyến tính mới cho mỗi tác vụ hạ nguồn, bạn chỉ cần mô tả tác vụ bằng ngôn ngữ tự nhiên. Đây là lý do CLIP khái quát hóa tốt như vậy: bộ mã hóa văn bản đã thấy hàng triệu mô tả đa dạng trong quá trình tiền huấn luyện.
-
Thiết kế prompt (prompt engineering) rất quan trọng. Độ chính xác zero-shot của CLIP trên ImageNet tăng từ 63,2% lên 68,4% chỉ bằng cách thay đổi mẫu prompt từ \"{class name}\" thành \"a photo of a {class name}.\". Thậm chí tốt hơn, tổng hợp prompt (prompt ensembling) lấy trung bình các embedding văn bản của nhiều mẫu (ví dụ \"a photo of a {class name}\", \"a good photo of a {class name}\", \"a drawing of a {class name}\") để tạo ra một biểu diễn văn bản bền vững hơn.
Tương ứng Âm thanh-Thị giác¶
-
Hãy nhắm mắt lại và nghe tiếng ai đó nảy một quả bóng rổ. Bạn có thể biết khi nào nó chạm đất từ những tiếng thịch nhịp nhàng. Giờ hãy mở mắt: cú nảy hình ảnh căn chỉnh hoàn hảo với mỗi tiếng thịch. Sự tương ứng chặt chẽ giữa các sự kiện âm thanh và thị giác này là một tín hiệu giám sát tự do mà máy móc có thể học được. Học tương ứng âm thanh-thị giác (audio-visual correspondence learning) huấn luyện các mô hình liên kết âm thanh với nguồn hình ảnh của chúng mà không cần bất kỳ nhãn nào của con người.
-
Ý tưởng này rất giống với CLIP, nhưng thay thế văn bản bằng âm thanh. Cho các cặp frame video và đoạn âm thanh đã ghép cặp, mô hình học một không gian embedding nơi các cặp âm thanh-thị giác căn chỉnh theo thời gian nằm gần nhau và các cặp không căn chỉnh nằm xa nhau.
-
Các phương pháp Embedding Âm thanh-Thị giác (AVE) (Arandjelovic and Zisserman, 2017) huấn luyện một bộ mã hóa thị giác \(f\) và một bộ mã hóa âm thanh \(g\) với một mất mát đối chọi trên dữ liệu video. Cặp dương là (frame video, đoạn âm thanh từ cùng thời điểm), và các âm là các đoạn âm thanh từ các video khác hoặc các thời điểm khác. Mô hình học được rằng tiếng chó sủa đi với hình ảnh con chó, và tiếng đàn ghi-ta đi với hình ảnh cây đàn ghi-ta, tất cả mà không cần nhãn.
-
Bộ mã hóa âm thanh thường xử lý log-mel spectrogram (Chương 9 file 01) bằng một CNN hoặc transformer âm thanh, tạo ra một embedding có kích thước cố định. Bộ mã hóa thị giác xử lý các frame video bằng một backbone ảnh chuẩn (ResNet, ViT). Cả hai đều được chiếu vào một không gian \(d\) chiều chia sẻ, và huấn luyện dùng cùng mất mát InfoNCE như CLIP:
-
Các ứng dụng của học âm thanh-thị giác bao gồm: định vị nguồn âm thanh (âm thanh phát ra từ đâu trong ảnh?), nhận dạng tiếng nói âm thanh-thị giác (kết hợp chuyển động môi với âm thanh, như trong Chương 9 file 02), tách nguồn âm thanh-thị giác (cô lập giọng nói của một người nói bằng cách nhìn mặt họ, \"bài toán cocktail party\" từ Chương 9 file 05), và sinh video có điều kiện bởi âm thanh.
-
ImageBind (Girdhar et al., 2023) mở rộng điều này lên sáu phương thức: ảnh, văn bản, âm thanh, độ sâu (depth), nhiệt (thermal), và dữ liệu IMU. Hiểu biết then chốt là bạn không cần dữ liệu ghép cặp cho mọi tổ hợp. Bằng cách căn chỉnh mỗi phương thức với ảnh (dùng các cặp ảnh-văn bản cho văn bản, cặp ảnh-âm thanh cho âm thanh, v.v.), tất cả các phương thức đều được căn chỉnh ngầm qua không gian embedding ảnh chia sẻ. Sự \"ràng buộc\" này thông qua một phương thức neo chung tạo ra một căn chỉnh nổi lên: âm thanh và văn bản trở nên tương tự nhau ngay cả khi chúng chưa từng được huấn luyện trực tiếp cùng nhau.
Đánh giá¶
- Đánh giá các mô hình đa phương thức đòi hỏi các metric nắm bắt sự hiểu biết xuyên phương thức. Hai mô thức đánh giá thống trị là các benchmark zero-shot và các metric truy xuất.
Các Benchmark Zero-Shot¶
-
Đánh giá zero-shot đo lường xem một mô hình có thể thực hiện các tác vụ mà nó chưa từng được huấn luyện tường minh hay không. Benchmark phổ biến nhất là độ chính xác zero-shot ImageNet: nhúng tất cả 1.000 tên hạng mục ImageNet thành văn bản, nhúng mỗi ảnh kiểm thử, và đo độ chính xác phân lớp top-1 và top-5 dựa trên độ tương đồng cosine. CLIP ViT-L/14 đạt 75,5% top-1 zero-shot, tương đương với một ResNet-50 có giám sát được huấn luyện trên ImageNet.
-
Các benchmark zero-shot khác bao gồm: CIFAR-10/100, STL-10, Food-101, Oxford Pets, và Flowers-102. Đánh giá trên nhiều tập dữ liệu kiểm tra xem mô hình có thực sự có hiểu biết thị giác tổng quát hay chỉ ghi nhớ các mẫu từ dữ liệu tiền huấn luyện.
-
Đánh giá linear probe là một bài kiểm tra bổ sung. Bạn đóng băng bộ mã hóa ảnh đã tiền huấn luyện, trích xuất đặc trưng cho một tập dữ liệu có nhãn, và huấn luyện một bộ phân lớp tuyến tính đơn giản ở trên. Điều này đo chất lượng của các biểu diễn đã học độc lập với cơ chế truy xuất zero-shot. Các đặc trưng của CLIP là các đặc trưng linear probe xuất sắc, thường sánh ngang hoặc vượt qua tiền huấn luyện có giám sát.
Các Metric Truy xuất¶
-
Đối với các tác vụ truy xuất (ảnh-đến-văn bản và văn bản-đến-ảnh), metric chuẩn là Recall@K (R@K): tỉ lệ các truy vấn mà kết quả khớp đúng xuất hiện trong top \(K\) kết quả truy xuất. Các giá trị phổ biến là R@1, R@5, và R@10.
-
Một cách hình thức, cho một tập hợp \(Q\) truy vấn:
-
trong đó \(\text{rank}(q)\) là vị trí của kết quả khớp đúng trong danh sách truy xuất được xếp hạng cho truy vấn \(q\).
-
Các benchmark truy xuất chuẩn bao gồm Flickr30K (31.000 ảnh, mỗi ảnh có 5 chú thích) và MS-COCO (123.000 ảnh, mỗi ảnh có 5 chú thích). Đánh giá được thực hiện trên tập kiểm thử: cho một ảnh, truy xuất chú thích (các) đúng từ toàn bộ tập kiểm thử, và ngược lại.
-
Hạng trung vị (Median rank, MedR) là một metric bổ sung: vị trí trung vị của kết quả khớp đúng trên tất cả các truy vấn. Một mô hình hoàn hảo có MedR = 1. Thấp hơn thì tốt hơn.
-
Ngoài truy xuất, các mô hình đa phương thức còn được đánh giá trên các benchmark hiểu biết thành phần như Winoground (kiểm tra xem mô hình có thể phân biệt \"a mug in a dog\" và \"a dog in a mug\" không) và ARO (Attribute, Relation, Order), kiểm tra xem mô hình thực sự hiểu cấu trúc ngôn ngữ hay chỉ khớp các bao từ (bag of words). Các mô hình kiểu CLIP thường gặp khó khăn trên những cái này, bộc lộ một hạn chế căn bản: tiền huấn luyện đối chọi căn chỉnh ngữ nghĩa toàn cục nhưng có thể không nắm bắt cấu trúc thành phần tinh vi.
Tổng kết¶
-
Các biểu diễn đa phương thức trong file này tạo thành nền tảng cho mọi thứ tiếp theo trong chương này. Các không gian embedding chung được huấn luyện bởi CLIP và các hệ thống kế thừa nó là \"keo\" kết nối thị giác và ngôn ngữ. File 02 xây dựng trên nền tảng này với các mô hình thị giác-ngôn ngữ vượt ra ngoài truy xuất để sinh văn bản về ảnh. File 03 khám phá cách ảnh và video được token hóa để dùng trong các mô hình chuỗi. File 04 bao quát sinh xuyên phương thức (văn bản-đến-ảnh, văn bản-đến-video). Và file 05 xem xét các kiến trúc thống nhất xử lý nhiều phương thức trong một mô hình duy nhất.
-
Điểm chính cần nhớ: học đối chọi trên dữ liệu ghép cặp tạo ra các không gian embedding nơi các phương thức khác nhau có thể thay thế cho nhau. Một embedding ảnh và một embedding văn bản trở thành \"cùng một loại thứ\", cho phép phân lớp zero-shot, truy xuất, và tích hợp liền mạch vào các hệ thống lớn hơn. Sự đơn giản của ý tưởng này, chỉ cần đẩy các cặp khớp lại gần nhau và đẩy các cặp không khớp ra xa nhau, che giấu hiệu quả phi thường của nó.
Coding Tasks (dùng CoLab hoặc notebook)¶
-
Cài đặt hàm mất mát đối chọi CLIP từ đầu. Tạo các embedding ảnh và văn bản ngẫu nhiên, tính ma trận tương đồng, và tính mất mát cross-entropy đối xứng.
import jax import jax.numpy as jnp import matplotlib.pyplot as plt def clip_loss(image_embeds, text_embeds, temperature=0.07): """Compute symmetric CLIP contrastive loss.""" # L2 normalise embeddings image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=1, keepdims=True) text_embeds = text_embeds / jnp.linalg.norm(text_embeds, axis=1, keepdims=True) # Compute cosine similarity matrix (N x N) logits = image_embeds @ text_embeds.T / temperature # (N, N) # Labels: the diagonal (i-th image matches i-th text) N = logits.shape[0] labels = jnp.arange(N) # Symmetric cross-entropy: image-to-text + text-to-image loss_i2t = -jnp.mean(jax.nn.log_softmax(logits, axis=1)[jnp.arange(N), labels]) loss_t2i = -jnp.mean(jax.nn.log_softmax(logits, axis=0)[labels, jnp.arange(N)]) return (loss_i2t + loss_t2i) / 2, logits * temperature # Simulate a batch of 8 image-text pairs in 64-dim space key = jax.random.PRNGKey(42) k1, k2 = jax.random.split(key) N, D = 8, 64 image_embeds = jax.random.normal(k1, (N, D)) text_embeds = jax.random.normal(k2, (N, D)) loss, sim_matrix = clip_loss(image_embeds, text_embeds) print(f"CLIP loss (random embeddings): {loss:.4f}") # Visualise the similarity matrix fig, ax = plt.subplots(figsize=(6, 5)) im = ax.imshow(sim_matrix, cmap='coolwarm', vmin=-1, vmax=1) ax.set_xlabel("Text index"); ax.set_ylabel("Image index") ax.set_title(f"Cosine Similarity Matrix (loss={loss:.3f})") plt.colorbar(im); plt.tight_layout(); plt.show() # Try changing temperature (0.01, 0.1, 1.0) and observe how loss changes # Try making matched pairs similar: set text_embeds = image_embeds + small noise -
Xây dựng một mô hình embedding chung đồ chơi học cách căn chỉnh các \"ảnh\" 2D (vector ngẫu nhiên) với các \"chú thích\" (vector ngẫu nhiên khác) bằng mất mát InfoNCE và hạ gradient.
import jax import jax.numpy as jnp import matplotlib.pyplot as plt def info_nce_loss(img_enc, txt_enc, img_data, txt_data, tau=0.1): """InfoNCE over a batch of paired (image, text) data.""" z_img = img_data @ img_enc # (N, D) z_txt = txt_data @ txt_enc # (N, D) # L2 normalise z_img = z_img / jnp.linalg.norm(z_img, axis=1, keepdims=True) z_txt = z_txt / jnp.linalg.norm(z_txt, axis=1, keepdims=True) logits = z_img @ z_txt.T / tau labels = jnp.arange(logits.shape[0]) return -jnp.mean(jax.nn.log_softmax(logits, axis=1)[jnp.arange(len(labels)), labels]) # Create 32 paired samples: img in R^8, txt in R^6, embed into R^4 key = jax.random.PRNGKey(0) k1, k2, k3, k4 = jax.random.split(key, 4) N, d_img, d_txt, d_embed = 32, 8, 6, 4 img_data = jax.random.normal(k1, (N, d_img)) txt_data = jax.random.normal(k2, (N, d_txt)) # Learnable projection matrices img_enc = jax.random.normal(k3, (d_img, d_embed)) * 0.1 txt_enc = jax.random.normal(k4, (d_txt, d_embed)) * 0.1 grad_fn = jax.jit(jax.grad(info_nce_loss, argnums=(0, 1))) lr = 0.05 losses = [] for step in range(300): loss = info_nce_loss(img_enc, txt_enc, img_data, txt_data) losses.append(float(loss)) g_img, g_txt = grad_fn(img_enc, txt_enc, img_data, txt_data) img_enc = img_enc - lr * g_img txt_enc = txt_enc - lr * g_txt print(f"Initial loss: {losses[0]:.3f}, Final loss: {losses[-1]:.3f}") print(f"Random baseline (log N): {jnp.log(N):.3f}") plt.figure(figsize=(8, 4)) plt.plot(losses, color='#2c3e50') plt.axhline(y=0, color='green', linestyle='--', alpha=0.5, label='Perfect alignment') plt.axhline(y=float(jnp.log(N)), color='red', linestyle='--', alpha=0.5, label='Random (log N)') plt.xlabel("Step"); plt.ylabel("InfoNCE Loss") plt.title("Learning a Joint Embedding Space") plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show() # Modify d_embed (try 2, 4, 16) to see how embedding dimension affects alignment -
Cài đặt phân lớp zero-shot với các embedding đã tính sẵn. Mô phỏng các \"nguyên mẫu\" (prototypes) lớp như các embedding văn bản và phân lớp các ảnh mới bằng tìm kiếm láng giềng gần nhất.
import jax import jax.numpy as jnp import matplotlib.pyplot as plt # Simulate 5 classes, each with a prototype text embedding in R^32 key = jax.random.PRNGKey(42) n_classes, d = 5, 32 class_names = ["cat", "dog", "car", "plane", "ship"] # Class prototypes (imagine these came from a text encoder) k1, k2 = jax.random.split(key) class_prototypes = jax.random.normal(k1, (n_classes, d)) class_prototypes = class_prototypes / jnp.linalg.norm(class_prototypes, axis=1, keepdims=True) # Generate 200 test "images" (embeddings near their class prototype + noise) n_per_class = 40 true_labels = jnp.repeat(jnp.arange(n_classes), n_per_class) keys = jax.random.split(k2, n_classes * n_per_class) image_embeds = [] for i in range(n_classes): noise = jax.random.normal(keys[i], (n_per_class, d)) * 0.5 cluster = class_prototypes[i] + noise image_embeds.append(cluster) image_embeds = jnp.concatenate(image_embeds, axis=0) image_embeds = image_embeds / jnp.linalg.norm(image_embeds, axis=1, keepdims=True) # Zero-shot classification: cosine similarity with each prototype similarities = image_embeds @ class_prototypes.T # (200, 5) predicted_labels = jnp.argmax(similarities, axis=1) accuracy = jnp.mean(predicted_labels == true_labels) print(f"Zero-shot accuracy: {accuracy:.1%}") # Confusion matrix conf = jnp.zeros((n_classes, n_classes), dtype=jnp.int32) for true, pred in zip(true_labels, predicted_labels): conf = conf.at[true, pred].add(1) fig, ax = plt.subplots(figsize=(6, 5)) im = ax.imshow(conf, cmap='Blues') ax.set_xticks(range(n_classes)); ax.set_xticklabels(class_names, rotation=45) ax.set_yticks(range(n_classes)); ax.set_yticklabels(class_names) ax.set_xlabel("Predicted"); ax.set_ylabel("True") for i in range(n_classes): for j in range(n_classes): ax.text(j, i, int(conf[i, j]), ha='center', va='center', fontsize=11) ax.set_title(f"Zero-Shot Confusion Matrix (acc={accuracy:.1%})") plt.colorbar(im); plt.tight_layout(); plt.show() # Try increasing noise (0.5 -> 1.0 -> 2.0) to see accuracy degrade # Try adding prompt ensembling: average 3 noisy copies of each prototype