a
    þdg  ã                   @   sÄ   d dl Z d dlmZ d dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ e ¡ G dd„ deƒƒZdS )é    N)Úbuild_network)Ú
build_loss)Ú
r1_penalty)Úcalculate_metric)Ú	BaseModel)Úget_root_loggerÚimwriteÚ
tensor2img)ÚMODEL_REGISTRY)ÚOrderedDict)Ú
functional)Ú	roi_align)Útqdmc                       sŒ   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zd!dd„Z	dd„ Z
d"dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Z‡  ZS )#ÚGFPGANModelzZThe GFPGAN model for Towards real-world blind face restoratin with generative facial priorc                    s¸   t t| ƒ |¡ d| _t|d ƒ| _|  | j¡| _|  | j¡ | jd  	dd ¡}|d urŠ| jd  	dd¡}|  
| j|| jd  	dd¡|¡ tt | jd d	 d
¡ƒ| _| jr´|  ¡  d S )Nr   Ú	network_gÚpathÚpretrain_network_gZparam_key_gÚparamsÚstrict_load_gTÚout_sizeé   )Úsuperr   Ú__init__Úidxr   Únet_gÚmodel_to_deviceÚprint_networkÚoptÚgetÚload_networkÚintÚmathÚlogÚlog_sizeÚis_trainÚinit_training_settings)Úselfr   Ú	load_pathÚ	param_key©Ú	__class__© úc/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/gfpgan/models/gfpgan_model.pyr      s     zGFPGANModel.__init__c                 C   s¶  | j d }t| j d ƒ| _|  | j¡| _|  | j¡ | j d  dd ¡}|d url|  | j|| j d  dd¡¡ t| j d ƒ | j¡| _	| j d  dd ¡}|d urÀ|  | j	|| j d  d	d¡d
¡ n
|  
d¡ | j ¡  | j ¡  | j	 ¡  d| j v rd| j v rd| j v rd| _nd| _| jrXt| j d ƒ| _|  | j¡| _|  | j¡ | j d  d¡}|d urx|  | j|dd¡ t| j d ƒ| _|  | j¡| _|  | j¡ | j d  d¡}|d urÎ|  | j|dd¡ t| j d ƒ| _|  | j¡| _|  | j¡ | j d  d¡}|d ur$|  | j|dd¡ | j ¡  | j ¡  | j ¡  t|d ƒ | j¡| _| d¡r|t|d ƒ | j¡| _nd | _| d¡r¦t|d ƒ | j¡| _nd | _t|d ƒ | j¡| _t|d ƒ | j¡| _d| j v rìd| _nd| _| jrrt| j d ƒ| _|  | j¡| _|  | j¡ | j d  d¡}|d urP|  | j|dd ¡ | j ¡  | j ¡ D ]}d|_qd|d | _| dd¡| _| dd¡| _|d | _|   ¡  |  !¡  d S ) NÚtrainZ	network_dr   Zpretrain_network_dZstrict_load_dTr   r   r   Ú
params_emar   Znetwork_d_left_eyeZnetwork_d_right_eyeZnetwork_d_mouthFZpretrain_network_d_left_eyer   Zpretrain_network_d_right_eyeZpretrain_network_d_mouthZgan_component_optZ	pixel_optZperceptual_optZL1_optZgan_optÚnetwork_identityZpretrain_network_identityÚr1_reg_weightÚnet_d_itersé   Únet_d_init_itersÚnet_d_reg_every)"r   r   Únet_dr   r   r   r   ÚtoÚdeviceÚ	net_g_emaÚ	model_emar   r-   ÚevalÚuse_facial_discÚnet_d_left_eyeÚnet_d_right_eyeÚnet_d_mouthr   Úcri_componentÚcri_pixÚcri_perceptualÚcri_l1Úcri_ganÚuse_identityr/   Ú
parametersÚrequires_gradr0   r1   r3   r4   Úsetup_optimizersZsetup_schedulers)r&   Ú	train_optr'   Úparamr+   r+   r,   r%   )   sˆ    
"



