B
    b                 @   sj   d dl Z d dlmZ d dlZd dlZd dlZG dd dejZe	dkrfeddZ
e ddZe
e dS )	    Nc                   s@   e Zd Zd fdd	Zdd Zd	d
 ZdddZdd Z  ZS )MGVAEmgvae        c                s   t t|   || _|| _|| _|| _t| j| j| _	t
| j| j| _tjt||| _tjt||| _tjjt|| dd| _d S )NF)requires_grad)superr   __init__namez_dim	input_dimknets	EncoderV1encoder	DecoderV1decodertorchnn	Parameterzerosz_prior_meanonesz_prior_varz_prior_weight)selfr
   r   r   r   )	__class__ 9/Users/wangjiarui/Desktop/Learn/CS236/HW/HW2_VAE/MGVAE.pyr	      s    zMGVAE.__init__c             C   s   | j |\}}tj||dd}t|dd}t|||}t| j| j	| j
|}tj|| dd}| j|}| ||}	tj|	dd}
t|}t|
}
||
 ||
fS )N
   )
num_sampler      )dim)r   encodeprobssample_from_gaussian_repramr   	transposelog_gaussian_pdflog_mixture_gaussian_pdfr   r   r   meanr   decodecompute_log_likelihood)r   xr)   varzsZlog_qslog_PsKLP_x_given_zlog_likelihoodexpected_log_likelihoodr   r   r   negative_evidence_lower_bound   s    

z#MGVAE.negative_evidence_lower_boundc             C   s   | j |\}}t||}t|dd}t| j| j| j	|}t
|||}| j|}| ||}|| | }	tj|	ddd d d d f }
|
d ttjt|	|
 dd }t| S )Nr   r!   )r"   )r   r#   r$   r%   r   r&   r(   r   r   r   r'   r   r*   r+   maxlogr)   exp)r   r,   r)   r-   	z_samplesr/   log_q_z_given_xr1   log_P_x_given_z	log_probslog_probs_maxiwlbr   r   r   )negative_importance_weighting_lower_bound,   s    
z/MGVAE.negative_importance_weighting_lower_bound:0yE>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   sumr6   )r   r1   r,   epsr   r   r   r+   A   s    *zMGVAE.compute_log_likelihoodc             C   s&   t | j| j| j|}| j|}|S )N)r$   sample_from_mixture_gaussianr   r   r   r   r*   )r   r    zr1   r   r   r   sample_from_priorM   s    zMGVAE.sample_from_prior)r   r   r   r   )r?   )	__name__
__module____qualname__r	   r4   r>   r+   rE   __classcell__r   r   )r   r   r      s
   
r   __main__   )r      i  )r   torch.nnr   r$   r   numpynpModuler   rF   r   r   arrr>   r   r   r   r   <module>   s   P
