Download utils/nn/modules/sparse.py from sanganaka/SanDP: direct link, hf CLI and curl.
- Browser
- Download file 4.68 kB
-
https://huggingface.co/sanganaka/SanDP/resolve/main/utils/nn/modules/sparse.py
- Command line
-
hf download hf://sanganaka/SanDP/utils/nn/modules/sparse.py
-
curl -L -o sparse.py https://huggingface.co/sanganaka/SanDP/resolve/main/utils/nn/modules/sparse.py
4.68 kB
| import numpy as np | |
| import torch | |
| import torch.nn as nn | |
| from torch.nn.parameter import Parameter | |
| from torch.nn.functional import embedding | |
| from ..init import assign_tensor | |
| class Embedding(nn.Module): | |
| r"""A simple lookup table that stores embeddings of a fixed dictionary and size. | |
| This module is often used to store word embeddings and retrieve them using indices. | |
| The input to the module is a list of indices, and the output is the corresponding | |
| word embeddings. | |
| Args: | |
| num_embeddings (int): size of the dictionary of embeddings | |
| embedding_dim (int): the size of each embedding vector | |
| init_embedding (Tensor): If given, the embedding will be initialized with the given tensor. | |
| freeze (boolean, optional): If ``True``, the tensor does not get updated in the learning process. | |
| padding_idx (int, optional): If given, pads the output with zeros whenever it encounters the index. | |
| max_norm (float, optional): If given, will renormalize the embeddings to always have a norm lesser than this | |
| norm_type (float, optional): The p of the p-norm to compute for the max_norm option | |
| scale_grad_by_freq (boolean, optional): if given, this will scale gradients by the frequency of | |
| the words in the mini-batch. | |
| sparse (boolean, optional): if True, gradient w.r.t. weight matrix will be a sparse tensor. See Notes for | |
| more details regarding sparse gradients. | |
| Attributes: | |
| weight (Tensor): the learnable weights of the module of shape (num_embeddings, embedding_dim) | |
| Shape: | |
| - Input: LongTensor `(N1, N2, ...,Nm, W)`, N = mini-batch, W = number of indices to extract per mini-batch | |
| - Output: `(N1, N2, ..., Nm, W, embedding_dim)` | |
| Notes: | |
| Keep in mind that only a limited number of optimizers support | |
| sparse gradients: currently it's `optim.SGD` (`cuda` and `cpu`), | |
| and `optim.Adagrad` (`cpu`) | |
| """ | |
| def __init__(self, num_embeddings, embedding_dim, init_embedding=None, freeze=False, padding_idx=None, | |
| max_norm=None, norm_type=2, scale_grad_by_freq=False, sparse=False): | |
| super(Embedding, self).__init__() | |
| self.num_embeddings = num_embeddings | |
| self.embedding_dim = embedding_dim | |
| self.padding_idx = padding_idx | |
| self.max_norm = max_norm | |
| self.norm_type = norm_type | |
| self.scale_grad_by_freq = scale_grad_by_freq | |
| self.weight = Parameter(torch.Tensor(num_embeddings, embedding_dim)) | |
| self.frozen = freeze | |
| self.sparse = sparse | |
| self.reset_parameters(init_embedding) | |
| def reset_parameters(self, init_embedding): | |
| if init_embedding is None: | |
| scale = np.sqrt(3.0 / self.embedding_dim) | |
| self.weight.data.uniform_(-scale, scale) | |
| else: | |
| assign_tensor(self.weight, init_embedding) | |
| if self.padding_idx is not None: | |
| self.weight.data[self.padding_idx].fill_(0) | |
| if self.frozen: | |
| if init_embedding is None: | |
| raise Warning('Freeze embeddings which are randomly initialized.') | |
| self.weight.requires_grad = False | |
| def freeze(self): | |
| self.weight.requires_grad = False | |
| self.frozen = True | |
| def forward(self, input): | |
| padding_idx = self.padding_idx | |
| if padding_idx is None: | |
| padding_idx = -1 | |
| input_size = input.size() | |
| if input.dim() > 2: | |
| num_inputs = int(np.prod(input_size[:-1])) | |
| input = input.view(num_inputs, input_size[-1]) | |
| output_size = input_size + (self.embedding_dim,) | |
| return embedding(input,self.weight,padding_idx,self.max_norm, | |
| self.norm_type,self.scale_grad_by_freq, | |
| self.sparse).view(output_size) | |
| #return self._backend.Embedding.apply( | |
| # input, self.weight, | |
| # padding_idx, self.max_norm, self.norm_type, | |
| # self.scale_grad_by_freq, self.sparse).view(output_size) | |
| def __repr__(self): | |
| s = '{name}({num_embeddings}, {embedding_dim}' | |
| if self.padding_idx is not None: | |
| s += ', padding_idx={padding_idx}' | |
| if self.max_norm is not None: | |
| s += ', max_norm={max_norm}' | |
| if self.norm_type != 2: | |
| s += ', norm_type={norm_type}' | |
| if self.scale_grad_by_freq is not False: | |
| s += ', scale_grad_by_freq={scale_grad_by_freq}' | |
| if self.sparse is not False: | |
| s += ', sparse=True' | |
| s += ')' | |
| return s.format(name=self.__class__.__name__, **self.__dict__) | |