$










z"GFPGANModel.init_training_settingsc                 C   sÈ  | j d }d}g }| j ¡ D ]\}}| |¡ q||d d dœg}|d  d¡}|d d | }d| d| f}	| j||||	d	| _| j | j¡ | j| jd  }
g }| j	 ¡ D ]\}}| |¡ q²||d
 d dœg}|d
  d¡}|d
 d |
 }d|
 d|
 f}	| j||||	d	| _
| j | j
¡ | jrÄ|d  d¡}|d d }| j|| j ¡ |dd	| _| j | j¡ | j|| j ¡ |dd	| _| j | j¡ | j|| j ¡ |dd	| _| j | j¡ d S )Nr-   r2   Zoptim_gÚlr)r   rJ   Útyper   ç®Gáz®ï?)ÚbetasZoptim_dZoptim_component)gÍÌÌÌÌÌì?rL   )r   r   Znamed_parametersÚappendÚpopZget_optimizerÚoptimizer_gZ
optimizersr4   r5   Úoptimizer_dr;   r<   rE   Úoptimizer_d_left_eyer=   Úoptimizer_d_right_eyer>   Úoptimizer_d_mouth)r&   rH   Znet_g_reg_ratioZnormal_paramsÚ_rI   Zoptim_params_gZ
optim_typerJ   rM   Znet_d_reg_ratioZoptim_params_dr+   r+   r,   rG   –   sP    

þ
þÿÿÿzGFPGANModel.setup_optimizersc                 C   sV   |d   | j¡| _d|v r,|d   | j¡| _d|v rR|d | _|d | _|d | _d S )NÚlqÚgtZloc_left_eyeZloc_right_eyeZ	loc_mouth)r6   r7   rV   rW   Úloc_left_eyesÚloc_right_eyesÚ
loc_mouths)r&   Údatar+   r+   r,   Ú	feed_dataÉ   s    

zGFPGANModel.feed_datac                 C   sF   | j g}| j }td| jd ƒD ]"}tj|dddd}| d|¡ q|S )z9Construct image pyramid for intermediate restoration lossr   é   ç      à?ÚbilinearF)Zscale_factorÚmodeÚalign_corners)rW   Úranger#   ÚFÚinterpolateÚinsert)r&   Ú
pyramid_gtZdown_imgrU   r+   r+   r,   Úconstruct_img_pyramidá   s    z!GFPGANModel.construct_img_pyramidéP   éx   c                 C   sì  t | jd d d ƒ}||9 }||9 }g }g }t| j d¡ƒD ]œ}| j d|¡}tj| j|d d …f | j|d d …f gdd}tj	||gdd}	| 
|	¡ | j d|¡}tj	|| j||d	 …d d …f gdd}	| 
|	¡ q>t 	|d¡ | j¡}t 	|d¡ | j¡}t| j||d
| }
|
dd d…d d …d d …d d …f | _|
d	d d…d d …d d …d d …f | _t| j||d
| | _t| j||d
| }
|
dd d…d d …d d …d d …f | _|
d	d d…d d …d d …d d …f | _t| j||d
| | _d S )Nr   r   i   r   )r   r2   )Zdiméÿÿÿÿ)r2   r2   r2   )ZboxesZoutput_sizer   )r    r   rb   rX   ÚsizeZnew_fullÚtorchÚstackrY   ÚcatrN   rZ   r6   r7   r   rW   Úleft_eyes_gtÚright_eyes_gtÚ	mouths_gtÚoutputÚ	left_eyesÚ
right_eyesÚmouths)r&   Úeye_out_sizeÚmouth_out_sizeZ
face_ratioZ	rois_eyesZrois_mouthsÚbZimg_indsZbboxZroisZall_eyesr+   r+   r,   Úget_roi_regionsê   s.    .
($$$$zGFPGANModel.get_roi_regionsc           	      C   sH   |  ¡ \}}}}| |||| ¡}| dd¡}| |¡|| |  }|S )z¨Calculate Gram matrix.

        Args:
            x (torch.Tensor): Tensor with shape of (n, c, h, w).

        Returns:
            torch.Tensor: Gram matrix.
        r2   r   )rk   ÚviewZ	transposeZbmm)	r&   ÚxÚnÚcÚhÚwÚfeaturesZ
