Source code for embfile.initializers
"""
Embedding initializers.
"""
__all__ = ['Initializer', 'NormalInitializer', 'normal']
import abc
from typing import Sequence
import numpy
from overrides import overrides
from embfile.errors import IllegalOperation
from embfile.types import VectorType
[docs]class Initializer(abc.ABC):
"""
A random number generator meant to be used with :meth:`~embfile.build_matrix`.
It can be fit to a sequence of other vectors in order to compute stats to be used for
generation. When passed to ``build_matrix``, the initializer is fit to the found vectors.
.. automethod:: __call__
"""
[docs] @abc.abstractmethod
def fit(self, vectors: numpy.ndarray):
"""
*(Abstract method)* Computes stats that will be use for generating new vectors.
Args:
vectors:
"""
[docs] @abc.abstractmethod
def __call__(self, shape) -> VectorType:
""" *(Abstract method)* Generate an array of shape ``shape`` """
[docs]class NormalInitializer(Initializer):
"""
Generates vectors using a normal distribution with the same mean and standard deviation
of the set of vectors passed to the fit method. When used with
:meth:`~embfile.build_matrix`, it initializes out-of-file-vocabulary vectors so
that they have the same mean and deviation of the vectors found in the file.
If not fit before to generate vectors, it raises IllegalOperation
"""
def __init__(self):
self.loc = None
self.scale = None
[docs] @overrides
def fit(self, vectors: numpy.ndarray):
""" Computes mean and standard deviation of the input vectors """
if len(vectors) == 0:
raise ValueError('empty array')
self.loc = numpy.mean(vectors, axis=0)
self.scale = numpy.std(vectors, axis=0)
@overrides
def __call__(self, shape: Sequence[int]):
if self.loc is None or self.scale is None:
raise IllegalOperation('you must fit this initializer before you can use it')
return numpy.random.normal(loc=self.loc, scale=self.scale, size=shape)
[docs]def normal(mean=0.0, deviation=None):
"""
Returns a normal sampler. If deviation is not given, it is set dynamically to
1.0 / sqrt(shape[-1])
where shape[-1] is the vector size.
"""
def generate(shape):
scale = 1.0 / shape[-1] if deviation is None else deviation
return numpy.random.normal(loc=mean, scale=scale, size=shape)
return generate