U
    d                     @   s4   d dl mZ d dlmZ d dlZG dd deZdS )    )schema)ArcCosineFeatureMapNc                       s*   e Zd ZdZd fdd	Zd	d
 Z  ZS )SemiRandomFeaturesa  
    Implementation of the semi-random kernel feature map.

    Applies H(x_rand) * x_rand^s * x_learned, where
        H is the Heaviside step function,
        x_rand is the input after applying FC with randomized parameters,
        and x_learned is the input after applying FC with learnable parameters.

    If using multilayer model with semi-random layers, then input and output records
    should have a 'full' and 'random' Scalar. The random Scalar will be passed as
    input to process the random features.

    For more information, see the original paper:
        https://arxiv.org/pdf/1702.08882.pdf

    Inputs :
        output_dims -- dimensions of the output vector
        s -- if s == 0, will obtain linear semi-random features;
             else if s == 1, will obtain squared semi-random features;
             else s >= 2, will obtain higher order semi-random features
        scale_random -- amount to scale the standard deviation
                        (for random parameter initialization when weight_init or
                        bias_init hasn't been specified)
        scale_learned -- amount to scale the standard deviation
                        (for learned parameter initialization when weight_init or
                        bias_init hasn't been specified)

        weight_init_random -- initialization distribution for random weight parameter
                              (if None, will use Gaussian distribution)
        bias_init_random -- initialization distribution for random bias pararmeter
                            (if None, will use Uniform distribution)
        weight_init_learned -- initialization distribution for learned weight parameter
                               (if None, will use Gaussian distribution)
        bias_init_learned -- initialization distribution for learned bias pararmeter
                             (if None, will use Uniform distribution)
        weight_optim -- optimizer for weight params for learned features
        bias_optim -- optimizer for bias param for learned features

        set_weight_as_global_constant -- if True, initialized random parameters
                                         will be constant across all distributed
                                         instances of the layer
             ?NFsemi_random_featuresc                    s"  t |tjrBttdt fdt f| |j| _|j| _nt |tjrZ|| _|| _t	t
| j|| j|f||||d d |d|d	| tdttj|f|j|d fdttj|f|j|d f| _|dkstd| |td	| j  | _| jd
d|	|
||d\| _| _d S )NfullrandomF)	sZscaleZweight_initZ	bias_initweight_optim
bias_optimset_weight_as_global_constantZinitialize_output_schemanameZ_full_outputZ_random_outputg        z$Expected scale (learned) > 0, got %sr   	learned_w	learned_b)Zw_initZb_initZw_optimZb_optim)
isinstancer   StructZis_schema_subsetZScalarr   input_record_fullr	   input_record_randomsuperr   __init__npZfloat32netNextScopedBloboutput_schemaAssertionErrorsqrtZ
input_dimsstddevZ_initialize_paramsr   r   )selfmodelZinput_recordZoutput_dimsr
   Zscale_randomZscale_learnedZweight_init_randomZbias_init_randomZweight_init_learnedZbias_init_learnedr   r   r   r   kwargs	__class__ M/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/layers/semi_random_features.pyr   6   sh    




zSemiRandomFeatures.__init__c                 C   s~   | | j | j| jg |d}| | j | j| jg |d}| 	||| j
j | j}|||g| j
j  d S )Nlearned_featuresrandom_features)ZFCr   Zfield_blobsr   r   r   r   Zrandom_wZrandom_bZ_heaviside_with_powerr   r	   r
   ZMulr   )r   r   r%   r&   Zprocessed_random_featuresr#   r#   r$   add_ops   s&    




zSemiRandomFeatures.add_ops)r   r   r   NNNNNNFr   )__name__
__module____qualname____doc__r   r'   __classcell__r#   r#   r!   r$   r      s   /           Jr   )Zcaffe2.pythonr   Z+caffe2.python.layers.arc_cosine_feature_mapr   Znumpyr   r   r#   r#   r#   r$   <module>   s   