features_tZgramr+   r+   r,   Ú	_gram_mat
  s
    	zGFPGANModel._gram_maté€   c                 C   s„   d|d d …dd d …d d …f  d|d d …dd d …d d …f   d|d d …dd d …d d …f   }|  d¡}tj|||fddd	}|S )
NgÅ1w-!Ó?r   gbX9´Èâ?r2   gÉv¾Ÿ/½?r   r_   F)r`   ra   )Z	unsqueezerc   rd   )r&   Úoutrk   Úout_grayr+   r+   r,   Úgray_resize_for_identity  s    `
z$GFPGANModel.gray_resize_for_identityc           )         s˜  ˆ j  ¡ D ]
}d|_q
ˆ j ¡  ˆ jrhˆ j ¡ D ]
}d|_q0ˆ j ¡ D ]
}d|_qFˆ j ¡ D ]
}d|_q\ˆ j	d  
dd¡}|dkr |ˆ j	d  
dtdƒ¡kr d}|dkrÈˆ jˆ jdd	\ˆ _}ˆ  ¡ }nˆ jˆ jdd	\ˆ _}ˆ jròˆ jd
dd d}tƒ }|ˆ j dkrì|ˆ jkrìˆ jr@ˆ  ˆ jˆ j¡}||7 }||d< |dkr˜tdˆ jd ƒD ]<}	ˆ  ||	 ||	 ¡| }
||
7 }|
|dd|	d  › < qZˆ jrèˆ  ˆ jˆ j¡\}}|d urÎ||7 }||d< |d urè||7 }||d< ˆ   ˆ j¡}ˆ j|ddd}||7 }||d< ˆ jrtˆ jˆ jdd\}}ˆ j|ddd}||7 }||d< ˆ jˆ jdd\}}ˆ j|ddd}||7 }||d< ˆ jˆ jdd\}}ˆ j|ddd}||7 }||d< ˆ j	d  
dd¡dkrtˆ jˆ jdd\}}ˆ jˆ j dd\}}ˆ jˆ j!dd\}}‡ fdd„}d}||||ˆ jƒ7 }||||ˆ jƒ7 }||||ˆ jƒ7 }|ˆ j	d d  }||7 }||d< ˆ j"rÚˆ j	d d }ˆ  #ˆ j¡}ˆ  #ˆ j¡}ˆ  $|¡ %¡ }ˆ  $|¡}ˆ  ||¡| } || 7 }| |d< | &¡  ˆ j '¡  ˆ j(dd  ˆ j  ¡ D ]}d|_qˆ j) ¡  ˆ jrˆˆ j ¡ D ]}d|_q,ˆ j ¡ D ]}d|_qDˆ j ¡ D ]}d|_q\ˆ j* ¡  ˆ j+ ¡  ˆ j, ¡  ˆ   ˆ j %¡ ¡}!ˆ   ˆ j¡}"ˆ j|"dddˆ j|!ddd }#|#|d!< |" %¡  -¡ |d"< |! %¡  -¡ |d#< |# &¡  |ˆ j. dkr\dˆ j_ˆ   ˆ j¡}$t/|$ˆ jƒ}%ˆ j0d |% ˆ j. d|$d   }%|% %¡  -¡ |d$< |% &¡  ˆ j) '¡  ˆ jrˆˆ  ˆ j %¡ ¡\}!}ˆ  ˆ j¡\}"}ˆ j|"dddˆ j|!ddd }&|&|d%< |& &¡  ˆ  ˆ j %¡ ¡\}!}ˆ  ˆ j ¡\}"}ˆ j|"dddˆ j|!ddd }'|'|d&< |' &¡  ˆ  ˆ j %¡ ¡\}!}ˆ  ˆ j!¡\}"}ˆ j|"dddˆ j|!ddd }(|(|d'< |( &¡  ˆ j* '¡  ˆ j+ '¡  ˆ j, '¡  ˆ  1|¡ˆ _2d S )(NFr-   Úpyramid_loss_weightr   Zremove_pyramid_lossÚinfgê-™—q=T)Z
return_rgbrh   ri   )rv   rw   Úl_g_pixr   Zl_p_r]   Ú
l_g_percepÚ	l_g_style)Zis_discÚl_g_gan)Zreturn_featsZl_g_gan_left_eyeZl_g_gan_right_eyeZl_g_gan_mouthZcomp_style_weightc                    sH   |ˆ   | d ¡ˆ   |d  ¡ ¡ƒd |ˆ   | d ¡ˆ   |d  ¡ ¡ƒ S )Nr   r^   r2   )r   Údetach)ZfeatZfeat_gtÚ	criterion©r&   r+   r,   Ú_comp_stylet  s    
ÿÿÿÿz4GFPGANModel.optimize_parameters.<locals>._comp_styleZl_g_comp_style_lossÚidentity_weightÚ
l_identitygå…Ùíï?)ZdecayÚl_dZ
real_scoreZ
fake_scoreÚl_d_r1Úl_d_left_eyeÚl_d_right_eyeÚ	l_d_mouth)3r5   rE   rF   rP   Z	zero_gradr;   r<   r=   r>   r   r   Úfloatr   rV   rr   rg   ry   r   r1   r3   r@   rW   rb   r#   rB   rA   rC   rs   r?   rt   ru   ro   rp   rq   rD   r…   r/   rŒ   ZbackwardÚstepr9   rQ   rR   rS   rT   Úmeanr4   r   r0   Zreduce_loss_dictZlog_dict))r&   Úcurrent_iterÚpr†   Zout_rgbsrf   Z	l_g_totalZ	loss_dictrˆ   ÚiZ	l_pyramidr‰   rŠ   Zfake_g_predr‹   Zfake_left_eyeZfake_left_eye_featsZfake_right_eyeZfake_right_eye_featsZ
fake_mouthZfake_mouth_featsrU   Zreal_left_eye_featsZreal_right_eye_featsZreal_mouth_featsr   Zcomp_style_lossr   r„   Zgt_grayZidentity_gtZidentity_outr‘   Zfake_d_predZreal_d_predr’   Z	real_predr“   r”   r•   r–   r+   rŽ   r,   Úoptimize_parameters  s$   
"













  
ÿÿÿÿÿÿÿÿÿ


