Skip to main content

self-supervised-learning

Learning representations from unlabeled data using pretext tasks and contrastive methods

الانتقال إلى التثبيت

معلومات المصدر

المستودع
NeuralBlitz/Agent-Gateway
آخر نشاط في المصدر
١٠ أبريل ٢٠٢٦ في ٠٨:٠٤
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
Self-Supervised Learning
category
ai
description
Learning representations from unlabeled data using pretext tasks and contrastive methods
# Self-Supervised Learning ## What I do I enable machines to learn useful representations from large amounts of unlabeled data by creating supervised signals from the data itself. I eliminate the dependency on human-annotated labels by designing pretext tasks that encourage models to learn meaningful features. The learned representations can then be transferred to downstream tasks with minimal fine-tuning. ## When to use me - Pre-training on large unlabeled datasets when labeled data is scarce - Building representation learning systems for transfer learning - Learning from web-scale data without manual annotation - Reducing labeling costs for domain-specific applications - Pre-training foundation models for various downstream tasks - Learning from images, text, audio, and other data types - Building models that generalize across domains without supervision ## Core Concepts 1. **Pretext Tasks**: Artificially created supervised tasks that don't require labels but teach useful representations. 2. **Contrastive Learning**: Learning by pulling similar examples together and pushing dissimilar examples apart in embedding space. 3. **Momentum Contrast (MoCo)**: Using a momentum queue to maintain consistent negative samples during contrastive learning. 4. **SimCLR Framework**: Simple contrastive learning framework with data augmentation and large batch sizes. 5. **Masked Prediction**: Learning by predicting masked portions of input, used successfully in BERT and MAE. 6. **BYOL and Bootstrap Your Own Latent**: Methods that avoid negative samples through online and target networks. 7. **Cluster Assignment**: Methods like SwAV that assign cluster predictions as supervision signal. 8. **Information Maximization**: Learning representations that maximize mutual information between views. ## Code Examples ```python import torch import torch.nn as nn import torch.nn.functional as F class SimCLRProjectionHead(nn.Module): def __init__(self, input_dim=2048, hidden_dim=2048, output_dim=128): super().__init__() self.head = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, output_dim) ) def forward(self, features): return self.head(features) def nt_xent_loss(z_i, z_j, temperature=0.5): batch_size = z_i.size(0) z = torch.cat([z_i, z_j], dim=0) similarity = torch.matmul(z, z.t()) / temperature mask = torch.eye(2 * batch_size, device=z.device) similarity = similarity.masked_fill(mask.bool(), -float('inf')) pos_mask = torch.zeros(2 * batch_size, 2 * batch_size, device=z.device) pos_mask[:batch_size, batch_size:] = torch.eye(batch_size, device=z.device) pos_mask[batch_size:, :batch_size] = torch.eye(batch_size, device=z.device) loss_i = -torch.log( torch.exp(similarity[:batch_size, batch_size:2*batch_size].diag()) / torch.exp(similarity[:batch_size]).sum(dim=1) ) loss_j = -torch.log( torch.exp(similarity[batch_size:, :batch_size].diag()) / torch.exp(similarity[batch_size:]).sum(dim=1) ) return (loss_i + loss_j).mean() ``` ```python import torch import torch.nn as nn import torch.nn.functional as F class MoCoQueue: def __init__(self, queue_size=65536, embed_dim=128, momentum=0.999): self.queue_size = queue_size self.embed_dim = embed_dim self.momentum = momentum self.register_buffer("queue", torch.randn(queue_size, embed_dim)) self.queue = F.normalize(self.queue, p=2, dim=1) self.register_buffer("queue_ptr", torch.zeros(1, dtype=torch.long)) @torch.no_grad() def update(self, keys): batch_size = keys.size(0) ptr = int(self.queue_ptr) self.queue[ptr:ptr+batch_size] = keys ptr = (ptr + batch_size) % self.queue_size self.queue_ptr[0] = ptr def forward(self, query, key, momentum_encoder): query = F.normalize(query, p=2, dim=1) with torch.no_grad(): key = momentum_encoder(key) key = F.normalize(key, p=2, dim=1) self.update(key) positive = torch.sum(query * key, dim=-1, keepdim=True) negative = torch.matmul(query, self.queue.t()) logits = torch.cat([positive, negative], dim=1) / 0.07 labels = torch.zeros(logits.size(0), dtype=torch.long, device=query.device) return logits, labels class MoCoModel(nn.Module): def __init__(self, base_encoder, embed_dim=128, m=0.999): super().__init__() self.encoder_q = base_encoder self.encoder_k = base_encoder self.projector_q = SimCLRProjectionHead(output_dim=embed_dim) self.projector_k = SimCLRProjectionHead(output_dim=embed_dim) for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()): param_k.data.copy_(param_q.data) param_k.requires_grad = False self.moco_queue = MoCoQueue(embed_dim=embed_dim, momentum=m) def forward(self, im_q, im_k): q = self.encoder_q(im_q) q = self.projector_q(q) logits, labels = self.moco_queue.forward(q, im_k, self.encoder_k) return logits, labels @torch.no_grad() def _momentum_update_key_encoder(self): for param_q, param_k in zip(self.encoder_q.parameters(), self.encoder_k.parameters()): param_k.data = param_k.data * self.m + param_q.data * (1. - self.m) ``` ```python import torch import torch.nn as nn import torch.nn.functional as F class BYOLPredictor(nn.Module): def __init__(self, input_dim=2048, hidden_dim=512, output_dim=128): super().__init__() self.predictor = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.BatchNorm1d(hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, output_dim) ) def forward(self, z): return self.predictor(z) class BYOLModel(nn.Module): def __init__(self, base_encoder, input_dim=2048, hidden_dim=512, output_dim=128, m=0.996): super().__init__() self.encoder = base_encoder self.projector = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, output_dim) ) self.predictor = BYOLPredictor(input_dim, hidden_dim, output_dim) self.online_encoder = nn.Sequential(self.encoder, self.projector) self.target_encoder = nn.Sequential( type(self.encoder)(**self.encoder_kwargs), type(self.projector)(**self.projector_kwargs) ) for param in self.target_encoder.parameters(): param.requires_grad = False self.m = m def forward(self, v1, v2): h1 = self.online_encoder(v1) h2 = self.online_encoder(v2) z1 = F.normalize(h1, dim=1) z2 = F.normalize(h2, dim=1) p1 = self.predictor(z1) p2 = self.predictor(z2) with torch.no_grad(): t1 = self.target_encoder(v1) t2 = self.target_encoder(v2) z1_t = F.normalize(t1, dim=1) z2_t = F.normalize(t2, dim=1) loss = 2 - F.cosine_similarity(p1, z2_t, dim=-1).mean() - F.cosine_similarity(p2, z1_t, dim=-1).mean() return loss @torch.no_grad() def update_target(self): for param_o, param_t in zip(self.online_encoder.parameters(), self.target_encoder.parameters()): param_t.data = param_t.data * self.m + param_o.data * (1 - self.m) ``` ```python import torch import random from typing import Tuple, List class SimCLRTransforms: def __init__(self, size=224): self.color_jitter = torch.nn.ColorJitter( brightness=0.4, contrast=0.4, saturation=0.4, hue=0.1 ) self.gaussian_blur = GaussianBlur(kernel_size=23) self.size = size def __call__(self, img): t1 = self._transform(img) t2 = self._transform(img) return t1, t2 def _transform(self, img): img = self._random_resize_crop(img) img = self.color_jitter(img) img = self._random_grayscale(img) if random.random() < 0.5: img = self.gaussian_blur(img) img = self._normalize(img) return img def _random_resize_crop(self, img): i, j, h, w = transforms.RandomResizedCrop.get_params(img, (0.08, 1.0), (3/4, 4/3)) return transforms.functional.resized_crop(img, i, j, h, w, self.size) def _random_grayscale(self, img): if random.random() < 0.2: return transforms.functional.to_grayscale(img) return img def _normalize(self, img): return transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])(img) class GaussianBlur: def __init__(self, kernel_size=23): self.kernel_size = kernel_size def __call__(self, img): sigma = random.uniform(0.1, 2.0) return transforms.functional.gaussian_blur(img, self.kernel_size, sigma=[sigma]) ``` ```python import torch import torch.nn as nn class MAEEncoder(nn.Module): def __init__(self, patch_size=16, embed_dim=768, depth=12, num_heads=12): super().__init__() self.patch_embed = nn.Conv2d(3, embed_dim, kernel_size=patch_size, stride=patch_size) self.pos_embed = nn.Parameter(torch.zeros(1, 196, embed_dim)) self.blocks = nn.ModuleList([ nn.TransformerEncoderLayer( d_model=embed_dim, nhead=num_heads, dim_feedforward=4*embed_dim, dropout=0.0 ) for _ in range(depth) ]) self.norm = nn.LayerNorm(embed_dim) self._init_weights() def _init_weights(self): nn.init.trunc_normal_(self.pos_embed, std=0.02) nn.init.xavier_uniform_(self.patch_embed.weight) def forward(self, x): x = self.patch_embed(x) x = x.flatten(2).transpose(1, 2) x = x + self.pos_embed for block in self.blocks: x = block(x) return self.norm(x) class MAEDecoder(nn.Module): def __init__(self, embed_dim=768, depth=8, num_heads=16, patch_size=16, num_patches=196): super().__init__() self.mask_token = nn.Parameter(torch.zeros(1, 1, embed_dim)) self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim)) self.blocks = nn.ModuleList([ nn.TransformerEncoderLayer( d_model=embed_dim, nhead=num_heads, dim_feedforward=4*embed_dim ) for _ in range(depth) ]) self.head = nn.Linear(embed_dim, 3 * patch_size ** 2) self._init_weights() def _init_weights(self): nn.init.normal_(self.mask_token, std=0.02) nn.init.trunc_normal_(self.pos_embed, std=0.02) def forward(self, x, ids_restore, ids_keep): x = self._unpatchify(x) return x def _unpatchify(self, x): C = 3 p = 16 h = w = int(x.shape[1] ** 0.5) x = x.reshape(shape=(x.shape[0], h, w, p, p, C)) x = torch.einsum('nhwpqc->nchpwq', x) return x.reshape(x.shape[0], C, h * p, w * p) def mae_loss(reconstructed, original, mask): loss = (reconstructed - original) ** 2 loss = loss.mean(dim=-1) loss = (loss * mask).sum() / mask.sum() return loss ``` ## Best Practices 1. Use stronger augmentations for contrastive learning to create more informative positive pairs. 2. Increase batch size for SimCLR as it directly affects the number of negative samples. 3. Use learning rate warmup and cosine scheduling for stable contrastive training. 4. Monitor representation similarity metrics to track learning progress. 5. Use projection heads to map features to contrastive space, not raw backbone outputs. 6. Apply symmetric loss terms when using two views to ensure balanced optimization.
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub