U
    d7                     @   sH   d dl Zd dlmZmZ d dlmZ d dlmZm	Z	 G dd deZ
dS )    N)coreschema)
ModelLayer)BoundedGradientProjection
LogBarrierc                       sf   e Zd Zd fdd	Zd	d
 Zdd Zdd Zdd Zdd Zdd Z	dd Z
dd Zdd Z  ZS )AdaptiveWeightadaptive_weightNFlog_stdlog_barrier皙?c
                    s\  t t j|||f|
 ttj d _ j	
  _t j _| _|d k	rht| jkstn fddt jD }t|dkstdt|tj _t|  _t|  _t|	 _| _t  jd  _t  jd  _t  jd  _    jrX fd	dt jD  _ t jD ]} j!" j |  q>d S )
Nr   c                    s   g | ]}d  j  qS )g      ?)num).0_self H/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/layers/adaptive_weight.py
<listcomp>(   s     z+AdaptiveWeight.__init__.<locals>.<listcomp>r   z initial weights must be positive_initZ_weightZ_regc                    s   g | ]}  d | qS )zadaptive_weight_%d)get_next_blob_referencer   ir   r   r   r   6   s   )#superr   __init__r   ZScalarnpZfloat32r   output_schemainput_recordZfield_blobsdatalenr   	optimizerAssertionErrorrangeminarrayZastypeweightsstrlowerestimation_methodpos_optim_methodfloat
reg_lambdaenable_diagnosegetattrZ	init_funcweight_funcreg_funcweight_imodelZadd_ad_hoc_plot_blob)r   r0   r   namer   r$   r+   r'   r(   r*   kwargsr   	__class__r   r   r      s6     

zAdaptiveWeight.__init__c                    s|    fddt | jD }t | jD ]0} j| j| g||  d| gdgd q" d} j|| dgdd	 |S )
Nc                    s   g | ]}  d | qS )zreshaped_data_%d)NextScopedBlobr   netr   r   r   >   s     z.AdaptiveWeight.concat_data.<locals>.<listcomp>znew_shape_%d   )shapeZconcated_dataZconcated_new_shaper   )Zaxis)r!   r   ZReshaper   r5   ZConcat)r   r7   Zreshapedr   Zconcatedr   r6   r   concat_data=   s    

  zAdaptiveWeight.concat_datac                 C   s@   t d| j }d|tjjdf}| jd| jg|| jd| _	dS )z}
        mu = 2 log sigma, sigma = standard variance
        per task objective:
        min 1 / 2 / e^mu X + mu / 2
              ?GivenTensorFillvaluesZdtypemu)
param_namer9   initializerr   N)
r   logr$   r   DataTypeFLOATcreate_paramr   r   r?   )r   r>   rA   r   r   r   log_std_initL   s    zAdaptiveWeight.log_std_initc                 C   sB   | d}|| j| | d}||| |j||dd dS )z-
        min 1 / 2 / e^mu X + mu / 2
        mu_neg
mu_neg_expr;   ZscaleN)r5   ZNegativer?   ZExpScale)r   xr7   weightrG   rH   r   r   r   log_std_weight^   s
    

zAdaptiveWeight.log_std_weightc                 C   s   |j | j|dd d S Nr;   rI   )rJ   r?   )r   r7   regr   r   r   log_std_regh   s    zAdaptiveWeight.log_std_regc                 C   s|   d| j  }d|tjjdf}| jdkr4t| jd}n(| jdkrLtddd	}ntd
	| j| j
d| jg|| j|d| _dS )zg
        k = 1 / variance
        per task objective:
        min 1 / 2 * k  X - 1 / 2 * log k
        g       @r<   r=   r
   )r*   Zpos_grad_projr   T)ZlbZ	left_openz*unknown positivity optimization method: {}k)r@   r9   rA   r   regularizerN)r$   r   rC   rD   r(   r   r*   r   	TypeErrorformatrE   r   r   rQ   )r   r>   rA   rR   r   r   r   inv_var_initk   s(    


zAdaptiveWeight.inv_var_initc                 C   s   |j | j|dd d S rN   )rJ   rQ   )r   rK   r7   rL   r   r   r   inv_var_weight   s    zAdaptiveWeight.inv_var_weightc                 C   s,   | d}|| j| |j||dd d S )Nlog_kg      rI   )r5   LogrQ   rJ   )r   r7   rO   rW   r   r   r   inv_var_reg   s    
zAdaptiveWeight.inv_var_regc           	      C   s   |  |}|d}|d}|d}|d}| ||| | || |||g| |||g| |||   |rt| j	D ]$}|j
|| j| |g|d gd qd S )NrL   rO   
weighted_xweighted_x_add_regr8   )ZstartsZends)r:   r5   r-   r.   ZMulZAddZSumElementsr   r!   r   ZSlicer/   )	r   r7   r+   rK   rL   rO   rZ   r[   r   r   r   r   _add_ops_impl   s    




zAdaptiveWeight._add_ops_implc                 C   s   |  || j d S )N)r\   r+   )r   r7   r   r   r   add_ops   s    zAdaptiveWeight.add_ops)r   NNFr	   r
   r   )__name__
__module____qualname__r   r:   rF   rM   rP   rU   rV   rY   r\   r]   __classcell__r   r   r3   r   r      s"          ,
r   )Znumpyr   Zcaffe2.pythonr   r   Zcaffe2.python.layers.layersr   Zcaffe2.python.regularizerr   r   r   r   r   r   r   <module>   s   