Text Classification
Transformers
PyTorch
English
wrag2
weight-retrieval
domain-adaptation
medical
legal
code
Instructions to use Gyeti123/wrag2-text-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Gyeti123/wrag2-text-classifier with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-classification", model="Gyeti123/wrag2-text-classifier")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Gyeti123/wrag2-text-classifier", device_map="auto") - Notebooks
- Google Colab
- Kaggle
| """ | |
| Weight Retrieval Layer - Core Innovation of WRAG 2.0 | |
| This layer dynamically retrieves and composes weights during the forward pass, | |
| rather than using fixed weights like traditional neural networks. | |
| """ | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| class WeightRetrievalLayer(nn.Module): | |
| """ | |
| Dynamically retrieves and composes layer weights based on input. | |
| Traditional layer: x → W → output (W is fixed) | |
| This layer: x → retrieve W based on x → W → output (W is dynamic) | |
| Args: | |
| d_in: Input dimension | |
| d_out: Output dimension | |
| num_shards: Number of weight shards in the bank | |
| k: Number of shards to retrieve and compose | |
| """ | |
| def __init__(self, d_in, d_out, num_shards=10, k=3): | |
| super().__init__() | |
| self.d_in = d_in | |
| self.d_out = d_out | |
| self.num_shards = num_shards | |
| self.k = k | |
| # Weight bank: stores multiple weight matrices (shards) | |
| # Shape: [num_shards, d_in, d_out] | |
| self.weight_bank = nn.Parameter( | |
| torch.randn(num_shards, d_in, d_out) * 0.02 | |
| ) | |
| # Query network: converts input to retrieval query | |
| # This learns what kind of weights to retrieve for each input | |
| self.query_net = nn.Sequential( | |
| nn.Linear(d_in, d_in // 2), | |
| nn.ReLU(), | |
| nn.Linear(d_in // 2, num_shards) | |
| ) | |
| # Bias (optional, like standard linear layer) | |
| self.bias = nn.Parameter(torch.zeros(d_out)) | |
| def forward(self, x, return_weights=False): | |
| """ | |
| Forward pass with dynamic weight retrieval. | |
| Args: | |
| x: Input tensor [batch, d_in] | |
| return_weights: If True, return dynamic weight matrix instead of applying it | |
| Returns: | |
| If return_weights=False: output [batch, d_out], scores [batch, num_shards] | |
| If return_weights=True: dynamic_W [batch, d_in, d_out], scores [batch, num_shards] | |
| """ | |
| batch = x.shape[0] | |
| # Step 1: Compute retrieval scores | |
| retrieval_scores = self.query_net(x) # [batch, num_shards] | |
| # Step 2: Select top-k shards | |
| top_k_scores, top_k_indices = torch.topk( | |
| retrieval_scores, k=self.k, dim=1 | |
| ) # [batch, k] | |
| # Step 3: Softmax to get composition weights | |
| composition_weights = F.softmax(top_k_scores, dim=1) # [batch, k] | |
| # Step 4: Retrieve selected shards efficiently | |
| # Instead of indexing which causes memory explosion, use einsum | |
| # Create one-hot encoding for top-k selection | |
| selection_mask = torch.zeros(batch, self.num_shards, device=x.device) | |
| selection_mask.scatter_(1, top_k_indices, composition_weights) | |
| # Step 5: Compose dynamic weight matrix using einsum | |
| # weight_bank: [num_shards, d_in, d_out] | |
| # selection_mask: [batch, num_shards] | |
| dynamic_W = torch.einsum( | |
| 'bs,sio->bio', | |
| selection_mask, | |
| self.weight_bank | |
| ) # [batch, d_in, d_out] | |
| if return_weights: | |
| return dynamic_W, retrieval_scores | |
| # Step 6: Apply dynamic weights to input | |
| output = torch.bmm(x.unsqueeze(1), dynamic_W).squeeze(1) # [batch, d_out] | |
| # Add bias | |
| output = output + self.bias | |
| return output, retrieval_scores | |
| def get_retrieval_stats(self, x): | |
| """ | |
| Get statistics about which shards are being retrieved. | |
| Useful for debugging and analysis. | |
| """ | |
| if len(x.shape) == 3: | |
| query_input = x.mean(dim=1) | |
| else: | |
| query_input = x | |
| retrieval_scores = self.query_net(query_input) | |
| top_k_scores, top_k_indices = torch.topk( | |
| retrieval_scores, k=self.k, dim=1 | |
| ) | |
| return { | |
| 'top_k_indices': top_k_indices.cpu().numpy(), | |
| 'top_k_scores': top_k_scores.cpu().numpy(), | |
| 'all_scores': retrieval_scores.cpu().numpy() | |
| } | |
| class SimpleWeightRetrievalNet(nn.Module): | |
| """ | |
| Simple network using WeightRetrievalLayers for testing. | |
| Architecture: | |
| Input → WRLayer1 → ReLU → WRLayer2 → Output | |
| """ | |
| def __init__(self, input_dim, hidden_dim, output_dim, num_shards=10, k=3): | |
| super().__init__() | |
| self.layer1 = WeightRetrievalLayer( | |
| input_dim, hidden_dim, num_shards, k | |
| ) | |
| self.layer2 = WeightRetrievalLayer( | |
| hidden_dim, output_dim, num_shards, k | |
| ) | |
| def forward(self, x): | |
| x = self.layer1(x) | |
| x = F.relu(x) | |
| x = self.layer2(x) | |
| return x | |
| # Quick test | |
| if __name__ == "__main__": | |
| print("Testing WeightRetrievalLayer...") | |
| # Create layer | |
| layer = WeightRetrievalLayer( | |
| d_in=784, # MNIST flattened | |
| d_out=128, | |
| num_shards=10, | |
| k=3 | |
| ) | |
| # Test forward pass | |
| batch_size = 4 | |
| x = torch.randn(batch_size, 784) | |
| output = layer(x) | |
| print(f"Input shape: {x.shape}") | |
| print(f"Output shape: {output.shape}") | |
| # Check retrieval stats | |
| stats = layer.get_retrieval_stats(x) | |
| print(f"Retrieved shards: {stats['top_k_indices']}") | |
| print("\n✓ WeightRetrievalLayer works!") | |