o
    ei                     @   s   d Z ddlmZ ddlZddlmZ ddlm  mZ ddl	ZG dd dejj
ZG dd dejj
Zdd	d
ZdddZ			dddZdS )a  
This file contains two PyTorch modules which together consist of the SEGAN model architecture
(based on the paper: Pascual et al. https://arxiv.org/pdf/1703.09452.pdf).
Modification of the initialization parameters allows the change of the model described in the class project,
such as turning the generator to a VAE, or removing the latent variable concatenation.

Loss functions for training SEGAN are also defined in this file.

Authors
 * Francis Carter 2021
    )floorNc                       (   e Zd ZdZ fddZdd Z  ZS )	GeneratoraZ  CNN Autoencoder model to clean speech signals.

    Arguments
    ---------
    kernel_size : int
        Size of the convolutional kernel.
    latent_vae : bool
        Whether or not to convert the autoencoder to a vae
    z_prob : bool
        Whether to remove the latent variable concatenation. Is only applicable if latent_vae is False
    c           	         s8  t    tj | _tj | _d| _|| _|| _	g d}g d}t
t|d D ]0}|t|d kr@| jr@||d  d }n||d  }| jtj|| ||dt|d d q*t
t|d D ]6}|dkru| jru|d|d   }n
|d|d   d }| jtj||d|d   |d dt|d d qcd S )	N   )          r   @   r	      r
      r         )i   r   r   r   r   r   r
   r
   r	   r	   r   r   r      in_channelsout_channelskernel_sizestridepaddingr   )super__init__torchnn
ModuleListEncodeLayersDecodeLayersr   
latent_vaez_probrangelenappendConv1dr   ConvTranspose1d)	selfr   r   r   EncoderChannelsDecoderChannelsioutsins	__class__ b/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/speechbrain/lobes/models/segan_model.pyr   "   sJ   



zGenerator.__init__c                 C   s`  g }| ddd}t| jD ] \}}||}||  |t| jd kr'qtj|dd}q| j	rM|j
ddd\}}|t|d tj||jd  }n%| jrett|t|}t||fd}nt|}t||fd}t| jD ]'\}}||}|t| jd krqwt||d	|d   fd}tj|dd}qw| ddd}| j	r|||fS |S )
z Forward pass through autoencoderr   r   r   333333?negative_slope)dimg       @)devicer   )permute	enumerater   r!   cloner    r   F
leaky_relur   chunkr   exp
randn_liker2   r   normal
zeros_like	ones_likecat)r$   xskipsr'   layerz_meanz_logvarzr,   r,   r-   forwardY   s8   

zGenerator.forward__name__
__module____qualname____doc__r   rE   __classcell__r,   r,   r*   r-   r      s    7r   c                       r   )Discriminatorz|CNN discriminator of SEGAN

    Arguments
    ---------
    kernel_size : int
        Size of the convolutional kernel.
    c                    s   t    tj | _tj | _g d}tt|d D ]P}|t|d krN| j	tj
|| ||d  |dt|d d | j	tj||d  d q| j	tj
|| ||d  dddd | j	tjddd qd S )	N)r   r   r   r   r	   r	   r
   r
   r   r   r   r   r   r   r   r   )num_featuresr      )in_featuresout_features)r   r   r   r   r   LayersNormsr   r    r!   r"   r   BatchNorm1dLinear)r$   r   Channelsr'   r*   r,   r-   r      sL   


		
	zDiscriminator.__init__c                 C   sz   | ddd}tt| jD ]}| j| |}| j| |}tj|dd}q| jd |}| jd |}| ddd}|S )z&forward pass through the discriminatorr   r   r   r.   r/   r   )r3   r   r    rR   rQ   r6   r7   )r$   r?   r'   r,   r,   r-   rE      s   zDiscriminator.forwardrF   r,   r,   r*   r-   rL      s    *rL   meanc                 C   sD   d| d d  }|dkr|  S |dkr ||dd dS dS )	zBCalculates the loss of the discriminator when the inputs are clean      ?r   r   rW   batchr   r   NrW   viewsize	d_outputs	reductionoutputr,   r,   r-   d1_loss   s   ra   c                 C   s@   d| d  }|dkr|  S |dkr||dd dS dS )	zFCalculates the loss of the discriminator when the inputs are not cleanrX   r   rW   rY   r   r   r   NrZ   r]   r,   r,   r-   d2_loss   s   rb   c	                 C   s  d| d d  }	t jjj||dd}
|durJt |}t jj|t |d }t jj|t |d }t jj	
||}|jddjdd }nd}|d	kr^|	 ||
   ||  S |d
kr|	|	ddd}|
|
ddd}|||  ||  S dS )zDCalculates the loss of the generator given the discriminator outputsrX   r   r   none)r_   N)axisr   rW   rY   r   )r   r   
functionall1_lossr<   distributionsr;   Normalr9   klkl_divergencesumrW   r[   r\   )r^   predictionstargetslengthl1LossCoeffklLossCoeffrB   rC   r_   discrimlossl1normZEROdistqdistpri   dlossllossr,   r,   r-   g3_loss   s*   
rx   )rW   )NNrW   )rJ   mathr   r   torch.nnr   torch.nn.functionalre   r6   torch.utils.dataModuler   rL   ra   rb   rx   r,   r,   r,   r-   <module>   s    m
E
	