B
    @˜bW  ã               @   s”   d dl Z d dlmZ d dlZd dlZd dlmZ d dlZd dl	m	Z	 G dd„ dej
ƒZedkre	ƒ Zeƒ Ze d¡Ze d¡\ZZe eee¡ dS )é    N)Ú
functional)ÚMNISTc                   sB   e Zd Zd‡ fdd„	Zddd	„Zd
d„ Zddd„Zdd„ Z‡  ZS )ÚSSVAEÚssvaeé  é   é
   c                sº   t t| ƒ ¡  || _|| _|| _|| _d| _d| _t	 
|||¡| _t	 |||¡| _t	 ||¡| _t ¡ | _tjjt |¡dd| _tjjt |¡dd| _tjjt d¡d dd| _d S )Né   éÈ   F)Úrequires_gradr   )Úsuperr   Ú__init__ÚnameÚ	input_dimÚz_dimÚy_dimÚ
gen_weightÚclassification_weightÚnetsÚ	EncoderV1ÚencoderÚ	DecoderV1ÚdecoderÚClassifierV1Ú
classifierÚnnÚCrossEntropyLossÚclassification_lossÚtorchÚ	ParameterÚzerosÚz_prior_meanÚonesÚz_prior_varÚy_prior)Úselfr   r   r   r   )Ú	__class__© ú9/Users/wangjiarui/Desktop/Learn/CS236/HW/HW2_VAE/SSVAE.pyr   
   s    
zSSVAE.__init__é   c             C   sº  |j d }| j |¡}t |t |¡t | j¡¡}t |¡}| j |¡}t 	| j
¡d }t ||d¡}|d d …d d d …f }t || j
d¡}| j ||¡\}	}
t |	|
| j| j¡}tj|| dd}t |¡}t t |	|| j
 | jg¡t |
|| j
 | jg¡|¡}t ||| j
|| jg¡}|d d …d d …d d d …f }t ||d¡}| j ||¡}t |dd¡}|  ||¡}t |dd¡}tj|dd}tj|| dd}t |¡}|| | |||fS )Nr   )N.r	   éÿÿÿÿ)Údimé   )Úshaper   ÚclassifyÚprobsÚKL_categoricalr   Úlogr$   ÚmeanÚeyer   Úrepeat_interleaver   ÚencodeÚKL_gaussiansr!   r#   ÚsumÚsample_from_gaussian_repramÚreshaper   r   ÚdecodeÚ	transposeÚcompute_log_likelihood)r%   ÚxÚ
num_sampleÚ
batch_sizeZP_y_given_xZKL1Zq_y_given_xZgenerated_yZgenerated_xZz_meanZz_varZKL2Zexpected_KLÚ	z_samplesZ	y_samplesZP_x_given_y_zÚlog_likelihoodsZE_z_given_xy_log_likelihoodsZexpected_log_likelihoodsr'   r'   r(   Ú&negative_evidence_lower_bound_unlabeld   s:    



z,SSVAE.negative_evidence_lower_bound_unlabeldc       
      C   sH   |   |¡\}}}}| j |¡}|  ||¡}	| j| | j|	  ||||fS )N)rB   r   r.   r   r   r   )
r%   Zunlabeled_xr=   ÚyÚnelboÚKL_yÚKL_zrA   Zyhatr   r'   r'   r(   ÚlossH   s    z
SSVAE.lossç:Œ0âŽyE>c             C   s6   t j|t  || ¡ d| t  d| | ¡  ddS )z¤
		:param P_x_given_z: torch.Tensor, of shape [num_sample, batch, input_dim]
		:param x: torch.Tensor, of shape [batch, input_dim]
		:param eps: float
		:return:
		r	   r*   )r+   )r   r7   r1   )r%   ÚP_x_given_zr=   Úepsr'   r'   r(   r<   Q   s    *zSSVAE.compute_log_likelihoodc             C   sv   t |ƒ}tj|dgd}d|t|ƒ|f< t |¡ ¡ }t | j	d d d …f | j
d d d …f |¡d }| j ||¡}|S )Nr   )r-   r	   r   )ÚlenÚnpr    Úranger   Ú
from_numpyÚfloatr/   r8   r!   r#   r   r:   )r%   Úysr?   ÚYÚZZP_x_given_yzr'   r'   r(   Úsample_from_prior]   s    .zSSVAE.sample_from_prior)r   r   r   r   )r)   )rH   )	Ú__name__Ú
__module__Ú__qualname__r   rB   rG   r<   rS   Ú__classcell__r'   r'   )r&   r(   r   	   s
   
,	
r   Ú__main__r   )r   Útorch.nnr   r/   r   r   ÚFÚnumpyrL   r   ÚModuler   rT   Úmnistr   Ú
load_batchr=   Úload_batch_with_labelÚxlÚylrG   r'   r'   r'   r(   Ú<module>   s   a