zGFPGANModel.optimize_parametersc                 C   sŠ   t  ¡ n t| dƒr2| j ¡  |  | j¡\| _}n6tƒ }| d¡ | j	 ¡  |  	| j¡\| _}| j	 
¡  W d   ƒ n1 s|0    Y  d S )Nr8   z+Do not have self.net_g_ema, use self.net_g.)rl   Zno_gradÚhasattrr8   r:   rV   rr   r   Úwarningr   r-   )r&   rU   Úloggerr+   r+   r,   ÚtestÙ  s    




zGFPGANModel.testc                 C   s"   | j d dkr|  ||||¡ d S )NZrankr   )r   Únondist_validation)r&   Ú
dataloaderrš   Ú	tb_loggerÚsave_imgr+   r+   r,   Údist_validationå  s    zGFPGANModel.dist_validationc              	   C   sž  |j jd }| jd  d¡d u}| jd  dd¡}|rzt| dƒs^dd„ | jd d  ¡ D ƒ| _|  |¡ d	d„ | jD ƒ| _tƒ }|r”tt	|ƒd
d}	t
|ƒD ]š\}
}t t |d d ¡¡d }|  |¡ |  ¡  t| j ¡  ¡ dd}||d< t| dƒr t| j ¡  ¡ dd}||d< | `| `| `tj ¡  |rÞ| jd rjt | jd d ||› d|› d¡}nj| jd d rªt | jd d ||› d| jd d › d¡}n*t | jd d ||› d| jd › d¡}t||ƒ |r| jd d  ¡ D ]"\}}| j|  t||ƒ7  < qö|rœ|	 d¡ |	 d|› ¡ qœ|rH|	 ¡  |rš| j ¡ D ]2}| j|  |
d   < |   ||| j| |¡ qX|  !|||¡ d S )NÚnameÚvalZmetricsÚpbarFÚmetric_resultsc                 S   s   i | ]
}|d “qS ©r   r+   ©Ú.0Úmetricr+   r+   r,   Ú
<dictcomp>ð  ó    z2GFPGANModel.nondist_validation.<locals>.<dictcomp>c                 S   s   i | ]
}|d “qS r«   r+   r¬   r+   r+   r,   r¯   ô  r°   Úimage)ÚtotalÚunitZlq_pathr   )rj   r2   )Zmin_maxÚimgrW   Zimg2r$   r   ZvisualizationrU   z.pngÚsuffixr2   zTest )"Zdatasetr   r   rž   Úkeysrª   Z_initialize_best_metric_resultsÚdictr   ÚlenÚ	enumerateÚospÚsplitextÚbasenamer\   r¡   r	   rr   rŒ   ÚcpurW   rV   rl   ZcudaZempty_cacheÚjoinr   Úitemsr   ÚupdateÚset_descriptionÚcloseZ_update_best_metric_resultÚ_log_validation_metric_values)r&   r£   rš   r¤   r¥   Údataset_nameZwith_metricsZuse_pbarZmetric_datar©   r   Zval_dataZimg_nameZsr_imgZgt_imgZsave_img_pathr§   Zopt_r®   r+   r+   r,   r¢   é  sd    



ÿÿÿ

zGFPGANModel.nondist_validationc                 C   sÂ   d|› d}| j  ¡ D ]d\}}|d|› d|d›7 }t| dƒrr|d| j| | d d›d	| j| | d
 › d7 }|d7 }qtƒ }| |¡ |r¾| j  ¡ D ]"\}}| d|› d|› ||¡ qšd S )NzValidation Ú
z	 # z: z.4fÚbest_metric_resultsz	Best: r¨   z @ Úiterz iterzmetrics/ú/)rª   r¿   rž   rÆ   r   ÚinfoZ
add_scalar)r&   rš   rÄ   r¤   Zlog_strr®   Úvaluer    r+   r+   r,   rÃ   *  s    
ÿ


z)GFPGANModel._log_validation_metric_valuesc                 C   st   | j | j| jgd|ddgd |   | jd|¡ | jrd|   | jd|¡ |   | jd|¡ |   | jd|¡ |  ||¡ d S )	Nr   r   r.   )r(   r5   r<   r=   r>   )	Zsave_networkr   r8   r5   r;   r<   r=   r>   Zsave_training_state)r&   Úepochrš   r+   r+   r,   Úsave9  s    zGFPGANModel.save)rh   ri   )r‚   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r%   rG   r\   rg   ry   r   r…   r   r¡   r¦   r¢   rÃ   rÌ   Ú__classcell__r+   r+   r)   r,   r      s    m3	
 
 ;Ar   )r!   Úos.pathr   rº   rl   Zbasicsr.archsr   Zbasicsr.lossesr   Zbasicsr.losses.gan_lossr   Zbasicsr.metricsr   Zbasicsr.models.base_modelr   Zbasicsr.utilsr   r   r	   Zbasicsr.utils.registryr
   Úcollectionsr   Ztorch.nnr   rc   Ztorchvision.opsr   r   Úregisterr   r+   r+   r+   r,   Ú<module>   s   