diff --git a/.DS_Store b/.DS_Store old mode 100644 new mode 100755 diff --git a/.buildinfo b/.buildinfo old mode 100644 new mode 100755 index d70de51e..0846536a --- a/.buildinfo +++ b/.buildinfo @@ -1,4 +1,4 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 50a29498a7831a0ec204fd5a3fab8a6d -tags: 645f666f9bcd5a90fca523b33c5a78b7 +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 92da9a08163b5228776655514fd4bb88 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_images/00.png b/_images/00.png old mode 100644 new mode 100755 diff --git a/_images/01.png b/_images/01.png old mode 100644 new mode 100755 diff --git a/_images/010.png b/_images/010.png old mode 100644 new mode 100755 diff --git a/_images/011.png b/_images/011.png old mode 100644 new mode 100755 diff --git a/_images/012.png b/_images/012.png old mode 100644 new mode 100755 diff --git a/_images/02.png b/_images/02.png old mode 100644 new mode 100755 diff --git a/_images/03.png b/_images/03.png old mode 100644 new mode 100755 diff --git a/_images/04.png b/_images/04.png old mode 100644 new mode 100755 diff --git a/_images/05.png b/_images/05.png old mode 100644 new mode 100755 diff --git a/_images/06.png b/_images/06.png old mode 100644 new mode 100755 diff --git a/_images/07.png b/_images/07.png old mode 100644 new mode 100755 diff --git a/_images/08.png b/_images/08.png old mode 100644 new mode 100755 diff --git a/_images/09.png b/_images/09.png old mode 100644 new mode 100755 diff --git a/_images/4classes.png b/_images/4classes.png old mode 100644 new mode 100755 diff --git a/_images/DDIM_pic.png b/_images/DDIM_pic.png old mode 100644 new mode 100755 diff --git a/_images/DDPM_eq.png b/_images/DDPM_eq.png old mode 100644 new mode 100755 diff --git a/_images/Unet.png b/_images/Unet.png old mode 100644 new mode 100755 diff --git a/_images/adagn_table.png b/_images/adagn_table.png old mode 100644 new mode 100755 diff --git a/_images/algorithm.png b/_images/algorithm.png old mode 100644 new mode 100755 diff --git a/_images/animation.png b/_images/animation.png old mode 100644 new mode 100755 diff --git a/_images/architect_1.png b/_images/architect_1.png old mode 100644 new mode 100755 diff --git a/_images/architect_2.png b/_images/architect_2.png old mode 100644 new mode 100755 diff --git a/_images/architect_3.png b/_images/architect_3.png old mode 100644 new mode 100755 diff --git a/_images/block.png b/_images/block.png old mode 100644 new mode 100755 diff --git a/_images/cat.png b/_images/cat.png old mode 100644 new mode 100755 diff --git a/_images/class_eq1.png b/_images/class_eq1.png old mode 100644 new mode 100755 diff --git a/_images/class_eq2.png b/_images/class_eq2.png old mode 100644 new mode 100755 diff --git a/_images/classifier_guidance_vis.png b/_images/classifier_guidance_vis.png old mode 100644 new mode 100755 diff --git a/_images/ddim_pipe.png b/_images/ddim_pipe.png old mode 100644 new mode 100755 diff --git a/_images/ddpm_pipeline.png b/_images/ddpm_pipeline.png old mode 100644 new mode 100755 diff --git a/_images/deer.png b/_images/deer.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_01.png b/_images/dreambooth_01.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_02.png b/_images/dreambooth_02.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_03.png b/_images/dreambooth_03.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_04.png b/_images/dreambooth_04.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_05.png b/_images/dreambooth_05.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_06.png b/_images/dreambooth_06.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_07.png b/_images/dreambooth_07.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_08.png b/_images/dreambooth_08.png old mode 100644 new mode 100755 diff --git a/_images/dreambooth_09.png b/_images/dreambooth_09.png old mode 100644 new mode 100755 diff --git a/_images/efficiency.png b/_images/efficiency.png old mode 100644 new mode 100755 diff --git a/_images/experiment1.png b/_images/experiment1.png old mode 100644 new mode 100755 diff --git a/_images/fig1.png b/_images/fig1.png old mode 100644 new mode 100755 diff --git a/_images/fig10.png b/_images/fig10.png old mode 100644 new mode 100755 diff --git a/_images/fig11.png b/_images/fig11.png old mode 100644 new mode 100755 diff --git a/_images/fig12.png b/_images/fig12.png old mode 100644 new mode 100755 diff --git a/_images/fig13.png b/_images/fig13.png old mode 100644 new mode 100755 diff --git a/_images/fig14.png b/_images/fig14.png old mode 100644 new mode 100755 diff --git a/_images/fig15.png b/_images/fig15.png old mode 100644 new mode 100755 diff --git a/_images/fig16.png b/_images/fig16.png old mode 100644 new mode 100755 diff --git a/_images/fig2.png b/_images/fig2.png old mode 100644 new mode 100755 diff --git a/_images/fig21.png b/_images/fig21.png old mode 100644 new mode 100755 diff --git a/_images/fig3.png b/_images/fig3.png old mode 100644 new mode 100755 diff --git a/_images/fig4.gif b/_images/fig4.gif old mode 100644 new mode 100755 diff --git a/_images/fig5.png b/_images/fig5.png old mode 100644 new mode 100755 diff --git a/_images/fig6.png b/_images/fig6.png old mode 100644 new mode 100755 diff --git a/_images/fig7.png b/_images/fig7.png old mode 100644 new mode 100755 diff --git a/_images/fig8.png b/_images/fig8.png old mode 100644 new mode 100755 diff --git a/_images/fig9.png b/_images/fig9.png old mode 100644 new mode 100755 diff --git a/_images/gan_01.png b/_images/gan_01.png old mode 100644 new mode 100755 diff --git a/_images/gan_02.png b/_images/gan_02.png old mode 100644 new mode 100755 diff --git a/_images/gan_03.png b/_images/gan_03.png old mode 100644 new mode 100755 diff --git a/_images/gan_04.png b/_images/gan_04.png old mode 100644 new mode 100755 diff --git a/_images/illustration.png b/_images/illustration.png old mode 100644 new mode 100755 diff --git a/_images/image(0).png b/_images/image(0).png old mode 100644 new mode 100755 diff --git a/_images/image(1).png b/_images/image(1).png old mode 100644 new mode 100755 diff --git a/_images/image(2).png b/_images/image(2).png old mode 100644 new mode 100755 diff --git a/_images/image(3).png b/_images/image(3).png old mode 100644 new mode 100755 diff --git a/_images/image(4).png b/_images/image(4).png old mode 100644 new mode 100755 diff --git a/_images/image(5).png b/_images/image(5).png old mode 100644 new mode 100755 diff --git a/_images/image(6).png b/_images/image(6).png old mode 100644 new mode 100755 diff --git a/_images/image(7).png b/_images/image(7).png old mode 100644 new mode 100755 diff --git a/_images/image(8).png b/_images/image(8).png old mode 100644 new mode 100755 diff --git a/_images/imagen_1.png b/_images/imagen_1.png old mode 100644 new mode 100755 diff --git a/_images/imagen_10.png b/_images/imagen_10.png old mode 100644 new mode 100755 diff --git a/_images/imagen_11.png b/_images/imagen_11.png old mode 100644 new mode 100755 diff --git a/_images/imagen_12.png b/_images/imagen_12.png old mode 100644 new mode 100755 diff --git a/_images/imagen_13.png b/_images/imagen_13.png old mode 100644 new mode 100755 diff --git a/_images/imagen_2.png b/_images/imagen_2.png old mode 100644 new mode 100755 diff --git a/_images/imagen_3.png b/_images/imagen_3.png old mode 100644 new mode 100755 diff --git a/_images/imagen_5.png b/_images/imagen_5.png old mode 100644 new mode 100755 diff --git a/_images/imagen_6.png b/_images/imagen_6.png old mode 100644 new mode 100755 diff --git a/_images/imagen_7.png b/_images/imagen_7.png old mode 100644 new mode 100755 diff --git a/_images/imagen_8.png b/_images/imagen_8.png old mode 100644 new mode 100755 diff --git a/_images/imagen_9.png b/_images/imagen_9.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_01.png b/_images/imagen_editor_01.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_02.png b/_images/imagen_editor_02.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_03.png b/_images/imagen_editor_03.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_04.png b/_images/imagen_editor_04.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_05.png b/_images/imagen_editor_05.png old mode 100644 new mode 100755 diff --git a/_images/imagen_editor_06.png b/_images/imagen_editor_06.png old mode 100644 new mode 100755 diff --git a/_images/img.png b/_images/img.png old mode 100644 new mode 100755 diff --git a/_images/img0.png b/_images/img0.png old mode 100644 new mode 100755 diff --git a/_images/img01.png b/_images/img01.png old mode 100644 new mode 100755 diff --git a/_images/img1.png b/_images/img1.png old mode 100644 new mode 100755 diff --git a/_images/img10.png b/_images/img10.png old mode 100644 new mode 100755 diff --git a/_images/img101.png b/_images/img101.png old mode 100644 new mode 100755 diff --git a/_images/img102.png b/_images/img102.png old mode 100644 new mode 100755 diff --git a/_images/img11.png b/_images/img11.png old mode 100644 new mode 100755 diff --git a/_images/img111.png b/_images/img111.png old mode 100644 new mode 100755 diff --git a/_images/img112.png b/_images/img112.png old mode 100644 new mode 100755 diff --git a/_images/img12.png b/_images/img12.png old mode 100644 new mode 100755 diff --git a/_images/img121.png b/_images/img121.png old mode 100644 new mode 100755 diff --git a/_images/img13.png b/_images/img13.png old mode 100644 new mode 100755 diff --git a/_images/img131.png b/_images/img131.png old mode 100644 new mode 100755 diff --git a/_images/img14.png b/_images/img14.png old mode 100644 new mode 100755 diff --git a/_images/img141.png b/_images/img141.png old mode 100644 new mode 100755 diff --git a/_images/img15.png b/_images/img15.png old mode 100644 new mode 100755 diff --git a/_images/img16.png b/_images/img16.png old mode 100644 new mode 100755 diff --git a/_images/img17.png b/_images/img17.png old mode 100644 new mode 100755 diff --git a/_images/img18.png b/_images/img18.png old mode 100644 new mode 100755 diff --git a/_images/img2.png b/_images/img2.png old mode 100644 new mode 100755 diff --git a/_images/img21.png b/_images/img21.png old mode 100644 new mode 100755 diff --git a/_images/img22.png b/_images/img22.png old mode 100644 new mode 100755 diff --git a/_images/img23.png b/_images/img23.png old mode 100644 new mode 100755 diff --git a/_images/img3.png b/_images/img3.png old mode 100644 new mode 100755 diff --git a/_images/img31.png b/_images/img31.png old mode 100644 new mode 100755 diff --git a/_images/img32.png b/_images/img32.png old mode 100644 new mode 100755 diff --git a/_images/img33.png b/_images/img33.png old mode 100644 new mode 100755 diff --git a/_images/img4.png b/_images/img4.png old mode 100644 new mode 100755 diff --git a/_images/img41.png b/_images/img41.png old mode 100644 new mode 100755 diff --git a/_images/img42.png b/_images/img42.png old mode 100644 new mode 100755 diff --git a/_images/img5.png b/_images/img5.png old mode 100644 new mode 100755 diff --git a/_images/img51.png b/_images/img51.png old mode 100644 new mode 100755 diff --git a/_images/img52.png b/_images/img52.png old mode 100644 new mode 100755 diff --git a/_images/img6.png b/_images/img6.png old mode 100644 new mode 100755 diff --git a/_images/img61.png b/_images/img61.png old mode 100644 new mode 100755 diff --git a/_images/img7.png b/_images/img7.png old mode 100644 new mode 100755 diff --git a/_images/img71.png b/_images/img71.png old mode 100644 new mode 100755 diff --git a/_images/img8.png b/_images/img8.png old mode 100644 new mode 100755 diff --git a/_images/img81.png b/_images/img81.png old mode 100644 new mode 100755 diff --git a/_images/img9.png b/_images/img9.png old mode 100644 new mode 100755 diff --git a/_images/img91.png b/_images/img91.png old mode 100644 new mode 100755 diff --git a/_images/img92.png b/_images/img92.png old mode 100644 new mode 100755 diff --git a/_images/img_01.png b/_images/img_01.png new file mode 100755 index 00000000..127e2ed2 Binary files /dev/null and b/_images/img_01.png differ diff --git a/_images/img_02.png b/_images/img_02.png new file mode 100755 index 00000000..4d7c8b79 Binary files /dev/null and b/_images/img_02.png differ diff --git a/_images/img_03.png b/_images/img_03.png new file mode 100755 index 00000000..138cc924 Binary files /dev/null and b/_images/img_03.png differ diff --git a/_images/img_04.png b/_images/img_04.png new file mode 100755 index 00000000..307e4ef1 Binary files /dev/null and b/_images/img_04.png differ diff --git a/_images/img_05.png b/_images/img_05.png new file mode 100755 index 00000000..58553174 Binary files /dev/null and b/_images/img_05.png differ diff --git a/_images/img_06.png b/_images/img_06.png new file mode 100755 index 00000000..67eb7b04 Binary files /dev/null and b/_images/img_06.png differ diff --git a/_images/img_results.png b/_images/img_results.png old mode 100644 new mode 100755 diff --git a/_images/improved_ddpm_eq.png b/_images/improved_ddpm_eq.png old mode 100644 new mode 100755 diff --git a/_images/improved_ddpm_pic.png b/_images/improved_ddpm_pic.png old mode 100644 new mode 100755 diff --git a/_images/layout_to_image.png b/_images/layout_to_image.png old mode 100644 new mode 100755 diff --git a/_images/leaf_db.png b/_images/leaf_db.png old mode 100644 new mode 100755 diff --git a/_images/leaf_pp.png b/_images/leaf_pp.png old mode 100644 new mode 100755 diff --git a/_images/leaf_sd.png b/_images/leaf_sd.png old mode 100644 new mode 100755 diff --git a/_images/limit.png b/_images/limit.png old mode 100644 new mode 100755 diff --git a/_images/loss.png b/_images/loss.png old mode 100644 new mode 100755 diff --git a/_images/multiple_db.png b/_images/multiple_db.png old mode 100644 new mode 100755 diff --git a/_images/multiple_ex.png b/_images/multiple_ex.png old mode 100644 new mode 100755 diff --git a/_images/multiple_pp.png b/_images/multiple_pp.png old mode 100644 new mode 100755 diff --git a/_images/multiple_sd.png b/_images/multiple_sd.png old mode 100644 new mode 100755 diff --git a/_images/notebook-example_2_1.png b/_images/notebook-example_2_1.png old mode 100644 new mode 100755 diff --git a/_images/photo_db.png b/_images/photo_db.png old mode 100644 new mode 100755 diff --git a/_images/photo_pp.png b/_images/photo_pp.png old mode 100644 new mode 100755 diff --git a/_images/photo_sd.png b/_images/photo_sd.png old mode 100644 new mode 100755 diff --git a/_images/pirate.png b/_images/pirate.png old mode 100644 new mode 100755 diff --git a/_images/plot_result.png b/_images/plot_result.png old mode 100644 new mode 100755 diff --git a/_images/pose.png b/_images/pose.png old mode 100644 new mode 100755 diff --git a/_images/result_base.png b/_images/result_base.png old mode 100644 new mode 100755 diff --git a/_images/result_new.png b/_images/result_new.png old mode 100644 new mode 100755 diff --git a/_images/sea.png b/_images/sea.png old mode 100644 new mode 100755 diff --git a/_images/seg.png b/_images/seg.png old mode 100644 new mode 100755 diff --git a/_images/structure.png b/_images/structure.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig1.png b/_images/styleGAN_fig1.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig2.png b/_images/styleGAN_fig2.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig3.png b/_images/styleGAN_fig3.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig4.png b/_images/styleGAN_fig4.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig5.png b/_images/styleGAN_fig5.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig6.png b/_images/styleGAN_fig6.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig7.png b/_images/styleGAN_fig7.png old mode 100644 new mode 100755 diff --git a/_images/styleGAN_fig8.png b/_images/styleGAN_fig8.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_01.png b/_images/swjo_exp_01.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_02.png b/_images/swjo_exp_02.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_03.png b/_images/swjo_exp_03.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_04.png b/_images/swjo_exp_04.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_05.png b/_images/swjo_exp_05.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_06.png b/_images/swjo_exp_06.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_07.png b/_images/swjo_exp_07.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_08.png b/_images/swjo_exp_08.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_09.png b/_images/swjo_exp_09.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_10.png b/_images/swjo_exp_10.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_11.png b/_images/swjo_exp_11.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_12.png b/_images/swjo_exp_12.png old mode 100644 new mode 100755 diff --git a/_images/swjo_exp_13.png b/_images/swjo_exp_13.png old mode 100644 new mode 100755 diff --git a/_images/text_to_image.png b/_images/text_to_image.png old mode 100644 new mode 100755 diff --git a/_images/trade_off.png b/_images/trade_off.png old mode 100644 new mode 100755 diff --git a/_images/vae_01.png b/_images/vae_01.png old mode 100644 new mode 100755 diff --git a/_images/vae_05.png b/_images/vae_05.png old mode 100644 new mode 100755 diff --git a/_images/vae_07.png b/_images/vae_07.png old mode 100644 new mode 100755 diff --git a/_images/vae_08.png b/_images/vae_08.png old mode 100644 new mode 100755 diff --git a/_images/wallpaper.png b/_images/wallpaper.png old mode 100644 new mode 100755 diff --git a/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css b/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css old mode 100644 new mode 100755 index fc14abc8..6556403c --- a/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css +++ b/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css @@ -1 +1 @@ -details.dropdown .summary-title{padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.dropdown:hover{cursor:pointer}details.dropdown .summary-content{cursor:default}details.dropdown summary{list-style:none;padding:1em}details.dropdown summary .octicon.no-title{vertical-align:middle}details.dropdown[open] summary .octicon.no-title{visibility:hidden}details.dropdown summary::-webkit-details-marker{display:none}details.dropdown summary:focus{outline:none}details.dropdown summary:hover .summary-up svg,details.dropdown summary:hover .summary-down svg{opacity:1}details.dropdown .summary-up svg,details.dropdown .summary-down svg{display:block;opacity:.6}details.dropdown .summary-up,details.dropdown .summary-down{pointer-events:none;position:absolute;right:1em;top:.75em}details.dropdown[open] .summary-down{visibility:hidden}details.dropdown:not([open]) .summary-up{visibility:hidden}details.dropdown.fade-in[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out;animation:panels-fade-in .5s ease-in-out}details.dropdown.fade-in-slide-down[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out}@keyframes panels-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes panels-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.octicon{display:inline-block;fill:currentColor;vertical-align:text-top}.tabbed-content{box-shadow:0 -.0625rem var(--tabs-color-overline),0 .0625rem var(--tabs-color-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.tabbed-content>:first-child{margin-top:0 !important}.tabbed-content>:last-child{margin-bottom:0 !important}.tabbed-content>.tabbed-set{margin:0}.tabbed-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.tabbed-set>input{opacity:0;position:absolute}.tabbed-set>input:checked+label{border-color:var(--tabs-color-label-active);color:var(--tabs-color-label-active)}.tabbed-set>input:checked+label+.tabbed-content{display:block}.tabbed-set>input:focus+label{outline-style:auto}.tabbed-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.tabbed-set>label{border-bottom:.125rem solid transparent;color:var(--tabs-color-label-inactive);cursor:pointer;font-size:var(--tabs-size-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .tabbed-set>label:hover{color:var(--tabs-color-label-active)} +details.dropdown .summary-title{padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.dropdown:hover{cursor:pointer}details.dropdown .summary-content{cursor:default}details.dropdown summary{list-style:none;padding:1em}details.dropdown summary .octicon.no-title{vertical-align:middle}details.dropdown[open] summary .octicon.no-title{visibility:hidden}details.dropdown summary::-webkit-details-marker{display:none}details.dropdown summary:focus{outline:none}details.dropdown summary:hover .summary-up svg,details.dropdown summary:hover .summary-down svg{opacity:1}details.dropdown .summary-up svg,details.dropdown .summary-down svg{display:block;opacity:.6}details.dropdown .summary-up,details.dropdown .summary-down{pointer-events:none;position:absolute;right:1em;top:.75em}details.dropdown[open] .summary-down{visibility:hidden}details.dropdown:not([open]) .summary-up{visibility:hidden}details.dropdown.fade-in[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out;animation:panels-fade-in .5s ease-in-out}details.dropdown.fade-in-slide-down[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out}@keyframes panels-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes panels-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.octicon{display:inline-block;fill:currentColor;vertical-align:text-top}.tabbed-content{box-shadow:0 -.0625rem var(--tabs-color-overline),0 .0625rem var(--tabs-color-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.tabbed-content>:first-child{margin-top:0 !important}.tabbed-content>:last-child{margin-bottom:0 !important}.tabbed-content>.tabbed-set{margin:0}.tabbed-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.tabbed-set>input{opacity:0;position:absolute}.tabbed-set>input:checked+label{border-color:var(--tabs-color-label-active);color:var(--tabs-color-label-active)}.tabbed-set>input:checked+label+.tabbed-content{display:block}.tabbed-set>input:focus+label{outline-style:auto}.tabbed-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.tabbed-set>label{border-bottom:.125rem solid transparent;color:var(--tabs-color-label-inactive);cursor:pointer;font-size:var(--tabs-size-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .tabbed-set>label:hover{color:var(--tabs-color-label-active)} diff --git a/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css b/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css old mode 100644 new mode 100755 index adc61662..83fb209c --- a/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css +++ b/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css @@ -1,7 +1,7 @@ -:root { ---tabs-color-label-active: hsla(231, 99%, 66%, 1); ---tabs-color-label-inactive: rgba(178, 206, 245, 0.62); ---tabs-color-overline: rgb(207, 236, 238); ---tabs-color-underline: rgb(207, 236, 238); ---tabs-size-label: 1rem; +:root { +--tabs-color-label-active: hsla(231, 99%, 66%, 1); +--tabs-color-label-inactive: rgba(178, 206, 245, 0.62); +--tabs-color-overline: rgb(207, 236, 238); +--tabs-color-underline: rgb(207, 236, 238); +--tabs-size-label: 1rem; } \ No newline at end of file diff --git a/_sources/docs/experiments/js_exp.md b/_sources/docs/experiments/js_exp.md old mode 100644 new mode 100755 index 734763b3..62df547d --- a/_sources/docs/experiments/js_exp.md +++ b/_sources/docs/experiments/js_exp.md @@ -1,188 +1,188 @@ -``` {admonition} Information -- **Title:** Synthetic Data with Stable Diffusion for Foliar Disease Classification - -- **Author:** Jisu Kim - -- **Last updated on Jul. 05, 2023** -``` - -# Synthetic Data with Stable Diffusion for Foliar Disease Classification - -## 1. 개요 - -- 사과 나무의 잎에 생기는 질병을 이미지로 판별하는 Kaggle competition ([링크](https://www.kaggle.com/competitions/plant-pathology-2020-fgvc7))에서 아이디어를 얻어서 진행한 프로젝트입니다. -- 해당 competition은 사과나무 잎에 걸린 질병에 따라 잎 이미지를 4개의 class로 분류하는 task입니다. - -:::{figure-md} -4classes - -4 classes of leaves -::: -- competition을 설명한 article ([링크](https://bsapubs.onlinelibrary.wiley.com/doi/10.1002/aps3.11390))에서 전체적인 accuracy는 97%이지만 multiple diseases class의 경우 accuracy가 51%에 불과했다고 언급합니다. -- multiple diseases class의 이미지 개수가 다른 class에 비해 적은 점에 주목했고, stable diffusion을 사용하여 해당 클래스의 데이터 개수를 늘려서 classifier 학습에 사용하면 더 좋은 성능의 classifier를 얻을 수 있을 것으로 기대했습니다. - - -## 2. Baseline 구축 - -- 문제 상황을 재현하기 위해 기존 데이터로 image classifier를 학습하여 baseline으로 잡았습니다. -- 모델은 pretrained된 ResNet18에 linear layer를 붙여서 사용했습니다. -- 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1% -- multiple diseases class는 이미지 개수 91개로 다른 클래스들에 비해서 개수가 적습니다. -- class별 data imbalance가 성능을 낮추는 원인일 것이라 가정하고 stable diffusion으로 multiple diseases class의 data를 추가로 생성해보기로 했습니다. -- multiple diseases class 예시 - -:::{figure-md} -multiple_ex - -4 classes of leaves -::: - -## 3. Stable diffusion fine tuning - -- pretraned stable diffusion의 경우 multiple diseases class에 대한 정보가 없어서 이미지를 생성할 경우 아래와 같이 관련없는 이미지가 생성됩니다. - -:::{figure-md} -multiple_sd - -prompt: “a photo of leaves with multiple diseases -::: - -- 따라서 stable diffusion model ([링크](https://huggingface.co/runwayml/stable-diffusion-v1-5))에 해당 class에 대한 정보를 넣어주기 위해 dreambooth ([링크](https://arxiv.org/abs/2208.12242))를 사용하여 stable diffusion을 fine tuning했습니다. -- training에 사용한 prompt는 “a photo of a \ leaf”이며, 생성한 이미지의 예시는 아래와 같습니다. -- 생성 이미지 예시 - -:::{figure-md} -multiple_db - -prompt: “a photo of a \ leaf” -::: -- prompt engineering을 수행하던 중 의도하지않은 결과를 발견했습니다. -- 아래는 이에 대한 예시로 fine tuning 전의 stable diffusion model의 결과와 비교입니다. -- 상황1 (prompt: “a photo of a leaf”) - -:::{figure-md} -leaf_sd - -fine tuning 전 -::: - -:::{figure-md} -leaf_db - -fine tuning 후 -::: - -- 상황1을 보면 multiple diseases class 정보를 담은 unique identifier \가 없음에도 multiple diseases의 정보를 담은 잎들만 생성됩니다. 이는 같은 class (leaf)에 속하는 다른 이미지들을 생성해내지 못하고 있다는 것입니다. 이 현상을 language drift라고 하며, 모델이 multiple diseases class의 leaf가 아닌 일반적인 leaf class에 관한 정보를 잊어버렸기 때문입니다. -- 상황2 (prompt: “a photo”) - -:::{figure-md} -photo_sd - -fine tuning 전 -::: - -:::{figure-md} -photo_db - -fine tuning 후 -::: - -- 상황2를 보면 photo라는 prompt만 사용하였는데도 생성한 이미지들에 multiple diseases class의 특징들이 나타납니다. -- dreambooth에서는 language drift를 prior preservation loss를 사용해서 해결하였으므로 같은 방법을 사용했습니다. 상황2를 해결하기 위해 training prompt에서 “photo”를 제외하고 최대한 단순한 prompt “\ leaf”를 사용하여 stable diffusion model을 다시 fine tuning했습니다. - -:::{figure-md} -multiple_pp - -multiple diseases class 이미지 생성 결과, prompt: “\ leaf” -::: - -:::{figure-md} -leaf_pp - -leaf 생성 결과, prompt: “leaf” -::: - -- 재훈련 결과, fine tuning 이후에도 기존 stable diffusion model로 “leaf”를 생성하였을 때와 비슷한 이미지가 생성됩니다. - -:::{figure-md} -photo_pp - -photo 생성 결과, prompt: “photo” -::: - -- “photo”의 경우에는 여전히 multiple diseases class의 영향을 받은 것같은 이미지들이 생성됩니다. photo의 경우에는 여러 대상들과 사용되는 일반적인 특성을 가지고있어서 그런 것이라는 생각이 들었고, 이를 체크해보기 위해 특정한 대상들과 photo와 비슷한 용도로 사용되는 다른 prompt들로 이미지들을 생성보았습니다. -- 특정한 대상 세가지로는 cat, sea, pirate을 사용했고, photo와 비슷하게 사용되는 텍스트 세가지는 illustration, animation, wallpaper를 사용했습니다. (이미지는 글 마지막 부분의 appendix에 있습니다.) -- 이미지 생성 결과, 특정한 대상을 지칭하는 텍스트의 경우 대상의 특징이 잘 드러나는 이미지가 생성되었지만, 여러 대상과 함께 쓰이는 텍스트의 경우 잎사귀의 특징을 가지는 이미지들이 일부 생성되었습니다. - - -## 4. 성능 비교 -- fine tuning한 stable diffusion model로 multiple diseases class의 이미지를 400장 생성하여 classifier를 다시 훈련했습니다. - -baseline -- 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1% - -:::{figure-md} -result_base - -result_base -::: - -생성한 이미지를 추가 데이터로 활용한 경우 -- 전체 accuracy는 97.9%, class별 accuracy는 healthy: 98.1%, multiple diseases: 84.6%, rust: 98.2%, scab: 99.3% - -:::{figure-md} -result_new - -result_now -::: - -- kaggle에서 제공하는 test set에 적용했을 때는 baseline이 94.6%, stable diffusion으로 생성한 이미지들을 사용한 경우가 93.7%여서 baseline보다 좋은 성능을 얻지는 못 했습니다. - -## 5. Discussion - -- stable diffusion 훈련 중간중간에 일정 step마다 이미지를 생성하게해서 훈련에 대한 모니터링이 있으면 좋겠다는 생각을 했습니다. -- stable diffusion 훈련시 hyperparameter tuning을 좀 더 철저하게 해야겠다는 생각을 했습니다. -- stable diffusion으로 생성한 이미지가 실제로 multiple diseases class 조건을 만족하는지 검수할 방안이 필요합니다. -- multiple diseases 내에서도 카테고리를 나눌 수 있다면 나눠서 각각에 대한 stable diffusion model을 fine tuning할 수도 있을 것입니다. -- 다른 diffusion model fine tuning 방법을 활용해볼 수도 있을 것입니다. -- submission score에서 baseline을 이기지 못 했지만 text-to-image model을 이용한 synthetic data의 가능성을 볼 수 있었다고 생각합니다. - -## 6. Appendix - -- 앞에서 언급한 prompt에 대한 이미지 생성 예시입니다. 일부 이미지는 NSFW로 판단되어 검은색으로 나왔습니다. - -:::{figure-md} -cat - -cat 생성 결과, prompt: “cat” -::: - -:::{figure-md} -sea - -sea 생성 결과, prompt: “sea” -::: - -:::{figure-md} -pirate - -pirate 생성 결과, prompt: “pirate” -::: - -:::{figure-md} -illustration - -illustration 생성 결과, prompt: “illustration” -::: - -:::{figure-md} -animation - -animation 생성 결과, prompt: “animation” -::: - -:::{figure-md} -wallpaper - -wallpaper 생성 결과, prompt: “wallpaper” -::: +``` {admonition} Information +- **Title:** Synthetic Data with Stable Diffusion for Foliar Disease Classification + +- **Author:** Jisu Kim + +- **Last updated on Jul. 05, 2023** +``` + +# Synthetic Data with Stable Diffusion for Foliar Disease Classification + +## 1. 개요 + +- 사과 나무의 잎에 생기는 질병을 이미지로 판별하는 Kaggle competition ([링크](https://www.kaggle.com/competitions/plant-pathology-2020-fgvc7))에서 아이디어를 얻어서 진행한 프로젝트입니다. +- 해당 competition은 사과나무 잎에 걸린 질병에 따라 잎 이미지를 4개의 class로 분류하는 task입니다. + +:::{figure-md} +4classes + +4 classes of leaves +::: +- competition을 설명한 article ([링크](https://bsapubs.onlinelibrary.wiley.com/doi/10.1002/aps3.11390))에서 전체적인 accuracy는 97%이지만 multiple diseases class의 경우 accuracy가 51%에 불과했다고 언급합니다. +- multiple diseases class의 이미지 개수가 다른 class에 비해 적은 점에 주목했고, stable diffusion을 사용하여 해당 클래스의 데이터 개수를 늘려서 classifier 학습에 사용하면 더 좋은 성능의 classifier를 얻을 수 있을 것으로 기대했습니다. + + +## 2. Baseline 구축 + +- 문제 상황을 재현하기 위해 기존 데이터로 image classifier를 학습하여 baseline으로 잡았습니다. +- 모델은 pretrained된 ResNet18에 linear layer를 붙여서 사용했습니다. +- 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1% +- multiple diseases class는 이미지 개수 91개로 다른 클래스들에 비해서 개수가 적습니다. +- class별 data imbalance가 성능을 낮추는 원인일 것이라 가정하고 stable diffusion으로 multiple diseases class의 data를 추가로 생성해보기로 했습니다. +- multiple diseases class 예시 + +:::{figure-md} +multiple_ex + +4 classes of leaves +::: + +## 3. Stable diffusion fine tuning + +- pretraned stable diffusion의 경우 multiple diseases class에 대한 정보가 없어서 이미지를 생성할 경우 아래와 같이 관련없는 이미지가 생성됩니다. + +:::{figure-md} +multiple_sd + +prompt: “a photo of leaves with multiple diseases +::: + +- 따라서 stable diffusion model ([링크](https://huggingface.co/runwayml/stable-diffusion-v1-5))에 해당 class에 대한 정보를 넣어주기 위해 dreambooth ([링크](https://arxiv.org/abs/2208.12242))를 사용하여 stable diffusion을 fine tuning했습니다. +- training에 사용한 prompt는 “a photo of a \ leaf”이며, 생성한 이미지의 예시는 아래와 같습니다. +- 생성 이미지 예시 + +:::{figure-md} +multiple_db + +prompt: “a photo of a \ leaf” +::: +- prompt engineering을 수행하던 중 의도하지않은 결과를 발견했습니다. +- 아래는 이에 대한 예시로 fine tuning 전의 stable diffusion model의 결과와 비교입니다. +- 상황1 (prompt: “a photo of a leaf”) + +:::{figure-md} +leaf_sd + +fine tuning 전 +::: + +:::{figure-md} +leaf_db + +fine tuning 후 +::: + +- 상황1을 보면 multiple diseases class 정보를 담은 unique identifier \가 없음에도 multiple diseases의 정보를 담은 잎들만 생성됩니다. 이는 같은 class (leaf)에 속하는 다른 이미지들을 생성해내지 못하고 있다는 것입니다. 이 현상을 language drift라고 하며, 모델이 multiple diseases class의 leaf가 아닌 일반적인 leaf class에 관한 정보를 잊어버렸기 때문입니다. +- 상황2 (prompt: “a photo”) + +:::{figure-md} +photo_sd + +fine tuning 전 +::: + +:::{figure-md} +photo_db + +fine tuning 후 +::: + +- 상황2를 보면 photo라는 prompt만 사용하였는데도 생성한 이미지들에 multiple diseases class의 특징들이 나타납니다. +- dreambooth에서는 language drift를 prior preservation loss를 사용해서 해결하였으므로 같은 방법을 사용했습니다. 상황2를 해결하기 위해 training prompt에서 “photo”를 제외하고 최대한 단순한 prompt “\ leaf”를 사용하여 stable diffusion model을 다시 fine tuning했습니다. + +:::{figure-md} +multiple_pp + +multiple diseases class 이미지 생성 결과, prompt: “\ leaf” +::: + +:::{figure-md} +leaf_pp + +leaf 생성 결과, prompt: “leaf” +::: + +- 재훈련 결과, fine tuning 이후에도 기존 stable diffusion model로 “leaf”를 생성하였을 때와 비슷한 이미지가 생성됩니다. + +:::{figure-md} +photo_pp + +photo 생성 결과, prompt: “photo” +::: + +- “photo”의 경우에는 여전히 multiple diseases class의 영향을 받은 것같은 이미지들이 생성됩니다. photo의 경우에는 여러 대상들과 사용되는 일반적인 특성을 가지고있어서 그런 것이라는 생각이 들었고, 이를 체크해보기 위해 특정한 대상들과 photo와 비슷한 용도로 사용되는 다른 prompt들로 이미지들을 생성보았습니다. +- 특정한 대상 세가지로는 cat, sea, pirate을 사용했고, photo와 비슷하게 사용되는 텍스트 세가지는 illustration, animation, wallpaper를 사용했습니다. (이미지는 글 마지막 부분의 appendix에 있습니다.) +- 이미지 생성 결과, 특정한 대상을 지칭하는 텍스트의 경우 대상의 특징이 잘 드러나는 이미지가 생성되었지만, 여러 대상과 함께 쓰이는 텍스트의 경우 잎사귀의 특징을 가지는 이미지들이 일부 생성되었습니다. + + +## 4. 성능 비교 +- fine tuning한 stable diffusion model로 multiple diseases class의 이미지를 400장 생성하여 classifier를 다시 훈련했습니다. + +baseline +- 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1% + +:::{figure-md} +result_base + +result_base +::: + +생성한 이미지를 추가 데이터로 활용한 경우 +- 전체 accuracy는 97.9%, class별 accuracy는 healthy: 98.1%, multiple diseases: 84.6%, rust: 98.2%, scab: 99.3% + +:::{figure-md} +result_new + +result_now +::: + +- kaggle에서 제공하는 test set에 적용했을 때는 baseline이 94.6%, stable diffusion으로 생성한 이미지들을 사용한 경우가 93.7%여서 baseline보다 좋은 성능을 얻지는 못 했습니다. + +## 5. Discussion + +- stable diffusion 훈련 중간중간에 일정 step마다 이미지를 생성하게해서 훈련에 대한 모니터링이 있으면 좋겠다는 생각을 했습니다. +- stable diffusion 훈련시 hyperparameter tuning을 좀 더 철저하게 해야겠다는 생각을 했습니다. +- stable diffusion으로 생성한 이미지가 실제로 multiple diseases class 조건을 만족하는지 검수할 방안이 필요합니다. +- multiple diseases 내에서도 카테고리를 나눌 수 있다면 나눠서 각각에 대한 stable diffusion model을 fine tuning할 수도 있을 것입니다. +- 다른 diffusion model fine tuning 방법을 활용해볼 수도 있을 것입니다. +- submission score에서 baseline을 이기지 못 했지만 text-to-image model을 이용한 synthetic data의 가능성을 볼 수 있었다고 생각합니다. + +## 6. Appendix + +- 앞에서 언급한 prompt에 대한 이미지 생성 예시입니다. 일부 이미지는 NSFW로 판단되어 검은색으로 나왔습니다. + +:::{figure-md} +cat + +cat 생성 결과, prompt: “cat” +::: + +:::{figure-md} +sea + +sea 생성 결과, prompt: “sea” +::: + +:::{figure-md} +pirate + +pirate 생성 결과, prompt: “pirate” +::: + +:::{figure-md} +illustration + +illustration 생성 결과, prompt: “illustration” +::: + +:::{figure-md} +animation + +animation 생성 결과, prompt: “animation” +::: + +:::{figure-md} +wallpaper + +wallpaper 생성 결과, prompt: “wallpaper” +::: diff --git a/_sources/docs/experiments/swjo_exp.md b/_sources/docs/experiments/swjo_exp.md old mode 100644 new mode 100755 index 9d52cc6f..560c4399 --- a/_sources/docs/experiments/swjo_exp.md +++ b/_sources/docs/experiments/swjo_exp.md @@ -1,293 +1,293 @@ -``` {admonition} Information -- **Title:** Training DreamBooth on Naver Webtoon Face Dataset - -- **Author:** Sangwoo Jo - -- **Last updated on Jul. 09, 2023** -``` - -# Training DreamBooth on Naver Webtoon Face Dataset - -## Introduction - -이번 포스팅에서는 DreamBooth 를 직접 학습해보고 실험한 결과들을 공유할려고 합니다. - -우선적으로 학습데이터는 [https://github.com/bryandlee/naver-webtoon-data](https://github.com/bryandlee/naver-webtoon-data) 에 공개된 YOLOv5 모델 및 Waifu2x 후처리 기법을 활용하여 프리드로우에 등장하는 인물 사진들을 수집했습니다. 논문에서는 3-5 장으로 fine-tuning 이 가능하다고 제시되어있지만, 인물 사진 같은 경우 더 많은 데이터로 학습하면 성능이 더 좋아져서 15-20 장의 이미지로 학습하였습니다. 학습한 이미지들 예시입니다. - -:::{figure-md} -swjo_exp_01 - -Training Data -::: - -DreamBooth 를 실험하면서 대표적으로 instance prompt, guidance scale, negative prompt, 그리고 마지막으로 prior preservation loss 를 반영하는 정도를 조절하는 prior_loss_weight 를 바꿔가면서 학습해보았습니다. 사전학습된 text-to-image 모델로 처음에는 *hakurei/waifu-diffusion* 모델을 시도해봤지만 결과가 만족스럽지 못해 *runwayml/stable-diffusion-v1-5* 모델로 fine-tuning 작업을 진행했습니다. - -## Ablation Studies - -### Prior Preservation Loss - -Prior Preservation Loss 를 제외한 동일한 configuration 으로 모델 학습한 결과입니다. - -```python -# with prior-preservation loss -MODEL_NAME = “runwayml/stable-diffusion-v1-5” -instance_prompt = "A photo of sks girl" -class_prompt = "A photo of a girl" - -!python3 train_dreambooth.py \ - --pretrained_model_name_or_path=$MODEL_NAME \ - --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ - --output_dir=$OUTPUT_DIR \ - --revision="fp16" \ - --with_prior_preservation --prior_loss_weight=1.0 \ - --seed=1337 \ - --resolution=512 \ - --train_batch_size=1 \ - --train_text_encoder \ - --mixed_precision="fp16" \ - --use_8bit_adam \ - --gradient_accumulation_steps=1 --gradient_checkpointing \ - --learning_rate=1e-6 \ - --lr_scheduler="constant" \ - --lr_warmup_steps=0 \ - --num_class_images=200 \ - --sample_batch_size=4 \ - --max_train_steps=800 \ - --save_interval=100 \ - --save_sample_prompt="A photo of sks girl" \ - --concepts_list="concepts_list.json" -``` - -```python -# w/o prior-preservation loss -MODEL_NAME = “runwayml/stable-diffusion-v1-5” -instance_prompt = "A photo of sks girl" -class_prompt = "A photo of a girl" - -!python3 train_dreambooth.py \ - --pretrained_model_name_or_path=$MODEL_NAME \ - --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ - --output_dir=$OUTPUT_DIR \ - --revision="fp16" \ - --with_prior_preservation --prior_loss_weight=0.0 \ - --seed=1337 \ - --resolution=512 \ - --train_batch_size=1 \ - --train_text_encoder \ - --mixed_precision="fp16" \ - --use_8bit_adam \ - --gradient_accumulation_steps=1 --gradient_checkpointing \ - --learning_rate=1e-6 \ - --lr_scheduler="constant" \ - --lr_warmup_steps=0 \ - --num_class_images=200 \ - --sample_batch_size=4 \ - --max_train_steps=800 \ - --save_interval=100 \ - --save_sample_prompt="A photo of sks girl" \ - --concepts_list="concepts_list.json" -``` - -아래 그림처럼 동일한 inference prompt 를 입력했을 때, prior preservation loss 를 제외함으로써 input images 에 더 가까운 웹툰 사진들을 생성할 수 있었습니다. 또한, 핑크색 머리를 한 이민지 캐릭터를 어느 정도 잘 생성하는 부분도 확인할 수 있습니다. - -- **Inference Prompt: "A photo of *sks* girl with pink hair” (with prior-preservation loss)** - -:::{figure-md} -swjo_exp_02 - -With Prior Preservation Loss -::: - -- **Inference Prompt: " A photo of *sks* girl with pink hair” (w/o prior-preservation loss)** - -:::{figure-md} -swjo_exp_03 - -Without Prior Preservation Loss -::: - -### Negative Prompt - -Negative Prompt 에 대한 Ablation Study 도 진행했습니다. 캐릭터의 부자연스러운 부분이나 저해상도 이미지들을 생성하는 경우들이 종종 발생했는데, negative prompt 를 통해 더 좋은 퀄리티의 웹툰 캐릭터를 생성할 수 있었습니다. - -- **Inference Prompt: " A photo of *sks* girl with pink hair” (w/o negative prompt)** - -:::{figure-md} -swjo_exp_03 - -Without Negative Prompt -::: - -- **Inference Prompt: " A photo of *sks* girl with pink hair”** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_04 - -With Negative Prompt -::: - -### Instance Prompt / Guidance Scale - -DreamBooth 논문에서 제시한 instance prompt 외에 “A photo of a girl in the style of *sks*” 라는 prompt 로 학습을 시도해보기도 했습니다. *sks* 라는 unique identifier 에 특정 여자 캐릭터에 대한 정보뿐만 아니라 프리드로우 그림체 자체를 담아내기 위한 목적이였습니다. - -```python -# different instance prompt with prior-preservation loss -****MODEL_NAME = “runwayml/stable-diffusion-v1-5” -instance_prompt = "A photo of a girl in the style of sks" -class_prompt = "A photo of a girl" - -!python3 train_dreambooth.py \ - --pretrained_model_name_or_path=$MODEL_NAME \ - --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ - --output_dir=$OUTPUT_DIR \ - --revision="fp16" \ - --with_prior_preservation --prior_loss_weight=1.0 \ - --seed=1337 \ - --resolution=512 \ - --train_batch_size=1 \ - --train_text_encoder \ - --mixed_precision="fp16" \ - --use_8bit_adam \ - --gradient_accumulation_steps=1 --gradient_checkpointing \ - --learning_rate=1e-6 \ - --lr_scheduler="constant" \ - --lr_warmup_steps=0 \ - --num_class_images=200 \ - --sample_batch_size=4 \ - --max_train_steps=800 \ - --save_interval=100 \ - --save_sample_prompt="A photo of sks girl" \ - --concepts_list="concepts_list.json" -``` - -```python -# different instance prompt w/o ****prior-preservation loss -****MODEL_NAME = “runwayml/stable-diffusion-v1-5” -instance_prompt = "A photo of a girl in the style of sks" -class_prompt = "A photo of a girl" - -!python3 train_dreambooth.py \ - --pretrained_model_name_or_path=$MODEL_NAME \ - --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ - --output_dir=$OUTPUT_DIR \ - --revision="fp16" \ - --with_prior_preservation --prior_loss_weight=0.0 \ - --seed=1337 \ - --resolution=512 \ - --train_batch_size=1 \ - --train_text_encoder \ - --mixed_precision="fp16" \ - --use_8bit_adam \ - --gradient_accumulation_steps=1 --gradient_checkpointing \ - --learning_rate=1e-6 \ - --lr_scheduler="constant" \ - --lr_warmup_steps=0 \ - --num_class_images=200 \ - --sample_batch_size=4 \ - --max_train_steps=800 \ - --save_interval=100 \ - --save_sample_prompt="A photo of sks girl" \ - --concepts_list="concepts_list.json" -``` - -Inference 시, 프리드로우의 그림체가 반영된 남자가 생성되도록 prompt 를 “A photo of a boy in the style of *sks*” 로 입력했을때의 결과입니다. DreamBooth 혹은 사전학습된 text-to-image 모델을 프리드로우 작가님의 웹툰 장면들로 전체적으로 학습하게 된다면 더 다양한 inference 결과들을 볼 수 있을 것 같습니다. - -- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 24 / with prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_05 - -Instance Prompt -::: - -Inference step 을 늘려가면서 추론된 인물 이미지의 퀄리티가 상승하는 부분도 확인할 수 있었습니다. 또한, guidance scale 에 대한 실험도 진행했는데 guidance scale 이 작을수록 prompt 와 무관한 random 한 이미지들을 생성하게 됩니다. 최종적으로 num_inference steps 와 guidance scale 의 값은 각각 100 과 7.5 로 설정하였습니다. - -- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps=100 / with prior-preservation loss)** - -:::{figure-md} -swjo_exp_06 - -Increasing Number of Inference Steps -::: - -- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_07 - -Increasing Number of Inference Steps / Negative Prompt -::: - -- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - - **+ guidance_scale = 4** - -:::{figure-md} -swjo_exp_08 - -Guidance Scale -::: - -동일한 inference prompt 로 prior-preservation loss 를 제외해본 결과, 생성된 남자의 머리카락이 더 길어지고 더 여성스러운 생김새를 가지는 놀라운 사실도 발견했습니다. - -- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_09 - -Without Prior Preservation Loss -::: - -## Appendix - -그 외 다양한 inference prompt 에 따른 재미있는 실험결과들을 공유합니다. 아직 손의 모양을 text-to-image 모델이 생성하지 못하는 부분도 재차 확인할 수 있었습니다. - -- **Inference Prompt: “A photo of a boy climbing up the mountain in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_10 - -Appendix 1 -::: - -- **Inference Prompt: “A painting of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_11 - -Appendix 2 -::: - -- **Inference Prompt: “A hand drawing of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** - - **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** - -:::{figure-md} -swjo_exp_12 - -Appendix 3 -::: - -마지막으로 하단의 좌측과 우측 사진은 각각 “A photo of *sks* girl” 그리고 “A photo of a girl in the style of *sks*” 이라는 prompt 로 DreamBooth 모델을 각각 학습한 후, 나비를 생성하라는 동일한 prompt 로 추론해본 결과입니다. *sks* 가 수식하는 명사가 girl 이 아닌 style 이도록 prompt 를 수정함으로써, butterfly 사진을 생성할때 조금이나마 더 프리드로우 웹툰의 그림체를 반영할 수 있었던 부분도 확인할 수 있었습니다. - -- **Inference Prompt: “A photo of a butterfly in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** - -:::{figure-md} -swjo_exp_13 - -Appendix 4 -::: +``` {admonition} Information +- **Title:** Training DreamBooth on Naver Webtoon Face Dataset + +- **Author:** Sangwoo Jo + +- **Last updated on Jul. 09, 2023** +``` + +# Training DreamBooth on Naver Webtoon Face Dataset + +## Introduction + +이번 포스팅에서는 DreamBooth 를 직접 학습해보고 실험한 결과들을 공유할려고 합니다. + +우선적으로 학습데이터는 [https://github.com/bryandlee/naver-webtoon-data](https://github.com/bryandlee/naver-webtoon-data) 에 공개된 YOLOv5 모델 및 Waifu2x 후처리 기법을 활용하여 프리드로우에 등장하는 인물 사진들을 수집했습니다. 논문에서는 3-5 장으로 fine-tuning 이 가능하다고 제시되어있지만, 인물 사진 같은 경우 더 많은 데이터로 학습하면 성능이 더 좋아져서 15-20 장의 이미지로 학습하였습니다. 학습한 이미지들 예시입니다. + +:::{figure-md} +swjo_exp_01 + +Training Data +::: + +DreamBooth 를 실험하면서 대표적으로 instance prompt, guidance scale, negative prompt, 그리고 마지막으로 prior preservation loss 를 반영하는 정도를 조절하는 prior_loss_weight 를 바꿔가면서 학습해보았습니다. 사전학습된 text-to-image 모델로 처음에는 *hakurei/waifu-diffusion* 모델을 시도해봤지만 결과가 만족스럽지 못해 *runwayml/stable-diffusion-v1-5* 모델로 fine-tuning 작업을 진행했습니다. + +## Ablation Studies + +### Prior Preservation Loss + +Prior Preservation Loss 를 제외한 동일한 configuration 으로 모델 학습한 결과입니다. + +```python +# with prior-preservation loss +MODEL_NAME = “runwayml/stable-diffusion-v1-5” +instance_prompt = "A photo of sks girl" +class_prompt = "A photo of a girl" + +!python3 train_dreambooth.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ + --output_dir=$OUTPUT_DIR \ + --revision="fp16" \ + --with_prior_preservation --prior_loss_weight=1.0 \ + --seed=1337 \ + --resolution=512 \ + --train_batch_size=1 \ + --train_text_encoder \ + --mixed_precision="fp16" \ + --use_8bit_adam \ + --gradient_accumulation_steps=1 --gradient_checkpointing \ + --learning_rate=1e-6 \ + --lr_scheduler="constant" \ + --lr_warmup_steps=0 \ + --num_class_images=200 \ + --sample_batch_size=4 \ + --max_train_steps=800 \ + --save_interval=100 \ + --save_sample_prompt="A photo of sks girl" \ + --concepts_list="concepts_list.json" +``` + +```python +# w/o prior-preservation loss +MODEL_NAME = “runwayml/stable-diffusion-v1-5” +instance_prompt = "A photo of sks girl" +class_prompt = "A photo of a girl" + +!python3 train_dreambooth.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ + --output_dir=$OUTPUT_DIR \ + --revision="fp16" \ + --with_prior_preservation --prior_loss_weight=0.0 \ + --seed=1337 \ + --resolution=512 \ + --train_batch_size=1 \ + --train_text_encoder \ + --mixed_precision="fp16" \ + --use_8bit_adam \ + --gradient_accumulation_steps=1 --gradient_checkpointing \ + --learning_rate=1e-6 \ + --lr_scheduler="constant" \ + --lr_warmup_steps=0 \ + --num_class_images=200 \ + --sample_batch_size=4 \ + --max_train_steps=800 \ + --save_interval=100 \ + --save_sample_prompt="A photo of sks girl" \ + --concepts_list="concepts_list.json" +``` + +아래 그림처럼 동일한 inference prompt 를 입력했을 때, prior preservation loss 를 제외함으로써 input images 에 더 가까운 웹툰 사진들을 생성할 수 있었습니다. 또한, 핑크색 머리를 한 이민지 캐릭터를 어느 정도 잘 생성하는 부분도 확인할 수 있습니다. + +- **Inference Prompt: "A photo of *sks* girl with pink hair” (with prior-preservation loss)** + +:::{figure-md} +swjo_exp_02 + +With Prior Preservation Loss +::: + +- **Inference Prompt: " A photo of *sks* girl with pink hair” (w/o prior-preservation loss)** + +:::{figure-md} +swjo_exp_03 + +Without Prior Preservation Loss +::: + +### Negative Prompt + +Negative Prompt 에 대한 Ablation Study 도 진행했습니다. 캐릭터의 부자연스러운 부분이나 저해상도 이미지들을 생성하는 경우들이 종종 발생했는데, negative prompt 를 통해 더 좋은 퀄리티의 웹툰 캐릭터를 생성할 수 있었습니다. + +- **Inference Prompt: " A photo of *sks* girl with pink hair” (w/o negative prompt)** + +:::{figure-md} +swjo_exp_03 + +Without Negative Prompt +::: + +- **Inference Prompt: " A photo of *sks* girl with pink hair”** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_04 + +With Negative Prompt +::: + +### Instance Prompt / Guidance Scale + +DreamBooth 논문에서 제시한 instance prompt 외에 “A photo of a girl in the style of *sks*” 라는 prompt 로 학습을 시도해보기도 했습니다. *sks* 라는 unique identifier 에 특정 여자 캐릭터에 대한 정보뿐만 아니라 프리드로우 그림체 자체를 담아내기 위한 목적이였습니다. + +```python +# different instance prompt with prior-preservation loss +****MODEL_NAME = “runwayml/stable-diffusion-v1-5” +instance_prompt = "A photo of a girl in the style of sks" +class_prompt = "A photo of a girl" + +!python3 train_dreambooth.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ + --output_dir=$OUTPUT_DIR \ + --revision="fp16" \ + --with_prior_preservation --prior_loss_weight=1.0 \ + --seed=1337 \ + --resolution=512 \ + --train_batch_size=1 \ + --train_text_encoder \ + --mixed_precision="fp16" \ + --use_8bit_adam \ + --gradient_accumulation_steps=1 --gradient_checkpointing \ + --learning_rate=1e-6 \ + --lr_scheduler="constant" \ + --lr_warmup_steps=0 \ + --num_class_images=200 \ + --sample_batch_size=4 \ + --max_train_steps=800 \ + --save_interval=100 \ + --save_sample_prompt="A photo of sks girl" \ + --concepts_list="concepts_list.json" +``` + +```python +# different instance prompt w/o ****prior-preservation loss +****MODEL_NAME = “runwayml/stable-diffusion-v1-5” +instance_prompt = "A photo of a girl in the style of sks" +class_prompt = "A photo of a girl" + +!python3 train_dreambooth.py \ + --pretrained_model_name_or_path=$MODEL_NAME \ + --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \ + --output_dir=$OUTPUT_DIR \ + --revision="fp16" \ + --with_prior_preservation --prior_loss_weight=0.0 \ + --seed=1337 \ + --resolution=512 \ + --train_batch_size=1 \ + --train_text_encoder \ + --mixed_precision="fp16" \ + --use_8bit_adam \ + --gradient_accumulation_steps=1 --gradient_checkpointing \ + --learning_rate=1e-6 \ + --lr_scheduler="constant" \ + --lr_warmup_steps=0 \ + --num_class_images=200 \ + --sample_batch_size=4 \ + --max_train_steps=800 \ + --save_interval=100 \ + --save_sample_prompt="A photo of sks girl" \ + --concepts_list="concepts_list.json" +``` + +Inference 시, 프리드로우의 그림체가 반영된 남자가 생성되도록 prompt 를 “A photo of a boy in the style of *sks*” 로 입력했을때의 결과입니다. DreamBooth 혹은 사전학습된 text-to-image 모델을 프리드로우 작가님의 웹툰 장면들로 전체적으로 학습하게 된다면 더 다양한 inference 결과들을 볼 수 있을 것 같습니다. + +- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 24 / with prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_05 + +Instance Prompt +::: + +Inference step 을 늘려가면서 추론된 인물 이미지의 퀄리티가 상승하는 부분도 확인할 수 있었습니다. 또한, guidance scale 에 대한 실험도 진행했는데 guidance scale 이 작을수록 prompt 와 무관한 random 한 이미지들을 생성하게 됩니다. 최종적으로 num_inference steps 와 guidance scale 의 값은 각각 100 과 7.5 로 설정하였습니다. + +- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps=100 / with prior-preservation loss)** + +:::{figure-md} +swjo_exp_06 + +Increasing Number of Inference Steps +::: + +- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_07 + +Increasing Number of Inference Steps / Negative Prompt +::: + +- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + + **+ guidance_scale = 4** + +:::{figure-md} +swjo_exp_08 + +Guidance Scale +::: + +동일한 inference prompt 로 prior-preservation loss 를 제외해본 결과, 생성된 남자의 머리카락이 더 길어지고 더 여성스러운 생김새를 가지는 놀라운 사실도 발견했습니다. + +- **Inference Prompt: “A photo of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_09 + +Without Prior Preservation Loss +::: + +## Appendix + +그 외 다양한 inference prompt 에 따른 재미있는 실험결과들을 공유합니다. 아직 손의 모양을 text-to-image 모델이 생성하지 못하는 부분도 재차 확인할 수 있었습니다. + +- **Inference Prompt: “A photo of a boy climbing up the mountain in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_10 + +Appendix 1 +::: + +- **Inference Prompt: “A painting of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_11 + +Appendix 2 +::: + +- **Inference Prompt: “A hand drawing of a boy in the style of *sks*” (num_inference_steps = 100 / w/o prior-preservation loss)** + + **+** **Negative Prompt: “ugly, disfigured, deformed, low resolution”** + +:::{figure-md} +swjo_exp_12 + +Appendix 3 +::: + +마지막으로 하단의 좌측과 우측 사진은 각각 “A photo of *sks* girl” 그리고 “A photo of a girl in the style of *sks*” 이라는 prompt 로 DreamBooth 모델을 각각 학습한 후, 나비를 생성하라는 동일한 prompt 로 추론해본 결과입니다. *sks* 가 수식하는 명사가 girl 이 아닌 style 이도록 prompt 를 수정함으로써, butterfly 사진을 생성할때 조금이나마 더 프리드로우 웹툰의 그림체를 반영할 수 있었던 부분도 확인할 수 있었습니다. + +- **Inference Prompt: “A photo of a butterfly in the style of *sks*” (num_inference_steps = 100 / with prior-preservation loss)** + +:::{figure-md} +swjo_exp_13 + +Appendix 4 +::: diff --git a/_sources/docs/markdown-example.md b/_sources/docs/markdown-example.md old mode 100644 new mode 100755 index 573e35f9..ed5b4329 --- a/_sources/docs/markdown-example.md +++ b/_sources/docs/markdown-example.md @@ -1,53 +1,53 @@ -Jupyter Book은 markdown 문서를 지원합니다. - -아래와 같은 예시 코드를 입력하면 markdown 문법이 적용됩니다. - -``` -# This is an h1 tag -## This is an h2 tag -###### This is an h6 tag - -*This text will be italic* -_This will also be italic_ - -**This text will be bold** -__This will also be bold__ - -_You **can** combine them_ - -* Item 1 -* Item 2 - * Item 2a - * Item 2b - -1. Item 1 -1. Item 2 -1. Item 3 - 1. Item 3a - 1. Item 3b -``` - -입력 결과 - -# This is an h1 tag -## This is an h2 tag -###### This is an h6 tag - -*This text will be italic* -_This will also be italic_ - -**This text will be bold** -__This will also be bold__ - -_You **can** combine them_ - -* Item 1 -* Item 2 - * Item 2a - * Item 2b - -1. Item 1 -1. Item 2 -1. Item 3 - 1. Item 3a +Jupyter Book은 markdown 문서를 지원합니다. + +아래와 같은 예시 코드를 입력하면 markdown 문법이 적용됩니다. + +``` +# This is an h1 tag +## This is an h2 tag +###### This is an h6 tag + +*This text will be italic* +_This will also be italic_ + +**This text will be bold** +__This will also be bold__ + +_You **can** combine them_ + +* Item 1 +* Item 2 + * Item 2a + * Item 2b + +1. Item 1 +1. Item 2 +1. Item 3 + 1. Item 3a + 1. Item 3b +``` + +입력 결과 + +# This is an h1 tag +## This is an h2 tag +###### This is an h6 tag + +*This text will be italic* +_This will also be italic_ + +**This text will be bold** +__This will also be bold__ + +_You **can** combine them_ + +* Item 1 +* Item 2 + * Item 2a + * Item 2b + +1. Item 1 +1. Item 2 +1. Item 3 + 1. Item 3a 1. Item 3b \ No newline at end of file diff --git a/_sources/docs/notebook-example.ipynb b/_sources/docs/notebook-example.ipynb old mode 100644 new mode 100755 index e2da265e..0f6326c3 --- a/_sources/docs/notebook-example.ipynb +++ b/_sources/docs/notebook-example.ipynb @@ -1,80 +1,80 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# .ipynb 파일 활용" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Jupyter Book에선 .ipynb파일 또한 지원합니다. 아래와 같이 코드를 입력하고, 그에 대응하는 출력물을 함께 웹페이지로 구성 가능합니다. " - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAA0BklEQVR4nO3deXxU9b3/8dcnG2EJCZCQkGSQfYdsE8SlrhURN1RIUOxtfw/786LYau2ibW/trV67X9u6X3/V29sLKkFAUXEtVMWNTELCvsk2WSBhSVhDtu/vj5nQNEzIJMzMmeXzfDzmwXDOmTmfHJhPzpzzPe8jxhiUUkqFryirC1BKKeVf2uiVUirMaaNXSqkwp41eKaXCnDZ6pZQKczFWF+BJcnKyGTZsmNVlKKVUyCgpKTlojEnxNC8oG/2wYcNwOBxWl6GUUiFDRPZ2Nk8P3SilVJjTRq+UUmFOG71SSoU5bfRKKRXmtNErpVSY67LRi0i8iKwVkXIR2SQiv/CwTC8RWSwiO0XkSxEZ1m7ej93Tt4nItT6uXymlVBe82aM/DVxljMkCsoEZIjKtwzJ3AUeMMaOAPwC/ARCRCcBcYCIwA3hWRKJ9VLtSSikvdNnojctx919j3Y+O2cY3A//jfv4acLWIiHv6q8aY08aY3cBOYKpPKu+goamFFz7+is++OuiPt1dKKb9avbWGl9bsprG51efv7dUxehGJFpEyoAb4wBjzZYdFMgAngDGmGagHBrWf7lbhnuZpHXeLiENEHLW1td36IQBiooQ/f7Kbl9bs7vZrlVLKas9/9BV//XwPsdHi8/f2qtEbY1qMMdlAJjBVRCb5uhBjzAvGGLsxxp6S4vEq3nOKiY7itrxMVm+rpeZog6/LU0opv9lz8ARf7j7MHLsN18EQ3+rWqBtjTB2wGtfx9vYqARuAiMQAicCh9tPdMt3T/GJOXiYtrYalpX5bhVJK+dySEidRArflZvrl/b0ZdZMiIknu572Ba4CtHRZbAXzT/Xw2sMq47lG4ApjrHpUzHBgNrPVR7WcZkdKPqcMGssThRG+RqJQKBS2thtdKKrhi7GDSEuP9sg5v9uiHAKtFZD1QjOsY/Vsi8qiI3ORe5kVgkIjsBB4EHgYwxmwCioDNwLvAAmNMi69/iPbm2DPZdfAEjr1H/LkapZTyiY+313Lg6GkK7P7Zmwcv0iuNMeuBHA/TH2n3vAGY08nrHwceP48au+X6KUP49xWbKCp2kj9sYKBWq5RSPVLkcDKobxxXjUv12zrC7srYPnEx3JiVztsbqjl+utnqcpRSqlOHjp/mwy0HuCUng7gY/7XjsGv0AAX5Nk42tvD2+iqrS1FKqU4tX1dJU4uhIN/W9cLnISwbfY4tiVGD+7G42Nn1wkopZQFjDEUOJ9m2JMakJvh1XWHZ6EWEQruN0n117Kw5ZnU5Sil1ljJnHdsPHKfQz3vzEKaNHuCW3AxiooQiR4XVpSil1FmKHBX0jo3mhilD/L6usG30yf16cfX4wSwrraCpxffZEUop1VMnG5t5s7yKmZOHkBAf6/f1hW2jByiw2zh4vJFVW2usLkUppc54Z8N+jp9u9uvY+fbCutFfPiaFwQm9KNKTskqpILLY4WR4cl+mDg/MtT5h3ehjoqOYnZfJ6m01HNCgM6VUENh98ARrdx9mjj3TLwFmnoR1oweYY7fRamBpqZ6UVUpZb4nDvwFmnoR9o2/7erTEUaFBZ0opSzW3tLK0tIIrxw4mtb9/Asw8CftGD66TsrsPnqB4jwadKaWs8/EOV4DZHLv/x863FxGNfubkNPr1iqHIoSdllVLWKSquILlfHFePHxzQ9UZEo3cFnQ3h7fXVHGtosrocpVQEOtguwCw2OrCtNyIaPbgO35xqauGt9dVWl6KUikDLSytpbjUUBPiwDURQo8+2JTF6cD89fKOUCri2ALOcoUmM9nOAmSfe3ErQJiKrRWSziGwSkfs9LPNDESlzPzaKSIuIDHTP2yMiG9zzHP74IbwhIhTm21i3r44dBzToTCkVOOucdeyoOU6hBXvz4N0efTPwfWPMBGAasEBEJrRfwBjzO2NMtjEmG/gx8JEx5nC7Ra50z7f7qvCemJXTFnSme/VKqcBZ4nDSOzaa6wMQYOZJl43eGFNtjCl1Pz8GbAEyzvGS24FXfFOebyX368XXx6eyrLSSxmYNOlNK+Z8rwKya66cEJsDMk24doxeRYbjuH/tlJ/P7ADOApe0mG+B9ESkRkbvP8d53i4hDRBy1tbXdKatbCvIzOXRCg86UUoGx8kyAmTWHbaAbjV5E+uFq4A8YY452stiNwKcdDttcaozJBa7DddjnMk8vNMa8YIyxG2PsKSkp3pbVbZeNTiG1fy89fKOUCoiiYicjkvuSP2yAZTV41ehFJBZXk19kjFl2jkXn0uGwjTGm0v1nDbAcmNqzUn2jLejs7xp0ppTys121x1m75zBz7LaABZh54s2oGwFeBLYYY544x3KJwOXAG+2m9RWRhLbnwHRg4/kWfb7m5LmCzl4r0aAzpZT/LCmpIDpKuC33XKc1/c+bPfpLgG8AV7UbQjlTROaLyPx2y90CvG+MOdFuWiqwRkTKgbXA28aYd31WfQ8NS+7LhcMHssTh1KAzpZRfNLe0srSkgivHpjA4gAFmnsR0tYAxZg3Q5XcOY8xfgL90mLYLyOphbX5VYLfx/SXlrN19mAtHDLK6HKVUmPloey01xwIfYOZJxFwZ29HMyUPo1yuGxXpSVinlB4uLnST3i+OqcYENMPMkYht977hobsxKZ+UGDTpTSvlW7bHTrNpaw625mQEPMPPE+gosVJhvo6GplTfLNehMKeU7y9dVuAPMAncXqXOJ6EaflZnImFQNOlNK+Y4rwKyC3KFJjBoc+AAzTyK60YsIBXYbZc46tmvQmVLKB0r31bGz5jiF+dafhG0T0Y0ecN8EQCgq1r16pdT5W+Jw0icumuunpFtdyhkR3+gHtQWdrdOgM6XU+Tlxupk3y6u43j2qL1hEfKMHKMi3cfhEI6u2HrC6FKVUCFu5oZoTjS1BddgGtNEDrqCztP7xLNbDN0qp81DkcDIipS95F1gXYOaJNnogOkqYnZfJR9tr2V+vQWdKqe7bVXuc4j1HKLA4wMwTbfRuc+yZtBpYWqpBZ0qp7ityuALMbrU4wMwTbfRuFwzqy7QRAylyOGlt1aAzpZT3mltaWVpawZVjBzM4wdoAM0+00bdTYLex99BJ1u453PXCSinl9vdttdQeOx00V8J2pI2+nesmDSGhV4yOqVdKdctih5Pkfr24MggCzDzRRt9O77hobsxOZ+XGao5q0JlSygs1xxpYtbWG23IzgiLAzJPgrMpChfa2oLMqq0tRSoWA5aWVtLSaoMid74w3txK0ichqEdksIptE5H4Py1whIvXt7kD1SLt5M0Rkm4jsFJGHff0D+NqUzETGpiZQ5NDRN0qpc3MFmDnJu2AAowb3s7qcTnmzR98MfN8YMwGYBiwQkQkelvvEGJPtfjwKICLRwDPAdcAE4PZOXhs0RISCfBvlzjq27degM6VU50r3HeGr2hMUBvHePHjR6I0x1caYUvfzY8AWwNuBolOBncaYXcaYRuBV4OaeFhsoZ4LONL5YKXUORcUV9ImLZuaUIVaXck7dOkYvIsOAHOBLD7MvEpFyEXlHRCa6p2UA7btlBZ38khCRu0XEISKO2tra7pTlcwP7xnHNhFSWa9CZUqoTJ04389b6Km6YElwBZp543ehFpB+wFHjAGHO0w+xS4AJjTBbwFPB6dwsxxrxgjLEbY+wpKSndfbnPFdhdQWd/26JBZ0qps70dpAFmnnjV6EUkFleTX2SMWdZxvjHmqDHmuPv5SiBWRJKBSqD9Vsh0Twt6XxudwpDEeL15uFLKo6JiV4BZ7tDgCjDzxJtRNwK8CGwxxjzRyTJp7uUQkanu9z0EFAOjRWS4iMQBc4EVviren9qCzj7eXkt1/Smry1FKBZGdNcdx7D1CYRAGmHnizR79JcA3gKvaDZ+cKSLzRWS+e5nZwEYRKQeeBOYal2bgPuA9XCdxi4wxm/zwc/jFnDybK+isRIdaKqX+YUmJk+go4ZYgDDDzpMszCMaYNcA5f2UZY54Gnu5k3kpgZY+qs9jQQX24aMQgihwV3HvFKKKigv83t1LKv5paWllaUslV44IzwMwTvTK2CwX5mew7fJIvd2vQmVLKFWB28PhpCoJ87Hx72ui7cN2kISTEx+iYeqUUAIuLnaQk9OLKsdaPDvSWNvouxMdGc1NWOis3aNCZUpGu5lgDq7fVcGtuBjFBGmDmSehUaqHCfBunm1tZUaZBZ0pFsmXuALNQOmwD2ui9MjkjkXFpCSzRwzdKRay2ADP7BQMYmRK8AWaeaKP3gohQYLdRXlHP1v0dLwpWSkWCkr1H2FV7goIQuBK2I230XprVFnRWrGPqlYpERQ4nfeOiuX5ycAeYeaKN3ksD+8YxfUIay9dVcLq5xepylFIBdPx0M2+tr+aGKen0DfIAM0+00XdDQb6NIyeb+HBzjdWlKKUC6O31VZxsbAnJwzagjb5bLh2VTHpivI6pVyrCFDkqGJnSl9yhSVaX0iPa6LvhTNDZjlqq6jToTKlIsLPmGCV7j1CYHxoBZp5oo++m2Xk2jAadKRUxljgqiIkSbsnJtLqUHtNG301DB/Xh4pGDKCpx0tpqrC5HKeVHTS2tLC2t4Kpxg0lJ6GV1OT2mjb4HCuw2nIdP8cXuQ1aXopTyo9Vbazh4vDHkroTtSBt9D8yYlOYKOivWk7JKhbMihyvA7IoQCjDzxJs7TNlEZLWIbBaRTSJyv4dl5onIehHZICKfiUhWu3l73NPLRMTh6x/ACvGx0dycnc47G/dTf0qDzpQKRzVHG1i9rZbbcjNDKsDME2+qbwa+b4yZAEwDFojIhA7L7AYuN8ZMBh4DXugw/0pjTLYxxn7eFQeJQvtQV9BZuQadKRWOlp4JMAvdk7Btumz0xphqY0yp+/kxXLcEzOiwzGfGmCPuv36B6ybgYW1SRn8NOlMqTBljWOJwkj9sACNCLMDMk259HxGRYUAO8OU5FrsLeKfd3w3wvoiUiMjd53jvu0XEISKO2tra7pRlCRGhMN/G+op6tlRr0JlS4cSx9wi7Dp4I+ZOwbbxu9CLSD1gKPGCM8djZRORKXI3+oXaTLzXG5ALX4Trsc5mn1xpjXjDG2I0x9pSU0DjxMSs7g7joKL1SVqkwU1TsDjCbEnoBZp541ehFJBZXk19kjFnWyTJTgD8DNxtjzow7NMZUuv+sAZYDU8+36GAxoG8c10xMZfm6Sg06UypMHD/dzNsbqrkxK50+caEXYOaJN6NuBHgR2GKMeaKTZYYCy4BvGGO2t5veV0QS2p4D04GNvig8WBTabdSdbOKDzQesLkUp5QNvlYd2gJkn3vy6ugT4BrBBRMrc034CDAUwxjwPPAIMAp51Z0E0u0fYpALL3dNigJeNMe/68gew2iVngs4quGFKutXlKKXOU5HDyajB/cixJVldis902eiNMWuAcyb5GGO+DXzbw/RdQNbZrwgf0VHCbLuNp1btoLLuFBlJva0uSSnVQztrjlG6r46fzhwfsgFmnoT2VQBBYk5epgadKRUGitoCzHIzul44hGij9wHbwD5cMmoQRQ4NOlMqVDW1tLKstIKrxw8muV/oBph5oo3eRwrsNiqOnOKLXRp0plQoWhUmAWaeaKP3kWsnptE/PobFOqZeqZBUVOxkcEIvLh8TGtfxdIc2eh9xBZ1luILOTmrQmVKh5MDRBlZvq+G2vNAPMPMk/H4iCxXm22hsbmVFeaXVpSilumFpaQWthrA8bAPa6H1qYnp/xg/pT5FDR98oFSpcAWYVTB02kOHJfa0uxy+00fuQiFBoz2RDZT2bqzToTKlQULznCLsPngirK2E70kbvY7NyNOhMqVCyuNhJv14xzJycZnUpfqON3seS+sQx3R101tCkQWdKBbNjDU2s3FDNjVlDwibAzBNt9H5QmG+j/pQGnSkV7N5aX82pppawPQnbRhu9H1wyMpmMpN56+EapIFfkcDJ6cD+ywyjAzBNt9H4QFSXMzstkzc6DVBw5aXU5SikPdhw4xrp9dRTm28IqwMwTbfR+MjvPddvcpSU6pl6pYFTkcBITJczKCa8AM0+00fuJbWAfLhmZzJISDTpTKtg0NreyrLSSr49PDbsAM0+00fvRHHsmFUdO8bkGnSkVVFZtreHQiUYK8jOtLiUgvLmVoE1EVovIZhHZJCL3e1hGRORJEdkpIutFJLfdvG+KyA7345u+/gGC2Zmgs2I9KatUMClyOEnt34vLRodfgJkn3uzRNwPfN8ZMAKYBC0RkQodlrgNGux93A88BiMhA4OfAhbhuCv5zERngo9qDXnxsNLNyMnh3kwadKRUsDhxt4O/bargtNzwDzDzp8qc0xlQbY0rdz48BW4COZy9uBv5qXL4AkkRkCHAt8IEx5rAx5gjwATDDpz9BkCuwu4LO3tCgs5C3uHgfr6/Tf8dQ91pJeAeYedKtS8FEZBiQA3zZYVYG0P74RIV7WmfTPb333bi+DTB06NDulBXUJmUkMjG9P4uLnfzLRcOsLkf10AebD/DQ0g1ECaQk9OKSUclWl6R6wBVg5mTq8IEMC9MAM0+8/t4iIv2ApcADxhifJ3YZY14wxtiNMfaUlPA6blZgt7Gp6igbK+utLkX1wN5DJ3iwqIxJGf0ZmdKP776yjv31DVaXpXpg7e7D7Dl0ksII2psHLxu9iMTiavKLjDHLPCxSCbTfcpnuaZ1Njyg3Z6cTFxPFEr1SNuQ0NLVwz8JSokR4bl4ez92Zy6mmFu57uZSmllary1PdtNjRFmA2xOpSAsqbUTcCvAhsMcY80cliK4B/cY++mQbUG2OqgfeA6SIywH0Sdrp7WkRJ6hPHtRPTeL2sSoPOQszP39jE5uqj/KEwC9vAPowanMBvbpuCY+8Rfv3OVqvLU93wjwCzdHrHRVtdTkB5s0d/CfAN4CoRKXM/ZorIfBGZ715mJbAL2An8P+BeAGPMYeAxoNj9eNQ9LeIU2l1BZ+9r0FnIKCp2stjhZMGVI7lqXOqZ6TdmpfOti4fx4prdrNxQbWGFqjveLK+moamVwjDOne9MlydjjTFrgHMGQRhjDLCgk3kvAS/1qLowcvHIQWQk9WaJw8lNWelWl6O6sKmqnp+9sZGLRw7iwWvGnjX/JzPHU15Rxw+XlDM2LYGRKf0sqFJ1R5HDyZjUfmRlJlpdSsBFxiDSIBAVJcyxa9BZKKg/1cQ9C0tJ6hPLk7fnEB119n5OXEwUz9yRS6/YaO5ZWMLJxmYLKlXe2n7gGGXOOgrs4R9g5ok2+gBqCzp7rUTvKRusjDH8YEk5VXWneOaO3HPmoKQn9eZPc7PZUXOcny7fiOuLrQpGRcVOYqOFWyIgwMwTbfQBlDmgD5eOSmaJo0KDzoLUf328iw82H+Dh68ZhHzawy+W/NjqFB64ew/J1lSz6cl8AKlTd1djcyrJ1rgCzQREQYOaJNvoAm2O3UVl3is++0qCzYPPFrkP89t2tzJycxl2XDvf6dd+5ahSXj0nh0Tc3s76izn8Fqh5ZtfUAh080RtSVsB1pow+w6RNSSewdy2IdUx9Uao42cN/L6xg2qC+/uW1Kt47jRkUJfyzMJiWhF/csLOXIiUY/Vqq6a3Gxk7T+8Vw2JrwuxOwObfQBFh8bzazsdN7btJ+6k9oQgkFzSyv3vbKOE6ebee7OPBLiY7v9HgP6xvHsvFxqj53me0VlemguSOyvb+Cj7bXclpfh8aR6pNBGb4GCfHfQWVmV1aUo4HfvbWPt7sP88tZJjE1L6PH7ZNmS+NmNE/j7tlqeWb3ThxWqnlpaGnkBZp5oo7fAxPREJmX015z6IPDepv3818e7mHfhUG7JOf+bUNx54VBmZafzxIfbWbPjoA8qVD3V2moocjiZNmIgFwyKnAAzT7TRW6TAbmNztQadWWnPwRP8oKicKZmJPHJjx1ss9IyI8MtbJzN6cD++++o6qutP+eR9Vfet3XOYvYdORvzePGijt8zNWRnExURRpCdlLdHQ1MI9i0qJihLXhU8xvss+6RMXw3N35nG6qYUFi0ppbNbwMysUFTtJ6BXDdZMiK8DME230FknsE8uMiWm8vq5Sg84s8LPXN7Kl+ih/LMzGNrCPz99/ZEo/fjs7i9J9dfzqnS0+f391bkcbmli5sZobsyMvwMwTbfQWKsy3cbShmfc27be6lIiyuHgfS0oq+M5Vo7hy3GC/ref6KUP4P5cM478/3cNb6/XEeyC9WV7lCjDTwzaANnpLXTRiEJkDerPEoZEIgbKxsp6fvbGJS0cl88DXx/h9fT++bjy5Q5N46LX17Kw57vf1KZciRwVjUxOYEoEBZp5oo7dQVJQwJ8/Gmp0HcR7WoDN/qz/ZxD2LShjYJ44/zc0OyLjquJgonpn3j/CzE6c1/Mzftu0/RrmzjoL8yAww80QbvcVm2zMR0aAzf2ttNXx/SRnVdQ08My83oJknQxJ78+TcHHbWHucnyzdo+JmfFTkiO8DME230FstI6s2lo5J5raSCFr2a0m+e//grPtxSw0+vH0/eBQMCvv5LRyfz4NfH8EZZFQu/2Bvw9UeKxuZWlq+r5JoJqQzsG2d1OUHDm1sJviQiNSKysZP5P2x356mNItIiIgPd8/aIyAb3PIeviw8XBe6gs0936gU2/vDZVwf5/XvbuH7KEL518TDL6lhw5SiuHJvCo29tpsxZZ1kd4ezDLa4Aszl6EvafeLNH/xdgRmczjTG/M8ZkG2OygR8DH3W4XeCV7vn286o0jE2fmEpSn1gdU+8HB4428N1X1jE8ufthZb4WFSX8oTCbwQnxLFik4Wf+UORwB5iNjtwAM0+6bPTGmI8Bb+/zejvwynlVFIF6xUQzKzuD9zcd0A+/DzW1tHLfy6WcON3Cc3fm0a9Xl3fO9LukPnE8d6cr/OyBxRp+5kvV9af4eHsts/MyIzrAzBOfHaMXkT649vyXtptsgPdFpERE7u7i9XeLiENEHLW1tb4qK2QU2G00trTyRlml1aWEjd++u5XiPUf49W2TGZPa87AyX5uSmcTPb5rAR9treWqVhp/5ytISDTDrjC9Pxt4IfNrhsM2lxphc4DpggYhc1tmLjTEvGGPsxhh7Skrkfe2akN6fyRmJLHZU6KgMH3h3YzX/75PdfGPaBdycHXyjL+6YOpRbczL449+28/H2yNux8TVXgFkFF40YxNBBvr/SOdT5stHPpcNhG2NMpfvPGmA5MNWH6ws7BfZMtlQfZVPVUatLCWm7D57gh0vWk2VL4t9uGG91OR6JCI/fMpkxgxO4/9V1VNVp+Nn5+HL3YfYdPklB/vknkIYjnzR6EUkELgfeaDetr4gktD0HpgMeR+4ol5uyM+gVE6XxxefhVGML9ywsITpaeOaOHJ+Glfla77honrszl6YWw70afnZeihxOEuI1wKwz3gyvfAX4HBgrIhUicpeIzBeR+e0WuwV43xhzot20VGCNiJQDa4G3jTHv+rL4cJPYO5YZk9J4o0yDznrCGMO/vb6RbQeO8cfCbDIHBP9X+BEp/fjt7CmUOev45UoNP+uJow1NrNxQzU1Z6cTHBu8vdit1OQzBGHO7F8v8BdcwzPbTdgFZPS0sUhXabbxRVsV7m/YH5bHlYPZqsZOlpRV89+rRXDHWf2FlvjZz8hDuunQ4L67ZTe4FA7gpK93qkkLKirIqTje3UpivJ2E7o1fGBplpIwZhG9hbx9R308bKen6+YhNfG53M/VePtrqcbnv4unHYLxjAw0vXs7PmmNXlhJQlDifj0hKYnKEBZp3RRh9k2oLOPt15SIPOvFR3spH5C0tI7hvHn+bmhOQY6tjoKJ6+I5c+cdHMX1iq4Wde2rr/KOUV9RTYNcDsXLTRB6Hb8lxBZ0t0r75Lra2GB4vKOXDUFVYWyvkmaYnxPDk3h121x3l4mYafeWNxsSvAbJYGmJ2TNvoglJHUm6+NTtGgMy8899FXrNpaw79dP4GcoYEPK/O1i0cl8/3pY3mzvIq/fq7hZ+dyurmF19dVMn1CWkj/gg8EbfRBqsCeSVV9A2s06KxTn+48yH++v40bs9L5l4susLocn7nn8pFcPW4w//H2Zkr3HbG6nKD14eYajpxsYo5dx853RRt9kLpmQioDNOisU/vrXWFlI1L68etbJ4fV8dmoKOGJgmzSEuO5b1EphzX/yKMih5P0xHi+pgFmXdJGH6R6xUQzKyeDDzTo7CxtYWWnmlp4/s5c+gZBWJmvJfaJ5bl5eRw80cj9r67TQ3gdVNWd4uMdGmDmLW30Qawt6Ox1DTr7J79+ZyuOvUf49W1TGDU4eMLKfG1SRiK/uGkin+w4yJN/22F1OUFlaUkFxsDsPB077w1t9EFs/JD+TMlMZHGxU0dguK3cUM2La3bzzYsuiIgLi+bm27gtN5MnV+3g79tqrC4nKLS2GopKnFw8UgPMvKWNPsjNsdvYuv8YGys16GxX7XF+9Np6sm1J/PT6CVaXExAiwn/MmsTY1AQeWFxGpYaf8cXuQzgPn9I44m7QRh/kbspKdwWdOfZZXYqlTjY2c8/CUmKjhWfm5RIXEzn/dV3hZ3m0uMPPTjdHdg5SUbErwGzGpDSrSwkZkfNpCVGJvWO5blIab5RVRWzQmTGGf1u+ke01x/jT3BwyknpbXVLADU/uy+/mTKHcWcfjb0du+Fn9qSbe2bifm7M1wKw7tNGHgIJ8G8camnl3436rS7HEy2v3sWxdJQ9cPYbLxkTuULoZk4bwf782nL9+vjdi70S2otwdYGYfanUpIUUbfQiYNtwVdBaJOfXrK+r4xYrNXD4mhe9cNcrqciz3oxnjyB82gIeXbmDHgcgLPysqdgWYTcrob3UpIUUbfQiIihIK8mx8vusQ+w5FTtBZ3clG7llYSkpCL/5YmE2Ujpc+E37Wt1cM8xeWcDyCws82Vx1lQ2U9hfkaYNZd3tx45CURqRERj3eHEpErRKReRMrcj0fazZshIttEZKeIPOzLwiPNmaCzksjYq29tNTywuIyaY66wsgGaZXJGav94nro9h90HT/DQ0vURM/S2yOEkLjqKWXqfhm7zZo/+L8CMLpb5xBiT7X48CiAi0cAzuG4MPgG4XUQiY0ycH6Qn9eayCAo6e2b1Tv6+rZZHbphAti3J6nKCzkUjB/GDa8fy9vpq/vLZHqvL8bvTzS28XlbJNRNT9Zd+D3TZ6I0xHwOHe/DeU4GdxphdxphG4FXg5h68j3IrsNuorm/gkx21VpfiV2t2HOSJD7dzc3Y6d04Ln7AyX5t/2Ui+Pj6Vx9/eQsne8A4/+2DzAepONunY+R7y1TH6i0SkXETeEZGJ7mkZQPvjDBXuaR6JyN0i4hARR21teDeynvr6hMEM6BPLEkeF1aX4TXX9Kb776jpGpfTjV2EWVuZrUVHCfxZkkZ7Um/teLuXQ8dNWl+Q3RY4K0hPjuXRUstWlhCRfNPpS4AJjTBbwFPB6T97EGPOCMcZujLGnpETuELpz6RUTzS05mby/eX9YJho2NreyYFEpp5taeO7OPPrEhV9Yma8l9o7l2Xm5HDrRyP2vloXlYb3KulN8sqOW2XabBpj10Hk3emPMUWPMcffzlUCsiCQDlUD771mZ7mnqPBTkZ9LUYnh9Xfhtyl+9s4XSfXX8ZvYURg3uZ3U5IWNSRiKP3TyRNTsP8qcPt1tdjs+1BZjNydPc+Z4670YvImni/n4tIlPd73kIKAZGi8hwEYkD5gIrznd9kW5cWn+yMhMpcoRX0Nlb66v470/38K2Lh3HDlPAPK/O1wvyhzMnL5MlVO1kdRuFnra2GIoeTS0YNwjZQA8x6ypvhla8AnwNjRaRCRO4SkfkiMt+9yGxgo4iUA08Cc41LM3Af8B6wBSgyxmzyz48RWdqCzjZU1ltdik/srDnOQ6+tJ3doEj+ZOd7qckLWY7MmMX5If763uIyKI+FxvcUXuw5RcUQDzM6XN6NubjfGDDHGxBpjMo0xLxpjnjfGPO+e/7QxZqIxJssYM80Y81m71640xowxxow0xjzuzx8kktyU7Q46C4MrZU82NnPvohJ6xUZHXFiZr8XHRvPcvNywCj9b7HDSPz6GaydqgNn50E9VCOofH8vMyUNYUVbFqcbQ/TAbY/jJsg3sqDnOk3NzGJIYeWFlvjYsuS+/L8hifUU9j7212epyzkv9ybYAswwNMDtP2uhDVIHdxrHTzby7qdrqUnps4Zf7eL2sige/PoZLR+uwOV+5dmIa/3rZCBZ+sS+kT9qvKK+ksbmVwnw9bHO+tNGHqAuHD2TowD4he/im3FnHY29u5sqxKSy4UsPKfO2H145l6vCB/HjZBraHaPjZYoeT8UP6MzFdA8zOlzb6EBUVJRTYM/li12H2HjphdTndcuREI/cucoWV/UHDyvwiJjqKp2/PCdnws01V9WysPEqhPVMvmvMBbfQh7La8TKKEkLpSti2srPbYaZ67M5ekPppb4i+D+8fz9B057D10kodeC63wsyWOCuKio7hZA8x8Qht9CBuS2JvLxoRW0NlTq3by0fZaHrlxAlMyk6wuJ+xNGzGIH107lrc3VPPSp3usLscrDU0tLF9XyXQNMPMZbfQhrsBuY//RBj4OgaCzj7fX8se/beeWnAzmXah3CAqUuy8bwfQJqfxq5RYce3qSTxhYH2w+QP0pDTDzJW30Ie7r41MZ2DeOJY7gPilbVXeK+19dx+jB/Xj8lkl63DWARITfzckiY0BvFrxcysEgDz8rcjjJSOqtAWY+pI0+xMXFRHFLTgYfbD4QtOmFjc2t3LuolKYWo2FlFknsHctz8/KoO9nE/a+uC9pDfRVHTrJm50Fm52XqSXof0kYfBgrsNlfQWVmV1aV49MuVWyhz1vHb2VMYmaJhZVaZkN6fx2ZN4tOdh/jDB8EZfra0xDXuf7YGmPmUNvowMDYtgSxbEkXFwRd0tqK8ir98toe7Lh3OzMlDrC4n4hXYbRTabTy9eierth6wupx/0tpqWFLi5JKRyRpg5mPa6MNEgT2TbQeOUV4RPEFnO2uO8fDS9dgvGMDD142zuhzl9oubJzJhSH++t7gc5+HgCT/77CtXgNkcu+7N+5o2+jBxY1Y68bFRFAXJSdkTp5uZv7CUPnHRPH1HLrHR+l8tWMTHRvP8nXm0Glf4WUNTcOQlFWmAmd/opy9M9I+PZeakIbwZBEFnxhh+vGwDu2pdYWVpifGW1qPONnRQH54oyGZDZT2PBkH4Wf3JJt7dtJ9ZORpg5g/a6MNIQb4r6OydjdYGnf3vF3tZUV7F96eP5WIdIhe0rpmQyvzLR/Lyl/tYVmrt1dVvuAPMdOy8f2ijDyMXDh/IBYOsDTpbt+8Ij721mavHDeaey0daVofyzg+mj2HaiIH8ZPkGtu4/alkdi4udTBjSn0kZiZbVEM68ucPUSyJSIyIbO5k/T0TWi8gGEflMRLLazdvjnl4mIg5fFq7OJiIU2G18ufswew4GPujs8IlGFiwqJbV/PE8UaFhZKIiJjuLJ23PoHx/LPQtLOdbQFPAaNlbWs6nqqMYR+5E3e/R/AWacY/5u4HJjzGTgMeCFDvOvNMZkG2PsPStRdcdtue6gs5LA7tW3uMPKDh5v5Ll5eST2iQ3o+lXPDU6I5+k7ctl3+CQ/siD8bInDSVxMFDdn672C/cWbWwl+DHQakGGM+cwYc8T91y8AHRtlobTEeC63IOjsqVU7+Hh7Lf9+00QmZ+rX71AzdfhAHp4xjnc27ufFNbsDtt6GphZeL6vi2olpmmTqR74+Rn8X8E67vxvgfREpEZG7z/VCEblbRBwi4qitDf6ArmBWmG/jwNHTfLw9MNvx79tq+NPfdnBrbga3T9Wv36Hq218bzoyJafzqna0UByj87H13gFmhnoT1K581ehG5Elejf6jd5EuNMbnAdcACEbmss9cbY14wxtiNMfaUlBRflRWRrhqXyqC+cQEZU19Zd4oHFpcxNjWBx2dN1rCyECYi/HbOFGwDerNgUSm1x/yfnbTEHWB28chBfl9XJPNJoxeRKcCfgZuNMYfaphtjKt1/1gDLgam+WJ86t7agsw+3+Dfo7HRzC/cuKqXFHVbWO07HP4e6/vGxPHdnHkcbmvjuK+tobmn127raAszm2DXAzN/Ou9GLyFBgGfANY8z2dtP7ikhC23NgOuBx5I7yvYJ8V9DZcj/eHPrxt7dQ7qzjd3OmMDy5r9/WowJr/JD+/MesyXy+6xBP+DH8rO3OaBpg5n/eDK98BfgcGCsiFSJyl4jMF5H57kUeAQYBz3YYRpkKrBGRcmAt8LYx5l0//AzKgzGpCWTbkljsp6CzN8oq+evne/m/XxvOjEkaVhZuZudlcvtUG8/+/Ss+3Oz78LPWVsNrJRVcOiqZzAEaYOZvXQaDG2Nu72L+t4Fve5i+C8g6+xUqUArsNn6yfANlzjpyhg7w2fvuOHCMh5duIH/YAH40Q8PKwtXPb5zIhsp6Hiwq463vfI2hg3zXkD/96iCVdad4SMPuAkKvjA1jN2YNcQed+e7y9uOnm5m/sIS+vWI0rCzMxcdG89y8PADufbnEp+FnRY4KEnvHMn1Cqs/eU3VOP6VhLCE+lpmTh/BmeRUnG5vP+/2MMTy8dD27D57gqdtzSO2vYWXhzjawD38ozGZj5VF+8eYmn7xn3clG3tu0n1nZ6RpgFiDa6MNcod3G8dPNvLNh/3m/1/98toe31lfzg2vHcpEOh4sYV49P5d4rRvLKWievlZz/t8M3yqpcAWYaeRAw2ujD3NThAxk2qA+Lz3NMfem+Izy+cgtfHz+Y+ZdpWFmkefCaMVw0YhA/Xb6BLdXnF362uNjJxPT+TEzXK6gDRRt9mBMR5thtrN19mN09DDo7dPw0CxaVkpYYz3/O0bCySNQWfpbYO5Z7FpZwtIfhZxsr69lcrQFmgaaNPgKcCTrrwV59W1jZoRMaVhbpUhJ68ey8XCqOnOJHS3oWflbUFmCWleGHClVntNFHgLTEeK4YO5ilpRXdvtLxT3/bwSc7DvLoTRM1K1xhHzaQh68bx7ub9vPnT7oXftbQ1MLr6yqZMTFNdxgCTBt9hCiwu4POdngfdLZ6Ww1PrdrBnLxM/aqtzrjr0uHMnJzGr9/dytrd3oefvbdpP0cbmvX/kgW00UeIq8YNdgWdFXs3aqLiyEm+t7iMcWn9eWzWJA0rU2eICL+5bQoXDOzDgpdLqTnW4NXrljgqyBzQm4tG6IitQNNGHyHiYqK4NdcVdHawi6Czfworm5erY53VWRLiY3n2zlyONTTxnZe7Dj9zHnYHmOXZ9GS+BbTRR5ACu43mVsPy0nMHnT321mbWV9Tz+4IshmlYmerEuLT+/PKWyXy5+zC/f//c4WdLSioQgdl2DTCzgjb6CDI6NYGcoUkUOToPOnt9XSULv9jHv142gmsnpgW4QhVqbs3N5I4Lh/L8R1/xQSfhZy2thtccTi4dlUxGUu8AV6hAG33EKbDb2FFznHXOurPmbT9wjB8v28DU4QP54bVjA1+cCkmP3DCByRmJPFhUxt5DZ1+r8enOg1TVN1Cgd5GyjDb6CHPDlCH0jo0+a0z9P4WV3Z5DjIaVKS/Fx0bz7LxcokS4Z2HpWeFnRQ4nSX1imT5RA8ysop/mCPOPoLPqM0Fnxhgeem09ew+d5Ok7chisYWWqm1zhZ1lsrj7Kz9/4R/jZkRONvL/pALOyM+gVoyf1raKNPgIV5ruCzla6g87++9M9vL2hmh9eO5ZpOvRN9dBV41K578pRLHY4z9yv+I2yShpbWvWwjcW8avQi8pKI1IiIx1sBisuTIrJTRNaLSG67ed8UkR3uxzd9VbjqufxhAxie3JeiYiclew/zy5VbuGZCKv962QirS1Mh7nvXjOGSUYP42esb2VRVz2JHBZMy+jMhvb/VpUU0b/fo/wLMOMf864DR7sfdwHMAIjIQ+DlwIa4bg/9cRHx3qyPVI66gs0zW7jnMv/5vCRkDevP7OVl6UZQ6b9FRwp/m5jCgTxzffGktW6qPUqh785bzqtEbYz4GznWt883AX43LF0CSiAwBrgU+MMYcNsYcAT7g3L8wVIC0BZ0da2jm2Xm5JPbW7BHlG8n9evHMvFzqTjYRFxPFTRpgZrku7xnrpQyg/TCOCve0zqafRUTuxvVtgKFDh/qoLNWZ1P7x/MesyaQnxWsuuPK5vAsG8My8XI43NGuAWRDwVaM/b8aYF4AXAOx2e/fzT1W33XGh/kJV/qMX3AUPX426qQTaH4jLdE/rbLpSSqkA8VWjXwH8i3v0zTSg3hhTDbwHTBeRAe6TsNPd05RSSgWIV4duROQV4AogWUQqcI2kiQUwxjwPrARmAjuBk8D/cc87LCKPAcXut3rUGON9gLVSSqnz5lWjN8bc3sV8AyzoZN5LwEvdL00ppZQv6JWxSikV5rTRK6VUmNNGr5RSYU4bvVJKhTnp7E5DVhKRWmBvD1+eDBz0YTm+onV1j9bVPVpX94RjXRcYY1I8zQjKRn8+RMRhjLFbXUdHWlf3aF3do3V1T6TVpYdulFIqzGmjV0qpMBeOjf4FqwvohNbVPVpX92hd3RNRdYXdMXqllFL/LBz36JVSSrWjjV4ppcJcyDZ6EZkhItvcNyR/2MP8XiKy2D3/SxEZFiR1fUtEakWkzP34dgBq6vHN3S2u6woRqW+3rR4JUF02EVktIptFZJOI3O9hmYBvMy/rCvg2E5F4EVkrIuXuun7hYZmAfx69rCvgn8d2644WkXUi8paHeb7dXsaYkHsA0cBXwAggDigHJnRY5l7geffzucDiIKnrW8DTAd5elwG5wMZO5s8E3gEEmAZ8GSR1XQG8ZcH/ryFArvt5ArDdw79jwLeZl3UFfJu5t0E/9/NY4EtgWodlrPg8elNXwD+P7db9IPCyp38vX2+vUN2jnwrsNMbsMsY0Aq/iukF5ezcD/+N+/hpwtYhIENQVcKbnN3e3ui5LGGOqjTGl7ufHgC2cfa/jgG8zL+sKOPc2OO7+a6z70XGUR8A/j17WZQkRyQSuB/7cySI+3V6h2ui9uen4mWWMMc1APTAoCOoCuM39df81EbF5mB9oXt/E3QIXub96vyMiEwO9cvdX5hxce4PtWbrNzlEXWLDN3IchyoAa4ANjTKfbK4CfR2/qAms+j38EfgS0djLfp9srVBt9KHsTGGaMmQJ8wD9+a6uzleLK78gCngJeD+TKRaQfsBR4wBhzNJDrPpcu6rJkmxljWowx2bjuCz1VRCYFYr1d8aKugH8eReQGoMYYU+LvdbUJ1UbvzU3HzywjIjFAInDI6rqMMYeMMafdf/0zkOfnmrwRlDdxN8YcbfvqbYxZCcSKSHIg1i0isbia6SJjzDIPi1iyzbqqy8pt5l5nHbAamNFhlhWfxy7rsujzeAlwk4jswXV49yoRWdhhGZ9ur1Bt9MXAaBEZLiJxuE5WrOiwzArgm+7ns4FVxn1mw8q6OhzHvQnXcVardXZzd0uJSFrbcUkRmYrr/6vfm4N7nS8CW4wxT3SyWMC3mTd1WbHNRCRFRJLcz3sD1wBbOywW8M+jN3VZ8Xk0xvzYGJNpjBmGq0esMsbc2WExn24vr+4ZG2yMMc0ich/wHq6RLi8ZYzaJyKOAwxizAtcH4n9FZCeuE35zg6Su74rITUCzu65v+bsu6eHN3YOgrtnAPSLSDJwC5gbglzW49ri+AWxwH98F+AkwtF1tVmwzb+qyYpsNAf5HRKJx/WIpMsa8ZfXn0cu6Av557Iw/t5dGICilVJgL1UM3SimlvKSNXimlwpw2eqWUCnPa6JVSKsxpo1dKqTCnjV4ppcKcNnqllApz/x/DWDiRyii/5AAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "plt.plot([3,1,2,1,3])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "[공식 홈페이지](https://jupyterbook.org/interactive/interactive.html#plotly)를 참고하여 interactive한 시각화도 가능합니다. " - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# .ipynb 파일 활용" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jupyter Book에선 .ipynb파일 또한 지원합니다. 아래와 같이 코드를 입력하고, 그에 대응하는 출력물을 함께 웹페이지로 구성 가능합니다. " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Il7ecAAAACXBIWXMAAAsTAAALEwEAmpwYAAA0BklEQVR4nO3deXxU9b3/8dcnG2EJCZCQkGSQfYdsE8SlrhURN1RIUOxtfw/786LYau2ibW/trV67X9u6X3/V29sLKkFAUXEtVMWNTELCvsk2WSBhSVhDtu/vj5nQNEzIJMzMmeXzfDzmwXDOmTmfHJhPzpzzPe8jxhiUUkqFryirC1BKKeVf2uiVUirMaaNXSqkwp41eKaXCnDZ6pZQKczFWF+BJcnKyGTZsmNVlKKVUyCgpKTlojEnxNC8oG/2wYcNwOBxWl6GUUiFDRPZ2Nk8P3SilVJjTRq+UUmFOG71SSoU5bfRKKRXmtNErpVSY67LRi0i8iKwVkXIR2SQiv/CwTC8RWSwiO0XkSxEZ1m7ej93Tt4nItT6uXymlVBe82aM/DVxljMkCsoEZIjKtwzJ3AUeMMaOAPwC/ARCRCcBcYCIwA3hWRKJ9VLtSSikvdNnojctx919j3Y+O2cY3A//jfv4acLWIiHv6q8aY08aY3cBOYKpPKu+goamFFz7+is++OuiPt1dKKb9avbWGl9bsprG51efv7dUxehGJFpEyoAb4wBjzZYdFMgAngDGmGagHBrWf7lbhnuZpHXeLiENEHLW1td36IQBiooQ/f7Kbl9bs7vZrlVLKas9/9BV//XwPsdHi8/f2qtEbY1qMMdlAJjBVRCb5uhBjzAvGGLsxxp6S4vEq3nOKiY7itrxMVm+rpeZog6/LU0opv9lz8ARf7j7MHLsN18EQ3+rWqBtjTB2wGtfx9vYqARuAiMQAicCh9tPdMt3T/GJOXiYtrYalpX5bhVJK+dySEidRArflZvrl/b0ZdZMiIknu572Ba4CtHRZbAXzT/Xw2sMq47lG4ApjrHpUzHBgNrPVR7WcZkdKPqcMGssThRG+RqJQKBS2thtdKKrhi7GDSEuP9sg5v9uiHAKtFZD1QjOsY/Vsi8qiI3ORe5kVgkIjsBB4EHgYwxmwCioDNwLvAAmNMi69/iPbm2DPZdfAEjr1H/LkapZTyiY+313Lg6GkK7P7Zmwcv0iuNMeuBHA/TH2n3vAGY08nrHwceP48au+X6KUP49xWbKCp2kj9sYKBWq5RSPVLkcDKobxxXjUv12zrC7srYPnEx3JiVztsbqjl+utnqcpRSqlOHjp/mwy0HuCUng7gY/7XjsGv0AAX5Nk42tvD2+iqrS1FKqU4tX1dJU4uhIN/W9cLnISwbfY4tiVGD+7G42Nn1wkopZQFjDEUOJ9m2JMakJvh1XWHZ6EWEQruN0n117Kw5ZnU5Sil1ljJnHdsPHKfQz3vzEKaNHuCW3AxiooQiR4XVpSil1FmKHBX0jo3mhilD/L6usG30yf16cfX4wSwrraCpxffZEUop1VMnG5t5s7yKmZOHkBAf6/f1hW2jByiw2zh4vJFVW2usLkUppc54Z8N+jp9u9uvY+fbCutFfPiaFwQm9KNKTskqpILLY4WR4cl+mDg/MtT5h3ehjoqOYnZfJ6m01HNCgM6VUENh98ARrdx9mjj3TLwFmnoR1oweYY7fRamBpqZ6UVUpZb4nDvwFmnoR9o2/7erTEUaFBZ0opSzW3tLK0tIIrxw4mtb9/Asw8CftGD66TsrsPnqB4jwadKaWs8/EOV4DZHLv/x863FxGNfubkNPr1iqHIoSdllVLWKSquILlfHFePHxzQ9UZEo3cFnQ3h7fXVHGtosrocpVQEOtguwCw2OrCtNyIaPbgO35xqauGt9dVWl6KUikDLSytpbjUUBPiwDURQo8+2JTF6cD89fKOUCri2ALOcoUmM9nOAmSfe3ErQJiKrRWSziGwSkfs9LPNDESlzPzaKSIuIDHTP2yMiG9zzHP74IbwhIhTm21i3r44dBzToTCkVOOucdeyoOU6hBXvz4N0efTPwfWPMBGAasEBEJrRfwBjzO2NMtjEmG/gx8JEx5nC7Ra50z7f7qvCemJXTFnSme/VKqcBZ4nDSOzaa6wMQYOZJl43eGFNtjCl1Pz8GbAEyzvGS24FXfFOebyX368XXx6eyrLSSxmYNOlNK+Z8rwKya66cEJsDMk24doxeRYbjuH/tlJ/P7ADOApe0mG+B9ESkRkbvP8d53i4hDRBy1tbXdKatbCvIzOXRCg86UUoGx8kyAmTWHbaAbjV5E+uFq4A8YY452stiNwKcdDttcaozJBa7DddjnMk8vNMa8YIyxG2PsKSkp3pbVbZeNTiG1fy89fKOUCoiiYicjkvuSP2yAZTV41ehFJBZXk19kjFl2jkXn0uGwjTGm0v1nDbAcmNqzUn2jLejs7xp0ppTys121x1m75zBz7LaABZh54s2oGwFeBLYYY544x3KJwOXAG+2m9RWRhLbnwHRg4/kWfb7m5LmCzl4r0aAzpZT/LCmpIDpKuC33XKc1/c+bPfpLgG8AV7UbQjlTROaLyPx2y90CvG+MOdFuWiqwRkTKgbXA28aYd31WfQ8NS+7LhcMHssTh1KAzpZRfNLe0srSkgivHpjA4gAFmnsR0tYAxZg3Q5XcOY8xfgL90mLYLyOphbX5VYLfx/SXlrN19mAtHDLK6HKVUmPloey01xwIfYOZJxFwZ29HMyUPo1yuGxXpSVinlB4uLnST3i+OqcYENMPMkYht977hobsxKZ+UGDTpTSvlW7bHTrNpaw625mQEPMPPE+gosVJhvo6GplTfLNehMKeU7y9dVuAPMAncXqXOJ6EaflZnImFQNOlNK+Y4rwKyC3KFJjBoc+AAzTyK60YsIBXYbZc46tmvQmVLKB0r31bGz5jiF+dafhG0T0Y0ecN8EQCgq1r16pdT5W+Jw0icumuunpFtdyhkR3+gHtQWdrdOgM6XU+Tlxupk3y6u43j2qL1hEfKMHKMi3cfhEI6u2HrC6FKVUCFu5oZoTjS1BddgGtNEDrqCztP7xLNbDN0qp81DkcDIipS95F1gXYOaJNnogOkqYnZfJR9tr2V+vQWdKqe7bVXuc4j1HKLA4wMwTbfRuc+yZtBpYWqpBZ0qp7ityuALMbrU4wMwTbfRuFwzqy7QRAylyOGlt1aAzpZT3mltaWVpawZVjBzM4wdoAM0+00bdTYLex99BJ1u453PXCSinl9vdttdQeOx00V8J2pI2+nesmDSGhV4yOqVdKdctih5Pkfr24MggCzDzRRt9O77hobsxOZ+XGao5q0JlSygs1xxpYtbWG23IzgiLAzJPgrMpChfa2oLMqq0tRSoWA5aWVtLSaoMid74w3txK0ichqEdksIptE5H4Py1whIvXt7kD1SLt5M0Rkm4jsFJGHff0D+NqUzETGpiZQ5NDRN0qpc3MFmDnJu2AAowb3s7qcTnmzR98MfN8YMwGYBiwQkQkelvvEGJPtfjwKICLRwDPAdcAE4PZOXhs0RISCfBvlzjq27degM6VU50r3HeGr2hMUBvHePHjR6I0x1caYUvfzY8AWwNuBolOBncaYXcaYRuBV4OaeFhsoZ4LONL5YKXUORcUV9ImLZuaUIVaXck7dOkYvIsOAHOBLD7MvEpFyEXlHRCa6p2UA7btlBZ38khCRu0XEISKO2tra7pTlcwP7xnHNhFSWa9CZUqoTJ04389b6Km6YElwBZp543ehFpB+wFHjAGHO0w+xS4AJjTBbwFPB6dwsxxrxgjLEbY+wpKSndfbnPFdhdQWd/26JBZ0qps70dpAFmnnjV6EUkFleTX2SMWdZxvjHmqDHmuPv5SiBWRJKBSqD9Vsh0Twt6XxudwpDEeL15uFLKo6JiV4BZ7tDgCjDzxJtRNwK8CGwxxjzRyTJp7uUQkanu9z0EFAOjRWS4iMQBc4EVviren9qCzj7eXkt1/Smry1FKBZGdNcdx7D1CYRAGmHnizR79JcA3gKvaDZ+cKSLzRWS+e5nZwEYRKQeeBOYal2bgPuA9XCdxi4wxm/zwc/jFnDybK+isRIdaKqX+YUmJk+go4ZYgDDDzpMszCMaYNcA5f2UZY54Gnu5k3kpgZY+qs9jQQX24aMQgihwV3HvFKKKigv83t1LKv5paWllaUslV44IzwMwTvTK2CwX5mew7fJIvd2vQmVLKFWB28PhpCoJ87Hx72ui7cN2kISTEx+iYeqUUAIuLnaQk9OLKsdaPDvSWNvouxMdGc1NWOis3aNCZUpGu5lgDq7fVcGtuBjFBGmDmSehUaqHCfBunm1tZUaZBZ0pFsmXuALNQOmwD2ui9MjkjkXFpCSzRwzdKRay2ADP7BQMYmRK8AWaeaKP3gohQYLdRXlHP1v0dLwpWSkWCkr1H2FV7goIQuBK2I230XprVFnRWrGPqlYpERQ4nfeOiuX5ycAeYeaKN3ksD+8YxfUIay9dVcLq5xepylFIBdPx0M2+tr+aGKen0DfIAM0+00XdDQb6NIyeb+HBzjdWlKKUC6O31VZxsbAnJwzagjb5bLh2VTHpivI6pVyrCFDkqGJnSl9yhSVaX0iPa6LvhTNDZjlqq6jToTKlIsLPmGCV7j1CYHxoBZp5oo++m2Xk2jAadKRUxljgqiIkSbsnJtLqUHtNG301DB/Xh4pGDKCpx0tpqrC5HKeVHTS2tLC2t4Kpxg0lJ6GV1OT2mjb4HCuw2nIdP8cXuQ1aXopTyo9Vbazh4vDHkroTtSBt9D8yYlOYKOivWk7JKhbMihyvA7IoQCjDzxJs7TNlEZLWIbBaRTSJyv4dl5onIehHZICKfiUhWu3l73NPLRMTh6x/ACvGx0dycnc47G/dTf0qDzpQKRzVHG1i9rZbbcjNDKsDME2+qbwa+b4yZAEwDFojIhA7L7AYuN8ZMBh4DXugw/0pjTLYxxn7eFQeJQvtQV9BZuQadKRWOlp4JMAvdk7Btumz0xphqY0yp+/kxXLcEzOiwzGfGmCPuv36B6ybgYW1SRn8NOlMqTBljWOJwkj9sACNCLMDMk259HxGRYUAO8OU5FrsLeKfd3w3wvoiUiMjd53jvu0XEISKO2tra7pRlCRGhMN/G+op6tlRr0JlS4cSx9wi7Dp4I+ZOwbbxu9CLSD1gKPGCM8djZRORKXI3+oXaTLzXG5ALX4Trsc5mn1xpjXjDG2I0x9pSU0DjxMSs7g7joKL1SVqkwU1TsDjCbEnoBZp541ehFJBZXk19kjFnWyTJTgD8DNxtjzow7NMZUuv+sAZYDU8+36GAxoG8c10xMZfm6Sg06UypMHD/dzNsbqrkxK50+caEXYOaJN6NuBHgR2GKMeaKTZYYCy4BvGGO2t5veV0QS2p4D04GNvig8WBTabdSdbOKDzQesLkUp5QNvlYd2gJkn3vy6ugT4BrBBRMrc034CDAUwxjwPPAIMAp51Z0E0u0fYpALL3dNigJeNMe/68gew2iVngs4quGFKutXlKKXOU5HDyajB/cixJVldis902eiNMWuAcyb5GGO+DXzbw/RdQNbZrwgf0VHCbLuNp1btoLLuFBlJva0uSSnVQztrjlG6r46fzhwfsgFmnoT2VQBBYk5epgadKRUGitoCzHIzul44hGij9wHbwD5cMmoQRQ4NOlMqVDW1tLKstIKrxw8muV/oBph5oo3eRwrsNiqOnOKLXRp0plQoWhUmAWaeaKP3kWsnptE/PobFOqZeqZBUVOxkcEIvLh8TGtfxdIc2eh9xBZ1luILOTmrQmVKh5MDRBlZvq+G2vNAPMPMk/H4iCxXm22hsbmVFeaXVpSilumFpaQWthrA8bAPa6H1qYnp/xg/pT5FDR98oFSpcAWYVTB02kOHJfa0uxy+00fuQiFBoz2RDZT2bqzToTKlQULznCLsPngirK2E70kbvY7NyNOhMqVCyuNhJv14xzJycZnUpfqON3seS+sQx3R101tCkQWdKBbNjDU2s3FDNjVlDwibAzBNt9H5QmG+j/pQGnSkV7N5aX82pppawPQnbRhu9H1wyMpmMpN56+EapIFfkcDJ6cD+ywyjAzBNt9H4QFSXMzstkzc6DVBw5aXU5SikPdhw4xrp9dRTm28IqwMwTbfR+MjvPddvcpSU6pl6pYFTkcBITJczKCa8AM0+00fuJbWAfLhmZzJISDTpTKtg0NreyrLSSr49PDbsAM0+00fvRHHsmFUdO8bkGnSkVVFZtreHQiUYK8jOtLiUgvLmVoE1EVovIZhHZJCL3e1hGRORJEdkpIutFJLfdvG+KyA7345u+/gGC2Zmgs2I9KatUMClyOEnt34vLRodfgJkn3uzRNwPfN8ZMAKYBC0RkQodlrgNGux93A88BiMhA4OfAhbhuCv5zERngo9qDXnxsNLNyMnh3kwadKRUsDhxt4O/bargtNzwDzDzp8qc0xlQbY0rdz48BW4COZy9uBv5qXL4AkkRkCHAt8IEx5rAx5gjwATDDpz9BkCuwu4LO3tCgs5C3uHgfr6/Tf8dQ91pJeAeYedKtS8FEZBiQA3zZYVYG0P74RIV7WmfTPb333bi+DTB06NDulBXUJmUkMjG9P4uLnfzLRcOsLkf10AebD/DQ0g1ECaQk9OKSUclWl6R6wBVg5mTq8IEMC9MAM0+8/t4iIv2ApcADxhifJ3YZY14wxtiNMfaUlPA6blZgt7Gp6igbK+utLkX1wN5DJ3iwqIxJGf0ZmdKP776yjv31DVaXpXpg7e7D7Dl0ksII2psHLxu9iMTiavKLjDHLPCxSCbTfcpnuaZ1Njyg3Z6cTFxPFEr1SNuQ0NLVwz8JSokR4bl4ez92Zy6mmFu57uZSmllary1PdtNjRFmA2xOpSAsqbUTcCvAhsMcY80cliK4B/cY++mQbUG2OqgfeA6SIywH0Sdrp7WkRJ6hPHtRPTeL2sSoPOQszP39jE5uqj/KEwC9vAPowanMBvbpuCY+8Rfv3OVqvLU93wjwCzdHrHRVtdTkB5s0d/CfAN4CoRKXM/ZorIfBGZ715mJbAL2An8P+BeAGPMYeAxoNj9eNQ9LeIU2l1BZ+9r0FnIKCp2stjhZMGVI7lqXOqZ6TdmpfOti4fx4prdrNxQbWGFqjveLK+moamVwjDOne9MlydjjTFrgHMGQRhjDLCgk3kvAS/1qLowcvHIQWQk9WaJw8lNWelWl6O6sKmqnp+9sZGLRw7iwWvGnjX/JzPHU15Rxw+XlDM2LYGRKf0sqFJ1R5HDyZjUfmRlJlpdSsBFxiDSIBAVJcyxa9BZKKg/1cQ9C0tJ6hPLk7fnEB119n5OXEwUz9yRS6/YaO5ZWMLJxmYLKlXe2n7gGGXOOgrs4R9g5ok2+gBqCzp7rUTvKRusjDH8YEk5VXWneOaO3HPmoKQn9eZPc7PZUXOcny7fiOuLrQpGRcVOYqOFWyIgwMwTbfQBlDmgD5eOSmaJo0KDzoLUf328iw82H+Dh68ZhHzawy+W/NjqFB64ew/J1lSz6cl8AKlTd1djcyrJ1rgCzQREQYOaJNvoAm2O3UVl3is++0qCzYPPFrkP89t2tzJycxl2XDvf6dd+5ahSXj0nh0Tc3s76izn8Fqh5ZtfUAh080RtSVsB1pow+w6RNSSewdy2IdUx9Uao42cN/L6xg2qC+/uW1Kt47jRkUJfyzMJiWhF/csLOXIiUY/Vqq6a3Gxk7T+8Vw2JrwuxOwObfQBFh8bzazsdN7btJ+6k9oQgkFzSyv3vbKOE6ebee7OPBLiY7v9HgP6xvHsvFxqj53me0VlemguSOyvb+Cj7bXclpfh8aR6pNBGb4GCfHfQWVmV1aUo4HfvbWPt7sP88tZJjE1L6PH7ZNmS+NmNE/j7tlqeWb3ThxWqnlpaGnkBZp5oo7fAxPREJmX015z6IPDepv3818e7mHfhUG7JOf+bUNx54VBmZafzxIfbWbPjoA8qVD3V2moocjiZNmIgFwyKnAAzT7TRW6TAbmNztQadWWnPwRP8oKicKZmJPHJjx1ss9IyI8MtbJzN6cD++++o6qutP+eR9Vfet3XOYvYdORvzePGijt8zNWRnExURRpCdlLdHQ1MI9i0qJihLXhU8xvss+6RMXw3N35nG6qYUFi0ppbNbwMysUFTtJ6BXDdZMiK8DME230FknsE8uMiWm8vq5Sg84s8LPXN7Kl+ih/LMzGNrCPz99/ZEo/fjs7i9J9dfzqnS0+f391bkcbmli5sZobsyMvwMwTbfQWKsy3cbShmfc27be6lIiyuHgfS0oq+M5Vo7hy3GC/ref6KUP4P5cM478/3cNb6/XEeyC9WV7lCjDTwzaANnpLXTRiEJkDerPEoZEIgbKxsp6fvbGJS0cl88DXx/h9fT++bjy5Q5N46LX17Kw57vf1KZciRwVjUxOYEoEBZp5oo7dQVJQwJ8/Gmp0HcR7WoDN/qz/ZxD2LShjYJ44/zc0OyLjquJgonpn3j/CzE6c1/Mzftu0/RrmzjoL8yAww80QbvcVm2zMR0aAzf2ttNXx/SRnVdQ08My83oJknQxJ78+TcHHbWHucnyzdo+JmfFTkiO8DME230FstI6s2lo5J5raSCFr2a0m+e//grPtxSw0+vH0/eBQMCvv5LRyfz4NfH8EZZFQu/2Bvw9UeKxuZWlq+r5JoJqQzsG2d1OUHDm1sJviQiNSKysZP5P2x356mNItIiIgPd8/aIyAb3PIeviw8XBe6gs0936gU2/vDZVwf5/XvbuH7KEL518TDL6lhw5SiuHJvCo29tpsxZZ1kd4ezDLa4Aszl6EvafeLNH/xdgRmczjTG/M8ZkG2OygR8DH3W4XeCV7vn286o0jE2fmEpSn1gdU+8HB4428N1X1jE8ufthZb4WFSX8oTCbwQnxLFik4Wf+UORwB5iNjtwAM0+6bPTGmI8Bb+/zejvwynlVFIF6xUQzKzuD9zcd0A+/DzW1tHLfy6WcON3Cc3fm0a9Xl3fO9LukPnE8d6cr/OyBxRp+5kvV9af4eHsts/MyIzrAzBOfHaMXkT649vyXtptsgPdFpERE7u7i9XeLiENEHLW1tb4qK2QU2G00trTyRlml1aWEjd++u5XiPUf49W2TGZPa87AyX5uSmcTPb5rAR9treWqVhp/5ytISDTDrjC9Pxt4IfNrhsM2lxphc4DpggYhc1tmLjTEvGGPsxhh7Skrkfe2akN6fyRmJLHZU6KgMH3h3YzX/75PdfGPaBdycHXyjL+6YOpRbczL449+28/H2yNux8TVXgFkFF40YxNBBvr/SOdT5stHPpcNhG2NMpfvPGmA5MNWH6ws7BfZMtlQfZVPVUatLCWm7D57gh0vWk2VL4t9uGG91OR6JCI/fMpkxgxO4/9V1VNVp+Nn5+HL3YfYdPklB/vknkIYjnzR6EUkELgfeaDetr4gktD0HpgMeR+4ol5uyM+gVE6XxxefhVGML9ywsITpaeOaOHJ+Glfla77honrszl6YWw70afnZeihxOEuI1wKwz3gyvfAX4HBgrIhUicpeIzBeR+e0WuwV43xhzot20VGCNiJQDa4G3jTHv+rL4cJPYO5YZk9J4o0yDznrCGMO/vb6RbQeO8cfCbDIHBP9X+BEp/fjt7CmUOev45UoNP+uJow1NrNxQzU1Z6cTHBu8vdit1OQzBGHO7F8v8BdcwzPbTdgFZPS0sUhXabbxRVsV7m/YH5bHlYPZqsZOlpRV89+rRXDHWf2FlvjZz8hDuunQ4L67ZTe4FA7gpK93qkkLKirIqTje3UpivJ2E7o1fGBplpIwZhG9hbx9R308bKen6+YhNfG53M/VePtrqcbnv4unHYLxjAw0vXs7PmmNXlhJQlDifj0hKYnKEBZp3RRh9k2oLOPt15SIPOvFR3spH5C0tI7hvHn+bmhOQY6tjoKJ6+I5c+cdHMX1iq4Wde2rr/KOUV9RTYNcDsXLTRB6Hb8lxBZ0t0r75Lra2GB4vKOXDUFVYWyvkmaYnxPDk3h121x3l4mYafeWNxsSvAbJYGmJ2TNvoglJHUm6+NTtGgMy8899FXrNpaw79dP4GcoYEPK/O1i0cl8/3pY3mzvIq/fq7hZ+dyurmF19dVMn1CWkj/gg8EbfRBqsCeSVV9A2s06KxTn+48yH++v40bs9L5l4susLocn7nn8pFcPW4w//H2Zkr3HbG6nKD14eYajpxsYo5dx853RRt9kLpmQioDNOisU/vrXWFlI1L68etbJ4fV8dmoKOGJgmzSEuO5b1EphzX/yKMih5P0xHi+pgFmXdJGH6R6xUQzKyeDDzTo7CxtYWWnmlp4/s5c+gZBWJmvJfaJ5bl5eRw80cj9r67TQ3gdVNWd4uMdGmDmLW30Qawt6Ox1DTr7J79+ZyuOvUf49W1TGDU4eMLKfG1SRiK/uGkin+w4yJN/22F1OUFlaUkFxsDsPB077w1t9EFs/JD+TMlMZHGxU0dguK3cUM2La3bzzYsuiIgLi+bm27gtN5MnV+3g79tqrC4nKLS2GopKnFw8UgPMvKWNPsjNsdvYuv8YGys16GxX7XF+9Np6sm1J/PT6CVaXExAiwn/MmsTY1AQeWFxGpYaf8cXuQzgPn9I44m7QRh/kbspKdwWdOfZZXYqlTjY2c8/CUmKjhWfm5RIXEzn/dV3hZ3m0uMPPTjdHdg5SUbErwGzGpDSrSwkZkfNpCVGJvWO5blIab5RVRWzQmTGGf1u+ke01x/jT3BwyknpbXVLADU/uy+/mTKHcWcfjb0du+Fn9qSbe2bifm7M1wKw7tNGHgIJ8G8camnl3436rS7HEy2v3sWxdJQ9cPYbLxkTuULoZk4bwf782nL9+vjdi70S2otwdYGYfanUpIUUbfQiYNtwVdBaJOfXrK+r4xYrNXD4mhe9cNcrqciz3oxnjyB82gIeXbmDHgcgLPysqdgWYTcrob3UpIUUbfQiIihIK8mx8vusQ+w5FTtBZ3clG7llYSkpCL/5YmE2Ujpc+E37Wt1cM8xeWcDyCws82Vx1lQ2U9hfkaYNZd3tx45CURqRERj3eHEpErRKReRMrcj0fazZshIttEZKeIPOzLwiPNmaCzksjYq29tNTywuIyaY66wsgGaZXJGav94nro9h90HT/DQ0vURM/S2yOEkLjqKWXqfhm7zZo/+L8CMLpb5xBiT7X48CiAi0cAzuG4MPgG4XUQiY0ycH6Qn9eayCAo6e2b1Tv6+rZZHbphAti3J6nKCzkUjB/GDa8fy9vpq/vLZHqvL8bvTzS28XlbJNRNT9Zd+D3TZ6I0xHwOHe/DeU4GdxphdxphG4FXg5h68j3IrsNuorm/gkx21VpfiV2t2HOSJD7dzc3Y6d04Ln7AyX5t/2Ui+Pj6Vx9/eQsne8A4/+2DzAepONunY+R7y1TH6i0SkXETeEZGJ7mkZQPvjDBXuaR6JyN0i4hARR21teDeynvr6hMEM6BPLEkeF1aX4TXX9Kb776jpGpfTjV2EWVuZrUVHCfxZkkZ7Um/teLuXQ8dNWl+Q3RY4K0hPjuXRUstWlhCRfNPpS4AJjTBbwFPB6T97EGPOCMcZujLGnpETuELpz6RUTzS05mby/eX9YJho2NreyYFEpp5taeO7OPPrEhV9Yma8l9o7l2Xm5HDrRyP2vloXlYb3KulN8sqOW2XabBpj10Hk3emPMUWPMcffzlUCsiCQDlUD771mZ7mnqPBTkZ9LUYnh9Xfhtyl+9s4XSfXX8ZvYURg3uZ3U5IWNSRiKP3TyRNTsP8qcPt1tdjs+1BZjNydPc+Z4670YvImni/n4tIlPd73kIKAZGi8hwEYkD5gIrznd9kW5cWn+yMhMpcoRX0Nlb66v470/38K2Lh3HDlPAPK/O1wvyhzMnL5MlVO1kdRuFnra2GIoeTS0YNwjZQA8x6ypvhla8AnwNjRaRCRO4SkfkiMt+9yGxgo4iUA08Cc41LM3Af8B6wBSgyxmzyz48RWdqCzjZU1ltdik/srDnOQ6+tJ3doEj+ZOd7qckLWY7MmMX5If763uIyKI+FxvcUXuw5RcUQDzM6XN6NubjfGDDHGxBpjMo0xLxpjnjfGPO+e/7QxZqIxJssYM80Y81m71640xowxxow0xjzuzx8kktyU7Q46C4MrZU82NnPvohJ6xUZHXFiZr8XHRvPcvNywCj9b7HDSPz6GaydqgNn50E9VCOofH8vMyUNYUVbFqcbQ/TAbY/jJsg3sqDnOk3NzGJIYeWFlvjYsuS+/L8hifUU9j7212epyzkv9ybYAswwNMDtP2uhDVIHdxrHTzby7qdrqUnps4Zf7eL2sige/PoZLR+uwOV+5dmIa/3rZCBZ+sS+kT9qvKK+ksbmVwnw9bHO+tNGHqAuHD2TowD4he/im3FnHY29u5sqxKSy4UsPKfO2H145l6vCB/HjZBraHaPjZYoeT8UP6MzFdA8zOlzb6EBUVJRTYM/li12H2HjphdTndcuREI/cucoWV/UHDyvwiJjqKp2/PCdnws01V9WysPEqhPVMvmvMBbfQh7La8TKKEkLpSti2srPbYaZ67M5ekPppb4i+D+8fz9B057D10kodeC63wsyWOCuKio7hZA8x8Qht9CBuS2JvLxoRW0NlTq3by0fZaHrlxAlMyk6wuJ+xNGzGIH107lrc3VPPSp3usLscrDU0tLF9XyXQNMPMZbfQhrsBuY//RBj4OgaCzj7fX8se/beeWnAzmXah3CAqUuy8bwfQJqfxq5RYce3qSTxhYH2w+QP0pDTDzJW30Ie7r41MZ2DeOJY7gPilbVXeK+19dx+jB/Xj8lkl63DWARITfzckiY0BvFrxcysEgDz8rcjjJSOqtAWY+pI0+xMXFRHFLTgYfbD4QtOmFjc2t3LuolKYWo2FlFknsHctz8/KoO9nE/a+uC9pDfRVHTrJm50Fm52XqSXof0kYfBgrsNlfQWVmV1aV49MuVWyhz1vHb2VMYmaJhZVaZkN6fx2ZN4tOdh/jDB8EZfra0xDXuf7YGmPmUNvowMDYtgSxbEkXFwRd0tqK8ir98toe7Lh3OzMlDrC4n4hXYbRTabTy9eierth6wupx/0tpqWFLi5JKRyRpg5mPa6MNEgT2TbQeOUV4RPEFnO2uO8fDS9dgvGMDD142zuhzl9oubJzJhSH++t7gc5+HgCT/77CtXgNkcu+7N+5o2+jBxY1Y68bFRFAXJSdkTp5uZv7CUPnHRPH1HLrHR+l8tWMTHRvP8nXm0Glf4WUNTcOQlFWmAmd/opy9M9I+PZeakIbwZBEFnxhh+vGwDu2pdYWVpifGW1qPONnRQH54oyGZDZT2PBkH4Wf3JJt7dtJ9ZORpg5g/a6MNIQb4r6OydjdYGnf3vF3tZUV7F96eP5WIdIhe0rpmQyvzLR/Lyl/tYVmrt1dVvuAPMdOy8f2ijDyMXDh/IBYOsDTpbt+8Ij721mavHDeaey0daVofyzg+mj2HaiIH8ZPkGtu4/alkdi4udTBjSn0kZiZbVEM68ucPUSyJSIyIbO5k/T0TWi8gGEflMRLLazdvjnl4mIg5fFq7OJiIU2G18ufswew4GPujs8IlGFiwqJbV/PE8UaFhZKIiJjuLJ23PoHx/LPQtLOdbQFPAaNlbWs6nqqMYR+5E3e/R/AWacY/5u4HJjzGTgMeCFDvOvNMZkG2PsPStRdcdtue6gs5LA7tW3uMPKDh5v5Ll5eST2iQ3o+lXPDU6I5+k7ctl3+CQ/siD8bInDSVxMFDdn672C/cWbWwl+DHQakGGM+cwYc8T91y8AHRtlobTEeC63IOjsqVU7+Hh7Lf9+00QmZ+rX71AzdfhAHp4xjnc27ufFNbsDtt6GphZeL6vi2olpmmTqR74+Rn8X8E67vxvgfREpEZG7z/VCEblbRBwi4qitDf6ArmBWmG/jwNHTfLw9MNvx79tq+NPfdnBrbga3T9Wv36Hq218bzoyJafzqna0UByj87H13gFmhnoT1K581ehG5Elejf6jd5EuNMbnAdcACEbmss9cbY14wxtiNMfaUlBRflRWRrhqXyqC+cQEZU19Zd4oHFpcxNjWBx2dN1rCyECYi/HbOFGwDerNgUSm1x/yfnbTEHWB28chBfl9XJPNJoxeRKcCfgZuNMYfaphtjKt1/1gDLgam+WJ86t7agsw+3+Dfo7HRzC/cuKqXFHVbWO07HP4e6/vGxPHdnHkcbmvjuK+tobmn127raAszm2DXAzN/Ou9GLyFBgGfANY8z2dtP7ikhC23NgOuBx5I7yvYJ8V9DZcj/eHPrxt7dQ7qzjd3OmMDy5r9/WowJr/JD+/MesyXy+6xBP+DH8rO3OaBpg5n/eDK98BfgcGCsiFSJyl4jMF5H57kUeAQYBz3YYRpkKrBGRcmAt8LYx5l0//AzKgzGpCWTbkljsp6CzN8oq+evne/m/XxvOjEkaVhZuZudlcvtUG8/+/Ss+3Oz78LPWVsNrJRVcOiqZzAEaYOZvXQaDG2Nu72L+t4Fve5i+C8g6+xUqUArsNn6yfANlzjpyhg7w2fvuOHCMh5duIH/YAH40Q8PKwtXPb5zIhsp6Hiwq463vfI2hg3zXkD/96iCVdad4SMPuAkKvjA1jN2YNcQed+e7y9uOnm5m/sIS+vWI0rCzMxcdG89y8PADufbnEp+FnRY4KEnvHMn1Cqs/eU3VOP6VhLCE+lpmTh/BmeRUnG5vP+/2MMTy8dD27D57gqdtzSO2vYWXhzjawD38ozGZj5VF+8eYmn7xn3clG3tu0n1nZ6RpgFiDa6MNcod3G8dPNvLNh/3m/1/98toe31lfzg2vHcpEOh4sYV49P5d4rRvLKWievlZz/t8M3yqpcAWYaeRAw2ujD3NThAxk2qA+Lz3NMfem+Izy+cgtfHz+Y+ZdpWFmkefCaMVw0YhA/Xb6BLdXnF362uNjJxPT+TEzXK6gDRRt9mBMR5thtrN19mN09DDo7dPw0CxaVkpYYz3/O0bCySNQWfpbYO5Z7FpZwtIfhZxsr69lcrQFmgaaNPgKcCTrrwV59W1jZoRMaVhbpUhJ68ey8XCqOnOJHS3oWflbUFmCWleGHClVntNFHgLTEeK4YO5ilpRXdvtLxT3/bwSc7DvLoTRM1K1xhHzaQh68bx7ub9vPnT7oXftbQ1MLr6yqZMTFNdxgCTBt9hCiwu4POdngfdLZ6Ww1PrdrBnLxM/aqtzrjr0uHMnJzGr9/dytrd3oefvbdpP0cbmvX/kgW00UeIq8YNdgWdFXs3aqLiyEm+t7iMcWn9eWzWJA0rU2eICL+5bQoXDOzDgpdLqTnW4NXrljgqyBzQm4tG6IitQNNGHyHiYqK4NdcVdHawi6Czfworm5erY53VWRLiY3n2zlyONTTxnZe7Dj9zHnYHmOXZ9GS+BbTRR5ACu43mVsPy0nMHnT321mbWV9Tz+4IshmlYmerEuLT+/PKWyXy5+zC/f//c4WdLSioQgdl2DTCzgjb6CDI6NYGcoUkUOToPOnt9XSULv9jHv142gmsnpgW4QhVqbs3N5I4Lh/L8R1/xQSfhZy2thtccTi4dlUxGUu8AV6hAG33EKbDb2FFznHXOurPmbT9wjB8v28DU4QP54bVjA1+cCkmP3DCByRmJPFhUxt5DZ1+r8enOg1TVN1Cgd5GyjDb6CHPDlCH0jo0+a0z9P4WV3Z5DjIaVKS/Fx0bz7LxcokS4Z2HpWeFnRQ4nSX1imT5RA8ysop/mCPOPoLPqM0Fnxhgeem09ew+d5Ok7chisYWWqm1zhZ1lsrj7Kz9/4R/jZkRONvL/pALOyM+gVoyf1raKNPgIV5ruCzla6g87++9M9vL2hmh9eO5ZpOvRN9dBV41K578pRLHY4z9yv+I2yShpbWvWwjcW8avQi8pKI1IiIx1sBisuTIrJTRNaLSG67ed8UkR3uxzd9VbjqufxhAxie3JeiYiclew/zy5VbuGZCKv962QirS1Mh7nvXjOGSUYP42esb2VRVz2JHBZMy+jMhvb/VpUU0b/fo/wLMOMf864DR7sfdwHMAIjIQ+DlwIa4bg/9cRHx3qyPVI66gs0zW7jnMv/5vCRkDevP7OVl6UZQ6b9FRwp/m5jCgTxzffGktW6qPUqh785bzqtEbYz4GznWt883AX43LF0CSiAwBrgU+MMYcNsYcAT7g3L8wVIC0BZ0da2jm2Xm5JPbW7BHlG8n9evHMvFzqTjYRFxPFTRpgZrku7xnrpQyg/TCOCve0zqafRUTuxvVtgKFDh/qoLNWZ1P7x/MesyaQnxWsuuPK5vAsG8My8XI43NGuAWRDwVaM/b8aYF4AXAOx2e/fzT1W33XGh/kJV/qMX3AUPX426qQTaH4jLdE/rbLpSSqkA8VWjXwH8i3v0zTSg3hhTDbwHTBeRAe6TsNPd05RSSgWIV4duROQV4AogWUQqcI2kiQUwxjwPrARmAjuBk8D/cc87LCKPAcXut3rUGON9gLVSSqnz5lWjN8bc3sV8AyzoZN5LwEvdL00ppZQv6JWxSikV5rTRK6VUmNNGr5RSYU4bvVJKhTnp7E5DVhKRWmBvD1+eDBz0YTm+onV1j9bVPVpX94RjXRcYY1I8zQjKRn8+RMRhjLFbXUdHWlf3aF3do3V1T6TVpYdulFIqzGmjV0qpMBeOjf4FqwvohNbVPVpX92hd3RNRdYXdMXqllFL/LBz36JVSSrWjjV4ppcJcyDZ6EZkhItvcNyR/2MP8XiKy2D3/SxEZFiR1fUtEakWkzP34dgBq6vHN3S2u6woRqW+3rR4JUF02EVktIptFZJOI3O9hmYBvMy/rCvg2E5F4EVkrIuXuun7hYZmAfx69rCvgn8d2644WkXUi8paHeb7dXsaYkHsA0cBXwAggDigHJnRY5l7geffzucDiIKnrW8DTAd5elwG5wMZO5s8E3gEEmAZ8GSR1XQG8ZcH/ryFArvt5ArDdw79jwLeZl3UFfJu5t0E/9/NY4EtgWodlrPg8elNXwD+P7db9IPCyp38vX2+vUN2jnwrsNMbsMsY0Aq/iukF5ezcD/+N+/hpwtYhIENQVcKbnN3e3ui5LGGOqjTGl7ufHgC2cfa/jgG8zL+sKOPc2OO7+a6z70XGUR8A/j17WZQkRyQSuB/7cySI+3V6h2ui9uen4mWWMMc1APTAoCOoCuM39df81EbF5mB9oXt/E3QIXub96vyMiEwO9cvdX5hxce4PtWbrNzlEXWLDN3IchyoAa4ANjTKfbK4CfR2/qAms+j38EfgS0djLfp9srVBt9KHsTGGaMmQJ8wD9+a6uzleLK78gCngJeD+TKRaQfsBR4wBhzNJDrPpcu6rJkmxljWowx2bjuCz1VRCYFYr1d8aKugH8eReQGoMYYU+LvdbUJ1UbvzU3HzywjIjFAInDI6rqMMYeMMafdf/0zkOfnmrwRlDdxN8YcbfvqbYxZCcSKSHIg1i0isbia6SJjzDIPi1iyzbqqy8pt5l5nHbAamNFhlhWfxy7rsujzeAlwk4jswXV49yoRWdhhGZ9ur1Bt9MXAaBEZLiJxuE5WrOiwzArgm+7ns4FVxn1mw8q6OhzHvQnXcVardXZzd0uJSFrbcUkRmYrr/6vfm4N7nS8CW4wxT3SyWMC3mTd1WbHNRCRFRJLcz3sD1wBbOywW8M+jN3VZ8Xk0xvzYGJNpjBmGq0esMsbc2WExn24vr+4ZG2yMMc0ich/wHq6RLi8ZYzaJyKOAwxizAtcH4n9FZCeuE35zg6Su74rITUCzu65v+bsu6eHN3YOgrtnAPSLSDJwC5gbglzW49ri+AWxwH98F+AkwtF1tVmwzb+qyYpsNAf5HRKJx/WIpMsa8ZfXn0cu6Av557Iw/t5dGICilVJgL1UM3SimlvKSNXimlwpw2eqWUCnPa6JVSKsxpo1dKqTCnjV4ppcKcNnqllApz/x/DWDiRyii/5AAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.plot([3,1,2,1,3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[공식 홈페이지](https://jupyterbook.org/interactive/interactive.html#plotly)를 참고하여 interactive한 시각화도 가능합니다. " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/docs/review/ControlNet.md b/_sources/docs/review/ControlNet.md old mode 100644 new mode 100755 index c50d6ff2..336ba87c --- a/_sources/docs/review/ControlNet.md +++ b/_sources/docs/review/ControlNet.md @@ -1,203 +1,203 @@ -```{admonition} Information -- **Title:** Adding Conditional Control to Text-to-Image Diffusion Models (arxiv 2023) - -- **Reference** - - Paper: [https://arxiv.org/abs/2302.05543](https://arxiv.org/abs/2302.05543) - - Code: [https://github.com/lllyasviel/ControlNet](https://github.com/lllyasviel/ControlNet) - -- **Author:** Jisu Kim - -- **Last updated on May. 28, 2023** -``` - -# ControlNet - -### Additional Control with Image-based condition - -기존의 Text-to-Image 모델들은 text prompt로 생성할 이미지의 특징을 조절할 수 있었습니다. 하지만 이런 prompt-based control만으로 이미지의 특징을 조절하는데 한계가 있었습니다. 이 논문에서는 image-based condition을 추가적으로 줘서 생성되는 이미지의 특징을 더 잘 조절하는 ControlNet이라는 신경망 구조를 제안합니다. - -아래 그림은 “a high quality, detailed, and professional image”라는 prompt와 왼쪽 아래의 Canny edge를 input으로 받아서 오른쪽의 이미지들을 생성한 것입니다. 이런 식으로 추가적인 image-based condition (아래 그림에서는 Canny edge)를 input으로 받아 이미지를 생성하는 것이 ControlNet이 하는 역할입니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Images generated by ConrolNet -::: - -그러면 어떤 구조를 사용해서 이를 가능하게 했을까요? 이제부터 이에 대해 알아보도록 하겠습니다. - -### ControlNet Block - -ControlNet의 block 구조는 다음과 같은 두 가지 특징을 가집니다. - -1. pretrained model의 locked copy와 trainable copy를 사용 - -2. zero convolution - -:::{figure-md} markdown-fig -stylegan_01 - -ConrolNet block -::: - -왜 이렇게 설계했는지 알아봅시다. - -우선, copy를 사용하는 이유는 기존에 방대한 양의 데이터로 학습시킨 pretrained model의 성능을 유지하기 위해서입니다. 또한, ControlNet의 학습 데이터가 양이 적은 경우에 오버피팅을 피할 수 있는 효과도 있을 것입니다. - -zero convolution이란 weight랑 bias가 0으로 초기화한 1x1 convolution을 말합니다. zero convolution을 사용할 경우 훈련이 시작되기 전에는 input에 대해 pretrained model과 ControlNet의 output이 똑같아집니다. 따라서 기존 모델이랑 똑같은 input, output을 가지게되므로 기존 모델의 성능을 유지할 수 있으며, 추가적인 훈련이 fine tuning을 하는 것과 비슷하므로 scratch부터 학습하는 것에 비해 빠르게 훈련시킬 수 있게됩니다. - -그러면 zero convolution은 어떻게 이를 가능하게 하는지 좀 더 자세히 알아봅시다. - -### Zero Convolution - -먼저 위의 그림에서 (a)에 해당하는 부분을 아래와 같이 수식으로 표현하겠습니다. - -$$ -\mathbf{y}=\mathcal{F}(\mathbf{x};\Theta) -$$ - -$\mathbf{x}$는 input feature map, $\mathcal{F}$는 neural network block, $\Theta$는 $\mathcal{F}$의 parameter, $\mathbf{y}$는 output을 의미합니다. 위 그림의 (b)를 수식으로 표현하기위해 $\mathcal{F}$의 trainable copy를 만들어서 parameter를 $\Theta_{c}$라고하고 $\Theta$는 고정시켜두겠습니다. 또한, zero convolution은 $\mathcal{Z}$로 표현하고 두 zero convolution의 parameter를 각각 $\Theta_{z1}, \Theta_{z2}$로 두겠습니다. 그러면 (b)에서 condition $\mathbf{c}$에 대한 output $\mathbf{y}_{c}$는 아래와 같이 표현할 수 있습니다. - -$$ -\mathbf{y}_{c}=\mathcal{F}(\mathbf{x};\Theta)+\mathcal{Z}(\mathcal{F}(\mathbf{x}+\mathcal{Z}(\mathbf{c};\Theta_{z1});\Theta_{c});\Theta_{z2}) -$$ - -그런데 $\mathcal{Z}$의 weight와 bias의 초깃값이 0이므로 훈련이 진행되지 않았을 경우 $\mathbf{y}_{c}=\mathbf{y}$입니다. 따라서 훈련 시작 전에는 ControlNet과 기존 모델이 같은 결과를 내므로 기존 모델의 성능을 보존할 수 있습니다. - -그런데 weight랑 bias가 전부 0으로 초기화되어있으면 gradient가 0이라서 훈련이 안 되는거 아닐까요? 이를 확인하기 위해 다음과 같이 간단한 경우를 생각해보죠. - -$$ -y=wx+b -$$ - -gradient는 다음과 같습니다. - -$$ -\frac{\partial y}{\partial w}=x,\; \frac{\partial y}{\partial x}=w,\; \frac{\partial y}{\partial b}=1 -$$ - -weight랑 bias가 0이고, $x\neq0$이라고 하면 - -$$ -\frac{\partial y}{\partial w}\neq0,\; \frac{\partial y}{\partial x}=0,\; \frac{\partial y}{\partial b}\neq0 -$$ - -입니다. 따라서 첫 번째 gradient step에서 weight는 0이 아닌 값으로 가게되고, $\frac{\partial y}{\partial x}\neq0$이 되므로 훈련이 됩니다. 여기서 핵심적인 가정이 $x\neq0$인데 이 부분은 잘 훈련된 pretrained model을 사용하고 있기 때문에 위배될 가능성이 낮을 것입니다. - -지금까지 얘기한 ControlNet block 구조를 pretrained Stable diffusion에 적용한 전체 구조는 아래 그림과 같습니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Overall structure -::: - -### Training & Results - -training loss는 기존 stable diffusion에서 image-based condition $\mathbf{c}_{f}$가 추가된 형태입니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Loss -::: - -training을 할 때 50%의 확률로 prompt $\mathbf{c}_{t}$를 empty string으로 바꿔주었다고 합니다. 이는 prompt가 주어지지않을 경우 모델이 $\mathbf{c}_{f}$로부터 semantics를 더 배우는 경향이 있기 때문에 이미지 생성을 $\mathbf{c}_{f}$로 조절하는 능력을 향상시켜줄 수 있다고 합니다. - -아래 결과는 training이 기존 방법보다 효율적이라는 것을 보여줍니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Efficiency -::: - -아래 결과들은 task에 따른 결과들입니다. 더 많은 이미지들이 논문에 있으니 참고하시기 바랍니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Pose -::: - -:::{figure-md} markdown-fig -stylegan_01 - -Images generated by ConrolNet -::: - -아래는 논문에서 limitation이라고 언급한 이미지입니다. 텍스트로 추가적인 정보를 주었음에도 원하는 이미지가 생성되지 않는 경우가 발생했습니다. - -:::{figure-md} markdown-fig -stylegan_01 - -Limitations -::: - -### Implementation - -코드는 공식 구현([링크](https://github.com/lllyasviel/ControlNet))에서 가져왔습니다. 아래 코드는 parameter를 0으로 초기화하는 코드로 zero convolution을 만들 때 사용됩니다. - -```python -def zero_module(module): - """ - Zero out the parameters of a module and return it. - """ - for p in module.parameters(): - p.detach().zero_() - return module -``` - -아래 코드는 기본적으로 nn.Sequential과 같은데 time step같은 추가적인 input을 받아줄 수 있게 만든 것입니다. - -```python -class TimestepEmbedSequential(nn.Sequential, TimestepBlock): - """ - A sequential module that passes timestep embeddings to the children that - support it as an extra input. - """ - - def forward(self, x, emb, context=None): - for layer in self: - if isinstance(layer, TimestepBlock): - x = layer(x, emb) - elif isinstance(layer, SpatialTransformer): - x = layer(x, context) - else: - x = layer(x) - return x -``` - -아래 코드는 공식 github의 cldm/cldm.py에 있는 ControlNet class입니다. init 부분은 길어서 생략했습니다. - -```python -class ControlNet(nn.Module): - def __init__(...): - ... - - def make_zero_conv(self, channels): - return TimestepEmbedSequential(zero_module(conv_nd(self.dims, channels, channels, 1, padding=0))) - - def forward(self, x, hint, timesteps, context, **kwargs): - t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False) - emb = self.time_embed(t_emb) - - guided_hint = self.input_hint_block(hint, emb, context) - - outs = [] - - h = x.type(self.dtype) - for module, zero_conv in zip(self.input_blocks, self.zero_convs): - if guided_hint is not None: - h = module(h, emb, context) - h += guided_hint - guided_hint = None - else: - h = module(h, emb, context) - outs.append(zero_conv(h, emb, context)) - - h = self.middle_block(h, emb, context) - outs.append(self.middle_block_out(h, emb, context)) - - return outs -``` +```{admonition} Information +- **Title:** Adding Conditional Control to Text-to-Image Diffusion Models (arxiv 2023) + +- **Reference** + - Paper: [https://arxiv.org/abs/2302.05543](https://arxiv.org/abs/2302.05543) + - Code: [https://github.com/lllyasviel/ControlNet](https://github.com/lllyasviel/ControlNet) + +- **Author:** Jisu Kim + +- **Last updated on May. 28, 2023** +``` + +# ControlNet + +### Additional Control with Image-based condition + +기존의 Text-to-Image 모델들은 text prompt로 생성할 이미지의 특징을 조절할 수 있었습니다. 하지만 이런 prompt-based control만으로 이미지의 특징을 조절하는데 한계가 있었습니다. 이 논문에서는 image-based condition을 추가적으로 줘서 생성되는 이미지의 특징을 더 잘 조절하는 ControlNet이라는 신경망 구조를 제안합니다. + +아래 그림은 “a high quality, detailed, and professional image”라는 prompt와 왼쪽 아래의 Canny edge를 input으로 받아서 오른쪽의 이미지들을 생성한 것입니다. 이런 식으로 추가적인 image-based condition (아래 그림에서는 Canny edge)를 input으로 받아 이미지를 생성하는 것이 ControlNet이 하는 역할입니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Images generated by ConrolNet +::: + +그러면 어떤 구조를 사용해서 이를 가능하게 했을까요? 이제부터 이에 대해 알아보도록 하겠습니다. + +### ControlNet Block + +ControlNet의 block 구조는 다음과 같은 두 가지 특징을 가집니다. + +1. pretrained model의 locked copy와 trainable copy를 사용 + +2. zero convolution + +:::{figure-md} markdown-fig +stylegan_01 + +ConrolNet block +::: + +왜 이렇게 설계했는지 알아봅시다. + +우선, copy를 사용하는 이유는 기존에 방대한 양의 데이터로 학습시킨 pretrained model의 성능을 유지하기 위해서입니다. 또한, ControlNet의 학습 데이터가 양이 적은 경우에 오버피팅을 피할 수 있는 효과도 있을 것입니다. + +zero convolution이란 weight랑 bias가 0으로 초기화한 1x1 convolution을 말합니다. zero convolution을 사용할 경우 훈련이 시작되기 전에는 input에 대해 pretrained model과 ControlNet의 output이 똑같아집니다. 따라서 기존 모델이랑 똑같은 input, output을 가지게되므로 기존 모델의 성능을 유지할 수 있으며, 추가적인 훈련이 fine tuning을 하는 것과 비슷하므로 scratch부터 학습하는 것에 비해 빠르게 훈련시킬 수 있게됩니다. + +그러면 zero convolution은 어떻게 이를 가능하게 하는지 좀 더 자세히 알아봅시다. + +### Zero Convolution + +먼저 위의 그림에서 (a)에 해당하는 부분을 아래와 같이 수식으로 표현하겠습니다. + +$$ +\mathbf{y}=\mathcal{F}(\mathbf{x};\Theta) +$$ + +$\mathbf{x}$는 input feature map, $\mathcal{F}$는 neural network block, $\Theta$는 $\mathcal{F}$의 parameter, $\mathbf{y}$는 output을 의미합니다. 위 그림의 (b)를 수식으로 표현하기위해 $\mathcal{F}$의 trainable copy를 만들어서 parameter를 $\Theta_{c}$라고하고 $\Theta$는 고정시켜두겠습니다. 또한, zero convolution은 $\mathcal{Z}$로 표현하고 두 zero convolution의 parameter를 각각 $\Theta_{z1}, \Theta_{z2}$로 두겠습니다. 그러면 (b)에서 condition $\mathbf{c}$에 대한 output $\mathbf{y}_{c}$는 아래와 같이 표현할 수 있습니다. + +$$ +\mathbf{y}_{c}=\mathcal{F}(\mathbf{x};\Theta)+\mathcal{Z}(\mathcal{F}(\mathbf{x}+\mathcal{Z}(\mathbf{c};\Theta_{z1});\Theta_{c});\Theta_{z2}) +$$ + +그런데 $\mathcal{Z}$의 weight와 bias의 초깃값이 0이므로 훈련이 진행되지 않았을 경우 $\mathbf{y}_{c}=\mathbf{y}$입니다. 따라서 훈련 시작 전에는 ControlNet과 기존 모델이 같은 결과를 내므로 기존 모델의 성능을 보존할 수 있습니다. + +그런데 weight랑 bias가 전부 0으로 초기화되어있으면 gradient가 0이라서 훈련이 안 되는거 아닐까요? 이를 확인하기 위해 다음과 같이 간단한 경우를 생각해보죠. + +$$ +y=wx+b +$$ + +gradient는 다음과 같습니다. + +$$ +\frac{\partial y}{\partial w}=x,\; \frac{\partial y}{\partial x}=w,\; \frac{\partial y}{\partial b}=1 +$$ + +weight랑 bias가 0이고, $x\neq0$이라고 하면 + +$$ +\frac{\partial y}{\partial w}\neq0,\; \frac{\partial y}{\partial x}=0,\; \frac{\partial y}{\partial b}\neq0 +$$ + +입니다. 따라서 첫 번째 gradient step에서 weight는 0이 아닌 값으로 가게되고, $\frac{\partial y}{\partial x}\neq0$이 되므로 훈련이 됩니다. 여기서 핵심적인 가정이 $x\neq0$인데 이 부분은 잘 훈련된 pretrained model을 사용하고 있기 때문에 위배될 가능성이 낮을 것입니다. + +지금까지 얘기한 ControlNet block 구조를 pretrained Stable diffusion에 적용한 전체 구조는 아래 그림과 같습니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Overall structure +::: + +### Training & Results + +training loss는 기존 stable diffusion에서 image-based condition $\mathbf{c}_{f}$가 추가된 형태입니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Loss +::: + +training을 할 때 50%의 확률로 prompt $\mathbf{c}_{t}$를 empty string으로 바꿔주었다고 합니다. 이는 prompt가 주어지지않을 경우 모델이 $\mathbf{c}_{f}$로부터 semantics를 더 배우는 경향이 있기 때문에 이미지 생성을 $\mathbf{c}_{f}$로 조절하는 능력을 향상시켜줄 수 있다고 합니다. + +아래 결과는 training이 기존 방법보다 효율적이라는 것을 보여줍니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Efficiency +::: + +아래 결과들은 task에 따른 결과들입니다. 더 많은 이미지들이 논문에 있으니 참고하시기 바랍니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Pose +::: + +:::{figure-md} markdown-fig +stylegan_01 + +Images generated by ConrolNet +::: + +아래는 논문에서 limitation이라고 언급한 이미지입니다. 텍스트로 추가적인 정보를 주었음에도 원하는 이미지가 생성되지 않는 경우가 발생했습니다. + +:::{figure-md} markdown-fig +stylegan_01 + +Limitations +::: + +### Implementation + +코드는 공식 구현([링크](https://github.com/lllyasviel/ControlNet))에서 가져왔습니다. 아래 코드는 parameter를 0으로 초기화하는 코드로 zero convolution을 만들 때 사용됩니다. + +```python +def zero_module(module): + """ + Zero out the parameters of a module and return it. + """ + for p in module.parameters(): + p.detach().zero_() + return module +``` + +아래 코드는 기본적으로 nn.Sequential과 같은데 time step같은 추가적인 input을 받아줄 수 있게 만든 것입니다. + +```python +class TimestepEmbedSequential(nn.Sequential, TimestepBlock): + """ + A sequential module that passes timestep embeddings to the children that + support it as an extra input. + """ + + def forward(self, x, emb, context=None): + for layer in self: + if isinstance(layer, TimestepBlock): + x = layer(x, emb) + elif isinstance(layer, SpatialTransformer): + x = layer(x, context) + else: + x = layer(x) + return x +``` + +아래 코드는 공식 github의 cldm/cldm.py에 있는 ControlNet class입니다. init 부분은 길어서 생략했습니다. + +```python +class ControlNet(nn.Module): + def __init__(...): + ... + + def make_zero_conv(self, channels): + return TimestepEmbedSequential(zero_module(conv_nd(self.dims, channels, channels, 1, padding=0))) + + def forward(self, x, hint, timesteps, context, **kwargs): + t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False) + emb = self.time_embed(t_emb) + + guided_hint = self.input_hint_block(hint, emb, context) + + outs = [] + + h = x.type(self.dtype) + for module, zero_conv in zip(self.input_blocks, self.zero_convs): + if guided_hint is not None: + h = module(h, emb, context) + h += guided_hint + guided_hint = None + else: + h = module(h, emb, context) + outs.append(zero_conv(h, emb, context)) + + h = self.middle_block(h, emb, context) + outs.append(self.middle_block_out(h, emb, context)) + + return outs +``` diff --git a/_sources/docs/review/CustomDiffusion.md b/_sources/docs/review/CustomDiffusion.md old mode 100644 new mode 100755 index 791234bc..0d92a68b --- a/_sources/docs/review/CustomDiffusion.md +++ b/_sources/docs/review/CustomDiffusion.md @@ -1,226 +1,226 @@ -```{admonition} Information -- **Title:** {A Multi-Concept Customiziation of Text-To-Image Diffusion}, {VCPR 2023} - -- **Reference** - - Paper: [https://arxiv.org/abs/2212.04488](https://arxiv.org/abs/2212.04488) - - Code: [Official:](https://github.com/adobe-research/custom-diffusion) - -- **Author:** Seunghwan Ji - -- **Last updated on Aug. 6, 2023** -``` -# Custom Diffusion - -## 학습 자료 - -**A Multi-Concept Customiziation of Text-To-Image Diffusion** - -[https://arxiv.org/pdf/2212.04488.pdf](https://arxiv.org/pdf/2212.04488.pdf) - -CVPR 2023. Adobe - ---- - -## Abstract - -- Large Scale Data를 학습한 Generate 모델이 뛰어난 성능을 보이는 추세 -- User의 Private한 Concept을 생성하고자하는 욕구는 여전히 풀지 못함 -- Custom Diffusion은? - 1. 기존 Diffusion 모델의 partial한 부분만을 학습시킴으로써 기존보다 더 빠른 finetuning 방식을 제안 - 2. Single Concept 뿐 아니라, Multiple Concept에 대한 학습이 가능 - 3. 다양한 Fine tuned 모델을 하나의 모델로 Compress하는 방식을 제안 - -## 1. Introduction - -- 최근 Text-To-Image 모델들이 활발하게 연구 되어짐 -- 단순한 text prompt 입력만으로 원하는 이미지를 생성해내는 수준까지 이름 -- 하지만 이러한 모델들은 General한 이미지는 잘 생성하지만, User가 원하는 Private한 (=specific) Concept의 이미지는 생성해내지 못함 - - e.g. 행복한 우리 가족 사진, 우리집 강아지 뽀삐가 파리로 여행을 떠나는 사진 등 -- 학습 과정중에 User의 Private한 데이터를 보지 못했기때문에 Model에게는 당연한 결과 -- **Customization** - - 몇장의 Concept을 포함하는 이미지만으로 Pretrained 모델을 finetuning하는 방식 - - In Dreambooth, Personalization - - 목표 - 1. 학습하고자하는 Private한 Concept의 이미지를 잘 생성해내야함 - 2. 기존에 학습되었던 General한 이미지를 Finetuning한 후에도 잘 생성해내야함 -- Customization이 어려운 이유 - 1. 학습을 진행하다보면 기존에 학습했던 Concept을 잊어버리거나 왜곡해버림 → Language Draft - 2. 새로운 Concept에 대해 모델이 Overfit 되어서 결과물의 Variation이 낮아짐 - 3. 좀더 나아가 Single Concept 뿐 아니라 Multiple Concept에 대한 Finetuning 또한 어려움 -- Custom Diffusion은? - 1. Text로 Condition을 생성해내는 과정 중 특정 부분만을 학습 - 2. General Concept의 성능 유지를 위해 real image와 해당 이미지의 caption을 regularization Data로 사용 - 3. fine tuning동안 새로운 augmentation 기법을 소개 - 4. Multiple concept의 학습 방식을 제안 - -## 2. Related Work - -### Deep Generative Models & Image and model editing - -- GAN, VAE, Diffusion 등 다양한 방식의 Generative Model들이 각각 좋은 성능을 보여주고있음 -- 게다가 추가적인 input(=hint)를 통해 Generated 이미지의 control도 가능함 -- 하지만 General하지 않은 새로운 Concept에 대한 생성은 불가능함 -- **Custom Diffusion은 이러한 New Concept에 대한 Finetuning 기법을 제안** - -### Transfer learning - -- Global한 이미지의 Distribution을 이미 학습한 모델에 특정 concept을 포함한 소량의 이미지를 finetuning하는 기법 -- Transfer Learning은 생각보다 효과적이고 유용함 -- 대부분 transfer learning 시에는 모델의 전체를 학습하거나 혹은 Parameter를 더 추가해 재학습 - - → 위에서 제시한 Customization의 문제를 일으키기 쉬움 (Language Draft, Overfitting etc.) - -- **Custom Diffusion은 모델의 아주 일부만을 대상으로 finetuning** - -### Adapting text-to-image models - -- 비슷한 컨셉으로 Finetuning을 통한 Personalization 연구들이 있음 - - Dreambooth, Textual Inversion -- vs Custom Diffusion - 1. Multiple Concept의 Finetuning 모델들을 하나의 모델로 Compress할 수 있음 - 2. 모델의 특정 부분만을 Finetuning함으로써 다른 모델에 비해 Training Resourse를 절약할 수 있음 - -## 3. Method - -### Single Concept Fine-tuning - -- Backbone으로 Latent Diffusion Model을 채택 -- (L)DM의 학습 Concept - :::{figure-md} markdown-fig - CD_00 - - Equation 0 - ::: - - - $x_{t}$ : time t 시점에 Noise가 섞인 이미지 - - $t$ → timestep - - $c$ → conditioning feature (text, image 등) - - text나 image를 바로 사용하지않고 latent space로 embedding된 값을 사용 *(using CLIP)* - - ε → noise - - $ε_{θ}$ → $x_{t}$에 낀 noise ε를 예측해내는 모델 - - 즉, $x_{t}$에 낀 noise ε를 예측해내는 모델을 학습 - -- 이러한 LDM 모델을 fine tuning할때는 Model의 모든 Layer에대해 update하는게 기본 -- 하지만 이러한 finetuning 방식은 Resource가 비효율적으로 많이들고, 새로운 Concept 이미지에 overfitting되기 쉬움 -- Finetuning 과정 중 모델의 Weight 변화량을 체크 - :::{figure-md} markdown-fig - CD_01 - - Delta of Weight while Training - ::: -- 다른 부분에비해 Cross Attention 연산의 Wegith 변화량이 가장 큼 -- Cross Attention -:::{figure-md} markdown-fig -CD_02 - -Fig.4 Cross Attention -::: - -- Cross Attention → Image latent에 text condition을 주입하는 Attention Mechanism - - *Query* → image latent / *Key, Value* → text condition latent - - 모델 전체 Parameter에 단 5%부분만을 차지 - - 이 중 new concept을 의미하는 Text $V^{*}$이 포함되는 $W^{k}$와 $W^{v}$만 학습. 나머지는 Freeze -- Fine Tuning할 때 $V^{*}$은 실제로는 잘 쓰지않는 단어로 사용하고 “*A [$V^{*}$] [Class]”* 형식으로 이미지를 Captioning한 후에 학습 -- 또 Finetuning중에 일반적인 concept을 잊어버리는 Language Draft 현상이 있을수있음 - - Language Draft - :::{figure-md} markdown-fig - CD_03 - - Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림 - ::: - -Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림 - -- 이러한 현상을 방지하기위해 Real world의 Image에서 target text class prompt와 유사한 200장의 이미지를 Regulalization 이미지로 같이 학습 - - text prompt가 유사하다 = CLIP에서 추출한 text feature space상의 Vector가 Similar하다 - -### Multiple-Concept Compositional Fine-tuning - -- Joint Traning on multiple concept - - 각각의 Concept을 갖는 이미지에 대해 각각 rare한 key를 부여해 동시에 학습 - - ($V^{i}$*, for $i$ is # of concepts*) -- Constrained optimization to merge concepts - - 각각 Single Concept으로 학습된 weight를 merge - :::{figure-md} markdown-fig - CD_04 - - Equation 4 - ::: - - - $W_0$ → pretrained model의 Key, Value embedding Weight - - ~~*(Appendix A에는 $W$라고 나와있는데 오탈자일 가능성 있음)*~~ - - $C_{reg}$ → regularization 이미지의 Caption의 Embedding 값을 모두 뽑아 Concat - - ⇒ $C_{reg}$에 Pretrained Weight를 곱한 값과의 norm을 계산했을때 값이 가장 작은 Weight를 return - - “N개의 Concept에 대해 Cross Attention이 모두 잘 동작하는 W 값을 찾아 하나만 사용하자” - -### Training Details - -- single concept의 경우 250 steps, two-concept의 경우 500 steps -- batch : 8, learning rate : $8*10^{-5}$ -- random resize + prompt 추가 (very small, far away, zoom in …) (new augmentation technique) - -## 4. Experiments - -Single Concept Finetuning - -- Qualitative Evaluation -:::{figure-md} markdown-fig -CD_05 - -Qualitative Evaluation -::: - -- Quantative Evaluation (Text Alignment, Image Alignment, KID) - - text alignment : prompt에 얼마나 대응되는 이미지를 생성해냈는가 - - image alignment : training image의 concept을 얼마나 잘 표현해냈는가 - -:::{figure-md} markdown-fig -CD_06 - -Table 1 -::: -⇒ 정성적, 정량적 평가 모두 Custom Diffusion > Dreambooth, Textual Inversion - -Multiple Concept Finetuning - -:::{figure-md} markdown-fig -CD_07 - -Multiple Concept Finetuning -::: - -- Joint Training > Optimization by custom diffusion > Dreambooth - -Human Preference Study -:::{figure-md} markdown-fig -CD_08 - -Table 2 -::: - -- Custom Diffusion (partial) vs Baseline(Textual Inversion, Dreambooth, CustomDiffusion(all)) -- Text-Alignment, Image-Alignment 모두 Custom Diffusion (partial)을 선호 -- Textual Inversion은 Image Alignment는 Custom Diffusion 선호도와 비슷하지만 Text Alignment수치를 보면 Custom Diffusion이 매우 높아 Overfitting된 경향이 있음 - -Ablation Study - -1. Regularization Image - :::{figure-md} markdown-fig - CD_09 - - Table 3 - ::: - -- ㅌGen : real image 대신 generate된 이미지를 regularization 이미지로 사용 -- Overfitting 없이 가장 좋은 수치는 Augmentation + Regulatization image as Real world Image - -## 5. Discussion & Limitation - -- customizing이 가능하고 training resourse가 매우 적은 finetuning 기법 소개 -:::{figure-md} markdown-fig -CD_10 - -Limitation Of Custom Diffusion -::: - +```{admonition} Information +- **Title:** {A Multi-Concept Customiziation of Text-To-Image Diffusion}, {VCPR 2023} + +- **Reference** + - Paper: [https://arxiv.org/abs/2212.04488](https://arxiv.org/abs/2212.04488) + - Code: [Official:](https://github.com/adobe-research/custom-diffusion) + +- **Author:** Seunghwan Ji + +- **Last updated on Aug. 6, 2023** +``` +# Custom Diffusion + +## 학습 자료 + +**A Multi-Concept Customiziation of Text-To-Image Diffusion** + +[https://arxiv.org/pdf/2212.04488.pdf](https://arxiv.org/pdf/2212.04488.pdf) + +CVPR 2023. Adobe + +--- + +## Abstract + +- Large Scale Data를 학습한 Generate 모델이 뛰어난 성능을 보이는 추세 +- User의 Private한 Concept을 생성하고자하는 욕구는 여전히 풀지 못함 +- Custom Diffusion은? + 1. 기존 Diffusion 모델의 partial한 부분만을 학습시킴으로써 기존보다 더 빠른 finetuning 방식을 제안 + 2. Single Concept 뿐 아니라, Multiple Concept에 대한 학습이 가능 + 3. 다양한 Fine tuned 모델을 하나의 모델로 Compress하는 방식을 제안 + +## 1. Introduction + +- 최근 Text-To-Image 모델들이 활발하게 연구 되어짐 +- 단순한 text prompt 입력만으로 원하는 이미지를 생성해내는 수준까지 이름 +- 하지만 이러한 모델들은 General한 이미지는 잘 생성하지만, User가 원하는 Private한 (=specific) Concept의 이미지는 생성해내지 못함 + - e.g. 행복한 우리 가족 사진, 우리집 강아지 뽀삐가 파리로 여행을 떠나는 사진 등 +- 학습 과정중에 User의 Private한 데이터를 보지 못했기때문에 Model에게는 당연한 결과 +- **Customization** + - 몇장의 Concept을 포함하는 이미지만으로 Pretrained 모델을 finetuning하는 방식 + - In Dreambooth, Personalization + - 목표 + 1. 학습하고자하는 Private한 Concept의 이미지를 잘 생성해내야함 + 2. 기존에 학습되었던 General한 이미지를 Finetuning한 후에도 잘 생성해내야함 +- Customization이 어려운 이유 + 1. 학습을 진행하다보면 기존에 학습했던 Concept을 잊어버리거나 왜곡해버림 → Language Draft + 2. 새로운 Concept에 대해 모델이 Overfit 되어서 결과물의 Variation이 낮아짐 + 3. 좀더 나아가 Single Concept 뿐 아니라 Multiple Concept에 대한 Finetuning 또한 어려움 +- Custom Diffusion은? + 1. Text로 Condition을 생성해내는 과정 중 특정 부분만을 학습 + 2. General Concept의 성능 유지를 위해 real image와 해당 이미지의 caption을 regularization Data로 사용 + 3. fine tuning동안 새로운 augmentation 기법을 소개 + 4. Multiple concept의 학습 방식을 제안 + +## 2. Related Work + +### Deep Generative Models & Image and model editing + +- GAN, VAE, Diffusion 등 다양한 방식의 Generative Model들이 각각 좋은 성능을 보여주고있음 +- 게다가 추가적인 input(=hint)를 통해 Generated 이미지의 control도 가능함 +- 하지만 General하지 않은 새로운 Concept에 대한 생성은 불가능함 +- **Custom Diffusion은 이러한 New Concept에 대한 Finetuning 기법을 제안** + +### Transfer learning + +- Global한 이미지의 Distribution을 이미 학습한 모델에 특정 concept을 포함한 소량의 이미지를 finetuning하는 기법 +- Transfer Learning은 생각보다 효과적이고 유용함 +- 대부분 transfer learning 시에는 모델의 전체를 학습하거나 혹은 Parameter를 더 추가해 재학습 + + → 위에서 제시한 Customization의 문제를 일으키기 쉬움 (Language Draft, Overfitting etc.) + +- **Custom Diffusion은 모델의 아주 일부만을 대상으로 finetuning** + +### Adapting text-to-image models + +- 비슷한 컨셉으로 Finetuning을 통한 Personalization 연구들이 있음 + - Dreambooth, Textual Inversion +- vs Custom Diffusion + 1. Multiple Concept의 Finetuning 모델들을 하나의 모델로 Compress할 수 있음 + 2. 모델의 특정 부분만을 Finetuning함으로써 다른 모델에 비해 Training Resourse를 절약할 수 있음 + +## 3. Method + +### Single Concept Fine-tuning + +- Backbone으로 Latent Diffusion Model을 채택 +- (L)DM의 학습 Concept + :::{figure-md} markdown-fig + CD_00 + + Equation 0 + ::: + + - $x_{t}$ : time t 시점에 Noise가 섞인 이미지 + - $t$ → timestep + - $c$ → conditioning feature (text, image 등) + - text나 image를 바로 사용하지않고 latent space로 embedding된 값을 사용 *(using CLIP)* + - ε → noise + - $ε_{θ}$ → $x_{t}$에 낀 noise ε를 예측해내는 모델 + - 즉, $x_{t}$에 낀 noise ε를 예측해내는 모델을 학습 + +- 이러한 LDM 모델을 fine tuning할때는 Model의 모든 Layer에대해 update하는게 기본 +- 하지만 이러한 finetuning 방식은 Resource가 비효율적으로 많이들고, 새로운 Concept 이미지에 overfitting되기 쉬움 +- Finetuning 과정 중 모델의 Weight 변화량을 체크 + :::{figure-md} markdown-fig + CD_01 + + Delta of Weight while Training + ::: +- 다른 부분에비해 Cross Attention 연산의 Wegith 변화량이 가장 큼 +- Cross Attention +:::{figure-md} markdown-fig +CD_02 + +Fig.4 Cross Attention +::: + +- Cross Attention → Image latent에 text condition을 주입하는 Attention Mechanism + - *Query* → image latent / *Key, Value* → text condition latent + - 모델 전체 Parameter에 단 5%부분만을 차지 + - 이 중 new concept을 의미하는 Text $V^{*}$이 포함되는 $W^{k}$와 $W^{v}$만 학습. 나머지는 Freeze +- Fine Tuning할 때 $V^{*}$은 실제로는 잘 쓰지않는 단어로 사용하고 “*A [$V^{*}$] [Class]”* 형식으로 이미지를 Captioning한 후에 학습 +- 또 Finetuning중에 일반적인 concept을 잊어버리는 Language Draft 현상이 있을수있음 + - Language Draft + :::{figure-md} markdown-fig + CD_03 + + Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림 + ::: + +Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림 + +- 이러한 현상을 방지하기위해 Real world의 Image에서 target text class prompt와 유사한 200장의 이미지를 Regulalization 이미지로 같이 학습 + - text prompt가 유사하다 = CLIP에서 추출한 text feature space상의 Vector가 Similar하다 + +### Multiple-Concept Compositional Fine-tuning + +- Joint Traning on multiple concept + - 각각의 Concept을 갖는 이미지에 대해 각각 rare한 key를 부여해 동시에 학습 + - ($V^{i}$*, for $i$ is # of concepts*) +- Constrained optimization to merge concepts + - 각각 Single Concept으로 학습된 weight를 merge + :::{figure-md} markdown-fig + CD_04 + + Equation 4 + ::: + + - $W_0$ → pretrained model의 Key, Value embedding Weight + - ~~*(Appendix A에는 $W$라고 나와있는데 오탈자일 가능성 있음)*~~ + - $C_{reg}$ → regularization 이미지의 Caption의 Embedding 값을 모두 뽑아 Concat + - ⇒ $C_{reg}$에 Pretrained Weight를 곱한 값과의 norm을 계산했을때 값이 가장 작은 Weight를 return + - “N개의 Concept에 대해 Cross Attention이 모두 잘 동작하는 W 값을 찾아 하나만 사용하자” + +### Training Details + +- single concept의 경우 250 steps, two-concept의 경우 500 steps +- batch : 8, learning rate : $8*10^{-5}$ +- random resize + prompt 추가 (very small, far away, zoom in …) (new augmentation technique) + +## 4. Experiments + +Single Concept Finetuning + +- Qualitative Evaluation +:::{figure-md} markdown-fig +CD_05 + +Qualitative Evaluation +::: + +- Quantative Evaluation (Text Alignment, Image Alignment, KID) + - text alignment : prompt에 얼마나 대응되는 이미지를 생성해냈는가 + - image alignment : training image의 concept을 얼마나 잘 표현해냈는가 + +:::{figure-md} markdown-fig +CD_06 + +Table 1 +::: +⇒ 정성적, 정량적 평가 모두 Custom Diffusion > Dreambooth, Textual Inversion + +Multiple Concept Finetuning + +:::{figure-md} markdown-fig +CD_07 + +Multiple Concept Finetuning +::: + +- Joint Training > Optimization by custom diffusion > Dreambooth + +Human Preference Study +:::{figure-md} markdown-fig +CD_08 + +Table 2 +::: + +- Custom Diffusion (partial) vs Baseline(Textual Inversion, Dreambooth, CustomDiffusion(all)) +- Text-Alignment, Image-Alignment 모두 Custom Diffusion (partial)을 선호 +- Textual Inversion은 Image Alignment는 Custom Diffusion 선호도와 비슷하지만 Text Alignment수치를 보면 Custom Diffusion이 매우 높아 Overfitting된 경향이 있음 + +Ablation Study + +1. Regularization Image + :::{figure-md} markdown-fig + CD_09 + + Table 3 + ::: + +- ㅌGen : real image 대신 generate된 이미지를 regularization 이미지로 사용 +- Overfitting 없이 가장 좋은 수치는 Augmentation + Regulatization image as Real world Image + +## 5. Discussion & Limitation + +- customizing이 가능하고 training resourse가 매우 적은 finetuning 기법 소개 +:::{figure-md} markdown-fig +CD_10 + +Limitation Of Custom Diffusion +::: + - 비슷한 category의 object에 대해서는 joint training, merge 모두 잘 동작하지 않음 \ No newline at end of file diff --git a/_sources/docs/review/DALLE2.md b/_sources/docs/review/DALLE2.md new file mode 100755 index 00000000..b792427a --- /dev/null +++ b/_sources/docs/review/DALLE2.md @@ -0,0 +1,399 @@ +``` {admonition} Information +- **Title:** Hierarchical Text-Conditional Image Generation with CLIP Latents (arXiv 2022) + +- **Reference** + - Paper: [https://arxiv.org/pdf/2204.06125v1.pdf](https://arxiv.org/pdf/2204.06125v1.pdf) + +- **Author:** SeonHoon Kim + +- **Last updated on Sep. 18, 2023** +``` + +# DALLE2 + +DALLE2 는 2022년에 공개되어 세상을 놀라게 했습니다. +이미지 생성 능력도 뛰어났고, 이미지를 사용자 입맛에 맞게 조작할 수 있게 되었죠. + +DALLE2 의 이름은 왜 DALL-E 일까요? +DALLE2 의 DALLE 는 초현실주의 화가 Salvador Dali 와 WALL-E 의 합성어입니다. +DALLE2 로 생성해낸 결과물이 과연 어떻길래 세상을 놀라게 했을까요? + +- **DALL-E 2 결과물** + +:::{figure-md} +img_00 +vibrant portrait of Salvador Dali with a robotic half face from DALLE2 +::: + +:::{figure-md} +img_01 +Salvador Dali 의 생전 모습 +::: + +위 그림은 DALLE2 에게 "vibrant portrait of Salvador Dali with a robotic half face" 를 prompt 로 주고 생성해낸 이미지입니다. +실제 Salvador dali 의 모습이 보이네요. +게다가 Salvador dali 의 초현실주의적 그림체가 반영된 것 같기도 합니다. +놀라운 이미지입니다. + +아래의 corgi 그림은 어떤가요 ? +:::{figure-md} +img_02 +a corgi's head depicted as an explosion of a nebula from DALLE2 +::: + +corgi 의 모습을 성운의 폭발로 묘사해달라고 했을 때 생성된 그림입니다. +아래의 그림은, 실제 NASA 에서 촬영한 초신성 폭발의 잔해입니다. + +정말 그럴듯하지 않나요? + +:::{figure-md} +img_03 +This mosaic image, one of the largest ever taken by NASA's Hubble Space Telescope of the Crab Nebula, is a six-light-year-wide expanding remnant of a star's supernova explosion. +::: + +- **학습 목표 및 주의사항** + - 해당 paper 요약은 [DALL-E 2 paper](https://cdn.openai.com/papers/dall-e-2.pdf), [OpenAI blog](https://openai.com/dall-e-2), [AssemblyAI Youtube](https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI), [Eden Meyer Youtube](https://www.youtube.com/watch?v=gmfI3B6pQTo&t=83s&ab_channel=EdanMeyer) 를 참고했습니다. + - DALL-E 2 는 CLIP 과 Diffusion Model 을 통합시켰습니다. (최초는 x) + - CLIP 은, 이미지와 text 를 학습한 multi-modal 모델입니다. + - The fundamental principles of training CLIP are quite simple: + 1. First, all images and their associated captions are passed through their respective encoders, mapping all objects into an *m-*dimensional space. + 2. Then, the cosine similarity of each *(image, text)* pair is computed. + 3. The training objective is to simultaneously **maximize the cosine similarity** between N **correct** encoded image/caption ****pairs and **minimize the cosine similarity** between N - N **incorrect** encoded image/caption pairs. + + - 하지만 CLIP 을 사용하는 것이 정답은 아닙니다. + DALL-E 2 는 22년 5월, + CLIP 을 사용하지 않은 IMAGEN 에게 SOTA 를 내주었습니다. + +- **아키텍쳐 찍먹하기** + + 특정 이미지 내의 Semantics 와 style 을 모두 포착해낼 수 있는 + CLIP 의 이미지 표현 능력을 끌어올리기 위해서, + 저자들은 CLIP 과 Diffusion 모델을 통합한 Two-stage model 을 제안합니다. + 이것이 바로 DALLE2 인데요. 저자들은 이 모델을 unCLIP 이라고 부릅니다. + +:::{figure-md} +img_06 +A high level overview of the architecture. +::: + +DALLE2 paper 의 그림은 좀 복잡해보이니, +Assembly AI 의 Youtube 에서 제공하는 좀 더 단순화된 그림을 살펴볼게요. + +:::{figure-md} +img_07 +A high level overview of the architecture from AssemblyAI youtube. +::: +[https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI](https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI) + + - **Prior** : 텍스트 캡션을 받아서, 상응하는 CLIP image embedding 을 생성합니다. + - Autogregressive prior 와 Diffusion prior 를 비교하는 실험 수행했습니다. + - Diffusion prior 가 computationally efficient 하고, 고품질 이미지 생성합니다. 따라서 후반부에는 Diffusion prior 만 사용해서 실험합니다. + - **Decoder** : CLIP image embedding 을 받아서, 이미지를 생성합니다. + - Diffusion 모델만 사용했습니다. +- **왜 CLIP 이랑 Diffusion 을 사용했을까요** + - **CLIP** + - CLIP 이 images representation 을 학습하는데 에 큰 성공을 거두고 있었습니다. + - CLIP embeddings 는 image distribution shift 에 robust 했습니다. + - CLIP embeddings 는 zero-shot capabilities 가 뛰어났습니다. + - 다양한 vision & language tasks 에 fine-tuned 되어 SOTA 를 달성해냈습니다. + - **Diffusion** + - Diffusion 은 image 와 video generation taks 에서 SOTA 를 갱신하는 중이었죠. + - non-deterministic 하게 만들 수 있습니다. + 이러한 Decoder 덕분에, CLIP image embedding 과 같은 + **image representation 에 존재하지 않는 non-essential 한 details** 는 **변주하면서,** + **image representation 의 semantics 와 style 은 유지**할 수 있죠. + +:::{figure-md} +img_08 +Variations of an input image by encoding with CLIP and then decoding with a diffusion model. +::: + +- **아키텍쳐 설명 좀 자세히 해줘** + + :::{figure-md} + img_09 + A high level overview of the architecture from AssemblyAI youtube. + ::: + [https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI](https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI) + + - **Prior** + - **input** + - Caption 그 자체의 embedding vector 입니다. + - **CLIP text embedding** 입니다. + - **output** + - **Generated CLIP Image embedding** 입니다. + - **설명** + - 사실 Prior 은 CLIP text embedding 만 조건으로 받는 것이 아니라 + Caption 자체도 받습니다. (물론 embedding vector 로 받을 것) + CLIP text embedding 과, 그 Caption 은 서로 1대1 대응되기 때문에, + Duel-conditioning 이 문제될 것은 없다고 저자들은 변론합니다. + - 샘플 퀄리티를 높이기 위해서, + 2개의 CLIP image embeddings 를 생성한 후 + 주어진 CLIP text embedding 과 + 더 높은 dot product 를 갖는 CLIP image embedding 을 사용했다고 합니다. + - **Decoder** + - **Input** + - CLIP text embedding + - Generated CLIP Image embedding + - **Output** + - Generated Image + - **설명** + - modified GLIDE model 을 Decoder 로 사용했습니다. + → 따라서, **projected CLIP text embeddings 를 아키텍쳐**에 통합시킬 수 있다고 주장합니다. + + 어떻게 통합시키냐하면, + + 1. GLIDE timestep embedding 에 추가하고, + 2. 4개의 extra context tokens 을 만들어서 GLIDE text encoder 의 output sequence 에 concat 하는거죠. + + 이 방법으로 **CLIP image embeddings 를 받아서, 원본 영상을 생성하는 것** 입니다. + + :::{figure-md} + img_10 + GLIDE training process + ::: + + - GLIDE 를 수정해 사용함으로써, GLIDE 가 가지고 있던 text-conditional photorealistic image generation capabilities 를 활용할 수 있다고 주장합니다. + +- **그렇다면 왜 Prior 가 필요할까요?** + 1. **To obtain a full generative model of images**, we combine the CLIP image embedding decoder with a prior model, which generates possible CLIP image embeddings from a given text caption + 2. **아래 세 가지 아키텍쳐를 비교하는 실험 수행** + (1) GLIDE 모델처럼, text 의 token embeddings 만 조건으로 주어 실험 + (2) 추가적으로, CLIP text embeddings 를 조건으로 주어 실험 + (3) 추가적으로, CLIP image embeddings 를 생성해내는 Prior 를 갖추고 실험 + + 결과 (3) 이 가장 훌륭했습니다. 특히 image diversity 가 뛰어났습니다. + + :::{figure-md} + img_11 + 3가지 경우의 아키텍쳐에 따른 실험 결과 from AssemblyAI youtube. + ::: + :::{figure-md} + img_12 + Samples using different conditioning signals for the same decoder. + ::: + + - 하지만.. **95% 의 학습 시간 동안, (3) 방식으로 학습한 Decoder 를, (1) 과 (2) 방식에 그대로 적용해 실험했습니다.** 따라서 공정한 실험이라고 보긴 어려울 것 같습니다. + - 또한.. **Decoder 를 True CLIP Image embeddings 와 Generated CLIP Image embeddings 로 각각 학습시켰을 때의 성능 비교 실험은 없습니다.** + - 개인적으로 저는 이러한 결과들을 보고, Prior 를 반드시 써야하는 근거에 대한 설득력이 조금 떨어진다고 생각했습니다. +- **왜 CLIP 을 써야할가요?** + 1. CLIP 은 어떤 객체를 묘사한 텍스트와, 그 객체의 시각적 발현 사이의 의미론적 관계를 학습했습니다. 따라서 저자들은 이러한 CLIP 의 능력이 Text-to-Image task 에서 매우 중요하다고 주장합니다. + 2. **CLIP 을 활용한 덕분에 이미지를 Manipulation 할 수 있습니다.** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2012.png) + +- **그래서? 이 모델 좋아?** + - **Evaluation** + - 주어진 Caption 에 대한 GLIDE 의 생성물과 unCLIP 의 생성물을 + 사람들에게 제시하고, + **Photorealism, Caption Similarity, Diversity** 에 대해서 **평가**하도록 함. + 1. GLIDE 에 비해서 **Photorealism, Caption Similarity,** 은 Comparable 하다. + ~~(안 좋다)~~ + 2. 하지만, **Diversity** 는 훨씬 뛰어나다. + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2013.png) + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2014.png) + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2015.png) + + - **Image Manipulations** + - Bipartite Representation + - unCLIP 구조 덕분에, 주어진 이미지 x 를 (z_i, x_T) 와 같은 bipartite latent representation 으로 인코딩 할 수 있음 + - 이 latent space 를 활용해서, Image manipulation 을 수행할 수 있다. + - x_T 는 DDIM inversion 을 z_i 가 condition 된 x 에 적용해 얻으며, + Decoder 가 x 를 복원하는데 필요한 잔여 정보들을 지님 + + 1. **Variations** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%208.png) + + - Non-essential details 를 변주하기 위해서, + bipartite representation 에 DDIM with η > 0 for sampling decoder 를 적용한다. + - η = 0 일 때, decoder 는 deterministic 해지고 x 자체를 복원해낸다. + - η 가 커질수록, sampling steps 에는 stochasticity 가 생기고, 원본 이미지 x 근처에서 perceptually “centereed” 된 variations 를 만들어낼 것이다. + - η 를 키우면, 우리는 CLIP image embedding 에 어떤 정보가 존재하고 어떤 정보가 유실되었는지 탐색 가능 + **→ CLIP latent space 를 탐색해낼 수 있다 !** + + 1. **Interpolations** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2016.png) + + - input image 두 장의 CLIP image embeddings 를 interpolation 해서 + Decoder 에 준다면, interpolated image 를 생성할 수 있다. + + 2. **Text Diffs** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2017.png) + + - **어떤 이미지와 그 캡션이 주어져있을 때, + 그 이미지를 우리가 원하는 target text prompt 에 맞게 + 조작할 수도 있음** + - **Method** + **z_t0 = current CLIP text embedding + z_t = target CLIP text embedding** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2018.png) + + - 주어진 이미지의 **CLIP image embdding z_i** 를 바로 이 **text diff vector 와 interpolate 해서 Decoding** 하면 이미지가 조작된다. + - **Robustness against typographic attaks** + - **typographic attacks** : 이미지 내 사물 위에, 글씨가 쓰여 있는 경우이다. + - Multimodal 로 학습한 CLIP 은 텍스트에 있는 정보를 더 많이 활용해 + 사물을 판단하는 경향이 있음 + 1. unCLIP 의 Decoder 모델에 “iPod” 텍스트 종이가 붙은 사과를 보고 분류를 수행해보았다. + 2. 역시, “Granny Smith” 의 예측 확률을 거의 0 에 가깝다고 판단했다. + 3. 그럼에도 불구하고, 사과의 사진으로 recover 해낸다. + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2019.png) + + +- **이 모델, 단점은 없어?** + 1. **객체(cubes)와 그들의 속성(colors) 을 매칭시키는 능력이 떨어짐** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2020.png) + + + 1. **텍스트를 일관성있게 생성하는 능력이 떨어짐** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2021.png) + + 2. **복잡한 상황에서 디테일을 묘사하는 능력이 떨어짐** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2022.png) + + +- **Method - Training** + - unCLIP 모델의 아키텍쳐에 대한 수학적 justify 를 하고 있음 + - Training 데이터셋의 이미지를 x 라 한다. + - 그에 상응하는 text captions 을 y 라 한다. + - 각각에 대한 embeddings 인 Z_i, Z_t 를 기존의 CLIP 으로 생성. + - image **x —CLIP Image encoder—> Z_i** image embeddings + - text caption **y —CLIP text encoder—> Z_t** text embeddings + + - 저자의 주장 + - unCLIP 으로, text caption y 로부터 image x 를 샘플링할 수 있다. + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2023.png) + + - ***The first equality holds because z_i is a deterministic function of x.*** + - ***The second equality holds because of the chain rule.*** + + - **내 부가 설명** + - z_t 도 y 의 deterministic function 이므로, 다음과 같이 쓸 수 있다. + + $$ + P(x|y) = P(x, z_i|y, z_t) = P(x|z_i, y, z_t)P(z_i|y, z_t) + $$ + + - Prior 를 사용해 Z_t 로부터 Z_i 를 샘플링하고, + Decoder 를 사용해 x 를 샘플링함으로써 + True conditional distribution 인 P(x|y) 샘플링이 가능해짐 + +- **DALL-E 2 Bias** + + [https://github.com/openai/dalle-2-preview/blob/main/system-card.md](https://github.com/openai/dalle-2-preview/blob/main/system-card.md) + + - **현재 OpenAI 가 DALL-E 2 의 Safety 를 위해 하고 있는 노력** + 1. 학습 데이터에서 violent, hate, or adult images 를 제거함으로써 + 이러한 이미지들에 DALL-E 2 가 노출되는 시간을 최소화함 + 2. Safety policies 를 위반한 text prompts 혹은 생성된 images 를 자정하는 시스템 보유 + 3. 신뢰할 수 있는 전문가들과 DALL-E 2 에 대한 사전 검토를 진행했음 + - **DALL-EVAL : 이미지 생성형 AI 의 Bias 를 평가하는 방법 소개** + + [https://arxiv.org/pdf/2202.04053.pdf](https://arxiv.org/pdf/2202.04053.pdf) + + [https://github.com/j-min/DallEval](https://github.com/j-min/DallEval) + + - **Contribution** + - Text to Image Generation models 의 시각적 추론 능력 3가지를 평가하기 위한 데이터셋 제공 + - 최근의 모델들이 object recognition skill 은 상대적으로 뛰어나지만, object counting 및 spaial relation 이해 능력은 떨어짐을 발견 + - Text to Image Generation models 에 존재하는 **gender 및 skin tone biases 를 측정하는 evaluation metrics 와 그 분석 결과를 제시한 최초의 논문** + - web 에서 image-text pairs 를 학습한 현재 T2I 생성 모델들은 특정한 gender/skin tone biases 를 학습했음을 보여줌 + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2024.png) + + - **Social Bias Evaluation 측정 방법 (Sec. 4.2.1 참고)** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2025.png) + + 1. **Diagnostic prompts 로 이미지들을 생성한다.** + 1. ex) “a person who works as a nurse” + 2. 총 252개의 Diagnostic prompts 제공 + 2. **Gender, Skin tone, Attributes 를 생성된 이미지로부터 탐지** + 1. using automated detection models and verify the reliability of detection models with human evaluation + 2. **Gender** + 1. BLIP-2 라는 모델에 생성된 영상을 주면서 영상 내 사람의 성별을 맞추게 함. BLIP-2 의 답변을 기반으로 Gender Bias 측정 + 3. **Skin tone** + 1. 신경망으로 facial landmark 를 추출하고, illumination 을 측정 + 4. **Attributes** + 1. BLIP-2 라는 모델에 생성된 영상을 주면서 영상 내 사람의 복장을 맞추게 함. BLIP-2 의 답변을 기반으로 Attributes Bias 측정 + 3. 탐지된 Gender, Skin tone, Attributes 가 unbiased uniform distribution 으로부터 얼마나 skewed 되어있는지 측정한다. + - **실험 결과** + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2026.png) + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2027.png) + + ![Untitled](DALL-E%202%20paper%2064d873e56fd8435b98a6713546cc2405/Untitled%2028.png) + + + +이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다. + +Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다. + +:::{figure-md} +img_01 + +Effect of Object Masking +::: + +Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다. + +:::{figure-md} +img_02 + +Imagen Editor Architecture +::: + +Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다. + +논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다. + +EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, *attribute-object-scene* 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다. + +- Attributes (material, color, shape, size, count) +- Objects (common, rare, text rendering) +- Scenes (indoor, outdoor, realistic, paintings) + +예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 *Mask-Simple*, *Mask-Rich*, 그리고 *Full* 로 정의합니다. + +:::{figure-md} +img_03 + +EditBench example +::: + +데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다. + +:::{figure-md} +img_04 + +Human Evaluations on EditBench +::: + +또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다. + +:::{figure-md} +img_05 + +Imagen Editor failure cases by attribute +::: + +마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다. + +:::{figure-md} +img_06 + +Example model outputs for Mask-Simple vs MaskRich prompts +::: diff --git a/_sources/docs/review/DDIM.md b/_sources/docs/review/DDIM.md old mode 100644 new mode 100755 index dfbc746c..24b69b78 --- a/_sources/docs/review/DDIM.md +++ b/_sources/docs/review/DDIM.md @@ -1,287 +1,287 @@ -```{admonition} Information -- **Title:** {Denoising Diffusion Implicit Models}, {ICLR 2021} - -- **Reference** - - Paper: [https://arxiv.org/abs/2010.02502](https://arxiv.org/abs/2010.02502) - - Code: [Official:](https://github.com/ermongroup/ddim) - -- **Author:** Seunghwan Ji - -- **Last updated on April. 23, 2023** -``` - -# DDIM -## Abstract - -- DDPM의 단점인 Markov Process를 Non markovian process로 정의함으로서 Time efficient, deterministic한 Sampling이 가능한 모델을 제안 - - Deterministic vs Stochastic - -## 1. Introduction - -- 생성 분야에서 GAN(Generative Adversarial Network)이 뛰어난 성능을 보여주고있다. -- 하지만, GAN은 학습 과정에서 불안정성을 보이는 경우가 많다. - - Generator와 Discriminator의 Imbalanced에 의한 Mode collapse -- 그러던 중, DDPM과 NCSN같은 adversarial training구조가 아닌 model들이 등장하였고 성공의 가능성을 보여주었다. -- 이 중 DDPM은 Forward Process에서 Markov Process를 거치는데 이때문에 GAN에 비해 매우 느린 Performance를 보여준다. - - - | sampling | GAN | DDPM | - | --- | --- | --- | - | 32 x 32 x 50k | Less than 1 min | About 20h | - | 256 x 256 x 50k | - | About 1000h | -- DDIM은, - 1. Markov Chain에 기반한 Process를 Non Markovian Process로 대체하였고 - 2. 결국 좀더 빠르고 비교적 우수한 Quality의 결과를 생성해내고, (with accelate) - 3. DDPM과는 다르게 Consistency한 학습 결과를 보여줌으로써 latent간의 Interpolation이 가능하다. - - Consistency? - - If x, y is equivalent, then f(x) = f(y) - -## 2. Background - -### DDPM - -:::{figure-md} markdown-fig -DDIM_00 - -DDPM & DDIM Architectures -::: - -- DDPM의 Forward Process는 Markov process로 동작한다. - - ***Markov process*** - - *미래 시점을 예측하기위해 현재 시점의 값을 이용한다.* - - *미래 시점은 과거 시점의 값에는 독립적인 값을 갖는다.* -- time step T는 DDPM에서 성능을 좌지우지하는 중요한 Hyper parameter이다. (대충 T=1000 정도?) -- 하지만, Sampling 과정에서 DDPM은 결국 T 번의 inference 과정을 모두 Sequential하게 거쳐야하고 이는 다른 Method(GAN 등)보다 현저히 느린 속도를 보이는 요소가 된다. - -## 3. Variational Inference For Non-Markovian Forward Process - -**3.1. Non-Markovian Forward Processes** - -- Inference’s Distribution 정의 - -:::{figure-md} markdown-fig -DDIM_01 - -Equation 1 -::: - -:::{figure-md} markdown-fig -DDIM_02 - -Equation 2 -::: -- t 시점의 값을 구하기위해 $X_{t-1}$의 값과 $X_{0}$의 값을 참조 - - DDPM은? $X_{t-1}$의 값만을 참조 - - σ는 Forward process의 stochastic한 정도를 조절하는 hyper parameter (chap 4 참조) - -**3.2. Generative Process And Unified Variational Inference Objective (Reverse Process)** - -:::{figure-md} markdown-fig -DDIM_00 - -Equation 3 -::: - -:::{figure-md} markdown-fig -DDIM_00 - -Equation 4 -::: - -1. $X_{t}$을 통해 $X_{0}$의 값을 예측 (trainable) -2. 위의 식을 통해 $X_{t}$와, $X_{0}$의 값을 이용해 $X_{t-1}$을 샘플링 - -실제로는 - -- noise(ε)와 $X_{0}$, $X_{t}$의 관계 - - :::{figure-md} markdown-fig - DDIM_05 - - Equation 5 - ::: - -1. $X_{t}$을 통해 $X_{0}$을 예측 - 1. t 시점의 이미지를 통해 t 시점의 noise를 예측 - 2. t 시점의 이미지와 t 시점의 noise를 통해 0 시점의 이미지를 계산 (fixed) -2. 위의 식을 통해 t시점의 값과 예측한 0 시점의 값을 이용해 t-1 시점의 값을 샘플링 - -## 4. Sampling From Generalized Generative Process - -4.1. Denoising Diffusion Implicit Models - -1. If σ → 0 - -:::{figure-md} markdown-fig -DDIM_06 - -Equation 6 -::: - -1. σ가 특정 값을 가질 때 DDPM의 generative process의 수식과 동일하다. -:::{figure-md} markdown-fig -DDIM_07 - -Explanation of σ -::: -4.2. Accelerated Generation Processes -:::{figure-md} markdown-fig -DDIM_08 - -Explanation of accelated method -::: - -- DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다. -- 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다. -- **DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.** - -4.3. Relevance To Neural ODEs - -- DDIM은 Object(e.g. 이미지)의 Encoding이 가능한 식을 유도할 수 있다. - -## 5. Experiments -:::{figure-md} markdown-fig -DDIM_09 - -Table1 -::: - -:::{figure-md} markdown-fig -DDIM_010 - -Euqation 7 -::: -- η → model을 simple하게 control하기위한 hyperparameter - - η = 1 → Model is DDPM - - η = 0 → Model is DDIM -- 모든 비교 모델이 S(sampling 횟수)의 값이 커질수록 더 낮은 FiD를 보여준다. -- Fig.3의 DDIM은 다른 모델(η가 0이 아닌 모델)과 다르게 sampling step에 consistency한 결과를 보여준다. - -:::{figure-md} markdown-fig -DDIM_011 - -Figure 4, 5 -::: -- Step과 Inference time이 linear한 관계를 갖는다. -- 적은 sampling step에서도 어느정도의 object를 보여준다. -:::{figure-md} markdown-fig -DDIM_012 - -Figure 6 -::: -- T 시점의 이미지에 interpolation이 가능하다. - -## 6. Code - -```python -# https://keras.io/examples/generative/ddim/ -class DiffusionModel(keras.Model): - def __init__(self, image_size, widths, block_depth): - super().__init__() - - self.normalizer = layers.Normalization() - self.network = get_network(image_size, widths, block_depth) # unet 구조 - - def denormalize(self, images): - # convert the pixel values back to 0-1 range - images = self.normalizer.mean + images * self.normalizer.variance**0.5 - return tf.clip_by_value(images, 0.0, 1.0) - - def diffusion_schedule(self, diffusion_times): - # diffusion times -> angles - start_angle = tf.acos(max_signal_rate) - end_angle = tf.acos(min_signal_rate) - - diffusion_angles = start_angle + diffusion_times * (end_angle - start_angle) - - # angles -> signal and noise rates - signal_rates = tf.cos(diffusion_angles) - noise_rates = tf.sin(diffusion_angles) - # note that their squared sum is always: sin^2(x) + cos^2(x) = 1 - - return noise_rates, signal_rates - - def denoise(self, noisy_images, noise_rates, signal_rates, training): - # the exponential moving average weights are used at evaluation - if training: - network = self.network - else: - network = self.ema_network - - # predict noise component and calculate the image component using it - pred_noises = network([noisy_images, noise_rates**2], training=training) - pred_images = (noisy_images - noise_rates * pred_noises) / signal_rates - - return pred_noises, pred_images - - - - def train_step(self, images): - # normalize images to have standard deviation of 1, like the noises - images = self.normalizer(images, training=True) - noises = tf.random.normal(shape=(batch_size, image_size, image_size, 3)) - - # sample uniform random diffusion times - diffusion_times = tf.random.uniform( - shape=(batch_size, 1, 1, 1), minval=0.0, maxval=1.0 - ) - noise_rates, signal_rates = self.diffusion_schedule(diffusion_times) - # mix the images with noises accordingly - noisy_images = signal_rates * images + noise_rates * noises - - with tf.GradientTape() as tape: - # train the network to separate noisy images to their components - pred_noises, pred_images = self.denoise( - noisy_images, noise_rates, signal_rates, training=True - ) - - noise_loss = self.loss(noises, pred_noises) # used for training - image_loss = self.loss(images, pred_images) # only used as metric - - gradients = tape.gradient(noise_loss, self.network.trainable_weights) - self.optimizer.apply_gradients(zip(gradients, self.network.trainable_weights)) - - self.noise_loss_tracker.update_state(noise_loss) - self.image_loss_tracker.update_state(image_loss) - - return {m.name: m.result() for m in self.metrics[:-1]} - - def reverse_diffusion(self, initial_noise, diffusion_steps): - # reverse diffusion = sampling - num_images = initial_noise.shape[0] - step_size = 1.0 / diffusion_steps - - # important line: - # at the first sampling step, the "noisy image" is pure noise - # but its signal rate is assumed to be nonzero (min_signal_rate) - next_noisy_images = initial_noise - for step in range(diffusion_steps): - noisy_images = next_noisy_images - - # separate the current noisy image to its components - diffusion_times = tf.ones((num_images, 1, 1, 1)) - step * step_size - noise_rates, signal_rates = self.diffusion_schedule(diffusion_times) - pred_noises, pred_images = self.denoise( - noisy_images, noise_rates, signal_rates, training=False - ) - # network used in eval mode - - # remix the predicted components using the next signal and noise rates - next_diffusion_times = diffusion_times - step_size - next_noise_rates, next_signal_rates = self.diffusion_schedule( - next_diffusion_times - ) - next_noisy_images = ( - next_signal_rates * pred_images + next_noise_rates * pred_noises - ) - # this new noisy image will be used in the next step - - return pred_images - - def generate(self, num_images, diffusion_steps): - # noise -> images -> denormalized images - initial_noise = tf.random.normal(shape=(num_images, image_size, image_size, 3)) - generated_images = self.reverse_diffusion(initial_noise, diffusion_steps) - generated_images = self.denormalize(generated_images) - return generated_images -``` +```{admonition} Information +- **Title:** {Denoising Diffusion Implicit Models}, {ICLR 2021} + +- **Reference** + - Paper: [https://arxiv.org/abs/2010.02502](https://arxiv.org/abs/2010.02502) + - Code: [Official:](https://github.com/ermongroup/ddim) + +- **Author:** Seunghwan Ji + +- **Last updated on April. 23, 2023** +``` + +# DDIM +## Abstract + +- DDPM의 단점인 Markov Process를 Non markovian process로 정의함으로서 Time efficient, deterministic한 Sampling이 가능한 모델을 제안 + - Deterministic vs Stochastic + +## 1. Introduction + +- 생성 분야에서 GAN(Generative Adversarial Network)이 뛰어난 성능을 보여주고있다. +- 하지만, GAN은 학습 과정에서 불안정성을 보이는 경우가 많다. + - Generator와 Discriminator의 Imbalanced에 의한 Mode collapse +- 그러던 중, DDPM과 NCSN같은 adversarial training구조가 아닌 model들이 등장하였고 성공의 가능성을 보여주었다. +- 이 중 DDPM은 Forward Process에서 Markov Process를 거치는데 이때문에 GAN에 비해 매우 느린 Performance를 보여준다. + + + | sampling | GAN | DDPM | + | --- | --- | --- | + | 32 x 32 x 50k | Less than 1 min | About 20h | + | 256 x 256 x 50k | - | About 1000h | +- DDIM은, + 1. Markov Chain에 기반한 Process를 Non Markovian Process로 대체하였고 + 2. 결국 좀더 빠르고 비교적 우수한 Quality의 결과를 생성해내고, (with accelate) + 3. DDPM과는 다르게 Consistency한 학습 결과를 보여줌으로써 latent간의 Interpolation이 가능하다. + - Consistency? + - If x, y is equivalent, then f(x) = f(y) + +## 2. Background + +### DDPM + +:::{figure-md} markdown-fig +DDIM_00 + +DDPM & DDIM Architectures +::: + +- DDPM의 Forward Process는 Markov process로 동작한다. + - ***Markov process*** + - *미래 시점을 예측하기위해 현재 시점의 값을 이용한다.* + - *미래 시점은 과거 시점의 값에는 독립적인 값을 갖는다.* +- time step T는 DDPM에서 성능을 좌지우지하는 중요한 Hyper parameter이다. (대충 T=1000 정도?) +- 하지만, Sampling 과정에서 DDPM은 결국 T 번의 inference 과정을 모두 Sequential하게 거쳐야하고 이는 다른 Method(GAN 등)보다 현저히 느린 속도를 보이는 요소가 된다. + +## 3. Variational Inference For Non-Markovian Forward Process + +**3.1. Non-Markovian Forward Processes** + +- Inference’s Distribution 정의 + +:::{figure-md} markdown-fig +DDIM_01 + +Equation 1 +::: + +:::{figure-md} markdown-fig +DDIM_02 + +Equation 2 +::: +- t 시점의 값을 구하기위해 $X_{t-1}$의 값과 $X_{0}$의 값을 참조 + - DDPM은? $X_{t-1}$의 값만을 참조 + - σ는 Forward process의 stochastic한 정도를 조절하는 hyper parameter (chap 4 참조) + +**3.2. Generative Process And Unified Variational Inference Objective (Reverse Process)** + +:::{figure-md} markdown-fig +DDIM_00 + +Equation 3 +::: + +:::{figure-md} markdown-fig +DDIM_00 + +Equation 4 +::: + +1. $X_{t}$을 통해 $X_{0}$의 값을 예측 (trainable) +2. 위의 식을 통해 $X_{t}$와, $X_{0}$의 값을 이용해 $X_{t-1}$을 샘플링 + +실제로는 + +- noise(ε)와 $X_{0}$, $X_{t}$의 관계 + + :::{figure-md} markdown-fig + DDIM_05 + + Equation 5 + ::: + +1. $X_{t}$을 통해 $X_{0}$을 예측 + 1. t 시점의 이미지를 통해 t 시점의 noise를 예측 + 2. t 시점의 이미지와 t 시점의 noise를 통해 0 시점의 이미지를 계산 (fixed) +2. 위의 식을 통해 t시점의 값과 예측한 0 시점의 값을 이용해 t-1 시점의 값을 샘플링 + +## 4. Sampling From Generalized Generative Process + +4.1. Denoising Diffusion Implicit Models + +1. If σ → 0 + +:::{figure-md} markdown-fig +DDIM_06 + +Equation 6 +::: + +1. σ가 특정 값을 가질 때 DDPM의 generative process의 수식과 동일하다. +:::{figure-md} markdown-fig +DDIM_07 + +Explanation of σ +::: +4.2. Accelerated Generation Processes +:::{figure-md} markdown-fig +DDIM_08 + +Explanation of accelated method +::: + +- DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다. +- 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다. +- **DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.** + +4.3. Relevance To Neural ODEs + +- DDIM은 Object(e.g. 이미지)의 Encoding이 가능한 식을 유도할 수 있다. + +## 5. Experiments +:::{figure-md} markdown-fig +DDIM_09 + +Table1 +::: + +:::{figure-md} markdown-fig +DDIM_010 + +Euqation 7 +::: +- η → model을 simple하게 control하기위한 hyperparameter + - η = 1 → Model is DDPM + - η = 0 → Model is DDIM +- 모든 비교 모델이 S(sampling 횟수)의 값이 커질수록 더 낮은 FiD를 보여준다. +- Fig.3의 DDIM은 다른 모델(η가 0이 아닌 모델)과 다르게 sampling step에 consistency한 결과를 보여준다. + +:::{figure-md} markdown-fig +DDIM_011 + +Figure 4, 5 +::: +- Step과 Inference time이 linear한 관계를 갖는다. +- 적은 sampling step에서도 어느정도의 object를 보여준다. +:::{figure-md} markdown-fig +DDIM_012 + +Figure 6 +::: +- T 시점의 이미지에 interpolation이 가능하다. + +## 6. Code + +```python +# https://keras.io/examples/generative/ddim/ +class DiffusionModel(keras.Model): + def __init__(self, image_size, widths, block_depth): + super().__init__() + + self.normalizer = layers.Normalization() + self.network = get_network(image_size, widths, block_depth) # unet 구조 + + def denormalize(self, images): + # convert the pixel values back to 0-1 range + images = self.normalizer.mean + images * self.normalizer.variance**0.5 + return tf.clip_by_value(images, 0.0, 1.0) + + def diffusion_schedule(self, diffusion_times): + # diffusion times -> angles + start_angle = tf.acos(max_signal_rate) + end_angle = tf.acos(min_signal_rate) + + diffusion_angles = start_angle + diffusion_times * (end_angle - start_angle) + + # angles -> signal and noise rates + signal_rates = tf.cos(diffusion_angles) + noise_rates = tf.sin(diffusion_angles) + # note that their squared sum is always: sin^2(x) + cos^2(x) = 1 + + return noise_rates, signal_rates + + def denoise(self, noisy_images, noise_rates, signal_rates, training): + # the exponential moving average weights are used at evaluation + if training: + network = self.network + else: + network = self.ema_network + + # predict noise component and calculate the image component using it + pred_noises = network([noisy_images, noise_rates**2], training=training) + pred_images = (noisy_images - noise_rates * pred_noises) / signal_rates + + return pred_noises, pred_images + + + + def train_step(self, images): + # normalize images to have standard deviation of 1, like the noises + images = self.normalizer(images, training=True) + noises = tf.random.normal(shape=(batch_size, image_size, image_size, 3)) + + # sample uniform random diffusion times + diffusion_times = tf.random.uniform( + shape=(batch_size, 1, 1, 1), minval=0.0, maxval=1.0 + ) + noise_rates, signal_rates = self.diffusion_schedule(diffusion_times) + # mix the images with noises accordingly + noisy_images = signal_rates * images + noise_rates * noises + + with tf.GradientTape() as tape: + # train the network to separate noisy images to their components + pred_noises, pred_images = self.denoise( + noisy_images, noise_rates, signal_rates, training=True + ) + + noise_loss = self.loss(noises, pred_noises) # used for training + image_loss = self.loss(images, pred_images) # only used as metric + + gradients = tape.gradient(noise_loss, self.network.trainable_weights) + self.optimizer.apply_gradients(zip(gradients, self.network.trainable_weights)) + + self.noise_loss_tracker.update_state(noise_loss) + self.image_loss_tracker.update_state(image_loss) + + return {m.name: m.result() for m in self.metrics[:-1]} + + def reverse_diffusion(self, initial_noise, diffusion_steps): + # reverse diffusion = sampling + num_images = initial_noise.shape[0] + step_size = 1.0 / diffusion_steps + + # important line: + # at the first sampling step, the "noisy image" is pure noise + # but its signal rate is assumed to be nonzero (min_signal_rate) + next_noisy_images = initial_noise + for step in range(diffusion_steps): + noisy_images = next_noisy_images + + # separate the current noisy image to its components + diffusion_times = tf.ones((num_images, 1, 1, 1)) - step * step_size + noise_rates, signal_rates = self.diffusion_schedule(diffusion_times) + pred_noises, pred_images = self.denoise( + noisy_images, noise_rates, signal_rates, training=False + ) + # network used in eval mode + + # remix the predicted components using the next signal and noise rates + next_diffusion_times = diffusion_times - step_size + next_noise_rates, next_signal_rates = self.diffusion_schedule( + next_diffusion_times + ) + next_noisy_images = ( + next_signal_rates * pred_images + next_noise_rates * pred_noises + ) + # this new noisy image will be used in the next step + + return pred_images + + def generate(self, num_images, diffusion_steps): + # noise -> images -> denormalized images + initial_noise = tf.random.normal(shape=(num_images, image_size, image_size, 3)) + generated_images = self.reverse_diffusion(initial_noise, diffusion_steps) + generated_images = self.denormalize(generated_images) + return generated_images +``` diff --git a/_sources/docs/review/DDPM.md b/_sources/docs/review/DDPM.md old mode 100644 new mode 100755 index bdee959d..03bebbc0 --- a/_sources/docs/review/DDPM.md +++ b/_sources/docs/review/DDPM.md @@ -1,509 +1,509 @@ -```{admonition} Information -- **Title:** Denoising Diffusion Probabilistic Models (ICLR 2021) - -- **Reference** - - Paper: [https://arxiv.org/abs/2006.11239](https://arxiv.org/abs/2006.11239) - - Code: [PyTorch implementation:](https://github.com/lucidrains/denoising-diffusion-pytorch) - - Review: [PR-409: Denoising Diffusion Probabilistic Models](https://www.youtube.com/watch?v=1j0W_lu55nc) - -- **Author:** Beomsoo Park - -- **Last updated on Apr. 19, 2023** -``` - - -# DDPM - - -:::{figure-md} markdown-fig -DDPM_01 - -DDPM samples \ (source: https://arxiv.org/abs/2006.11239) -::: - - ---- -# 1. Introduction - -:::{figure-md} markdown-fig -DDPM_02 - -Diffusion models \ (source: https://velog.io/@yetsyl0705/What-are-Diffusion-Models) -::: - -**Diffusion model**은 **variational inference로 학습시켜 데이터를 생성하는 parameterized Markov chain**. Diffusion model은 Markov가 데이터가 normal distribution의 형태를 할 때까지 **noise를 더해가는 diffusion process**와 **이를 역으로 거치며 학습하는 reverse process**로 구성됨. - -Diffusion model은 정의하기 쉽고 학습시키는 것도 편리함. 또한 높은 품질의 sample(output)도 생성이 가능. - -> - **Variational inference(변분추론)**: 사후확률(posterior) 분포 $p(z -|x)$를 다루기 쉬운 확률분포 $q(z)$로 근사(approximation)하는 것 -> - **Parameterize**: 하나의 표현식에 대해 다른 parameter를 사용하여 다시 표현하는 과정. 이 과정에서 보통 parameter의 개수를 표현 식의 차수보다 적은 수로 선택(ex. 3차 표현식 --> 2개 parameter 사용)하므로, 낮은 차수로의 mapping 함수(ex. 3D --> 2D)가 생성 -> - **Markov chain**: 어떤 상태에서 다른 상태로 넘어갈 때, 바로 전 단계의 상태에만 영향을 받는 확률 과정 - ---- -# 2. Background - -:::{figure-md} markdown-fig -DDPM_03 - -Graphical model of DDPM \ (source: https://arxiv.org/abs/2006.11239) -::: - -## 2-1. Forward(diffusion) process $q(\mathbf{x}_t|\mathbf{x}_{t-1})$ - -$$ -q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right):=\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right), \quad q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right):=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{1-\beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I}\right) -$$ - -Markov chain으로 **data에 noise를 추가**하는 과정. Noise를 추가할 때 **variance schedule $\beta_1,,,\beta_T$로 scaling**을 한 후 더해준다. -- $\beta_t = 1$이면 mean인 $\sqrt{1-\beta_t}\mathbf{x}_{t-1} = 0$. 이전 정보를 갖지 못하고 노이즈가 증가함 -- 단순히 noise만을 더해주는게 아니라 $\sqrt{1-\beta_t}$로 scaling하는 이유는 variance가 발산하는 것을 막기 위함 -- $q(x_1|x_0)$: $x_0$에 noise를 추가해 $x_1$을 만드는 과정 -- $x_T$는 완전 destroy된 noise 상태 ~ $N(x_T;0, I)$ - -## 2-2. Reverse process $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$ - -$$ -p_\theta\left(\mathbf{x}_{0: T}\right):=p\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right), \quad p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right):=\mathcal{N}\left(\mathbf{x}_{t-1} ; \boldsymbol{\mu}_\theta\left(\mathbf{x}_t, t\right), \boldsymbol{\Sigma}_\theta\left(\mathbf{x}_t, t\right)\right) -$$ - -Reverse process로 가우시안 노이즈를 사용하는 이유는 1994년 논문에 forward process가 가우시안이면 reverse process도 가우시안으로 쓰면 된다라는 증명이 있다고 함. - -여기서 우리가 해야 할 것은 **$\mathbf{x}_t$를 보고 $\mathbf{x}_{t-1}$의 평균 $\mu_\theta$과 분산 $\Sigma_\theta$을 예측해내는 것**. -- Hierarachical VAE에서의 decoding 과정과 비슷함 -- $\mu_\theta$과 분산 $\Sigma_\theta$는 학습 가능한 parameter - - -## 2-3. Loss Function $L$ - -Diffusion model의 목적은 **noise를 어떻게 제거할 것인가?**이다. $x_t$가 들어왔을 때 $x_{t-1}$을 예측할 수 있다면 $x_0$ 또한 예측이 가능해짐. - -$$ -\mathbb{E}\left[-\log p_\theta\left(\mathbf{x}_0\right)\right] \leq \mathbb{E}_q\left[-\log \frac{p_\theta\left(\mathbf{x}_{0: T}\right)}{q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right)}\right]=\mathbb{E}_q\left[-\log p\left(\mathbf{x}_T\right)-\sum_{t \geq 1} \log \frac{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}\right]=: L -$$ - -본 논문에서는 **negative log likelihood를 최소화**하는 방향으로 진행. 위 수식을 **ELBO**(Evidence of Lower BOund)로 우항과 같이 정리하고 이를 풀어내면 - -> ELBO의 역할은 우리가 관찰한 P(z|x)가 다루기 힘든 분포를 이루고 있을 때 이를 조금 더 다루기 쉬운 분포인 Q(x)로 대신 표현하려 하는 과정에서 **두 분포 (P(z|x)와 Q(x))의 차이 (KL Divergence)를 최소화** 하기 위해 사용된다. - -$$ -\mathbb{E}_q[\underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_T \mid \mathbf{x}_0\right) \| p\left(\mathbf{x}_T\right)\right)}_{L_T}+\sum_{t>1} \underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)\right)}_{L_{t-1}} \underbrace{-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}_{L_0}] -$$ - -와 같은 결과가 나온다. - -- $L_T$: Regularization term으로 $\beta_t$를 학습시킴 -- $L_{t-1}$: Reconstruction term으로 매 단계에서 noise를 지우는 지움 -- $L_0$: Reconstruction term으로 최종 단계에서 image를 생성 - ---- -# 3. Diffusion models and denoising encoders - -DDPM에서는 **inductive bias를 늘려** 모델을 더 stable하고 성능도 개선할 수 있었음. - -> Inductive bias: 학습 모델이 지금까지 만나보지 못했던 상황에서 정확한 예측을 하기 위해 사용하는 **추가적인 가정**, 즉 우리가 풀려는 문제에 대한 정보를 모델에 적용하는 것 - - -## 3-1. Forward process and $L_T$ - -**$\beta_t$를 고정**했더니 학습이 잘됨. 10^-4 ~ 0.02로 linear하게 image에 가까울수록 noise를 적게 주는 방식으로 설정. - -따라서 $q$에는 학습 가능한 parameter가 없어 **$L_T$는 0이 되기 때문에 삭제**할 수 있었음. - -## 3-2. Reverse process and $L_{1:T-1}$ - - -$$ -L_{t-1}=D_{K L}\left(q\left(x_{t-1} \mid x_t, x_0\right) \| p_\theta\left(x_{t-1} \mid x_t\right)\right) -$$ - -- $ -q\left(x_{t-1} \mid x_t, x_0\right)=N\left(x_{t-1} ; \tilde{\mu}\left(x_t, x_0\right), \tilde{\beta}_t \mathrm{I}\right) -$ -- $ -p_\theta\left(x_{t-1} \mid x_t\right)=\mathcal{N}\left(x_{t-1} ; \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) -$ - - -$L_{1:T-1}$는 forward progress posterior를 예측하는 loss. $\mathbf{x}_{t-1}$에서 noise를 더해 $\mathbf{x}_{t}$를 만들었을때, 그 과정을 복원 $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$ 하는 과정을 학습. - -:::{figure-md} markdown-fig -DDPM_08 - -Loss Simplication \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) -::: - -- $\Sigma_\theta$: $\beta$를 상수로 가정했고 $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$의 variance가 $\beta$에 영향을 받기 때문에 학습시키지 않아도 된다고 생각해 **variance term을 제거**함. - -:::{figure-md} markdown-fig -DDPM_09 - -Residual Estimation \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) -::: - -- $\mu_\theta$: DDPM에서는 $\mu_\theta$를 바로 구하지 않고 **residual $\epsilon_\theta$만 구해 정확도를 높임**. - -## 3-3. Data scaling, reverse process decoder and $L_0$ - -$$ -\begin{aligned} -p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right) & =\prod_{i=1}^D \int_{\delta_{-}\left(x_0^i\right)}^{\delta_{+}\left(x_0^i\right)} \mathcal{N}\left(x ; \mu_\theta^i\left(\mathbf{x}_1, 1\right), \sigma_1^2\right) d x \\ -\delta_{+}(x) & =\left\{\begin{array}{ll} -\infty & \text { if } x=1 \\ -x+\frac{1}{255} & \text { if } x<1 -\end{array} \quad \delta_{-}(x)= \begin{cases}-\infty & \text { if } x=-1 \\ -x-\frac{1}{255} & \text { if } x>-1\end{cases} \right. -\end{aligned} -$$ - -[0, 255]의 image를 [-1,1] 사이로 linearly mapping. Sampling 마지막 단계에는 noise를 추가하지 않음. - - -$L_0$은 두 normal distribution 사이의 KL divergence를 나타냄. -- $D$: Data dimensionality -- $i$: 좌표 - - -## 3-4. Simplified training objective - -:::{figure-md} markdown-fig -DDPM_10 - -Simplified training objective \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) -::: - -:::{figure-md} markdown-fig -DDPM_11 - -Final Loss \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) -::: - -최종 loss는 위와 같이 나타난다. Ground truth - estimated output간 MSE loss를 줄이는 과정이 denoising과 비슷해 DDPM이라는 이름이 붙음. - -Simplified objective을 통해 diffusion process를 학습하면 매우 작은 t 에서뿐만 아니라 **큰 t에 대해서도 network 학습이 가능하기 때문에 매우 효과적**. - -:::{figure-md} markdown-fig -DDPM_12 - -Psuedo code of training process \ (source: https://arxiv.org/abs/2006.11239) -::: - -- Algorithm 1: Training - - Noise를 더해나가는 과정, network($\epsilon_\theta$, $p_\theta$)가 t step에서 noise($\epsilon$)가 얼마만큼 더해졌는지를 학습한다. - - 학습 시에는 특정 step의 이미지가 얼마나 gaussian noise가 추가되었는지를 예측하도록 학습된다. - - 코드에서는 랜덤 노이즈와 시간 단계 t로 노이즈가 추가된 이미지를 얻고 해당 이미지를 보고 모델이 노이즈를 예측 - -```python -def p_losses(self, x_start, t, noise = None): - b, c, h, w = x_start.shape - noise = default(noise, lambda: torch.randn_like(x_start)) - - # noise sample - - x = self.q_sample(x_start = x_start, t = t, noise = noise) - - # if doing self-conditioning, 50% of the time, predict x_start from current set of times - # and condition with unet with that - # this technique will slow down training by 25%, but seems to lower FID significantly - - x_self_cond = None - if self.self_condition and random() < 0.5: - with torch.no_grad(): - x_self_cond = self.model_predictions(x, t).pred_x_start - x_self_cond.detach_() - - # predict and take gradient step - - model_out = self.model(x, t, x_self_cond) - - if self.objective == 'pred_noise': - target = noise - elif self.objective == 'pred_x0': - target = x_start - elif self.objective == 'pred_v': - v = self.predict_v(x_start, t, noise) - target = v - else: - raise ValueError(f'unknown objective {self.objective}') - - loss = self.loss_fn(model_out, target, reduction = 'none') - loss = reduce(loss, 'b ... -> b (...)', 'mean') - - loss = loss * extract(self.loss_weight, t, loss.shape) - return loss.mean() - ``` - -- Algorithm 2: Sampling - - Network를 학습하고 나면, gaussian noise에서 시작해서 순차적으로 denoising 하는 것이 가능하다. (by parameterized markovian chain) - - 코드에서는 noise 제거 후 소량의 noise를 다시 추가하고 있음 - -```python -@torch.no_grad() -def p_sample(self, x, t: int, x_self_cond = None): - b, *_, device = *x.shape, x.device - batched_times = torch.full((b,), t, device = x.device, dtype = torch.long) - model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = True) - noise = torch.randn_like(x) if t > 0 else 0. # no noise if t == 0 - pred_img = model_mean + (0.5 * model_log_variance).exp() * noise - return pred_img, x_start -``` - - - -# 4. Experiments - -- T: 1000 -- backbone: U-Net -각 down/upsampling 단계는 ResNet/ConvNext 블록 2개 + (groupnorm + attention + residual) + down/upsampling으로 구성됨 - -```python -block_klass = partial(ResnetBlock, groups = resnet_block_groups) - -self.downs.append(nn.ModuleList([ - block_klass(dim_in, dim_in, time_emb_dim = time_dim), - block_klass(dim_in, dim_in, time_emb_dim = time_dim), - Residual(PreNorm(dim_in, LinearAttention(dim_in))), - Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1) - ])) - - self.ups.append(nn.ModuleList([ - block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), - block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), - Residual(PreNorm(dim_out, LinearAttention(dim_out))), - Upsample(dim_out, dim_in) if not is_last else nn.Conv2d(dim_out, dim_in, 3, padding = 1) - ])) - -``` - - -```python -class Unet(nn.Module): - def __init__( - self, - dim, - init_dim = None, - out_dim = None, - dim_mults=(1, 2, 4, 8), - channels = 3, - self_condition = False, - resnet_block_groups = 8, - learned_variance = False, - learned_sinusoidal_cond = False, - random_fourier_features = False, - learned_sinusoidal_dim = 16 - ): - super().__init__() - - # determine dimensions - - self.channels = channels - self.self_condition = self_condition - input_channels = channels * (2 if self_condition else 1) - - init_dim = default(init_dim, dim) - self.init_conv = nn.Conv2d(input_channels, init_dim, 7, padding = 3) - - dims = [init_dim, *map(lambda m: dim * m, dim_mults)] - in_out = list(zip(dims[:-1], dims[1:])) - - block_klass = partial(ResnetBlock, groups = resnet_block_groups) - - # time embeddings - - time_dim = dim * 4 - - self.random_or_learned_sinusoidal_cond = learned_sinusoidal_cond or random_fourier_features - - if self.random_or_learned_sinusoidal_cond: - sinu_pos_emb = RandomOrLearnedSinusoidalPosEmb(learned_sinusoidal_dim, random_fourier_features) - fourier_dim = learned_sinusoidal_dim + 1 - else: - sinu_pos_emb = SinusoidalPosEmb(dim) - fourier_dim = dim - - self.time_mlp = nn.Sequential( - sinu_pos_emb, - nn.Linear(fourier_dim, time_dim), - nn.GELU(), - nn.Linear(time_dim, time_dim) - ) - - # layers - - self.downs = nn.ModuleList([]) - self.ups = nn.ModuleList([]) - num_resolutions = len(in_out) - - for ind, (dim_in, dim_out) in enumerate(in_out): - is_last = ind >= (num_resolutions - 1) - - self.downs.append(nn.ModuleList([ - block_klass(dim_in, dim_in, time_emb_dim = time_dim), - block_klass(dim_in, dim_in, time_emb_dim = time_dim), - Residual(PreNorm(dim_in, LinearAttention(dim_in))), - Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1) - ])) - - mid_dim = dims[-1] - self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) - self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim))) - self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) - - for ind, (dim_in, dim_out) in enumerate(reversed(in_out)): - is_last = ind == (len(in_out) - 1) - - self.ups.append(nn.ModuleList([ - block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), - block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), - Residual(PreNorm(dim_out, LinearAttention(dim_out))), - Upsample(dim_out, dim_in) if not is_last else nn.Conv2d(dim_out, dim_in, 3, padding = 1) - ])) - - default_out_dim = channels * (1 if not learned_variance else 2) - self.out_dim = default(out_dim, default_out_dim) - - self.final_res_block = block_klass(dim * 2, dim, time_emb_dim = time_dim) - self.final_conv = nn.Conv2d(dim, self.out_dim, 1) - - def forward(self, x, time, x_self_cond = None): - if self.self_condition: - x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x)) - x = torch.cat((x_self_cond, x), dim = 1) - - x = self.init_conv(x) - r = x.clone() - - t = self.time_mlp(time) - - h = [] - - for block1, block2, attn, downsample in self.downs: - x = block1(x, t) - h.append(x) - - x = block2(x, t) - x = attn(x) - h.append(x) - - x = downsample(x) - - x = self.mid_block1(x, t) - x = self.mid_attn(x) - x = self.mid_block2(x, t) - - for block1, block2, attn, upsample in self.ups: - x = torch.cat((x, h.pop()), dim = 1) - x = block1(x, t) - - x = torch.cat((x, h.pop()), dim = 1) - x = block2(x, t) - x = attn(x) - - x = upsample(x) - - x = torch.cat((x, r), dim = 1) - - x = self.final_res_block(x, t) - return self.final_conv(x) -``` - - - -- 16 x 16 feature map resolution에 self-attention. conv에서 차원을 3배로 늘리고 q,k,v로 분해. - -```python -class Attention(nn.Module): - def __init__(self, dim, heads = 4, dim_head = 32): - super().__init__() - self.scale = dim_head ** -0.5 - self.heads = heads - hidden_dim = dim_head * heads - - self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False) - self.to_out = nn.Conv2d(hidden_dim, dim, 1) - - def forward(self, x): - b, c, h, w = x.shape - qkv = self.to_qkv(x).chunk(3, dim = 1) - q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv) - - q = q * self.scale - - sim = einsum('b h d i, b h d j -> b h i j', q, k) - attn = sim.softmax(dim = -1) - out = einsum('b h i j, b h d j -> b h i d', attn, v) - - out = rearrange(out, 'b h (x y) d -> b (h d) x y', x = h, y = w) - return self.to_out(out) -``` - -- Linear attention -```python -class LinearAttention(nn.Module): - def __init__(self, dim, heads = 4, dim_head = 32): - super().__init__() - self.scale = dim_head ** -0.5 - self.heads = heads - hidden_dim = dim_head * heads - self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False) - - self.to_out = nn.Sequential( - nn.Conv2d(hidden_dim, dim, 1), - LayerNorm(dim) - ) - - def forward(self, x): - b, c, h, w = x.shape - qkv = self.to_qkv(x).chunk(3, dim = 1) - q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv) - - q = q.softmax(dim = -2) - k = k.softmax(dim = -1) - - q = q * self.scale - v = v / (h * w) - - context = torch.einsum('b h d n, b h e n -> b h d e', k, v) - - out = torch.einsum('b h d e, b h d n -> b h e n', context, q) - out = rearrange(out, 'b h c (x y) -> b (h c) x y', h = self.heads, x = h, y = w) - return self.to_out(out) -``` - -- Diffusion time $T$는 각 residual block에 transformer sinusoidal positional embedding이 추가돼서 구분됨 - -```python -class SinusoidalPosEmb(nn.Module): - def __init__(self, dim): - super().__init__() - self.dim = dim - - def forward(self, x): - device = x.device - half_dim = self.dim // 2 - emb = math.log(10000) / (half_dim - 1) - emb = torch.exp(torch.arange(half_dim, device=device) * -emb) - emb = x[:, None] * emb[None, :] - emb = torch.cat((emb.sin(), emb.cos()), dim=-1) - return emb -``` - -## 4-1. Sample quality - -:::{figure-md} markdown-fig -DDPM_13 - -Train score of DDPM \ (source: https://arxiv.org/abs/2006.11239) -::: - -FID, IS로 metric 계산. Unconditional model인데도 conditional model보다 우월. Codelength에서 차이가 없기 때문에 overfitting의 가능성도 적음. - -> - **FID score**: Inception V3으로 이미지의 분포를 계산한 metric -> - **Unconditional model**: 한번 dataset에 학습되면 추가적인 context 없이 image를 생성 -> - **Conditional model**: Class, label 등의 추가 정보를 받아 image를 생성 - -$\mu$보다 $\epsilon$을 계산하는 것이 성적이 좋고, fixed variance를 사용했을 때에도 성능이 감소하지 않음. - - - - +```{admonition} Information +- **Title:** Denoising Diffusion Probabilistic Models (ICLR 2021) + +- **Reference** + - Paper: [https://arxiv.org/abs/2006.11239](https://arxiv.org/abs/2006.11239) + - Code: [PyTorch implementation:](https://github.com/lucidrains/denoising-diffusion-pytorch) + - Review: [PR-409: Denoising Diffusion Probabilistic Models](https://www.youtube.com/watch?v=1j0W_lu55nc) + +- **Author:** Beomsoo Park + +- **Last updated on Apr. 19, 2023** +``` + + +# DDPM + + +:::{figure-md} markdown-fig +DDPM_01 + +DDPM samples \ (source: https://arxiv.org/abs/2006.11239) +::: + + +--- +# 1. Introduction + +:::{figure-md} markdown-fig +DDPM_02 + +Diffusion models \ (source: https://velog.io/@yetsyl0705/What-are-Diffusion-Models) +::: + +**Diffusion model**은 **variational inference로 학습시켜 데이터를 생성하는 parameterized Markov chain**. Diffusion model은 Markov가 데이터가 normal distribution의 형태를 할 때까지 **noise를 더해가는 diffusion process**와 **이를 역으로 거치며 학습하는 reverse process**로 구성됨. + +Diffusion model은 정의하기 쉽고 학습시키는 것도 편리함. 또한 높은 품질의 sample(output)도 생성이 가능. + +> - **Variational inference(변분추론)**: 사후확률(posterior) 분포 $p(z +|x)$를 다루기 쉬운 확률분포 $q(z)$로 근사(approximation)하는 것 +> - **Parameterize**: 하나의 표현식에 대해 다른 parameter를 사용하여 다시 표현하는 과정. 이 과정에서 보통 parameter의 개수를 표현 식의 차수보다 적은 수로 선택(ex. 3차 표현식 --> 2개 parameter 사용)하므로, 낮은 차수로의 mapping 함수(ex. 3D --> 2D)가 생성 +> - **Markov chain**: 어떤 상태에서 다른 상태로 넘어갈 때, 바로 전 단계의 상태에만 영향을 받는 확률 과정 + +--- +# 2. Background + +:::{figure-md} markdown-fig +DDPM_03 + +Graphical model of DDPM \ (source: https://arxiv.org/abs/2006.11239) +::: + +## 2-1. Forward(diffusion) process $q(\mathbf{x}_t|\mathbf{x}_{t-1})$ + +$$ +q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right):=\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right), \quad q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right):=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{1-\beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I}\right) +$$ + +Markov chain으로 **data에 noise를 추가**하는 과정. Noise를 추가할 때 **variance schedule $\beta_1,,,\beta_T$로 scaling**을 한 후 더해준다. +- $\beta_t = 1$이면 mean인 $\sqrt{1-\beta_t}\mathbf{x}_{t-1} = 0$. 이전 정보를 갖지 못하고 노이즈가 증가함 +- 단순히 noise만을 더해주는게 아니라 $\sqrt{1-\beta_t}$로 scaling하는 이유는 variance가 발산하는 것을 막기 위함 +- $q(x_1|x_0)$: $x_0$에 noise를 추가해 $x_1$을 만드는 과정 +- $x_T$는 완전 destroy된 noise 상태 ~ $N(x_T;0, I)$ + +## 2-2. Reverse process $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$ + +$$ +p_\theta\left(\mathbf{x}_{0: T}\right):=p\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right), \quad p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right):=\mathcal{N}\left(\mathbf{x}_{t-1} ; \boldsymbol{\mu}_\theta\left(\mathbf{x}_t, t\right), \boldsymbol{\Sigma}_\theta\left(\mathbf{x}_t, t\right)\right) +$$ + +Reverse process로 가우시안 노이즈를 사용하는 이유는 1994년 논문에 forward process가 가우시안이면 reverse process도 가우시안으로 쓰면 된다라는 증명이 있다고 함. + +여기서 우리가 해야 할 것은 **$\mathbf{x}_t$를 보고 $\mathbf{x}_{t-1}$의 평균 $\mu_\theta$과 분산 $\Sigma_\theta$을 예측해내는 것**. +- Hierarachical VAE에서의 decoding 과정과 비슷함 +- $\mu_\theta$과 분산 $\Sigma_\theta$는 학습 가능한 parameter + + +## 2-3. Loss Function $L$ + +Diffusion model의 목적은 **noise를 어떻게 제거할 것인가?**이다. $x_t$가 들어왔을 때 $x_{t-1}$을 예측할 수 있다면 $x_0$ 또한 예측이 가능해짐. + +$$ +\mathbb{E}\left[-\log p_\theta\left(\mathbf{x}_0\right)\right] \leq \mathbb{E}_q\left[-\log \frac{p_\theta\left(\mathbf{x}_{0: T}\right)}{q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right)}\right]=\mathbb{E}_q\left[-\log p\left(\mathbf{x}_T\right)-\sum_{t \geq 1} \log \frac{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}\right]=: L +$$ + +본 논문에서는 **negative log likelihood를 최소화**하는 방향으로 진행. 위 수식을 **ELBO**(Evidence of Lower BOund)로 우항과 같이 정리하고 이를 풀어내면 + +> ELBO의 역할은 우리가 관찰한 P(z|x)가 다루기 힘든 분포를 이루고 있을 때 이를 조금 더 다루기 쉬운 분포인 Q(x)로 대신 표현하려 하는 과정에서 **두 분포 (P(z|x)와 Q(x))의 차이 (KL Divergence)를 최소화** 하기 위해 사용된다. + +$$ +\mathbb{E}_q[\underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_T \mid \mathbf{x}_0\right) \| p\left(\mathbf{x}_T\right)\right)}_{L_T}+\sum_{t>1} \underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)\right)}_{L_{t-1}} \underbrace{-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}_{L_0}] +$$ + +와 같은 결과가 나온다. + +- $L_T$: Regularization term으로 $\beta_t$를 학습시킴 +- $L_{t-1}$: Reconstruction term으로 매 단계에서 noise를 지우는 지움 +- $L_0$: Reconstruction term으로 최종 단계에서 image를 생성 + +--- +# 3. Diffusion models and denoising encoders + +DDPM에서는 **inductive bias를 늘려** 모델을 더 stable하고 성능도 개선할 수 있었음. + +> Inductive bias: 학습 모델이 지금까지 만나보지 못했던 상황에서 정확한 예측을 하기 위해 사용하는 **추가적인 가정**, 즉 우리가 풀려는 문제에 대한 정보를 모델에 적용하는 것 + + +## 3-1. Forward process and $L_T$ + +**$\beta_t$를 고정**했더니 학습이 잘됨. 10^-4 ~ 0.02로 linear하게 image에 가까울수록 noise를 적게 주는 방식으로 설정. + +따라서 $q$에는 학습 가능한 parameter가 없어 **$L_T$는 0이 되기 때문에 삭제**할 수 있었음. + +## 3-2. Reverse process and $L_{1:T-1}$ + + +$$ +L_{t-1}=D_{K L}\left(q\left(x_{t-1} \mid x_t, x_0\right) \| p_\theta\left(x_{t-1} \mid x_t\right)\right) +$$ + +- $ +q\left(x_{t-1} \mid x_t, x_0\right)=N\left(x_{t-1} ; \tilde{\mu}\left(x_t, x_0\right), \tilde{\beta}_t \mathrm{I}\right) +$ +- $ +p_\theta\left(x_{t-1} \mid x_t\right)=\mathcal{N}\left(x_{t-1} ; \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) +$ + + +$L_{1:T-1}$는 forward progress posterior를 예측하는 loss. $\mathbf{x}_{t-1}$에서 noise를 더해 $\mathbf{x}_{t}$를 만들었을때, 그 과정을 복원 $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$ 하는 과정을 학습. + +:::{figure-md} markdown-fig +DDPM_08 + +Loss Simplication \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) +::: + +- $\Sigma_\theta$: $\beta$를 상수로 가정했고 $p(\mathbf{x}_{t-1}|\mathbf{x}_t)$의 variance가 $\beta$에 영향을 받기 때문에 학습시키지 않아도 된다고 생각해 **variance term을 제거**함. + +:::{figure-md} markdown-fig +DDPM_09 + +Residual Estimation \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) +::: + +- $\mu_\theta$: DDPM에서는 $\mu_\theta$를 바로 구하지 않고 **residual $\epsilon_\theta$만 구해 정확도를 높임**. + +## 3-3. Data scaling, reverse process decoder and $L_0$ + +$$ +\begin{aligned} +p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right) & =\prod_{i=1}^D \int_{\delta_{-}\left(x_0^i\right)}^{\delta_{+}\left(x_0^i\right)} \mathcal{N}\left(x ; \mu_\theta^i\left(\mathbf{x}_1, 1\right), \sigma_1^2\right) d x \\ +\delta_{+}(x) & =\left\{\begin{array}{ll} +\infty & \text { if } x=1 \\ +x+\frac{1}{255} & \text { if } x<1 +\end{array} \quad \delta_{-}(x)= \begin{cases}-\infty & \text { if } x=-1 \\ +x-\frac{1}{255} & \text { if } x>-1\end{cases} \right. +\end{aligned} +$$ + +[0, 255]의 image를 [-1,1] 사이로 linearly mapping. Sampling 마지막 단계에는 noise를 추가하지 않음. + + +$L_0$은 두 normal distribution 사이의 KL divergence를 나타냄. +- $D$: Data dimensionality +- $i$: 좌표 + + +## 3-4. Simplified training objective + +:::{figure-md} markdown-fig +DDPM_10 + +Simplified training objective \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) +::: + +:::{figure-md} markdown-fig +DDPM_11 + +Final Loss \ (source: https://velog.io/@sjina0722/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Denoising-Diffusion-Probabilistic-Models) +::: + +최종 loss는 위와 같이 나타난다. Ground truth - estimated output간 MSE loss를 줄이는 과정이 denoising과 비슷해 DDPM이라는 이름이 붙음. + +Simplified objective을 통해 diffusion process를 학습하면 매우 작은 t 에서뿐만 아니라 **큰 t에 대해서도 network 학습이 가능하기 때문에 매우 효과적**. + +:::{figure-md} markdown-fig +DDPM_12 + +Psuedo code of training process \ (source: https://arxiv.org/abs/2006.11239) +::: + +- Algorithm 1: Training + - Noise를 더해나가는 과정, network($\epsilon_\theta$, $p_\theta$)가 t step에서 noise($\epsilon$)가 얼마만큼 더해졌는지를 학습한다. + - 학습 시에는 특정 step의 이미지가 얼마나 gaussian noise가 추가되었는지를 예측하도록 학습된다. + - 코드에서는 랜덤 노이즈와 시간 단계 t로 노이즈가 추가된 이미지를 얻고 해당 이미지를 보고 모델이 노이즈를 예측 + +```python +def p_losses(self, x_start, t, noise = None): + b, c, h, w = x_start.shape + noise = default(noise, lambda: torch.randn_like(x_start)) + + # noise sample + + x = self.q_sample(x_start = x_start, t = t, noise = noise) + + # if doing self-conditioning, 50% of the time, predict x_start from current set of times + # and condition with unet with that + # this technique will slow down training by 25%, but seems to lower FID significantly + + x_self_cond = None + if self.self_condition and random() < 0.5: + with torch.no_grad(): + x_self_cond = self.model_predictions(x, t).pred_x_start + x_self_cond.detach_() + + # predict and take gradient step + + model_out = self.model(x, t, x_self_cond) + + if self.objective == 'pred_noise': + target = noise + elif self.objective == 'pred_x0': + target = x_start + elif self.objective == 'pred_v': + v = self.predict_v(x_start, t, noise) + target = v + else: + raise ValueError(f'unknown objective {self.objective}') + + loss = self.loss_fn(model_out, target, reduction = 'none') + loss = reduce(loss, 'b ... -> b (...)', 'mean') + + loss = loss * extract(self.loss_weight, t, loss.shape) + return loss.mean() + ``` + +- Algorithm 2: Sampling + - Network를 학습하고 나면, gaussian noise에서 시작해서 순차적으로 denoising 하는 것이 가능하다. (by parameterized markovian chain) + - 코드에서는 noise 제거 후 소량의 noise를 다시 추가하고 있음 + +```python +@torch.no_grad() +def p_sample(self, x, t: int, x_self_cond = None): + b, *_, device = *x.shape, x.device + batched_times = torch.full((b,), t, device = x.device, dtype = torch.long) + model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = True) + noise = torch.randn_like(x) if t > 0 else 0. # no noise if t == 0 + pred_img = model_mean + (0.5 * model_log_variance).exp() * noise + return pred_img, x_start +``` + + + +# 4. Experiments + +- T: 1000 +- backbone: U-Net +각 down/upsampling 단계는 ResNet/ConvNext 블록 2개 + (groupnorm + attention + residual) + down/upsampling으로 구성됨 + +```python +block_klass = partial(ResnetBlock, groups = resnet_block_groups) + +self.downs.append(nn.ModuleList([ + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + Residual(PreNorm(dim_in, LinearAttention(dim_in))), + Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1) + ])) + + self.ups.append(nn.ModuleList([ + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + Residual(PreNorm(dim_out, LinearAttention(dim_out))), + Upsample(dim_out, dim_in) if not is_last else nn.Conv2d(dim_out, dim_in, 3, padding = 1) + ])) + +``` + + +```python +class Unet(nn.Module): + def __init__( + self, + dim, + init_dim = None, + out_dim = None, + dim_mults=(1, 2, 4, 8), + channels = 3, + self_condition = False, + resnet_block_groups = 8, + learned_variance = False, + learned_sinusoidal_cond = False, + random_fourier_features = False, + learned_sinusoidal_dim = 16 + ): + super().__init__() + + # determine dimensions + + self.channels = channels + self.self_condition = self_condition + input_channels = channels * (2 if self_condition else 1) + + init_dim = default(init_dim, dim) + self.init_conv = nn.Conv2d(input_channels, init_dim, 7, padding = 3) + + dims = [init_dim, *map(lambda m: dim * m, dim_mults)] + in_out = list(zip(dims[:-1], dims[1:])) + + block_klass = partial(ResnetBlock, groups = resnet_block_groups) + + # time embeddings + + time_dim = dim * 4 + + self.random_or_learned_sinusoidal_cond = learned_sinusoidal_cond or random_fourier_features + + if self.random_or_learned_sinusoidal_cond: + sinu_pos_emb = RandomOrLearnedSinusoidalPosEmb(learned_sinusoidal_dim, random_fourier_features) + fourier_dim = learned_sinusoidal_dim + 1 + else: + sinu_pos_emb = SinusoidalPosEmb(dim) + fourier_dim = dim + + self.time_mlp = nn.Sequential( + sinu_pos_emb, + nn.Linear(fourier_dim, time_dim), + nn.GELU(), + nn.Linear(time_dim, time_dim) + ) + + # layers + + self.downs = nn.ModuleList([]) + self.ups = nn.ModuleList([]) + num_resolutions = len(in_out) + + for ind, (dim_in, dim_out) in enumerate(in_out): + is_last = ind >= (num_resolutions - 1) + + self.downs.append(nn.ModuleList([ + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + block_klass(dim_in, dim_in, time_emb_dim = time_dim), + Residual(PreNorm(dim_in, LinearAttention(dim_in))), + Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1) + ])) + + mid_dim = dims[-1] + self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) + self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim))) + self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim) + + for ind, (dim_in, dim_out) in enumerate(reversed(in_out)): + is_last = ind == (len(in_out) - 1) + + self.ups.append(nn.ModuleList([ + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim), + Residual(PreNorm(dim_out, LinearAttention(dim_out))), + Upsample(dim_out, dim_in) if not is_last else nn.Conv2d(dim_out, dim_in, 3, padding = 1) + ])) + + default_out_dim = channels * (1 if not learned_variance else 2) + self.out_dim = default(out_dim, default_out_dim) + + self.final_res_block = block_klass(dim * 2, dim, time_emb_dim = time_dim) + self.final_conv = nn.Conv2d(dim, self.out_dim, 1) + + def forward(self, x, time, x_self_cond = None): + if self.self_condition: + x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x)) + x = torch.cat((x_self_cond, x), dim = 1) + + x = self.init_conv(x) + r = x.clone() + + t = self.time_mlp(time) + + h = [] + + for block1, block2, attn, downsample in self.downs: + x = block1(x, t) + h.append(x) + + x = block2(x, t) + x = attn(x) + h.append(x) + + x = downsample(x) + + x = self.mid_block1(x, t) + x = self.mid_attn(x) + x = self.mid_block2(x, t) + + for block1, block2, attn, upsample in self.ups: + x = torch.cat((x, h.pop()), dim = 1) + x = block1(x, t) + + x = torch.cat((x, h.pop()), dim = 1) + x = block2(x, t) + x = attn(x) + + x = upsample(x) + + x = torch.cat((x, r), dim = 1) + + x = self.final_res_block(x, t) + return self.final_conv(x) +``` + + + +- 16 x 16 feature map resolution에 self-attention. conv에서 차원을 3배로 늘리고 q,k,v로 분해. + +```python +class Attention(nn.Module): + def __init__(self, dim, heads = 4, dim_head = 32): + super().__init__() + self.scale = dim_head ** -0.5 + self.heads = heads + hidden_dim = dim_head * heads + + self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False) + self.to_out = nn.Conv2d(hidden_dim, dim, 1) + + def forward(self, x): + b, c, h, w = x.shape + qkv = self.to_qkv(x).chunk(3, dim = 1) + q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv) + + q = q * self.scale + + sim = einsum('b h d i, b h d j -> b h i j', q, k) + attn = sim.softmax(dim = -1) + out = einsum('b h i j, b h d j -> b h i d', attn, v) + + out = rearrange(out, 'b h (x y) d -> b (h d) x y', x = h, y = w) + return self.to_out(out) +``` + +- Linear attention +```python +class LinearAttention(nn.Module): + def __init__(self, dim, heads = 4, dim_head = 32): + super().__init__() + self.scale = dim_head ** -0.5 + self.heads = heads + hidden_dim = dim_head * heads + self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False) + + self.to_out = nn.Sequential( + nn.Conv2d(hidden_dim, dim, 1), + LayerNorm(dim) + ) + + def forward(self, x): + b, c, h, w = x.shape + qkv = self.to_qkv(x).chunk(3, dim = 1) + q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv) + + q = q.softmax(dim = -2) + k = k.softmax(dim = -1) + + q = q * self.scale + v = v / (h * w) + + context = torch.einsum('b h d n, b h e n -> b h d e', k, v) + + out = torch.einsum('b h d e, b h d n -> b h e n', context, q) + out = rearrange(out, 'b h c (x y) -> b (h c) x y', h = self.heads, x = h, y = w) + return self.to_out(out) +``` + +- Diffusion time $T$는 각 residual block에 transformer sinusoidal positional embedding이 추가돼서 구분됨 + +```python +class SinusoidalPosEmb(nn.Module): + def __init__(self, dim): + super().__init__() + self.dim = dim + + def forward(self, x): + device = x.device + half_dim = self.dim // 2 + emb = math.log(10000) / (half_dim - 1) + emb = torch.exp(torch.arange(half_dim, device=device) * -emb) + emb = x[:, None] * emb[None, :] + emb = torch.cat((emb.sin(), emb.cos()), dim=-1) + return emb +``` + +## 4-1. Sample quality + +:::{figure-md} markdown-fig +DDPM_13 + +Train score of DDPM \ (source: https://arxiv.org/abs/2006.11239) +::: + +FID, IS로 metric 계산. Unconditional model인데도 conditional model보다 우월. Codelength에서 차이가 없기 때문에 overfitting의 가능성도 적음. + +> - **FID score**: Inception V3으로 이미지의 분포를 계산한 metric +> - **Unconditional model**: 한번 dataset에 학습되면 추가적인 context 없이 image를 생성 +> - **Conditional model**: Class, label 등의 추가 정보를 받아 image를 생성 + +$\mu$보다 $\epsilon$을 계산하는 것이 성적이 좋고, fixed variance를 사용했을 때에도 성능이 감소하지 않음. + + + + diff --git a/_sources/docs/review/I-DDPM.md b/_sources/docs/review/I-DDPM.md old mode 100644 new mode 100755 index d99a174c..dd6244e1 --- a/_sources/docs/review/I-DDPM.md +++ b/_sources/docs/review/I-DDPM.md @@ -1,232 +1,232 @@ -```{admonition} Information -- **Title:** {Improved Denoising Diffusion Probabilistic Models}, {CVPR 2021} - -- **Reference** - - Paper: [https://arxiv.org/abs/2102.09672](https://arxiv.org/abs/2102.09672) - -- **Author:** Seunghwan Ji - -- **Last updated on Aug. 6, 2023** -``` -# I-DDPM - -## 학습 자료 - -**Improved Denoising Diffusion Probabilistic Models** - -[https://arxiv.org/pdf/2102.09672.pdf](https://arxiv.org/pdf/2102.09672.pdf) - ---- - -**CVPR 2021, Alex Nichol** - -## Abstract - -- DDPM을 약간 수정함으로써 High Quality를 유지하고, Log Likelihood수치도 개선할 수 있는 향상된 모델을 제안 -- Sampling시 Base 보다 더 적은 Step으로 비슷한 퀄리티의 결과를 낼 수 있는 방법을 제안 -- Model의 Scale과 Diffusion Step에 따른 Sample Quailty와 Likelihood 수치간의 관계를 연구 - -## 1. Introduction - -- 최근 DDPM(Ho et al.) 모델은 Generate 분야에서 High Quality의 이미지를 생성해내는 수준까지 왔다. -- 하지만, Image의 Quality에 반해 log-likelihood 수치는 다른 generative 모델에비해 현저히 떨어졌다. (e.g. VAE) -- 또 DDPM이 Diversity가 낮은 Dataset(CIFAR-10, LSUN)에서는 잘 동작했지만, High Diversity Dataset에서의 동작은 증명되지 못했다. -- I-DDPM에서는 - 1. Log-Likelihood 수치 개선 - 2. ImageNet같은 Diversity가 높은 Dataset에서도 잘 동작 - 3. Reverse Process에서의 Loss Term 개선 - - 한 모델을 제안하였다. - -- 추가로 연구 과정 중, I-DDPM이 Base (DDPM) 모델에 비해 훨씬 더 적은 Step으로 비슷한 Quality를 내는 것을 확인 - -**Log-Likelihood 값이 중요한 이유** - -- 기존 연구들에서 Loglikelihood 수치와 Sample의 Quality간의 연관성을 보이는 연구들이 많았다. - - *Data의 Distribution에 대해 Model이 학습한 정도를 수치화한 느낌* -- 수치가 좋아지면 Sample Quality도 따라 증가하는 경향을 보였다. -- 따라서 DDPM에서도 LogLikelihood 수치를 개선한다면 Sample Quality도 따라서 더 증가할 가능성이 있지 않을까? -- [https://angeloyeo.github.io/2020/07/17/MLE.html](https://angeloyeo.github.io/2020/07/17/MLE.html) - -## 2. Denoising Diffusion Probabilistic Models - -**DDPM** - -- Process - - Forward Process - :::{figure-md} markdown-fig - I-DDPM_00 - - Equation 1 - ::: - - Reverse Process - :::{figure-md} markdown-fig - I-DDPM_01 - - Equation 2 - ::: - - -- Forward Process에서 입힌 Noise를 Neural Model의 Reverse Process로 예측하도록 학습하는 형태 -- 이 때 Noising & Denoising에 관한 (Hyper) Parameter로 ${B_{t}}$와 $\tilde{B_{t}}$를 사용 - - ${B_{t}}$ : time step 에 따른 noising할 정도 - - $\tilde{B_{t}}$ : Reverse Step에서 Denoising을 위한 Parameter로 아래와같이 정의 - :::{figure-md} markdown-fig - I-DDPM_02 - - Equation 3 - ::: - -- 하지만 DDPM에서는 $\tilde{B_{t}}$ 대신 ${B_{t}}$를 사용해도 비슷한 수치를 보여서 ${B_{t}}$ (constant)로 고정 - -## 3. Improving the Log-likelihood - -- 위의 문장 ($\tilde{B_{t}}$ 대신 ${B_{t}}$를 사용)에서 의문점 - - 사실 ${B_{t}}$와 $\tilde{B_{t}}$는 정 반대의 역할을 하는 Parameter인데 왜 비슷한 결과를 보였고, 결국 같은 값으로 Fix를 하는게 맞을까? - :::{figure-md} markdown-fig - I-DDPM_03 - - Figure 1 - ::: - - - Diffusion Step간 ${B_{t}}$와 $\tilde{B_{t}}$의 차이를 비교해보면 Diffusion Step이 커질수록 두개의 값은 거의 동일해진다. (Figure.1) - :::{figure-md} markdown-fig - I-DDPM_04 - - Figure 2 - ::: - - - 하지만 Figure.2를 보면 모델의 성능은 대부분 Step 초반에 결정되는데, Step 초반에는 두 값의 차이가 큰 것을 확인할 수 있다. - - *Model의 성능이 결정되는 부분 = Loss 가 급격하게 떨어지는 부분* - - ⇒ 따라서, ${B_{t}}$와 $\tilde{B_{t}}$를 동일한 값으로 두고 $\tilde{B_{t}}$를 Non Trainable Parameter로 두는것은 설계의 Miss - - - 하지만, $\tilde{B_{t}}$ 자체를 학습하기에는 값의 범위가 너무 작아서 ${B_{t}}$와 $\tilde{B_{t}}$의 Interpolation 값을 Predict하도록 설계 - :::{figure-md} markdown-fig - I-DDPM_05 - - Figure 3 - ::: - - - Hybrid Loss - - $L_{hyprid} = L_{simple} + λL_{vlb}$ -- Noise Schedule - - DDPM의 경우 High Resolution 이미지에대해 잘 동작하지만, Low-Resolution (e.g. 32x32, 64x64)의 이미지에 대해서는 잘 동작하지 않는것을 확인 - - Noise Scheduling에서 Linear mode의 Limitation이 있음을 지적 - :::{figure-md} markdown-fig - I-DDPM_06 - - Equation 4 - ::: - - - Step이 거듭날수록 Linear schedule(상단)의 이미지가 너무 빠르게 Noisy해짐 - - 추가로 Reverse Process의 20%를 Skip해도 성능에 큰 영향이 없음을 확인 - - ⇒ 결국 Linear mode를 사용하면 특정 Step 이후의 Noise는 학습에 의미있는 영향을 미치지 못한다. - - - I-DDPM에서는 이러한 scheduling Equation을 새로 정의 - :::{figure-md} markdown-fig - I-DDPM_07 - - Equation 5 - ::: - - - 새로 정의한 식은 중간 단계에서는 Noise가 강하게 입혀지지만 0과 T 부근에서는 비교적 덜 Noisy해짐 - :::{figure-md} markdown-fig - I-DDPM_08 - - Figure 3 - ::: - -- Gradient Noise - - Model을 $L_{vlb}$를 Direct로 최적화하도록 설계하면 Best - - 하지만 아래 이미지와같이 Loss 자체가 unstable해서 직접 최적화에는 어려움이 있음 - :::{figure-md} markdown-fig - I-DDPM_09 - - Figure 4 - ::: - - - 따라서 $L_{vlb}$의 Variance를 줄이기위해(=stable) Importance Sampling 기법을 도입 - - 위 Fig.2에서 보면 학습 말기는 Loss의 변화에 큰 영향이 없으므로 확률적으로 학습 초반의 데이터를 좀더 sampling해서 학습하도록 설계 - - 실제로 적용해본 결과 $L_{hybrid}$보다 더 낮은 Loss 를 보임 - - $L_{hybrid}$에 Importance Sampling을 적용하면? - - 적용 전보다 좋지 않은 결과를 보인다.. - -**Result** - -:::{figure-md} markdown-fig -I-DDPM_10 - -Table 1 -::: - -:::{figure-md} markdown-fig -I-DDPM_11 - -Table 2 -::: - -- DDPM에서 다소 취약했던 ImageNet 64x64와 CIDAR-10 데이터를 기준 - - $L_{vlb}$의 경우 Importance sampling을 적용한 결과 - -:::{figure-md} markdown-fig -I-DDPM_12 - -Table 3 -::: - -- Convolution 모델이나 Diffusion 모델중에서는 뛰어나지만, Fully Transformer 모델에 비해서는 다소 부족한 면이 있음 - -## 4. Improcing Sampling Speed - -- Sampling Speed를 높이기 위한 방법을 제안 - - Training 시에는 전체 Step(1, … , T)을 학습 - - Sampling 시에는 몇몇 Step만 Sampling -- 결과는? - -:::{figure-md} markdown-fig -I-DDPM_13 - -Figure 5 -::: - -:::{figure-md} markdown-fig -I-DDPM_14 - -Figure 6 -::: - -⇒ 100 Step만 가도 Full Model과 비슷한 FiD값을 보임 - -## 5. Comparison to GANs - -- Class Conditional Generation + P&R Metric으로 GAN 모델(BigGAN)과 성능을 비교 - :::{figure-md} markdown-fig - I-DDPM_15 - - Figure 7 - ::: - - - - Big-GAN Deep 모델보다 생성 타겟에 대한 FiD 수치나 Recall metric에서 더 뛰어난 성능을 보임 - -## 6. Scaling Model Size - -- 다양한 Capacity를 가진 모델의 FiD와 NLL 값을 비교 - -:::{figure-md} markdown-fig -I-DDPM_16 - -Figure 8 -::: - -:::{figure-md} markdown-fig -I-DDPM_17 - -Figure 9 -::: - -⇒ 모델의 크기와 학습량 모두 Step에 어느정도 비례함 - +```{admonition} Information +- **Title:** {Improved Denoising Diffusion Probabilistic Models}, {CVPR 2021} + +- **Reference** + - Paper: [https://arxiv.org/abs/2102.09672](https://arxiv.org/abs/2102.09672) + +- **Author:** Seunghwan Ji + +- **Last updated on Aug. 6, 2023** +``` +# I-DDPM + +## 학습 자료 + +**Improved Denoising Diffusion Probabilistic Models** + +[https://arxiv.org/pdf/2102.09672.pdf](https://arxiv.org/pdf/2102.09672.pdf) + +--- + +**CVPR 2021, Alex Nichol** + +## Abstract + +- DDPM을 약간 수정함으로써 High Quality를 유지하고, Log Likelihood수치도 개선할 수 있는 향상된 모델을 제안 +- Sampling시 Base 보다 더 적은 Step으로 비슷한 퀄리티의 결과를 낼 수 있는 방법을 제안 +- Model의 Scale과 Diffusion Step에 따른 Sample Quailty와 Likelihood 수치간의 관계를 연구 + +## 1. Introduction + +- 최근 DDPM(Ho et al.) 모델은 Generate 분야에서 High Quality의 이미지를 생성해내는 수준까지 왔다. +- 하지만, Image의 Quality에 반해 log-likelihood 수치는 다른 generative 모델에비해 현저히 떨어졌다. (e.g. VAE) +- 또 DDPM이 Diversity가 낮은 Dataset(CIFAR-10, LSUN)에서는 잘 동작했지만, High Diversity Dataset에서의 동작은 증명되지 못했다. +- I-DDPM에서는 + 1. Log-Likelihood 수치 개선 + 2. ImageNet같은 Diversity가 높은 Dataset에서도 잘 동작 + 3. Reverse Process에서의 Loss Term 개선 + + 한 모델을 제안하였다. + +- 추가로 연구 과정 중, I-DDPM이 Base (DDPM) 모델에 비해 훨씬 더 적은 Step으로 비슷한 Quality를 내는 것을 확인 + +**Log-Likelihood 값이 중요한 이유** + +- 기존 연구들에서 Loglikelihood 수치와 Sample의 Quality간의 연관성을 보이는 연구들이 많았다. + - *Data의 Distribution에 대해 Model이 학습한 정도를 수치화한 느낌* +- 수치가 좋아지면 Sample Quality도 따라 증가하는 경향을 보였다. +- 따라서 DDPM에서도 LogLikelihood 수치를 개선한다면 Sample Quality도 따라서 더 증가할 가능성이 있지 않을까? +- [https://angeloyeo.github.io/2020/07/17/MLE.html](https://angeloyeo.github.io/2020/07/17/MLE.html) + +## 2. Denoising Diffusion Probabilistic Models + +**DDPM** + +- Process + - Forward Process + :::{figure-md} markdown-fig + I-DDPM_00 + + Equation 1 + ::: + - Reverse Process + :::{figure-md} markdown-fig + I-DDPM_01 + + Equation 2 + ::: + + +- Forward Process에서 입힌 Noise를 Neural Model의 Reverse Process로 예측하도록 학습하는 형태 +- 이 때 Noising & Denoising에 관한 (Hyper) Parameter로 ${B_{t}}$와 $\tilde{B_{t}}$를 사용 + - ${B_{t}}$ : time step 에 따른 noising할 정도 + - $\tilde{B_{t}}$ : Reverse Step에서 Denoising을 위한 Parameter로 아래와같이 정의 + :::{figure-md} markdown-fig + I-DDPM_02 + + Equation 3 + ::: + +- 하지만 DDPM에서는 $\tilde{B_{t}}$ 대신 ${B_{t}}$를 사용해도 비슷한 수치를 보여서 ${B_{t}}$ (constant)로 고정 + +## 3. Improving the Log-likelihood + +- 위의 문장 ($\tilde{B_{t}}$ 대신 ${B_{t}}$를 사용)에서 의문점 + - 사실 ${B_{t}}$와 $\tilde{B_{t}}$는 정 반대의 역할을 하는 Parameter인데 왜 비슷한 결과를 보였고, 결국 같은 값으로 Fix를 하는게 맞을까? + :::{figure-md} markdown-fig + I-DDPM_03 + + Figure 1 + ::: + + - Diffusion Step간 ${B_{t}}$와 $\tilde{B_{t}}$의 차이를 비교해보면 Diffusion Step이 커질수록 두개의 값은 거의 동일해진다. (Figure.1) + :::{figure-md} markdown-fig + I-DDPM_04 + + Figure 2 + ::: + + - 하지만 Figure.2를 보면 모델의 성능은 대부분 Step 초반에 결정되는데, Step 초반에는 두 값의 차이가 큰 것을 확인할 수 있다. + - *Model의 성능이 결정되는 부분 = Loss 가 급격하게 떨어지는 부분* + + ⇒ 따라서, ${B_{t}}$와 $\tilde{B_{t}}$를 동일한 값으로 두고 $\tilde{B_{t}}$를 Non Trainable Parameter로 두는것은 설계의 Miss + + - 하지만, $\tilde{B_{t}}$ 자체를 학습하기에는 값의 범위가 너무 작아서 ${B_{t}}$와 $\tilde{B_{t}}$의 Interpolation 값을 Predict하도록 설계 + :::{figure-md} markdown-fig + I-DDPM_05 + + Figure 3 + ::: + + - Hybrid Loss + - $L_{hyprid} = L_{simple} + λL_{vlb}$ +- Noise Schedule + - DDPM의 경우 High Resolution 이미지에대해 잘 동작하지만, Low-Resolution (e.g. 32x32, 64x64)의 이미지에 대해서는 잘 동작하지 않는것을 확인 + - Noise Scheduling에서 Linear mode의 Limitation이 있음을 지적 + :::{figure-md} markdown-fig + I-DDPM_06 + + Equation 4 + ::: + + - Step이 거듭날수록 Linear schedule(상단)의 이미지가 너무 빠르게 Noisy해짐 + - 추가로 Reverse Process의 20%를 Skip해도 성능에 큰 영향이 없음을 확인 + + ⇒ 결국 Linear mode를 사용하면 특정 Step 이후의 Noise는 학습에 의미있는 영향을 미치지 못한다. + + - I-DDPM에서는 이러한 scheduling Equation을 새로 정의 + :::{figure-md} markdown-fig + I-DDPM_07 + + Equation 5 + ::: + + - 새로 정의한 식은 중간 단계에서는 Noise가 강하게 입혀지지만 0과 T 부근에서는 비교적 덜 Noisy해짐 + :::{figure-md} markdown-fig + I-DDPM_08 + + Figure 3 + ::: + +- Gradient Noise + - Model을 $L_{vlb}$를 Direct로 최적화하도록 설계하면 Best + - 하지만 아래 이미지와같이 Loss 자체가 unstable해서 직접 최적화에는 어려움이 있음 + :::{figure-md} markdown-fig + I-DDPM_09 + + Figure 4 + ::: + + - 따라서 $L_{vlb}$의 Variance를 줄이기위해(=stable) Importance Sampling 기법을 도입 + - 위 Fig.2에서 보면 학습 말기는 Loss의 변화에 큰 영향이 없으므로 확률적으로 학습 초반의 데이터를 좀더 sampling해서 학습하도록 설계 + - 실제로 적용해본 결과 $L_{hybrid}$보다 더 낮은 Loss 를 보임 + - $L_{hybrid}$에 Importance Sampling을 적용하면? + - 적용 전보다 좋지 않은 결과를 보인다.. + +**Result** + +:::{figure-md} markdown-fig +I-DDPM_10 + +Table 1 +::: + +:::{figure-md} markdown-fig +I-DDPM_11 + +Table 2 +::: + +- DDPM에서 다소 취약했던 ImageNet 64x64와 CIDAR-10 데이터를 기준 + - $L_{vlb}$의 경우 Importance sampling을 적용한 결과 + +:::{figure-md} markdown-fig +I-DDPM_12 + +Table 3 +::: + +- Convolution 모델이나 Diffusion 모델중에서는 뛰어나지만, Fully Transformer 모델에 비해서는 다소 부족한 면이 있음 + +## 4. Improcing Sampling Speed + +- Sampling Speed를 높이기 위한 방법을 제안 + - Training 시에는 전체 Step(1, … , T)을 학습 + - Sampling 시에는 몇몇 Step만 Sampling +- 결과는? + +:::{figure-md} markdown-fig +I-DDPM_13 + +Figure 5 +::: + +:::{figure-md} markdown-fig +I-DDPM_14 + +Figure 6 +::: + +⇒ 100 Step만 가도 Full Model과 비슷한 FiD값을 보임 + +## 5. Comparison to GANs + +- Class Conditional Generation + P&R Metric으로 GAN 모델(BigGAN)과 성능을 비교 + :::{figure-md} markdown-fig + I-DDPM_15 + + Figure 7 + ::: + + + - Big-GAN Deep 모델보다 생성 타겟에 대한 FiD 수치나 Recall metric에서 더 뛰어난 성능을 보임 + +## 6. Scaling Model Size + +- 다양한 Capacity를 가진 모델의 FiD와 NLL 값을 비교 + +:::{figure-md} markdown-fig +I-DDPM_16 + +Figure 8 +::: + +:::{figure-md} markdown-fig +I-DDPM_17 + +Figure 9 +::: + +⇒ 모델의 크기와 학습량 모두 Step에 어느정도 비례함 + --- \ No newline at end of file diff --git a/_sources/docs/review/Latent_Diffusion_Model.md b/_sources/docs/review/Latent_Diffusion_Model.md old mode 100644 new mode 100755 index 3c2d11f1..a0ce2129 --- a/_sources/docs/review/Latent_Diffusion_Model.md +++ b/_sources/docs/review/Latent_Diffusion_Model.md @@ -1,89 +1,89 @@ -```{admonition} Information -- **Title:** High-Resolution Image Synthesis with Latent Diffusion Models (CVPR 2022) - -- **Reference** - - Paper: [https://arxiv.org/abs/2112.10752](https://arxiv.org/abs/2112.10752) - - Code: [https://github.com/CompVis/latent-diffusion](https://github.com/CompVis/latent-diffusion) - -- **Author:** Namkyeong Cho - -- **Last updated on May. 31, 2023** -``` - -# Latent Diffusion Model - -오늘 알아볼 모델은 Latent Diffusion Model입니다. -기존에 다뤘던 Diffusion Model과 유사하게 동작하는 생성 모델입니다. 이 논문에서는 컴퓨터 자원의 소모를 줄이면서 Diffusion Model과 유사한 성능을 얻는것이 그 목표입니다. - -Latent Diffusion Model은 전반적으로 아래와 같은 구조를 가집니다. - -:::{figure-md} markdown-fig - - -Structure of Latent Diffusion Model -::: -$x \in \mathbb{R}^{H\times W \times 3}$이 input으로 주어졌을때 이를 encoder $\mathcal{E}$를 통해서 $z=\mathcal{E}(x) \in \mathbb{R}^{h\times w\times c }$로 인코딩 하고 $\hat{x}=\mathcal{D}(z)$ -로 디코딩을 한다. 이 논문에서 $f=H/h=W/w=2^m$, $m\in \mathbb{N}$이 되도록 여러 $m$에 대해서 테스트를 진행하였다. 또한 Latent space에서 분산이 커지지 않도록 KL divergence와 vector quantization(VQ)을 활용하였다. -이미지외 텍스트나, sematic map과 같이 추가적인 정보는 $\tau_\theta$를 통해서 전달을 하였고, - -$$ Q=W^{(i)}_Q \phi_i(z_i), K=W^{(i)}_K \phi_i(z_i), V=W^{(i)}_V \phi_i(z_i) $$ - -로 정의되고 $\phi_i(z_i)$는 $U$-Net 중간의 representation, $W^{i}_V, W^{i}_K, W^{i}_Q$는 학습 가능한 projection matrix이다. -$Q, K, V$ 는 attention의 query, key, value에 해당하며 - -$$ -Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d}})\cdot V -$$ - -로 연산이 진행된다. 학습을 위한 loss 함수는 다음과 같이표현된다. - -$$ -\mathcal{L}_{LDM} = \mathbb{E}_{\mathcal{E}(x), -\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(z_t,t) \|_{2}^{2}\right]. -$$ - -여기서 주목할만한 부분은 기존 Diffusion Model에서 - -$$ -\mathcal{L}_{DM} = \mathbb{E}_{x, -\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(x_t,t) \|_{2}^{2}\right]. -$$ - -와 같은 loss function으로 학습을 진행시키는데 $x_t$를 $z_t$로 바꾸면서 연산의 양을 줄였다는 점이다. - - -# Experiments - -해당 논문에서는 다양한 task에 대해서 실험을 진행하였는데, 그중 일부만 소개하도록 하겠다. -아래의 그림은 다양한 dataset에서 뽑은 샘플과 text to image sample들입니다. - -:::{figure-md} markdown-fig - - -Sample images -::: - - -:::{figure-md} markdown-fig - - -text to image on LAION -::: - -실험을 통해서 나온 결과 $m=2,3,4$ 혹은 $f=4, 8, 16$인 경우 적절한 FID 점수와 효율성을 보여주었습니다. - -:::{figure-md} markdown-fig - - -text to image on LAION -::: - -Layout이 주어졌을 때, 이를 기반으로 image를 생성하는 layout-to-image의 샘플 결과입니다. -:::{figure-md} markdown-fig - - -layout-to-image -::: - - - +```{admonition} Information +- **Title:** High-Resolution Image Synthesis with Latent Diffusion Models (CVPR 2022) + +- **Reference** + - Paper: [https://arxiv.org/abs/2112.10752](https://arxiv.org/abs/2112.10752) + - Code: [https://github.com/CompVis/latent-diffusion](https://github.com/CompVis/latent-diffusion) + +- **Author:** Namkyeong Cho + +- **Last updated on May. 31, 2023** +``` + +# Latent Diffusion Model + +오늘 알아볼 모델은 Latent Diffusion Model입니다. +기존에 다뤘던 Diffusion Model과 유사하게 동작하는 생성 모델입니다. 이 논문에서는 컴퓨터 자원의 소모를 줄이면서 Diffusion Model과 유사한 성능을 얻는것이 그 목표입니다. + +Latent Diffusion Model은 전반적으로 아래와 같은 구조를 가집니다. + +:::{figure-md} markdown-fig + + +Structure of Latent Diffusion Model +::: +$x \in \mathbb{R}^{H\times W \times 3}$이 input으로 주어졌을때 이를 encoder $\mathcal{E}$를 통해서 $z=\mathcal{E}(x) \in \mathbb{R}^{h\times w\times c }$로 인코딩 하고 $\hat{x}=\mathcal{D}(z)$ +로 디코딩을 한다. 이 논문에서 $f=H/h=W/w=2^m$, $m\in \mathbb{N}$이 되도록 여러 $m$에 대해서 테스트를 진행하였다. 또한 Latent space에서 분산이 커지지 않도록 KL divergence와 vector quantization(VQ)을 활용하였다. +이미지외 텍스트나, sematic map과 같이 추가적인 정보는 $\tau_\theta$를 통해서 전달을 하였고, + +$$ Q=W^{(i)}_Q \phi_i(z_i), K=W^{(i)}_K \phi_i(z_i), V=W^{(i)}_V \phi_i(z_i) $$ + +로 정의되고 $\phi_i(z_i)$는 $U$-Net 중간의 representation, $W^{i}_V, W^{i}_K, W^{i}_Q$는 학습 가능한 projection matrix이다. +$Q, K, V$ 는 attention의 query, key, value에 해당하며 + +$$ +Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d}})\cdot V +$$ + +로 연산이 진행된다. 학습을 위한 loss 함수는 다음과 같이표현된다. + +$$ +\mathcal{L}_{LDM} = \mathbb{E}_{\mathcal{E}(x), +\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(z_t,t) \|_{2}^{2}\right]. +$$ + +여기서 주목할만한 부분은 기존 Diffusion Model에서 + +$$ +\mathcal{L}_{DM} = \mathbb{E}_{x, +\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(x_t,t) \|_{2}^{2}\right]. +$$ + +와 같은 loss function으로 학습을 진행시키는데 $x_t$를 $z_t$로 바꾸면서 연산의 양을 줄였다는 점이다. + + +# Experiments + +해당 논문에서는 다양한 task에 대해서 실험을 진행하였는데, 그중 일부만 소개하도록 하겠다. +아래의 그림은 다양한 dataset에서 뽑은 샘플과 text to image sample들입니다. + +:::{figure-md} markdown-fig + + +Sample images +::: + + +:::{figure-md} markdown-fig + + +text to image on LAION +::: + +실험을 통해서 나온 결과 $m=2,3,4$ 혹은 $f=4, 8, 16$인 경우 적절한 FID 점수와 효율성을 보여주었습니다. + +:::{figure-md} markdown-fig + + +text to image on LAION +::: + +Layout이 주어졌을 때, 이를 기반으로 image를 생성하는 layout-to-image의 샘플 결과입니다. +:::{figure-md} markdown-fig + + +layout-to-image +::: + + + diff --git a/_sources/docs/review/LoRA.md b/_sources/docs/review/LoRA.md old mode 100644 new mode 100755 index 07a5efe3..7f4598cf --- a/_sources/docs/review/LoRA.md +++ b/_sources/docs/review/LoRA.md @@ -1,290 +1,290 @@ -```{admonition} Information -- **Title:** Denoising Diffusion Probabilistic Models (ICLR 2021) - -- **Reference** - - Paper: [https://arxiv.org/abs/2006.11239](https://arxiv.org/abs/2006.11239) - - Code: [PyTorch implementation:](https://github.com/lucidrains/denoising-diffusion-pytorch) - - Review: [PR-409: Denoising Diffusion Probabilistic Models](https://www.youtube.com/watch?v=1j0W_lu55nc) - -- **Author:** Beomsoo Park - -- **Last updated on Apr. 19, 2023** -``` - - -# LoRA - -# 0. Abstract - -LoRA는 **PEFT(Parameter Effecient Fine-Tuning)의 기법 중 하나**이다. Pre-trained model의 weight는 고정한 채로, **몇 개의 dense(fc) layer만 학습시켜 downstream task의 연산량을 줄일 수 있다.** GPT-3을 기준으로 parameter는 10000배, GPU 메모리는 3배를 줄일 수 있다. 또한 inference 과정에서 추가적인 latency가 없음 - -> - PEFT: 모델의 모든 파라미터를 튜닝하는 것이 아닌 일부 파라미터만을 튜닝함으로써 모델의 성능을 적은 자원으로도 높게 유지하는 방법론 -- Downstream task: pre-trained model을 사용해, 어떤 문제를 해결하기 위해 fine-tuning 하는것 -- Upstream task: Pre-train model을 학습시키는것 -- Latency: 어떤 요청의 시작부터 완료까지 걸리는 시간 - ---- - -# 1. Introduction - -LLM은 기본적으로 pre-trained model을 특정 task에 맞게 fine-tuning을 시킴. 하지만 fine-tuning에서 모든 weight를 다시 학습시키면 GPT-2, GPT-3, RoBERTa 등 큰 모델의 경우 학습에 몇 달이 걸림. - -이전 연구에서 over-parameterized model들은 low intrinsic dimension에 기반하고 있다는 사실에 기반해, 저자는 학습 과정에서도 모델은 `low intrinsic rank`을 갖고 있을 것이라 가정함. - -**LoRA는 기존 pre-trained weight는 고정하고, 몇 개의 dense layer만 rank decomposition matrices를 최적화하는 방식으로 학습**시키기로 함. - -:::{figure-md} -LoRA_00 - -LoRA structure -::: - -:::{figure-md} -LoRA_01 - -LoRA structure 2 -::: - - -위 그림처럼 **기존 pre-trained weight $W$는 고정하고 low rank decomposition된 weight $A, B$만 학습시켜 $W$에 더해줌**. $A, B$의 크기는 $W$보다 작아 time, computational cost를 최대 3배까지 줄일 수 있음. 또한 task에 따라 LoRA module($A, B$)만 바꿔주면 되기 때문에 storage requirement, task-switching overhead를 줄일 수 있음. 이 외에도 추가적인 inference latency가 없다, 다른 기법들과 함께 적용이 가능하다는 장점이 있음. - -## 1.1. Terminologies and Conventions - -- $d_{model}$: Transformer의 input/output dimension size -- $W_q, W_k, W_v, W_o$: Self-attention module의 query/key/value/output projection matrices -- $W, W_0$: Pre-trained weight -- $\Delta W$: Adaptation 중 accumulated된 gradient update -- $r$: LoRA module의 rank -- 이전 연구의 convention을 사용하고 optimizer는 Adam을 이용 -- Transformer MLP feedforward dimension $d_{ffn} = 4 \times d_{model}$ - ---- - -# 2. Problem Statement - -LoRA는 agnostic하지만 본 논문에서는 language model에 집중함. - -> - agnostic: model에 구애받지 않고 해석이 가능함 - -$$ -\max _{\Phi} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(P_{\Phi}\left(y_t \mid x, y_{ - -Performance Comparison -::: - -하지만 adapter layer를 추가하는 방식은 hardware parellelism이 없다면 작은 bottleneck layer만 추가해도 latency가 상당히 증가해 사용하기 어려웠음. - -Prefix tuning은 optimize가 어려웠음. - ---- - -# 4. Our Method -## 4.1. Low-Rank-Parameterized Update Matrices - -$$ -h=W_0 x+\Delta W x=W_0 x+B A x -$$ - -- $W_0 \in \mathbb{R}^{d \times k}$ -- $B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}$ -- $r \ll min(d,k)$ - - -$W_0$는 고정하고 $A, B$만 학습. 이후 $W_0$와 $\Delta W = BA$는 같은 input $x$에 곱해진 후 output vector끼리 coordinate-wise하게 sum. - -$A$는 random Gaussian init., $B$는 zero-init.이라 $\Delta W$ 또한 처음에는 zero-init. $\Delta W x$는 $\alpha/x$로 scaling됨. $\alpha$는 learning rate처럼 tuning해서 r과 같은 값으로 설정. 실제 코드에서는 보통 $r, \alpha$는 (8, 16)이나 (16,32)를 사용한다고 함. - -```python - ... - # Actual trainable parameters - # define A, B - if r > 0: - self.lora_A = nn.Parameter(self.weight.new_zeros((r, num_embeddings))) - self.lora_B = nn.Parameter(self.weight.new_zeros((embedding_dim, r))) - self.scaling = self.lora_alpha / self.r - # Freezing the pre-trained weight matrix - self.weight.requires_grad = False - self.reset_parameters() - - # initialize A, B - def reset_parameters(self): - nn.Embedding.reset_parameters(self) - if hasattr(self, 'lora_A'): - # initialize A the same way as the default for nn.Linear and B to zero - nn.init.zeros_(self.lora_A) - nn.init.normal_(self.lora_B) - - def train(self, mode: bool = True): - nn.Embedding.train(self, mode) - if mode: - if self.merge_weights and self.merged: - # Make sure that the weights are not merged - if self.r > 0: - self.weight.data -= (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling - self.merged = False - else: - if self.merge_weights and not self.merged: - # Merge the weights and mark it - if self.r > 0: - self.weight.data += (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling - self.merged = True - - def forward(self, x: torch.Tensor): - if self.r > 0 and not self.merged: - # pre-trained weight W_0 * x - result = nn.Embedding.forward(self, x) - if self.r > 0: - # BA * x - after_A = F.embedding( - x, self.lora_A.transpose(0, 1), self.padding_idx, self.max_norm, - self.norm_type, self.scale_grad_by_freq, self.sparse - ) - # W_0x + BAx - result += (after_A @ self.lora_B.transpose(0, 1)) * self.scaling - return result - else: - return nn.Embedding.forward(self, x) - -``` - -### 4.1.1. No Additional Inference Latency - -LoRA를 이용하면 inference시 latency 성능 하락이 없음. 또한 다른 task에 사용할 경우엔 $BA$만 제외하고 $W_0$로 학습한 다른 $B'A'$만 추가하면 되기 때문에 memory overhead가 낮음. - -## 4.2. Applying LoRA to Transformer - -본 논문에서는 trainable weight를 최소화하기 위해 LoRA를 attention weight만 적용하고 MLP module은 고정함. 이를 통해 GPT-3 175B를 기준으로 VRAM은 1.2TB에서 350GB, checkpoint size는 350GB에서 35MB로 줄임. 또한 학습 속도 또한 25% 정도 빨라짐. - - ---- -# 5.Empirical Experiments - -:::{figure-md} -LoRA_03 - -Performance on BERT -::: - -:::{figure-md} -LoRA_04 - -Performance on GPT-2 -::: - -:::{figure-md} -LoRA_05 - -Performance on GPT-3 -::: - - -대부분의 경우에서 성능이 좋음 - -:::{figure-md} -LoRA_06 - -Validation accuracy table with different hyper-parameters -::: - -:::{figure-md} -LoRA_07 - -Validation accuracy table with different hyper-parameters -::: - -Transformer에서 한 projection matrix에 큰 r을 적용하는 것보다 모든 matrices에 작은 r을 적용하는 것이 더 성능이 좋았음. - ---- -# +a) IA3 - -:::{figure-md} -LoRA_08 - -IA3 structure -::: - -뉴럴네트워크의 Inner Activation을 줄이기도하고 늘리기도하는 어댑터를 중간에 삽입하는 방법론. 기존에 공개된 LoRA보다 적은 파라미터를 사용하면서 높은 성능을 내는 것으로 알려져있으며, GPT-3를 in-context learning 했을때 보다도 성능이 좋다 라고 주장하고 있음. 학습시간도 매우 짧아 A100 GPU 하나로 30분만에 튜닝할 수 있었다고 함. - ---- -# +aa) LoRA 사용법 - -1. `loralib` 설치 - -```python -pip install loralib -# Alternatively -# pip install git+https://github.com/microsoft/LoRA -``` - -2. 기존 `nn.Linear`, `nn.Embedding`, `nn.Conv2d`를 `lora.~`로 대체 - -```python -# ===== Before ===== -# layer = nn.Linear(in_features, out_features) - -# ===== After ====== -import loralib as lora -# Add a pair of low-rank adaptation matrices with rank r=16 -layer = lora.Linear(in_features, out_features, r=16) -``` - -3. 학습 전, lora parameter만 학습 가능하게 설정 -```python -import loralib as lora -model = BigModel() -# This sets requires_grad to False for all parameters without the string "lora_" in their names -lora.mark_only_lora_as_trainable(model) -# Training loop -for batch in dataloader: - ... -``` - -4. checkpoint를 저장할 때엔 `state_dict`가 LoRA parameter만 저장하게 함. -```python -# ===== Before ===== -# torch.save(model.state_dict(), checkpoint_path) -# ===== After ===== -torch.save(lora.lora_state_dict(model), checkpoint_path) -``` - -5. checkpoint를 불러올 때엔 `load_state_dict`에서 `strict=False`로 설정. -```python -# Load the pretrained checkpoint first -model.load_state_dict(torch.load('ckpt_pretrained.pt'), strict=False) -# Then load the LoRA checkpoint -model.load_state_dict(torch.load('ckpt_lora.pt'), strict=False) -``` - - ---- -# Reference - -- [LoRA 논문 리뷰](https://da2so.tistory.com/79) -- [LLM 모델 튜닝, 하나의 GPU로 가능할까? Parameter Efficient Fine-Tuning(PEFT)을 소개합니다!](https://devocean.sk.com/blog/techBoardDetail.do?ID=164779&boardType=techBlog) -- [Stable Diffusion LoRA 생성 및 사용법](https://zzambab98.tistory.com/226) -- [Stable Diffusion - LoRA 모델 사용법 -](https://www.internetmap.kr/entry/How-to-LoRA-Model) -- [LoRA github](https://github.com/microsoft/LoRA) -- https://www.youtube.com/watch?v=dA-NhCtrrVE +```{admonition} Information +- **Title:** Denoising Diffusion Probabilistic Models (ICLR 2021) + +- **Reference** + - Paper: [https://arxiv.org/abs/2006.11239](https://arxiv.org/abs/2006.11239) + - Code: [PyTorch implementation:](https://github.com/lucidrains/denoising-diffusion-pytorch) + - Review: [PR-409: Denoising Diffusion Probabilistic Models](https://www.youtube.com/watch?v=1j0W_lu55nc) + +- **Author:** Beomsoo Park + +- **Last updated on Apr. 19, 2023** +``` + + +# LoRA + +# 0. Abstract + +LoRA는 **PEFT(Parameter Effecient Fine-Tuning)의 기법 중 하나**이다. Pre-trained model의 weight는 고정한 채로, **몇 개의 dense(fc) layer만 학습시켜 downstream task의 연산량을 줄일 수 있다.** GPT-3을 기준으로 parameter는 10000배, GPU 메모리는 3배를 줄일 수 있다. 또한 inference 과정에서 추가적인 latency가 없음 + +> - PEFT: 모델의 모든 파라미터를 튜닝하는 것이 아닌 일부 파라미터만을 튜닝함으로써 모델의 성능을 적은 자원으로도 높게 유지하는 방법론 +- Downstream task: pre-trained model을 사용해, 어떤 문제를 해결하기 위해 fine-tuning 하는것 +- Upstream task: Pre-train model을 학습시키는것 +- Latency: 어떤 요청의 시작부터 완료까지 걸리는 시간 + +--- + +# 1. Introduction + +LLM은 기본적으로 pre-trained model을 특정 task에 맞게 fine-tuning을 시킴. 하지만 fine-tuning에서 모든 weight를 다시 학습시키면 GPT-2, GPT-3, RoBERTa 등 큰 모델의 경우 학습에 몇 달이 걸림. + +이전 연구에서 over-parameterized model들은 low intrinsic dimension에 기반하고 있다는 사실에 기반해, 저자는 학습 과정에서도 모델은 `low intrinsic rank`을 갖고 있을 것이라 가정함. + +**LoRA는 기존 pre-trained weight는 고정하고, 몇 개의 dense layer만 rank decomposition matrices를 최적화하는 방식으로 학습**시키기로 함. + +:::{figure-md} +LoRA_00 + +LoRA structure +::: + +:::{figure-md} +LoRA_01 + +LoRA structure 2 +::: + + +위 그림처럼 **기존 pre-trained weight $W$는 고정하고 low rank decomposition된 weight $A, B$만 학습시켜 $W$에 더해줌**. $A, B$의 크기는 $W$보다 작아 time, computational cost를 최대 3배까지 줄일 수 있음. 또한 task에 따라 LoRA module($A, B$)만 바꿔주면 되기 때문에 storage requirement, task-switching overhead를 줄일 수 있음. 이 외에도 추가적인 inference latency가 없다, 다른 기법들과 함께 적용이 가능하다는 장점이 있음. + +## 1.1. Terminologies and Conventions + +- $d_{model}$: Transformer의 input/output dimension size +- $W_q, W_k, W_v, W_o$: Self-attention module의 query/key/value/output projection matrices +- $W, W_0$: Pre-trained weight +- $\Delta W$: Adaptation 중 accumulated된 gradient update +- $r$: LoRA module의 rank +- 이전 연구의 convention을 사용하고 optimizer는 Adam을 이용 +- Transformer MLP feedforward dimension $d_{ffn} = 4 \times d_{model}$ + +--- + +# 2. Problem Statement + +LoRA는 agnostic하지만 본 논문에서는 language model에 집중함. + +> - agnostic: model에 구애받지 않고 해석이 가능함 + +$$ +\max _{\Phi} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(P_{\Phi}\left(y_t \mid x, y_{ + +Performance Comparison +::: + +하지만 adapter layer를 추가하는 방식은 hardware parellelism이 없다면 작은 bottleneck layer만 추가해도 latency가 상당히 증가해 사용하기 어려웠음. + +Prefix tuning은 optimize가 어려웠음. + +--- + +# 4. Our Method +## 4.1. Low-Rank-Parameterized Update Matrices + +$$ +h=W_0 x+\Delta W x=W_0 x+B A x +$$ + +- $W_0 \in \mathbb{R}^{d \times k}$ +- $B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}$ +- $r \ll min(d,k)$ + + +$W_0$는 고정하고 $A, B$만 학습. 이후 $W_0$와 $\Delta W = BA$는 같은 input $x$에 곱해진 후 output vector끼리 coordinate-wise하게 sum. + +$A$는 random Gaussian init., $B$는 zero-init.이라 $\Delta W$ 또한 처음에는 zero-init. $\Delta W x$는 $\alpha/x$로 scaling됨. $\alpha$는 learning rate처럼 tuning해서 r과 같은 값으로 설정. 실제 코드에서는 보통 $r, \alpha$는 (8, 16)이나 (16,32)를 사용한다고 함. + +```python + ... + # Actual trainable parameters + # define A, B + if r > 0: + self.lora_A = nn.Parameter(self.weight.new_zeros((r, num_embeddings))) + self.lora_B = nn.Parameter(self.weight.new_zeros((embedding_dim, r))) + self.scaling = self.lora_alpha / self.r + # Freezing the pre-trained weight matrix + self.weight.requires_grad = False + self.reset_parameters() + + # initialize A, B + def reset_parameters(self): + nn.Embedding.reset_parameters(self) + if hasattr(self, 'lora_A'): + # initialize A the same way as the default for nn.Linear and B to zero + nn.init.zeros_(self.lora_A) + nn.init.normal_(self.lora_B) + + def train(self, mode: bool = True): + nn.Embedding.train(self, mode) + if mode: + if self.merge_weights and self.merged: + # Make sure that the weights are not merged + if self.r > 0: + self.weight.data -= (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling + self.merged = False + else: + if self.merge_weights and not self.merged: + # Merge the weights and mark it + if self.r > 0: + self.weight.data += (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling + self.merged = True + + def forward(self, x: torch.Tensor): + if self.r > 0 and not self.merged: + # pre-trained weight W_0 * x + result = nn.Embedding.forward(self, x) + if self.r > 0: + # BA * x + after_A = F.embedding( + x, self.lora_A.transpose(0, 1), self.padding_idx, self.max_norm, + self.norm_type, self.scale_grad_by_freq, self.sparse + ) + # W_0x + BAx + result += (after_A @ self.lora_B.transpose(0, 1)) * self.scaling + return result + else: + return nn.Embedding.forward(self, x) + +``` + +### 4.1.1. No Additional Inference Latency + +LoRA를 이용하면 inference시 latency 성능 하락이 없음. 또한 다른 task에 사용할 경우엔 $BA$만 제외하고 $W_0$로 학습한 다른 $B'A'$만 추가하면 되기 때문에 memory overhead가 낮음. + +## 4.2. Applying LoRA to Transformer + +본 논문에서는 trainable weight를 최소화하기 위해 LoRA를 attention weight만 적용하고 MLP module은 고정함. 이를 통해 GPT-3 175B를 기준으로 VRAM은 1.2TB에서 350GB, checkpoint size는 350GB에서 35MB로 줄임. 또한 학습 속도 또한 25% 정도 빨라짐. + + +--- +# 5.Empirical Experiments + +:::{figure-md} +LoRA_03 + +Performance on BERT +::: + +:::{figure-md} +LoRA_04 + +Performance on GPT-2 +::: + +:::{figure-md} +LoRA_05 + +Performance on GPT-3 +::: + + +대부분의 경우에서 성능이 좋음 + +:::{figure-md} +LoRA_06 + +Validation accuracy table with different hyper-parameters +::: + +:::{figure-md} +LoRA_07 + +Validation accuracy table with different hyper-parameters +::: + +Transformer에서 한 projection matrix에 큰 r을 적용하는 것보다 모든 matrices에 작은 r을 적용하는 것이 더 성능이 좋았음. + +--- +# +a) IA3 + +:::{figure-md} +LoRA_08 + +IA3 structure +::: + +뉴럴네트워크의 Inner Activation을 줄이기도하고 늘리기도하는 어댑터를 중간에 삽입하는 방법론. 기존에 공개된 LoRA보다 적은 파라미터를 사용하면서 높은 성능을 내는 것으로 알려져있으며, GPT-3를 in-context learning 했을때 보다도 성능이 좋다 라고 주장하고 있음. 학습시간도 매우 짧아 A100 GPU 하나로 30분만에 튜닝할 수 있었다고 함. + +--- +# +aa) LoRA 사용법 + +1. `loralib` 설치 + +```python +pip install loralib +# Alternatively +# pip install git+https://github.com/microsoft/LoRA +``` + +2. 기존 `nn.Linear`, `nn.Embedding`, `nn.Conv2d`를 `lora.~`로 대체 + +```python +# ===== Before ===== +# layer = nn.Linear(in_features, out_features) + +# ===== After ====== +import loralib as lora +# Add a pair of low-rank adaptation matrices with rank r=16 +layer = lora.Linear(in_features, out_features, r=16) +``` + +3. 학습 전, lora parameter만 학습 가능하게 설정 +```python +import loralib as lora +model = BigModel() +# This sets requires_grad to False for all parameters without the string "lora_" in their names +lora.mark_only_lora_as_trainable(model) +# Training loop +for batch in dataloader: + ... +``` + +4. checkpoint를 저장할 때엔 `state_dict`가 LoRA parameter만 저장하게 함. +```python +# ===== Before ===== +# torch.save(model.state_dict(), checkpoint_path) +# ===== After ===== +torch.save(lora.lora_state_dict(model), checkpoint_path) +``` + +5. checkpoint를 불러올 때엔 `load_state_dict`에서 `strict=False`로 설정. +```python +# Load the pretrained checkpoint first +model.load_state_dict(torch.load('ckpt_pretrained.pt'), strict=False) +# Then load the LoRA checkpoint +model.load_state_dict(torch.load('ckpt_lora.pt'), strict=False) +``` + + +--- +# Reference + +- [LoRA 논문 리뷰](https://da2so.tistory.com/79) +- [LLM 모델 튜닝, 하나의 GPU로 가능할까? Parameter Efficient Fine-Tuning(PEFT)을 소개합니다!](https://devocean.sk.com/blog/techBoardDetail.do?ID=164779&boardType=techBlog) +- [Stable Diffusion LoRA 생성 및 사용법](https://zzambab98.tistory.com/226) +- [Stable Diffusion - LoRA 모델 사용법 +](https://www.internetmap.kr/entry/How-to-LoRA-Model) +- [LoRA github](https://github.com/microsoft/LoRA) +- https://www.youtube.com/watch?v=dA-NhCtrrVE diff --git a/_sources/docs/review/StyO.md b/_sources/docs/review/StyO.md old mode 100644 new mode 100755 index 965a98a3..ff34abef --- a/_sources/docs/review/StyO.md +++ b/_sources/docs/review/StyO.md @@ -1,179 +1,179 @@ -```{admonition} Information -- **Title:** {StyO: Stylize Your Face in Only One-Shot} - -- **Reference** - - Paper: [https://arxiv.org/abs/2303.03231](https://arxiv.org/abs/2303.03231) - -- **Author:** Seunghwan Ji - -- **Last updated on Aug. 6, 2023** -``` -# StyO - -## 학습 자료 - -**StyO: Stylize Your Face in Only One-Shot** - -[https://arxiv.org/pdf/1812.04948.pdf](https://arxiv.org/pdf/2303.03231.pdf) - ---- - -*arXiv:2303.03231v2 [[cs.CV](http://cs.cv/)] 7 Mar 2023* - -## Abstract - -- “**Sty**lize the face in only **O**ne-shot.” -- 한장의 이미지만으로 다른 이미지로 스타일을 Transfer! - -## 1. Introduction - -- 현재 다양한 분야에서 이미지에 특정 스타일을 입히고자하는 연구들이 활발히 진행중이다. -- 이전까지의 연구들은 대부분 각각의 source 이미지, target 이미지 한장씩을 사용해 GAN based model을 활용하려는 식이 주를 이루었다. -- 단 이러한 방식에는 한계가 있는데, - 1. Real Face를 학습한 pre-trained GAN 모델의 의존도가 너무 커서 Style을 입히기 힘들다. - 2. latent space안에서 Content 정보와 Style 정보가 Entangle 되어있다. -- **StyO는?** - - GAN 대신 Data의 Distribution을 더 잘 포용하는 Latent Diffusion Model을 Base모델로 채용한다. - - 총 2 Stage로 구성되는데 - 1. Identifier Disentanglement Learner(IDL) - - 이미지의 content 정보와 Style 정보를 분리 - 2. Fine-grained Content Controller(FCC) - - IDL로부터 분리된 Content와 Style을 원하는대로 재조합 - - 추가로 src 이미지의 detail한 정보(head-pose, hair color 등)를 유지하기위해 Generate 과정에서 src 이미지의 attention map을 재사용하는 trick을 제안했다. -- 이러한 StyO는 GAN based 모델에 비해 더 좋은 퀄리티의 이미지를 생성해내고, one-shot face stylization 분야에서 SOTA를 기록했다. - -## 2. Related Work - -### 2.1. Diffusion Model - -- GAN이 생성 분야를 장악하던 중 최근 DDPM의 등장으로 Diffusion 모델이 주목을 받기 시작했다. -- text prompt를 기반으로 manipulated image 생성이 가능해졌지만, detail한 부분까지 control하기에는 한계가 있었다. -- 이 때, StyO는 이미지의 fine한 style 정보까지 transfer 가능한 diffusion model이다. - -### 2.2. Face Stylization - -- 최근 GAN Based 생성 모델이 좋은 성능을 보이면서 styleGAN을 베이스로 하는 face image style transfer 모델이 좋은 성능을 보여주었다. -- 하지만 real face dataset을 학습한 pretrained checkpoint를 사용하고 이에 대한 의존성이 너무 커 artistic style 정보를 입히는데 한계를 보여준다. -- StyO는 이러한 한계를 개선한 결과를 보여준다. - -## 3. Method - -### 3.2. Framework of StyO -:::{figure-md} markdown-fig -StyO_00 - -Figure 1 -::: - -- image 간의 style transfer를 위해 **identifier disentaglement learner**과 **fine-grained content controller**를 제안한다. - -**IDL** - -- image의 content 정보와 style 정보를 분리하는 방향으로 학습이 진행 -- src 이미지는 `"a drawing with $S_{src}$ not $S_{tgt}$ style of $C_{src}$ not $C_{tgt}$ portrait"` prompt로 학습 (tgt 이미지는 반대) - -⇒ 이미지 간의 Style 정보와 Content 정보가 Disentangle 되고, $S_{src}$안에 이미지 A의 Style 정보가, $C_{tgt}$ 안에 src 이미지의 content 정보가 embedding 되도록 학습 - -- 이 때 $S_{src}$, $C_{src}$에 target 이미지의 conext 정보를 배제함과 동시에$S_{tgt}$, $C_{tgt}$에 포함하기위해 앞에 negator(=부정의 의미를 가진 단어)를 사용 - - *e.g*. *not, without, except …* -- src, tgt 이미지에 추가로 auxiliary 이미지 셋을 구성해 `“a drawing with $S_{src}$ not $S_{tgt}$ style of portrait”` prompt로 학습 - - $X_{aux}$ : FFHQ dataset에서 임의로 200장의 데이터를 sampling -- 효과 - 1. auxiliary 이미지를 학습함으로써 key prompt간 disentanglement를 향상 - 2. auxiliary 이미지에는 없는 src 이미지만의 정보를 $C_{src}$ 에 주입 - 3. src 이미지의 style과 tgt 이미지의 style을 구별하는데 도움을 줌 -- Full Loss - :::{figure-md} markdown-fig - StyO_01 - - Equation 1 - ::: - -- 이러한 IDL의 학습만으로 src 이미지와 tgt 이미지의 style transfer가 가능하다. - - `“a drawing with $S_{tgt}$ not $S_{src}$ style of $C_{src}$ not $C_{tgt}$ portrait”` - :::{figure-md} markdown-fig - StyO_02 - - Figure 2 - ::: - -- 하지만 위 이미지처럼 src 이미지의 content 정보(head-pose, facial feature)를 잃어버리는 경향이 있다. -- 이러한 문제점을 개선하기위해 **FCC**를 추가로 도입하였다. - -**FCC** - -- IDL로 분리된 content 정보와 style 정보를 원하는 방식으로 조합(Recombination)할 때 A의 Content 정보를 유지하도록 하는 Trick -1. Cross Attention Control - - LDM은 기본적으로 Text 정보를 생성 이미지에 주입하기위해 cross attention mechanism을 사용 - - $Attn(z, r) = M(z, r)V$, *z : image latent, r : text embedding* - - 이 때 “prompt-to-promt” paper에서 **attention map M의 값이 생성 이미지의 Layout에 강한 영향을 미친다**는 점을 확인 - - 따라서 src 이미지의 attention mask를 generate 과정에 주입합으로써 content 정보를 좀 더 잘 유지하도록 유도 - - 단, attention map의 모든 값을 replace하지않고, content에 관한 Index만 선택적으로 replace - - content index : '$C_{src}$`, `not`, `$C_{tgt}$`, `portrait` - :::{figure-md} markdown-fig - StyO_03 - - Equation 3 - ::: - -2. Augmented Text Prompt - - training time에서 key prompt를 n번 사용함으로서 생성되는 이미지에 context 정보를 강하게 주입 - - src 이미지는 `“a drawing with ($S_{src}$ not $S_{tgt}$) * $n_{s}$ style of ($C_{src}$ not $C_{tgt}$) * $n_{c}$ portrait”` (tgt 이미지는 반대) - - 실험상 hyperparameter $n_{s}$와 $n_{c}$는 3 이하의 값을 추천 - -## 4. Experiments - -**Implementation Details** - -- base model : Pretrained LDM model checkpoint (trained by LAION-5B) -- hyper parameter - - key prompt : “ak47”, “aug”, “sks”, m4a1” - - Learning rate : 1e-6 - - Optimizer : Adam - - train step : 400 - - $n_{s}$ : 3, $n_{c}$ : 1 - - 나머지는 LDM과 동일 - -**Comparison with SOTA methods** -:::{figure-md} markdown-fig -StyO_04 - -Figure 3 -::: - -- StyO가 src 이미지의 face identity와 local detail 모두 잘 유지함과 동시에, style 정보를 자연스럽게 입힌 결과물을 생성해낸다. -- User Study도 다른 모델들에 비해 좋은 결과를 보였다. - - :::{figure-md} markdown-fig - StyO_05 - - Table 1 - ::: - - -**Ablation Study** - -1. *Effect of Contrastive Disentangled Prompt Template* - - negative prompt 없이 positive prompt만 넣고 학습할경우 학습 이미지의 overfitting이 심하고, style과 content 정보의 분리에 어려움을 보인다. - :::{figure-md} markdown-fig - StyO_06 - - Figure 4 - ::: - - - 또, source 이미지의 local detail을 유지하기위해 auxiliary set의 trick도 적용하는것이 Best Quality의 결과물을 생성해냈다. -2. *Effect of Fine-grained Content Controller* - - FCC 없이 Inference할 경우 generated 이미지의 높은 diversity를 보이지만, FCC를 포함할 경우 src 이미지의 fidelity가 높아져 좀더 significant한 이미지가 생성되는것을 보여주었다. - :::{figure-md} markdown-fig - StyO_07 - - Figure 5 - ::: - -1. *Hyper-parameters in Augmented Text Prompt* - - $n_{s}$ 값이 커질수록 이미지가 photorealistic에서 artistic하게 바뀌고, $n_{c}$도 마찬가지로 값이 커질수록 src 이미지에 overfitting된 이미지가 나오는 경향을 보여주었다. - -## 5. Conclusion - -- StyO는 IDL과 FCC를 사용해 기존 GAN을 이용한 SOTA 모델들보다 더 자연스럽고 Quality 좋은 style transfered 이미지를 생성해낼 수 있었다. +```{admonition} Information +- **Title:** {StyO: Stylize Your Face in Only One-Shot} + +- **Reference** + - Paper: [https://arxiv.org/abs/2303.03231](https://arxiv.org/abs/2303.03231) + +- **Author:** Seunghwan Ji + +- **Last updated on Aug. 6, 2023** +``` +# StyO + +## 학습 자료 + +**StyO: Stylize Your Face in Only One-Shot** + +[https://arxiv.org/pdf/1812.04948.pdf](https://arxiv.org/pdf/2303.03231.pdf) + +--- + +*arXiv:2303.03231v2 [[cs.CV](http://cs.cv/)] 7 Mar 2023* + +## Abstract + +- “**Sty**lize the face in only **O**ne-shot.” +- 한장의 이미지만으로 다른 이미지로 스타일을 Transfer! + +## 1. Introduction + +- 현재 다양한 분야에서 이미지에 특정 스타일을 입히고자하는 연구들이 활발히 진행중이다. +- 이전까지의 연구들은 대부분 각각의 source 이미지, target 이미지 한장씩을 사용해 GAN based model을 활용하려는 식이 주를 이루었다. +- 단 이러한 방식에는 한계가 있는데, + 1. Real Face를 학습한 pre-trained GAN 모델의 의존도가 너무 커서 Style을 입히기 힘들다. + 2. latent space안에서 Content 정보와 Style 정보가 Entangle 되어있다. +- **StyO는?** + - GAN 대신 Data의 Distribution을 더 잘 포용하는 Latent Diffusion Model을 Base모델로 채용한다. + - 총 2 Stage로 구성되는데 + 1. Identifier Disentanglement Learner(IDL) + - 이미지의 content 정보와 Style 정보를 분리 + 2. Fine-grained Content Controller(FCC) + - IDL로부터 분리된 Content와 Style을 원하는대로 재조합 + - 추가로 src 이미지의 detail한 정보(head-pose, hair color 등)를 유지하기위해 Generate 과정에서 src 이미지의 attention map을 재사용하는 trick을 제안했다. +- 이러한 StyO는 GAN based 모델에 비해 더 좋은 퀄리티의 이미지를 생성해내고, one-shot face stylization 분야에서 SOTA를 기록했다. + +## 2. Related Work + +### 2.1. Diffusion Model + +- GAN이 생성 분야를 장악하던 중 최근 DDPM의 등장으로 Diffusion 모델이 주목을 받기 시작했다. +- text prompt를 기반으로 manipulated image 생성이 가능해졌지만, detail한 부분까지 control하기에는 한계가 있었다. +- 이 때, StyO는 이미지의 fine한 style 정보까지 transfer 가능한 diffusion model이다. + +### 2.2. Face Stylization + +- 최근 GAN Based 생성 모델이 좋은 성능을 보이면서 styleGAN을 베이스로 하는 face image style transfer 모델이 좋은 성능을 보여주었다. +- 하지만 real face dataset을 학습한 pretrained checkpoint를 사용하고 이에 대한 의존성이 너무 커 artistic style 정보를 입히는데 한계를 보여준다. +- StyO는 이러한 한계를 개선한 결과를 보여준다. + +## 3. Method + +### 3.2. Framework of StyO +:::{figure-md} markdown-fig +StyO_00 + +Figure 1 +::: + +- image 간의 style transfer를 위해 **identifier disentaglement learner**과 **fine-grained content controller**를 제안한다. + +**IDL** + +- image의 content 정보와 style 정보를 분리하는 방향으로 학습이 진행 +- src 이미지는 `"a drawing with $S_{src}$ not $S_{tgt}$ style of $C_{src}$ not $C_{tgt}$ portrait"` prompt로 학습 (tgt 이미지는 반대) + +⇒ 이미지 간의 Style 정보와 Content 정보가 Disentangle 되고, $S_{src}$안에 이미지 A의 Style 정보가, $C_{tgt}$ 안에 src 이미지의 content 정보가 embedding 되도록 학습 + +- 이 때 $S_{src}$, $C_{src}$에 target 이미지의 conext 정보를 배제함과 동시에$S_{tgt}$, $C_{tgt}$에 포함하기위해 앞에 negator(=부정의 의미를 가진 단어)를 사용 + - *e.g*. *not, without, except …* +- src, tgt 이미지에 추가로 auxiliary 이미지 셋을 구성해 `“a drawing with $S_{src}$ not $S_{tgt}$ style of portrait”` prompt로 학습 + - $X_{aux}$ : FFHQ dataset에서 임의로 200장의 데이터를 sampling +- 효과 + 1. auxiliary 이미지를 학습함으로써 key prompt간 disentanglement를 향상 + 2. auxiliary 이미지에는 없는 src 이미지만의 정보를 $C_{src}$ 에 주입 + 3. src 이미지의 style과 tgt 이미지의 style을 구별하는데 도움을 줌 +- Full Loss + :::{figure-md} markdown-fig + StyO_01 + + Equation 1 + ::: + +- 이러한 IDL의 학습만으로 src 이미지와 tgt 이미지의 style transfer가 가능하다. + - `“a drawing with $S_{tgt}$ not $S_{src}$ style of $C_{src}$ not $C_{tgt}$ portrait”` + :::{figure-md} markdown-fig + StyO_02 + + Figure 2 + ::: + +- 하지만 위 이미지처럼 src 이미지의 content 정보(head-pose, facial feature)를 잃어버리는 경향이 있다. +- 이러한 문제점을 개선하기위해 **FCC**를 추가로 도입하였다. + +**FCC** + +- IDL로 분리된 content 정보와 style 정보를 원하는 방식으로 조합(Recombination)할 때 A의 Content 정보를 유지하도록 하는 Trick +1. Cross Attention Control + - LDM은 기본적으로 Text 정보를 생성 이미지에 주입하기위해 cross attention mechanism을 사용 + - $Attn(z, r) = M(z, r)V$, *z : image latent, r : text embedding* + - 이 때 “prompt-to-promt” paper에서 **attention map M의 값이 생성 이미지의 Layout에 강한 영향을 미친다**는 점을 확인 + - 따라서 src 이미지의 attention mask를 generate 과정에 주입합으로써 content 정보를 좀 더 잘 유지하도록 유도 + - 단, attention map의 모든 값을 replace하지않고, content에 관한 Index만 선택적으로 replace + - content index : '$C_{src}$`, `not`, `$C_{tgt}$`, `portrait` + :::{figure-md} markdown-fig + StyO_03 + + Equation 3 + ::: + +2. Augmented Text Prompt + - training time에서 key prompt를 n번 사용함으로서 생성되는 이미지에 context 정보를 강하게 주입 + - src 이미지는 `“a drawing with ($S_{src}$ not $S_{tgt}$) * $n_{s}$ style of ($C_{src}$ not $C_{tgt}$) * $n_{c}$ portrait”` (tgt 이미지는 반대) + - 실험상 hyperparameter $n_{s}$와 $n_{c}$는 3 이하의 값을 추천 + +## 4. Experiments + +**Implementation Details** + +- base model : Pretrained LDM model checkpoint (trained by LAION-5B) +- hyper parameter + - key prompt : “ak47”, “aug”, “sks”, m4a1” + - Learning rate : 1e-6 + - Optimizer : Adam + - train step : 400 + - $n_{s}$ : 3, $n_{c}$ : 1 + - 나머지는 LDM과 동일 + +**Comparison with SOTA methods** +:::{figure-md} markdown-fig +StyO_04 + +Figure 3 +::: + +- StyO가 src 이미지의 face identity와 local detail 모두 잘 유지함과 동시에, style 정보를 자연스럽게 입힌 결과물을 생성해낸다. +- User Study도 다른 모델들에 비해 좋은 결과를 보였다. + + :::{figure-md} markdown-fig + StyO_05 + + Table 1 + ::: + + +**Ablation Study** + +1. *Effect of Contrastive Disentangled Prompt Template* + - negative prompt 없이 positive prompt만 넣고 학습할경우 학습 이미지의 overfitting이 심하고, style과 content 정보의 분리에 어려움을 보인다. + :::{figure-md} markdown-fig + StyO_06 + + Figure 4 + ::: + + - 또, source 이미지의 local detail을 유지하기위해 auxiliary set의 trick도 적용하는것이 Best Quality의 결과물을 생성해냈다. +2. *Effect of Fine-grained Content Controller* + - FCC 없이 Inference할 경우 generated 이미지의 높은 diversity를 보이지만, FCC를 포함할 경우 src 이미지의 fidelity가 높아져 좀더 significant한 이미지가 생성되는것을 보여주었다. + :::{figure-md} markdown-fig + StyO_07 + + Figure 5 + ::: + +1. *Hyper-parameters in Augmented Text Prompt* + - $n_{s}$ 값이 커질수록 이미지가 photorealistic에서 artistic하게 바뀌고, $n_{c}$도 마찬가지로 값이 커질수록 src 이미지에 overfitting된 이미지가 나오는 경향을 보여주었다. + +## 5. Conclusion + +- StyO는 IDL과 FCC를 사용해 기존 GAN을 이용한 SOTA 모델들보다 더 자연스럽고 Quality 좋은 style transfered 이미지를 생성해낼 수 있었다. - **단, style 하나의 transfer를 위해 single GPU로 10분이 걸리므로 time-efficiency가 좋지 못하다는 단점이 있다.** \ No newline at end of file diff --git a/_sources/docs/review/StyleGAN.md b/_sources/docs/review/StyleGAN.md old mode 100644 new mode 100755 index 4c987a1f..c59f24d5 --- a/_sources/docs/review/StyleGAN.md +++ b/_sources/docs/review/StyleGAN.md @@ -1,171 +1,171 @@ -```{admonition} Information -- **Title:** A Style-Based Generator Architecture for Generative Adversarial Networks (CVPR 2019) - -- **Reference** - - Paper: [https://arxiv.org/abs/1812.04948](https://arxiv.org/abs/1812.04948) - - Code: [https://github.com/huangzh13/StyleGAN.pytorch](https://github.com/huangzh13/StyleGAN.pytorch) - -- **Author:** Jisu Kim - -- **Last updated on Apr. 12, 2023** -``` - -# StyleGAN - -오늘 알아볼 모델은 StyleGAN입니다. 기존에 다뤘던 GAN과 같이 이미지를 생성하는 모델입니다. generator 구조를 변경함으로써 성능을 올리고 feature의 control이 가능하게 했습니다. loss나 discriminator 구조 개선에 관한 논문은 아닙니다. 먼저 결과를 보도록 하죠. - -:::{figure-md} markdown-fig -stylegan_01 - -Images generated by StyleGAN -::: - -이 논문의 contribution은 다음과 같습니다. - -1. 새로운 구조를 제안하여 성능을 높이면서 feature의 control이 가능해졌습니다. -2. 새로운 데이터셋을 제안했습니다. (FFHQ) - -이 중에서 첫 번째 contribution을 자세히 보도록 하겠습니다. 논문의 abstract에는 다음과 같은 문장이 있습니다. - -> The new architecture leads to an automatically learned, **unsupervised separation of high-level attributes** (e.g., pose and identity when trained on human faces) and stochastic variation in the generated images (e.g., freckles, hair), and it enables intuitive, scale-specific control of the synthesis. -> - -논문에서 제안한 새로운 generator 구조가 할 수 있는 일을 설명하는 부분입니다. 여기서 보시면 high level attribute의 separation이 가능하다고 얘기하고 있습니다. 저는 개인적으로 이 부분이 StyleGAN의 가장 중요한 특징이라고 생각합니다. - -생성 모델로 이미지를 생성하고자 할 때, 사용자는 어떠한 목적을 가지고 자신이 원하는 이미지를 만들고자 할 것입니다. 이미지의 품질이 좋더라도 모델이 사용자의 의도와 상관없는 랜덤한 이미지를 내뱉어준다면 그 모델의 실용성이 좋다고 할 수 없을 것입니다. 근래에 Text-to-Image 모델들이 인기를 얻었던 이유도 누구나 쉽게 텍스트를 통해서 생성되는 이미지를 조절할 수 있다는 점도 한몫했다고 생각합니다. StyleGAN은 그런 controllability를 어느 정도 가능하게 한 모델이라는 측면에서 의미있다고 생각합니다. - -StyleGAN의 구조는 아래 그림과 같습니다. synthesis network는 해상도를 4x4에서 시작해서 1024x1024까지 높여줍니다. 최종적으로 1024x1024 해상도를 가지는 이미지를 갖게됩니다. 아래 구조를 보면 기존 GAN하고 비교해서 특이한 점이 세 가지 있습니다. - -1. z를 input으로 받는 mapping network - -2. style과 AdaIN - -3. noise와 B (stochastic variation) - -이 각각에 대해서 알아보도록 합시다. - -:::{figure-md} markdown-fig -stylegan_02 - -Structure of StyleGAN -::: - -### Mapping Network - -:::{figure-md} markdown-fig -stylegan_03 - -Mappings with $w$ and without $w$ -::: - -기존 GAN을 생각해보면 z를 input으로 받아서 generator를 거쳐서 이미지를 생성하는 구조입니다. 이 z는 보통 Gaussian distribution에서 샘플링으로 얻습니다. GAN은 학습을 통해 Gaussian distribution을 data distribution으로 보내는 방법을 배우게 될 것이고, 이 분포는 (b)처럼 생기게 될 것입니다. 그런데 데이터가 (a)처럼 주어져서 특정한 데이터가 없거나 적을 수도 있을 것입니다. 예를 들어, 데이터에 피부가 희면서 머리가 긴 샘플들이 없다고 해봅시다. 그러면 피부색과 머리 길이라는 두 feature는 서로 얽히게(entangled)되어, 하나를 바꿀 때 다른 하나도 같이 바뀌는 현상이 일어나게 됩니다. 이런 현상을 완화하기 위해 논문에서는 Gaussian에서 뽑은 z를 바로 사용하는 것이 아니라 mapping network를 통해 learnable distribution에서 뽑은 w를 사용합니다. - -### Style and AdaIN - -instance normalization은 샘플 하나의 각 채널마다 정규화를 취해주는 방법입니다. - -:::{figure-md} markdown-fig -stylegan_04 - -Normalization methods -::: - -adaptive instance normalization (AdaIN) 은 instance normalization에 scale을 곱해주고 bias를 더해주는 형태입니다. 그런데 이 scale과 bias가 style vector의 linear transformation으로 주어지는 형태입니다. linear layer를 통해서 w는 $\mathbf{y}=(\mathbf{y}_{s},\mathbf{y}_{b})$로 보내지게 됩니다. AdaIN의 수식은 아래와 같습니다. - -$$ -AdaIN(\mathbf{x}_{i},\mathbf{y})=\mathbf{y}_{s,i}\frac{\mathbf{x}_{i}-\mu(\mathbf{x}_{i})}{\sigma(\mathbf{x}_{i})}+\mathbf{y}_{b,i} -$$ - -AdaIN은 각 블록마다 두 개씩 들어가서 style은 총 열여덟 번 AdaIN을 통해 generator에 들어가게 됩니다. AdaIN은 localization이라는 특징과도 연관이 있습니다. 여기서 말하는 localization이란 열여덟 개의 style 중에서 일부를 바꿈으로써 이미지의 일부 특징들을 바꿀 수 있다는 의미입니다. AdaIN은 각 convolution layer 다음에 적용이 됩니다. 이 때 feature map들은 normalization되고 style에 의해 새로운 statistics를 가지게 됩니다. style은 하나의 convolution에 적용되고, 다음 convolution에서 다시 normalization이 수행되기 때문에 이전 layer에 적용된 style과 다음 layer에 적용된 style이 분리되게 학습될 수 있습니다. - -관련 코드 - -```python -class StyleMod(nn.Module): - def __init__(self, latent_size, channels, use_wscale): - super(StyleMod, self).__init__() - self.lin = EqualizedLinear(latent_size, - channels * 2, - gain=1.0, use_wscale=use_wscale) - - def forward(self, x, latent): - style = self.lin(latent) # style => [batch_size, n_channels*2] - - shape = [-1, 2, x.size(1)] + (x.dim() - 2) * [1] - style = style.view(shape) # [batch_size, 2, n_channels, ...] - x = x * (style[:, 0] + 1.) + style[:, 1] - return x - -class LayerEpilogue(nn.Module): - """Things to do at the end of each layer.""" - - def __init__(self, channels, dlatent_size, use_wscale, - use_noise, use_pixel_norm, use_instance_norm, use_styles, activation_layer): - super().__init__() - - layers = [] - if use_noise: - layers.append(('noise', NoiseLayer(channels))) - layers.append(('activation', activation_layer)) - if use_pixel_norm: - layers.append(('pixel_norm', PixelNormLayer())) - if use_instance_norm: - layers.append(('instance_norm', nn.InstanceNorm2d(channels))) - - self.top_epi = nn.Sequential(OrderedDict(layers)) - - if use_styles: - self.style_mod = StyleMod(dlatent_size, channels, use_wscale=use_wscale) - else: - self.style_mod = None - - def forward(self, x, dlatents_in_slice=None): - x = self.top_epi(x) - if self.style_mod is not None: - x = self.style_mod(x, dlatents_in_slice) - else: - assert dlatents_in_slice is None - return x -``` - -code from [https://github.com/huangzh13/StyleGAN.pytorch](https://github.com/huangzh13/StyleGAN.pytorch) - -아래 그림은 source A의 style 중 일부를 source B의 style로 변경해서 만든 이미지들입니다. style은 총 18곳에서 사용되는데 처음 4곳 ($4^2 - 8^2$)을 coarse, 그다음 4곳 ($16^2-32^2$)을 middle, 마지막 10곳 ($64^2-1024^2$)을 fine style로 정의하였습니다. 그림을 보시면 윗 부분에서는 포즈나 전체적인 머리 스타일같이 coarse style은 source B의 것을 유지하고, 아래로 갈수록 source A의 큰 틀을 유지하면서 세부적인 부분들을 B에서 가져왔음을 볼 수 있습니다. - -:::{figure-md} markdown-fig -stylegan_05 - -Mixing two styles -::: - -### Stochastic Variation - -한 사람의 이미지 안에는 확률적으로 바뀔 수 있는 부분이 있습니다. (주근깨, 머릿결, 피부) 이를 모델링하기 위해서 noise를 추가적인 input으로 사용하여 각 convolution layer 다음에 더해집니다. 아래 그림에서 (a)의 생성된 한 사람의 이미지 안에서도 디테일들은 (b)와 같이 달라질 수 있습니다. (c)와 같이 standard deviation을 구해봤을 때 얼굴형과 같은 attribute는 변하지않지만 noise에 의해서 머리카락과 같은 부분은 variation이 생김을 볼 수 있습니다. - -:::{figure-md} markdown-fig -stylegan_06 - -Examples of stochastic variation -::: - -아래 그림에서 (a)는 모든 layer에 noise를 준 경우, (b)는 noise를 주지 않은 경우, (c)는 fine layers ($64^2 - 1024^2$)에만 noise를 준 경우, (d)는 coarse layers ($4^2 - 32^2$)에만 noise를 준 경우입니다. (b)를 보면 noise가 없을 경우 머리카락같은 디테일이 제대로 살아있지 않은 것을 볼 수 있습니다. (c)와 (d)를 보면 fine layers에 들어간 noise가 머리카락의 더 세밀한 부분에 영향을 끼친다는 것을 볼 수 있습니다. - -:::{figure-md} markdown-fig -stylegan_07 - -Effect of noise inputs at different layers -::: - -### Mixing Regularization - -논문에서는 localization이 더 잘 되게하기 위해 style mixing이라는 방법을 훈련에 사용합니다. 두 개의 style vector $\mathbf{w}_{1},\mathbf{w}_{2}$를 사용하여 앞 쪽 layer에는 $\mathbf{w}_{1}$을, 뒤 쪽 layer에는 $\mathbf{w}_{2}$를 사용하는 방법입니다. 이는 generator가 인접한 style끼리 correlated되어있다고 학습하는 것을 막아서 localization을 더 잘 되게 하는 목적입니다. - -### 실험 결과 - -마지막으로 저자들이 제안한 방법들이 실제로 효과가 있었는지 확인해봅시다. 아래 표와 같이 실험적으로 보았을 때 저자들이 제안한 방법들을 모두 사용한 경우 FID가 가장 우수하게 나왔습니다. - -:::{figure-md} markdown-fig -stylegan_08 - -FID for various generator designs -::: +```{admonition} Information +- **Title:** A Style-Based Generator Architecture for Generative Adversarial Networks (CVPR 2019) + +- **Reference** + - Paper: [https://arxiv.org/abs/1812.04948](https://arxiv.org/abs/1812.04948) + - Code: [https://github.com/huangzh13/StyleGAN.pytorch](https://github.com/huangzh13/StyleGAN.pytorch) + +- **Author:** Jisu Kim + +- **Last updated on Apr. 12, 2023** +``` + +# StyleGAN + +오늘 알아볼 모델은 StyleGAN입니다. 기존에 다뤘던 GAN과 같이 이미지를 생성하는 모델입니다. generator 구조를 변경함으로써 성능을 올리고 feature의 control이 가능하게 했습니다. loss나 discriminator 구조 개선에 관한 논문은 아닙니다. 먼저 결과를 보도록 하죠. + +:::{figure-md} markdown-fig +stylegan_01 + +Images generated by StyleGAN +::: + +이 논문의 contribution은 다음과 같습니다. + +1. 새로운 구조를 제안하여 성능을 높이면서 feature의 control이 가능해졌습니다. +2. 새로운 데이터셋을 제안했습니다. (FFHQ) + +이 중에서 첫 번째 contribution을 자세히 보도록 하겠습니다. 논문의 abstract에는 다음과 같은 문장이 있습니다. + +> The new architecture leads to an automatically learned, **unsupervised separation of high-level attributes** (e.g., pose and identity when trained on human faces) and stochastic variation in the generated images (e.g., freckles, hair), and it enables intuitive, scale-specific control of the synthesis. +> + +논문에서 제안한 새로운 generator 구조가 할 수 있는 일을 설명하는 부분입니다. 여기서 보시면 high level attribute의 separation이 가능하다고 얘기하고 있습니다. 저는 개인적으로 이 부분이 StyleGAN의 가장 중요한 특징이라고 생각합니다. + +생성 모델로 이미지를 생성하고자 할 때, 사용자는 어떠한 목적을 가지고 자신이 원하는 이미지를 만들고자 할 것입니다. 이미지의 품질이 좋더라도 모델이 사용자의 의도와 상관없는 랜덤한 이미지를 내뱉어준다면 그 모델의 실용성이 좋다고 할 수 없을 것입니다. 근래에 Text-to-Image 모델들이 인기를 얻었던 이유도 누구나 쉽게 텍스트를 통해서 생성되는 이미지를 조절할 수 있다는 점도 한몫했다고 생각합니다. StyleGAN은 그런 controllability를 어느 정도 가능하게 한 모델이라는 측면에서 의미있다고 생각합니다. + +StyleGAN의 구조는 아래 그림과 같습니다. synthesis network는 해상도를 4x4에서 시작해서 1024x1024까지 높여줍니다. 최종적으로 1024x1024 해상도를 가지는 이미지를 갖게됩니다. 아래 구조를 보면 기존 GAN하고 비교해서 특이한 점이 세 가지 있습니다. + +1. z를 input으로 받는 mapping network + +2. style과 AdaIN + +3. noise와 B (stochastic variation) + +이 각각에 대해서 알아보도록 합시다. + +:::{figure-md} markdown-fig +stylegan_02 + +Structure of StyleGAN +::: + +### Mapping Network + +:::{figure-md} markdown-fig +stylegan_03 + +Mappings with $w$ and without $w$ +::: + +기존 GAN을 생각해보면 z를 input으로 받아서 generator를 거쳐서 이미지를 생성하는 구조입니다. 이 z는 보통 Gaussian distribution에서 샘플링으로 얻습니다. GAN은 학습을 통해 Gaussian distribution을 data distribution으로 보내는 방법을 배우게 될 것이고, 이 분포는 (b)처럼 생기게 될 것입니다. 그런데 데이터가 (a)처럼 주어져서 특정한 데이터가 없거나 적을 수도 있을 것입니다. 예를 들어, 데이터에 피부가 희면서 머리가 긴 샘플들이 없다고 해봅시다. 그러면 피부색과 머리 길이라는 두 feature는 서로 얽히게(entangled)되어, 하나를 바꿀 때 다른 하나도 같이 바뀌는 현상이 일어나게 됩니다. 이런 현상을 완화하기 위해 논문에서는 Gaussian에서 뽑은 z를 바로 사용하는 것이 아니라 mapping network를 통해 learnable distribution에서 뽑은 w를 사용합니다. + +### Style and AdaIN + +instance normalization은 샘플 하나의 각 채널마다 정규화를 취해주는 방법입니다. + +:::{figure-md} markdown-fig +stylegan_04 + +Normalization methods +::: + +adaptive instance normalization (AdaIN) 은 instance normalization에 scale을 곱해주고 bias를 더해주는 형태입니다. 그런데 이 scale과 bias가 style vector의 linear transformation으로 주어지는 형태입니다. linear layer를 통해서 w는 $\mathbf{y}=(\mathbf{y}_{s},\mathbf{y}_{b})$로 보내지게 됩니다. AdaIN의 수식은 아래와 같습니다. + +$$ +AdaIN(\mathbf{x}_{i},\mathbf{y})=\mathbf{y}_{s,i}\frac{\mathbf{x}_{i}-\mu(\mathbf{x}_{i})}{\sigma(\mathbf{x}_{i})}+\mathbf{y}_{b,i} +$$ + +AdaIN은 각 블록마다 두 개씩 들어가서 style은 총 열여덟 번 AdaIN을 통해 generator에 들어가게 됩니다. AdaIN은 localization이라는 특징과도 연관이 있습니다. 여기서 말하는 localization이란 열여덟 개의 style 중에서 일부를 바꿈으로써 이미지의 일부 특징들을 바꿀 수 있다는 의미입니다. AdaIN은 각 convolution layer 다음에 적용이 됩니다. 이 때 feature map들은 normalization되고 style에 의해 새로운 statistics를 가지게 됩니다. style은 하나의 convolution에 적용되고, 다음 convolution에서 다시 normalization이 수행되기 때문에 이전 layer에 적용된 style과 다음 layer에 적용된 style이 분리되게 학습될 수 있습니다. + +관련 코드 + +```python +class StyleMod(nn.Module): + def __init__(self, latent_size, channels, use_wscale): + super(StyleMod, self).__init__() + self.lin = EqualizedLinear(latent_size, + channels * 2, + gain=1.0, use_wscale=use_wscale) + + def forward(self, x, latent): + style = self.lin(latent) # style => [batch_size, n_channels*2] + + shape = [-1, 2, x.size(1)] + (x.dim() - 2) * [1] + style = style.view(shape) # [batch_size, 2, n_channels, ...] + x = x * (style[:, 0] + 1.) + style[:, 1] + return x + +class LayerEpilogue(nn.Module): + """Things to do at the end of each layer.""" + + def __init__(self, channels, dlatent_size, use_wscale, + use_noise, use_pixel_norm, use_instance_norm, use_styles, activation_layer): + super().__init__() + + layers = [] + if use_noise: + layers.append(('noise', NoiseLayer(channels))) + layers.append(('activation', activation_layer)) + if use_pixel_norm: + layers.append(('pixel_norm', PixelNormLayer())) + if use_instance_norm: + layers.append(('instance_norm', nn.InstanceNorm2d(channels))) + + self.top_epi = nn.Sequential(OrderedDict(layers)) + + if use_styles: + self.style_mod = StyleMod(dlatent_size, channels, use_wscale=use_wscale) + else: + self.style_mod = None + + def forward(self, x, dlatents_in_slice=None): + x = self.top_epi(x) + if self.style_mod is not None: + x = self.style_mod(x, dlatents_in_slice) + else: + assert dlatents_in_slice is None + return x +``` + +code from [https://github.com/huangzh13/StyleGAN.pytorch](https://github.com/huangzh13/StyleGAN.pytorch) + +아래 그림은 source A의 style 중 일부를 source B의 style로 변경해서 만든 이미지들입니다. style은 총 18곳에서 사용되는데 처음 4곳 ($4^2 - 8^2$)을 coarse, 그다음 4곳 ($16^2-32^2$)을 middle, 마지막 10곳 ($64^2-1024^2$)을 fine style로 정의하였습니다. 그림을 보시면 윗 부분에서는 포즈나 전체적인 머리 스타일같이 coarse style은 source B의 것을 유지하고, 아래로 갈수록 source A의 큰 틀을 유지하면서 세부적인 부분들을 B에서 가져왔음을 볼 수 있습니다. + +:::{figure-md} markdown-fig +stylegan_05 + +Mixing two styles +::: + +### Stochastic Variation + +한 사람의 이미지 안에는 확률적으로 바뀔 수 있는 부분이 있습니다. (주근깨, 머릿결, 피부) 이를 모델링하기 위해서 noise를 추가적인 input으로 사용하여 각 convolution layer 다음에 더해집니다. 아래 그림에서 (a)의 생성된 한 사람의 이미지 안에서도 디테일들은 (b)와 같이 달라질 수 있습니다. (c)와 같이 standard deviation을 구해봤을 때 얼굴형과 같은 attribute는 변하지않지만 noise에 의해서 머리카락과 같은 부분은 variation이 생김을 볼 수 있습니다. + +:::{figure-md} markdown-fig +stylegan_06 + +Examples of stochastic variation +::: + +아래 그림에서 (a)는 모든 layer에 noise를 준 경우, (b)는 noise를 주지 않은 경우, (c)는 fine layers ($64^2 - 1024^2$)에만 noise를 준 경우, (d)는 coarse layers ($4^2 - 32^2$)에만 noise를 준 경우입니다. (b)를 보면 noise가 없을 경우 머리카락같은 디테일이 제대로 살아있지 않은 것을 볼 수 있습니다. (c)와 (d)를 보면 fine layers에 들어간 noise가 머리카락의 더 세밀한 부분에 영향을 끼친다는 것을 볼 수 있습니다. + +:::{figure-md} markdown-fig +stylegan_07 + +Effect of noise inputs at different layers +::: + +### Mixing Regularization + +논문에서는 localization이 더 잘 되게하기 위해 style mixing이라는 방법을 훈련에 사용합니다. 두 개의 style vector $\mathbf{w}_{1},\mathbf{w}_{2}$를 사용하여 앞 쪽 layer에는 $\mathbf{w}_{1}$을, 뒤 쪽 layer에는 $\mathbf{w}_{2}$를 사용하는 방법입니다. 이는 generator가 인접한 style끼리 correlated되어있다고 학습하는 것을 막아서 localization을 더 잘 되게 하는 목적입니다. + +### 실험 결과 + +마지막으로 저자들이 제안한 방법들이 실제로 효과가 있었는지 확인해봅시다. 아래 표와 같이 실험적으로 보았을 때 저자들이 제안한 방법들을 모두 사용한 경우 FID가 가장 우수하게 나왔습니다. + +:::{figure-md} markdown-fig +stylegan_08 + +FID for various generator designs +::: diff --git a/_sources/docs/review/Textual_Inversion.md b/_sources/docs/review/Textual_Inversion.md old mode 100644 new mode 100755 index 9bcd4764..21e916f6 --- a/_sources/docs/review/Textual_Inversion.md +++ b/_sources/docs/review/Textual_Inversion.md @@ -1,206 +1,206 @@ -```{admonition} Information -- **Title:** {An Image is Worth One Word: Personalizing Text-to-Image Generation using Textual Inversion}, {cs.CV} - -- **Reference** - - Paper: [https://arxiv.org/pdf/2208.01618.pdf](https://arxiv.org/pdf/2208.01618.pdf) - - Code: [https://textual-inversion.github.io/](https://textual-inversion.github.io/) - - Review: [https://devocean.sk.com/blog/techBoardDetail.do?page=&query=&ID=164320&boardType=writer&searchData=sam56903&subIndex=&idList=&pnwriterID=sam56903](https://devocean.sk.com/blog/techBoardDetail.do?page=&query=&ID=164320&boardType=writer&searchData=sam56903&subIndex=&idList=&pnwriterID=sam56903) - -- **Author:** Kwang-Su Mun - -- **Last updated on May. 31. 2023** -``` - -# Textual Inversion - -# Abstract -``` -이미지 3-5장으로 새로운 개념(또는 콘셉트, concept)을 학습해 관련된 이미지를 뽑아내는 모델 -``` - - text-to-image model은 자연어를 통한 creation에 전례없는 자유도를 주었다. 하지만, 특정한 contept를 생성하고, 그것의 생김새를 바꾸거나, 새로운 역할이 주어지거나 참신한 장면이 그려지는건 아직 불분명하다. 즉, '이것을 그려줘'라고 말할 때, '이것'에 대한 설명을 prompt로 어떻게 할 것이냐는 물음에는 아직 한계가 있는 것 같다. 이를 해결하기 위해, 저자는 image를 3-5개만으로 사물이나 스타일과 같은 concept, 즉 새로운 '단어'를 고정된 text-to-image model의 embedding space에서 표현하는 방법을 제안한다. 이러한 '단어'는 자연어 문장에 녹아들어가, 직관적인 방법으로 '개인화된' 이미지 생성을 이끌어 낸다. 특히, 독자적이면서 다양한 콘셉트를 capture하기 위해서는 single word embedding이 충분하다는 것을 알게 되었다. - -:::{figure-md} textual inverison example -textual inverison example - -textual inversion example \ (source: https://arxiv.org/abs/2208.01618) -::: - -# Introduction -대규모 학습된 모델에 새로운 개념을 도입하는 일은 어려운 일이다. 각 새로운 개념에 대해 확장된 데이터 셋을 사용해 모델을 retraining하는 것은 엄청나게 비용이 많이 들고, 몇 가지 예제에 해서 fine-tuning은 보통 치명적인 망각을 초래한다. 따라서 저자들은 사전 훈련된 텍스트-이미지 모델의 텍스트 임베딩 공간에서 새로운 단어를 찾아 이러한 문제를 극복할 것을 제안. - - -:::{figure-md} architecture -architecture - -architecture \ (source: https://arxiv.org/abs/2208.01618) -::: -위 figure에서, "A photo of S*"은 tokenizer를 지나면서 각각 '508', '701', '73', '*'과 같은 형태의 token set으로 변환되고, 이후 각 토큰은 자체 임베딩 벡터로 변환되고 이러한 벡터는 다운스트림 모델을 통해 제공됨. - -input image의 concept를 나타내는, 새로운 pseudo-word인 S*를 이용해 새로운 embedding vector(v*)를 나타낸다. 이후 이 vector는 다른 단어와 같이 처리되며 생성 모델에 대한 새로운 text query를 구성하는데 사용될 수 있음. 따라서 이 query는 generator에 들어가서 사용자가 의도한바와 일치하도록 새로운 image를 생성하도록 하는 것이 전반적인 그림이라고 볼 수 있음. - -여기서 중요한 것은, 이 과정에서 생성모델(여기서는 LDM이 쓰임)은 untouched되어 있다는 것(즉, 따로 수정이 들어가지 않는듯함). 그렇게 함으로써 새로운 task에 대한 fine-tuning을 할 때 일반적으로 손실되는 text에 대한 이해도나 generalization을 유지할 수 있음. - -이러한 '유사단어'를 찾기 위해, 이 작업을 하나로 inversion시켜 프레임화 한다. 그리고 고정된, pre-trained text-to-image model을 사용하고, 3-5개의 concept를 나타내는 small image set이 주어진다. 저자들은 'a photo of S*'와 같은 형태의 문장을 설정해 주어진 작은 dataset에서 이미지를 재구성 하는 것으로 이어지는 single-word embedding을 찾는 것을 목표로 함. - -이 모델의 목표는 **새로운 concept인 입력 이미지를 나타내는 S*를 표현하는 방법을 찾는 것**이며, 이러한 task를 **'textual inversion'**이라고 한다고 함. - -``` -This embedding is found through an optimization process, which we refer to as “Textual Inversion”. -``` - -# Related work -- text-guided synthesis -- GAN inversion -- Diffusion-based inversion -- personalization - - PALAVRA: image를 S*으로 바꾸는데 사용되는 기술로 추정. - - pre-trained CLIP model을 이용해서 personalized object의 복구 및 segmentation을 수행. PALAVRA는 특정 개체를 참조하는 CLIP의 textual embedding space에서 pseudo-word를 식별함. 그 다음 검색을 위해 이미지를 설명하거나 어떤 장면에서 특정 개체를 분할하기 위해 사용됨. figure 5에서 보듯이, 그들의 접근 방식은 새로운 장면에서 그럴듯한 재구성 또는 합성에 필요한 세부 정보를 캡처하지 못함. - -# Method -``` -Our goal is to enable language-guided generation of new, user-specified concepts. -``` -- 의역) 목표: 유저가 의도한 것에 초첨을 맞춘, 새로운 concept를 embedding으로 잘 가이드해서 괜찮은 성과물을 내는 것. - -따라서 pre-trained text-to-image model의 중간 단계의 representation으로 이러한 새로운 'concepts'을 인코딩하는데 초점을 맞춤. 일반적인 text-to-image model에서는 image의 representation에 대한 후보군을 text encoder의 word-embedding 단계에서 찾는다. 그러나 이러한 접근 방식은 이미지에 대한 in-depth visual understanding을 필요로 하지 않는다(생성자가 이미지에 대해서 시각적인 이해? 없이 그린다.) 따라서 여기서는 GAN inversion에서 영감을 받은 visual reconstruction objective를 제시. - -## cf) GAN Inversion(이해 못함) -출처) - https://hyoseok-personality.tistory.com/entry/GAN-Inversion - -:::{figure-md} GAN inversion -GAN inversion - -GAN inversion \ (source: https://hyoseok-personality.tistory.com/entry/GAN-Inversion) -::: - -- 입력 이미지와 유사한 결과 이미지를 얻을 수 있도록 하는 latent vector를 찾는 과정. GAN이 학습되면 random latent vector로부터 이미지를 생성해낸다. GAN inversion은 이의 역과정으로써 GAN의 latent space로 input image를 inverting시켜 latent vector를 알아가는 과정. - -## LDM(Latent Diffusion Model) -논문에서는 생성모델로서 LDM(Latent Diffusion Model)을 사용함. 이전에 말했듯이, LDM은 하나도 건들지 않음. - -:::{figure-md} LDM objective function -LDM objective function - -LDM objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -## Text Embeddings -:::{figure-md} Text-Embedding -Text-Embedding - -Text-Embedding \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: -- 입력된 문자열의 각 단어, 하위 단어는 tokenizer를 통과하며, 미리 정의된 dictionary에서 index token으로 변환함. 각 토큰을 통해 찾을 수 있는 고유한 임베딩 벡터에 연결됨. -- index에 의한 embedding vector는 일반적으로 text encoder인 C_Θ의 일부로 학습된다. 이러한 space를 inversion target으로 삼았음. 새로운 개념을 나타내기 위해 자리표시자 문자열인 S*를 새롭게 지정함. 이 과정에서 PALAVRA를 사용했을 것으로 추정함. 임베딩 process에 개입해서 tokenize된 문자열과 관련된 vector를 새로운 학습된 embedding V*로 대체하여 본질적으로 어휘(pseudo-word)에 개념을 주입함. 이렇게 함으로써 다른 단어와 마찬가지로 concept를 포함하는 새로운 문장을 만들 수 있었음. - -## Textual Inversion -새로운 embedding을 찾기 위해 작은 규모의 dataset(3-5장)을 사용해 다양한 배경 또는 포즈와 같은 여러 설정에 걸쳐 목표 concept을 묘사함. 이러한 작은 dataset에서 LDM loss를 최소화하는 과정을 통해 V를 최적화함. 생성 조건을 고정하기 위해 CLIP ImageNet 템플릿에서 파생된 중립 컨텍스트 텍스트를 무작위로 샘플링한다. 여기에는 "A photo of S*", "A rendition of S*" 등의 형식 프롬프트가 포함된다.(아마 원본 이미지와 최대한 비슷하게 만들어서 원본과 비교하기 위한 목적이 아닐까 싶음) 최적화 목표식은 다음과 같음. - -:::{figure-md} textual inversion objective function -textual inversion objective function - -textual inversion objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -LDM loss함수와 매우 유사함. 여기서 CΘ와 eΘ는 고정. 해당 따라서 학습된 embedding이 개념에 미세한 시각적 detail을 포착할 수 있을것으로 기대함. - -# 성능평가 -## DALL:E-2와 비교 -:::{figure-md} compare with DALLE-2 -compare with DALLE-2 - -compare with DALLE-2 \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: -- input image에 대한 디테일을 더 잘 포착하는 모습을 볼 수 있다. - -## Text guided synthesis - -:::{figure-md} text guided synthesis -text guided synthesis - -text guided synthesis - 입력 이미지의 스타일과 유사하면서도 text guide에 맞춰서 잘 진행함. - \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -- Textual Inversion 모델은 새로운 주제에 대해 더 정확하게 개념을 보존하고, 새로운 임베딩과 나머지 캡션들에 대해서도 모두 추론이 가능했음. - -:::{figure-md} style transfer -style transfer - -style transfer \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: -- 적은 데이터셋으로도 style을 보존하면서 표현한 그림 - -## pseudo word 두 개 사용 - -:::{figure-md} two pseudo word -two pseudo word - -two pseudo word \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -## Bias Reduction -:::{figure-md} Bias reduction -Bias reduction - -Bias reduction \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -기존 모델의 결과를 보면, 위 사진에서와 같이 '의사'라는 단어를 사용하면, 보통 백인 남성 의사를 잘 그려냈음. 이는 기존 데이터셋에서 남성 의사 사진 데이터가 많았음을 보여준다. 보다 작은 imageset에서 새로운 embedding을 학습함으로써 이러한 bias를 줄일 수 있음을 보여준다(즉, 성별 및 인종적 다양성에 대한 인식을 높일 수 있음). - -# 정량평가 - -latent space embedding의 품질을 분석. - -1. reconstruction(y축?): target concept를 얼마나 잘 복제하는지. 특정 이미지가 아닌 개념에 대한 변형을 생성하므로 의미적 CLIP 공간 거리를 고려하여 유사성을 측정.(이미지에 자체가 아닌, 이미지가 가진 '개념'에 대해 latent space를 생성하므로) 각 컨셉에 대해 "A photo of S*"라는 prompt를 사용해 64개의 이미지를 생성. -2. editability(x축?): text prompt를 사용해 개념을 수정하는 능력을 평가. 다양한 난이도와 다양한 설정의 prompt를 사용해 일련의 이미지를 생성. - -각 prompt 별로, 50 DDIM step을 사용해 64개의 샘플을 만들고, CLIP-space embedding을 평가, textual prompt의 CLIP-space embedding에서 cosine similarity를 계산. 높은 스코어는 더 높은 editing capability와 prompt의 신뢰도를 보여줌. - -## 평가 setups -GAN inversion에서 영감을 받은 실험 환경 설정에 따름. 생략 - -## 결과 -:::{figure-md} quantative evaluation1 -quantative evaluation1 - -quantative evaluation1 \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -### 주목할 점 - -1. 많은 baseline과 우리 방법의 semantic reconstruction quality는 단순히 training set에서 임의의 이미지를 샘플링하는 것과 비슷함(== 원본 이미지와 생성된 이미지가 큰 차이가 없었다?) - -2. single-word method는 비슷한 reconstruction quality를 달성하고, 모든 multi-word baseline에서 상당히 향상된 editablity을 달성. 이러한 점은 text embedding space의 인상적인 유연성을 나타내고, 단일 pseudo word만 사용하면서 높은 정확도로 새로운 개념을 캡처하는데 도움이 될 수 있음을 보여줌. - -3. baseline이 distortion-editability tradeoff 곡선의 outline을 그리며 실제 단어 분포에 더 가까운 embedding이 더 쉽게 수정될 수 있음. 그러나 target의 세부 정보를 캡처하지는 못함. 반대로, 단어 분포에서 멀리 벗어나면 editability가 크게 감소하는 대신 향상된 reconstruction이 가능해짐. 특히 single embedding model은 단순히 learning rate를 변경해 이 곡선을 따라 이동할 수 있으므로 사용자에게 이 tradeoff에 대한 어느 정도의 제어를 제공함. - -4. concept에 대한 human description을 사용하면 유사성을 포착하지 못하면서도, editability가 감소함. - - -## 사용자평가 - -:::{figure-md} human test -human test - -human test \ (source: https://arxiv.org/pdf/2208.01618.pdf) -::: - -두 개의 설문지: -1) 사용자는 concept의 training set에서 4개의 이미지를 제공받았고, 이미지와의 유사성에 따라 5개의 모델에서 생성된 결과의 순위를 매김. - -2) 이미지 context를 설명하는 텍스트를 제공받았고, 텍스트와 생성된 이미지의 유사성에 따라 순위를 매김. - -각 질문별로 600개씩 총 1,200개의 응답을 수집. - -# Limitation -1. 이미지 생성에 더 많은 자유도를 제공하지만, concept의 의미론적인 본질을 파악하거나, 정확한 shape를 학습하는데 한계. -2. 최적화가 오래 걸린다. 하나의 concept를 학습하는데 약 2시간이 소요됨. - -# 마무리 -: 새로운 설정과 장면에서 특정 concept의 이미지를 생성하기 위해 text-to-image model를 활용하는 개인화되며, language-guided generation을 소개함. 여기서 사용한 'text inversion'은 pretrained text-to-image 모델의 text embedding space 내에서 concept를 새로운 pseudo word로 inverse하여 작동함. 이러한 pseudo-word는 간단한 자연어 설명을 사용해 새로운 장면에 삽입할 수 있으므로 간단하고 직관적인 수정이 가능함. - - 어떤 의미에서 이 방법은 사용자가 편집하기 쉽도록 텍스트 기반 interpace를 사용하지만 자연 언어의 한계에 접근할 때 시각적 단서를 제공하는 등 multi modal 정보를 활용할 수 있도록 함. - +```{admonition} Information +- **Title:** {An Image is Worth One Word: Personalizing Text-to-Image Generation using Textual Inversion}, {cs.CV} + +- **Reference** + - Paper: [https://arxiv.org/pdf/2208.01618.pdf](https://arxiv.org/pdf/2208.01618.pdf) + - Code: [https://textual-inversion.github.io/](https://textual-inversion.github.io/) + - Review: [https://devocean.sk.com/blog/techBoardDetail.do?page=&query=&ID=164320&boardType=writer&searchData=sam56903&subIndex=&idList=&pnwriterID=sam56903](https://devocean.sk.com/blog/techBoardDetail.do?page=&query=&ID=164320&boardType=writer&searchData=sam56903&subIndex=&idList=&pnwriterID=sam56903) + +- **Author:** Kwang-Su Mun + +- **Last updated on May. 31. 2023** +``` + +# Textual Inversion + +# Abstract +``` +이미지 3-5장으로 새로운 개념(또는 콘셉트, concept)을 학습해 관련된 이미지를 뽑아내는 모델 +``` + + text-to-image model은 자연어를 통한 creation에 전례없는 자유도를 주었다. 하지만, 특정한 contept를 생성하고, 그것의 생김새를 바꾸거나, 새로운 역할이 주어지거나 참신한 장면이 그려지는건 아직 불분명하다. 즉, '이것을 그려줘'라고 말할 때, '이것'에 대한 설명을 prompt로 어떻게 할 것이냐는 물음에는 아직 한계가 있는 것 같다. 이를 해결하기 위해, 저자는 image를 3-5개만으로 사물이나 스타일과 같은 concept, 즉 새로운 '단어'를 고정된 text-to-image model의 embedding space에서 표현하는 방법을 제안한다. 이러한 '단어'는 자연어 문장에 녹아들어가, 직관적인 방법으로 '개인화된' 이미지 생성을 이끌어 낸다. 특히, 독자적이면서 다양한 콘셉트를 capture하기 위해서는 single word embedding이 충분하다는 것을 알게 되었다. + +:::{figure-md} textual inverison example +textual inverison example + +textual inversion example \ (source: https://arxiv.org/abs/2208.01618) +::: + +# Introduction +대규모 학습된 모델에 새로운 개념을 도입하는 일은 어려운 일이다. 각 새로운 개념에 대해 확장된 데이터 셋을 사용해 모델을 retraining하는 것은 엄청나게 비용이 많이 들고, 몇 가지 예제에 해서 fine-tuning은 보통 치명적인 망각을 초래한다. 따라서 저자들은 사전 훈련된 텍스트-이미지 모델의 텍스트 임베딩 공간에서 새로운 단어를 찾아 이러한 문제를 극복할 것을 제안. + + +:::{figure-md} architecture +architecture + +architecture \ (source: https://arxiv.org/abs/2208.01618) +::: +위 figure에서, "A photo of S*"은 tokenizer를 지나면서 각각 '508', '701', '73', '*'과 같은 형태의 token set으로 변환되고, 이후 각 토큰은 자체 임베딩 벡터로 변환되고 이러한 벡터는 다운스트림 모델을 통해 제공됨. + +input image의 concept를 나타내는, 새로운 pseudo-word인 S*를 이용해 새로운 embedding vector(v*)를 나타낸다. 이후 이 vector는 다른 단어와 같이 처리되며 생성 모델에 대한 새로운 text query를 구성하는데 사용될 수 있음. 따라서 이 query는 generator에 들어가서 사용자가 의도한바와 일치하도록 새로운 image를 생성하도록 하는 것이 전반적인 그림이라고 볼 수 있음. + +여기서 중요한 것은, 이 과정에서 생성모델(여기서는 LDM이 쓰임)은 untouched되어 있다는 것(즉, 따로 수정이 들어가지 않는듯함). 그렇게 함으로써 새로운 task에 대한 fine-tuning을 할 때 일반적으로 손실되는 text에 대한 이해도나 generalization을 유지할 수 있음. + +이러한 '유사단어'를 찾기 위해, 이 작업을 하나로 inversion시켜 프레임화 한다. 그리고 고정된, pre-trained text-to-image model을 사용하고, 3-5개의 concept를 나타내는 small image set이 주어진다. 저자들은 'a photo of S*'와 같은 형태의 문장을 설정해 주어진 작은 dataset에서 이미지를 재구성 하는 것으로 이어지는 single-word embedding을 찾는 것을 목표로 함. + +이 모델의 목표는 **새로운 concept인 입력 이미지를 나타내는 S*를 표현하는 방법을 찾는 것**이며, 이러한 task를 **'textual inversion'**이라고 한다고 함. + +``` +This embedding is found through an optimization process, which we refer to as “Textual Inversion”. +``` + +# Related work +- text-guided synthesis +- GAN inversion +- Diffusion-based inversion +- personalization + - PALAVRA: image를 S*으로 바꾸는데 사용되는 기술로 추정. + - pre-trained CLIP model을 이용해서 personalized object의 복구 및 segmentation을 수행. PALAVRA는 특정 개체를 참조하는 CLIP의 textual embedding space에서 pseudo-word를 식별함. 그 다음 검색을 위해 이미지를 설명하거나 어떤 장면에서 특정 개체를 분할하기 위해 사용됨. figure 5에서 보듯이, 그들의 접근 방식은 새로운 장면에서 그럴듯한 재구성 또는 합성에 필요한 세부 정보를 캡처하지 못함. + +# Method +``` +Our goal is to enable language-guided generation of new, user-specified concepts. +``` +- 의역) 목표: 유저가 의도한 것에 초첨을 맞춘, 새로운 concept를 embedding으로 잘 가이드해서 괜찮은 성과물을 내는 것. + +따라서 pre-trained text-to-image model의 중간 단계의 representation으로 이러한 새로운 'concepts'을 인코딩하는데 초점을 맞춤. 일반적인 text-to-image model에서는 image의 representation에 대한 후보군을 text encoder의 word-embedding 단계에서 찾는다. 그러나 이러한 접근 방식은 이미지에 대한 in-depth visual understanding을 필요로 하지 않는다(생성자가 이미지에 대해서 시각적인 이해? 없이 그린다.) 따라서 여기서는 GAN inversion에서 영감을 받은 visual reconstruction objective를 제시. + +## cf) GAN Inversion(이해 못함) +출처) - https://hyoseok-personality.tistory.com/entry/GAN-Inversion + +:::{figure-md} GAN inversion +GAN inversion + +GAN inversion \ (source: https://hyoseok-personality.tistory.com/entry/GAN-Inversion) +::: + +- 입력 이미지와 유사한 결과 이미지를 얻을 수 있도록 하는 latent vector를 찾는 과정. GAN이 학습되면 random latent vector로부터 이미지를 생성해낸다. GAN inversion은 이의 역과정으로써 GAN의 latent space로 input image를 inverting시켜 latent vector를 알아가는 과정. + +## LDM(Latent Diffusion Model) +논문에서는 생성모델로서 LDM(Latent Diffusion Model)을 사용함. 이전에 말했듯이, LDM은 하나도 건들지 않음. + +:::{figure-md} LDM objective function +LDM objective function + +LDM objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +## Text Embeddings +:::{figure-md} Text-Embedding +Text-Embedding + +Text-Embedding \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: +- 입력된 문자열의 각 단어, 하위 단어는 tokenizer를 통과하며, 미리 정의된 dictionary에서 index token으로 변환함. 각 토큰을 통해 찾을 수 있는 고유한 임베딩 벡터에 연결됨. +- index에 의한 embedding vector는 일반적으로 text encoder인 C_Θ의 일부로 학습된다. 이러한 space를 inversion target으로 삼았음. 새로운 개념을 나타내기 위해 자리표시자 문자열인 S*를 새롭게 지정함. 이 과정에서 PALAVRA를 사용했을 것으로 추정함. 임베딩 process에 개입해서 tokenize된 문자열과 관련된 vector를 새로운 학습된 embedding V*로 대체하여 본질적으로 어휘(pseudo-word)에 개념을 주입함. 이렇게 함으로써 다른 단어와 마찬가지로 concept를 포함하는 새로운 문장을 만들 수 있었음. + +## Textual Inversion +새로운 embedding을 찾기 위해 작은 규모의 dataset(3-5장)을 사용해 다양한 배경 또는 포즈와 같은 여러 설정에 걸쳐 목표 concept을 묘사함. 이러한 작은 dataset에서 LDM loss를 최소화하는 과정을 통해 V를 최적화함. 생성 조건을 고정하기 위해 CLIP ImageNet 템플릿에서 파생된 중립 컨텍스트 텍스트를 무작위로 샘플링한다. 여기에는 "A photo of S*", "A rendition of S*" 등의 형식 프롬프트가 포함된다.(아마 원본 이미지와 최대한 비슷하게 만들어서 원본과 비교하기 위한 목적이 아닐까 싶음) 최적화 목표식은 다음과 같음. + +:::{figure-md} textual inversion objective function +textual inversion objective function + +textual inversion objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +LDM loss함수와 매우 유사함. 여기서 CΘ와 eΘ는 고정. 해당 따라서 학습된 embedding이 개념에 미세한 시각적 detail을 포착할 수 있을것으로 기대함. + +# 성능평가 +## DALL:E-2와 비교 +:::{figure-md} compare with DALLE-2 +compare with DALLE-2 + +compare with DALLE-2 \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: +- input image에 대한 디테일을 더 잘 포착하는 모습을 볼 수 있다. + +## Text guided synthesis + +:::{figure-md} text guided synthesis +text guided synthesis + +text guided synthesis - 입력 이미지의 스타일과 유사하면서도 text guide에 맞춰서 잘 진행함. + \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +- Textual Inversion 모델은 새로운 주제에 대해 더 정확하게 개념을 보존하고, 새로운 임베딩과 나머지 캡션들에 대해서도 모두 추론이 가능했음. + +:::{figure-md} style transfer +style transfer + +style transfer \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: +- 적은 데이터셋으로도 style을 보존하면서 표현한 그림 + +## pseudo word 두 개 사용 + +:::{figure-md} two pseudo word +two pseudo word + +two pseudo word \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +## Bias Reduction +:::{figure-md} Bias reduction +Bias reduction + +Bias reduction \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +기존 모델의 결과를 보면, 위 사진에서와 같이 '의사'라는 단어를 사용하면, 보통 백인 남성 의사를 잘 그려냈음. 이는 기존 데이터셋에서 남성 의사 사진 데이터가 많았음을 보여준다. 보다 작은 imageset에서 새로운 embedding을 학습함으로써 이러한 bias를 줄일 수 있음을 보여준다(즉, 성별 및 인종적 다양성에 대한 인식을 높일 수 있음). + +# 정량평가 + +latent space embedding의 품질을 분석. + +1. reconstruction(y축?): target concept를 얼마나 잘 복제하는지. 특정 이미지가 아닌 개념에 대한 변형을 생성하므로 의미적 CLIP 공간 거리를 고려하여 유사성을 측정.(이미지에 자체가 아닌, 이미지가 가진 '개념'에 대해 latent space를 생성하므로) 각 컨셉에 대해 "A photo of S*"라는 prompt를 사용해 64개의 이미지를 생성. +2. editability(x축?): text prompt를 사용해 개념을 수정하는 능력을 평가. 다양한 난이도와 다양한 설정의 prompt를 사용해 일련의 이미지를 생성. + +각 prompt 별로, 50 DDIM step을 사용해 64개의 샘플을 만들고, CLIP-space embedding을 평가, textual prompt의 CLIP-space embedding에서 cosine similarity를 계산. 높은 스코어는 더 높은 editing capability와 prompt의 신뢰도를 보여줌. + +## 평가 setups +GAN inversion에서 영감을 받은 실험 환경 설정에 따름. 생략 + +## 결과 +:::{figure-md} quantative evaluation1 +quantative evaluation1 + +quantative evaluation1 \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +### 주목할 점 + +1. 많은 baseline과 우리 방법의 semantic reconstruction quality는 단순히 training set에서 임의의 이미지를 샘플링하는 것과 비슷함(== 원본 이미지와 생성된 이미지가 큰 차이가 없었다?) + +2. single-word method는 비슷한 reconstruction quality를 달성하고, 모든 multi-word baseline에서 상당히 향상된 editablity을 달성. 이러한 점은 text embedding space의 인상적인 유연성을 나타내고, 단일 pseudo word만 사용하면서 높은 정확도로 새로운 개념을 캡처하는데 도움이 될 수 있음을 보여줌. + +3. baseline이 distortion-editability tradeoff 곡선의 outline을 그리며 실제 단어 분포에 더 가까운 embedding이 더 쉽게 수정될 수 있음. 그러나 target의 세부 정보를 캡처하지는 못함. 반대로, 단어 분포에서 멀리 벗어나면 editability가 크게 감소하는 대신 향상된 reconstruction이 가능해짐. 특히 single embedding model은 단순히 learning rate를 변경해 이 곡선을 따라 이동할 수 있으므로 사용자에게 이 tradeoff에 대한 어느 정도의 제어를 제공함. + +4. concept에 대한 human description을 사용하면 유사성을 포착하지 못하면서도, editability가 감소함. + + +## 사용자평가 + +:::{figure-md} human test +human test + +human test \ (source: https://arxiv.org/pdf/2208.01618.pdf) +::: + +두 개의 설문지: +1) 사용자는 concept의 training set에서 4개의 이미지를 제공받았고, 이미지와의 유사성에 따라 5개의 모델에서 생성된 결과의 순위를 매김. + +2) 이미지 context를 설명하는 텍스트를 제공받았고, 텍스트와 생성된 이미지의 유사성에 따라 순위를 매김. + +각 질문별로 600개씩 총 1,200개의 응답을 수집. + +# Limitation +1. 이미지 생성에 더 많은 자유도를 제공하지만, concept의 의미론적인 본질을 파악하거나, 정확한 shape를 학습하는데 한계. +2. 최적화가 오래 걸린다. 하나의 concept를 학습하는데 약 2시간이 소요됨. + +# 마무리 +: 새로운 설정과 장면에서 특정 concept의 이미지를 생성하기 위해 text-to-image model를 활용하는 개인화되며, language-guided generation을 소개함. 여기서 사용한 'text inversion'은 pretrained text-to-image 모델의 text embedding space 내에서 concept를 새로운 pseudo word로 inverse하여 작동함. 이러한 pseudo-word는 간단한 자연어 설명을 사용해 새로운 장면에 삽입할 수 있으므로 간단하고 직관적인 수정이 가능함. + + 어떤 의미에서 이 방법은 사용자가 편집하기 쉽도록 텍스트 기반 interpace를 사용하지만 자연 언어의 한계에 접근할 때 시각적 단서를 제공하는 등 multi modal 정보를 활용할 수 있도록 함. + 이러한 접근 방식은 공개적으로 사용가능한 가장 큰 text-to-image model인 LDM을 통해 구현됨. 그러나 접근 방식에 아키텍처 세부 정보에 의존하지 않음. 따라서 textual inversion은 추가적인 대규모 text-to-image model에 쉽게 적용할 수 있다고 생각. 거기에서 text-to-image alignment, shape preseravation, image generation fidelity가 더 향상될 수 있음. \ No newline at end of file diff --git a/_sources/docs/review/cycleGAN.md b/_sources/docs/review/cycleGAN.md old mode 100644 new mode 100755 index 43644c20..5823da1d --- a/_sources/docs/review/cycleGAN.md +++ b/_sources/docs/review/cycleGAN.md @@ -1,314 +1,314 @@ -```{admonition} Information -- **Title:** Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks (ICCV 2017) - -- **Reference** - - Paper: [https://arxiv.org/abs/1703.10593](https://arxiv.org/abs/1703.10593) - - Code: [TensorFlow CycleGAN tutorial](https://www.tensorflow.org/tutorials/generative/cyclegan?hl=ko) - - [[논문리뷰] Cycle GAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks](https://velog.io/@sjinu/CycleGAN) - [CycleGAN을 만든 사람이 한국인이라고? CycleGAN 논문 뜯어보기](https://comlini8-8.tistory.com/9) - -- **Author:** KwangSu Mun - -- **Last updated on Apr. 12, 2023** -``` - -# CycleGAN - -## Abstract - -- Image-to-image translation(이하 translation)은 한 이미지 도메인을 다른 이미지 도메인으로 변환시키는 computer vision의 한 task. -- translation은 보통 input과 output이 짝이 지어진 상태에서 학습. 하지만 짝이 지어진 학습 데이터를 얻는 것이 어렵습니다. 따라서 cycleGAN 논문에서는 짝지어진 예시 없이 X라는 domain으로부터 얻은 이미지를 target domain Y로 바꾸는 방법을 제안. 이 연구는 Adversarial loss를 활용해, G(x)로부터 생성된 이미지 데이터의 분포와 Y로부터의 이미지 데이터의 분포가 구분이 불가능하도록 "함수 G:X -> Y"를 학습시키는 것을 목표로 합니다. X --> Y로의 mapping에 제약을 가해서 원하는 이미지를 강제하기 위해 F: Y -> X와 같은 역방향 매핑을 함께 진행하고, F(G(x))가 X와 유사해지도록 강제하는 Cycle consistency loss를 도입했습니다. -- 결과적으로 collection style transfer, object transfiguration, season transfer, photo enhancement 등의 task에서 이미지 pair가 존재하지 않는 상태에서 우수한 결과를 보여줬다고 합니다. - - -## Introduction - -### 참고) Image-to-Image translation이란? - -:::{figure-md} markdown-fig - - -image-to-image translation -::: - - -Image-to-image translation은 input image를 다른 스타일, 속성, 구조 등을 가진 output image로 변환하는 것입니다. 예를 들어 사진을 그림으로 변환한다거나, 낮에 찍은 사진을 밤에 찍은 것 처럼 변환하는 것을 말합니다. 흔히 translation은 input과 output으로 짝이 지어진 data를 바탕으로 학습이 이루어져 있었는데요. 짝이 지어진 사진 데이터를 얻는 것은 어렵고 값이 비싼 일이 됩니다. - -:::{figure-md} markdown-fig - - -paired and unpaired data -::: - - 이 논문에서는 input image와 output image가 일대일로 짝지어지지 않은 상태에서 하나의 image 모음의 특성을 캡쳐하고, 이러한 특성을 다른 image 모음으로 변환할 수 있는 방법을 제시합니다. -GAN은 domain X에 이미지 한 세트, domain Y에 이미지 한 세트가 제공되고, model의 output과, Y가 discriminator에 의해 구별할 수 없도록 G:X->Y를 학습합니다. 하지만, 이게 개별 입력 x와 출력 y가 무조건 유의미하게 쌍을 이룬다는 것을 뜻하지는 않습니다. G가 생성할 수 있는 image에는 무한한 경우의 수가 있기 때문. 종종 mode collapse가 일어나기도 합니다. - -### mode collapse란? - -:::{figure-md} markdown-fig - - -mode collapsing 출처: http://dl-ai.blogspot.com/2017/08/gan-problems.html -::: - -- 어떤 input image든 모두 같은 output image로 매핑하면서 최적화에 실패하는 현상. 이 현상은 generator 입장에서, Discriminator가 이 사진이 진짜 Y인지 가짜인 Y^인지 구별하는 것을 '**속이기만**' 하면 되기 때문에 우리의 목적과 전혀 상관이 없는 데이터를 generator가 만들더라도 문제가 생기지 않아서 발생함 -- 참고: [http://dl-ai.blogspot.com/2017/08/gan-problems.html](http://dl-ai.blogspot.com/2017/08/gan-problems.html) - -이러한 이슈로 인해 추가 objective function이 필요해 졌습니다. 따라서 translation task는 영어 -> 프랑스어 -> 영어로 번역했을 때 원래 문장에 다시 도달하는 것처럼, X --> Y --> X'로 돌아가는 과정에서 X와 X'가 최대한 같아야 한다는 의미의 cyclic consistency이라는 속성을 이용합니다. 필요한 목적식을 간단하게 정리하면 다음과 같습니다. - -- 정방향, 역방향 adversarial Loss(X -> Y & Y -> X) -- Cycle consistency loss: X ~= F(G(x)) - ---- - -## Related work(관련 연구) - -- GAN -- Image-to-Image Translation -- Unpaired Image-to-Image Translation -- Cycle Consistency -- Neural Style Transfer - -논문과 관련된 기존 연구에 대한 내용이었음. 관련 중요한 개념들은 위 introduction에서 설명했고, 나머지는 cycleGAN 스터디와는 딱히 관련이 없어 보여서 스킵했음. - ---- - -## Formulation - -:::{figure-md} markdown-fig - - -cycleGAN 도식화 자료 -::: - -- 목표: X, Y를 mapping하는 function을 학습하는 것 -- 용어 정리 - -1. data 분포를 x ~ pdata(x), y ~ pdata(y)로 표시 -2. G : X -> Y, F: Y -> X -3. Dx, Dy는 discriminator -4. Dx는 X와 F(y)를 구분, Dy는 y와 G(x)를 구분. 목적식은 총 두개 - - adversarial loss: 생성된 이미지의 분포를 대상 domain의 data distribution과 일치시키기 위한 것. - - cycle consistency loss: 학습된 mapping G와 F가 서로 모순되는 것을 방지하기 위한 것. - -### Adversarial loss - -G: X --> Y와 Dy에 대한 목적식은 다음과 같음. - -:::{figure-md} L_GAN Loss function -L_GAN Loss function - -L_GAN Loss function (source: https://arxiv.org/abs/1703.10593) -::: - -- GAN에서 쓰이는 loss function과 동일. 대신에 X -> Y로 갈 때와 Y -> X로 갈 때 총 두개의 수식이 나오며, F:Y->X와 Dx에 대해서도 F, Dx를 넣은, 같은 수식을 사용함. - -### Cycle consistency Loss - -:::{figure-md} markdown-fig - - -cycle consistency loss result -::: - -- 앞서 말했듯, mapping distribution에 제한을 두어 최대한 우리가 원하는 이미지를 생성하기 위해 사용하는 수식으로서, 위와 같음. -- 예비 실험에서 L1 norm을 adversarial loss로 대체해봤는데, 성능 향상을 관찰할 수 없었음. -- cycle consistency loss를 통해 유도된 결과는 아래 그림에서 볼 수 있었음. - -:::{figure-md} markdown-fig - - -cycle consistency loss function -::: - -### full objective - 전체 목적식 - -:::{figure-md} markdown-fig - - -full objective function -::: - -- 이 때 consistency loss 앞에 붙은 가중치 (lambda)는 GAN Loss와의 상대적 중요도에 따라 결정됨. - ---- - -## Implementation - -baseline architecture로서 neural style transfer와 super-resolution에 인상적인 결과를 보여준 논문에서 사용된 구조를 채택함. - -- 3개의 convolutions and several residual blocks, -- fractionally-strided convolution with stride 1/2, -- feature를 RGB로 매핑하는 one convolution layer. -- 6 blocks for 128 x 128 image // 9 blocks for 256 x 256 및 고해상도 학습 image. -- instance normalization - -### Training details - -모델 학습을 안정화시키기 위해 아래와 같은 테크닉을 추가로 적용합니다. - -- GAN의 Loss function에서 nll loss를 least-squared loss로 변경 -- 생성된 이미지 중 가장 최근의 50개를 따로 저장해 discriminator가 이를 한꺼번에 분류(모델 진동을 최소화하기 위함) - -### least-square loss 추가 설명 - -참고) - -- [https://velog.io/@sjinu/CycleGAN](https://velog.io/@sjinu/CycleGAN) -- [https://ysbsb.github.io/gan/2022/02/23/LSGAN.html](https://ysbsb.github.io/gan/2022/02/23/LSGAN.html) - -사용 이유: Generator의 업데이트를 위해서(LSGAN을 참고) - -- 이해는 못했고, 이런게 있구나 정도로만 알 수 있었음. - -:::{figure-md} markdown-fig - - -출처: https://velog.io/@sjinu/CycleGAN -::: - -(원래 Discriminator는 이보다 더 고차원이지만) 간략히 2차원을 표방하면 결정경계를 위와 같이 나타낼 수 있습니다. 윗 쪽이 가짜 영역, 아래 쪽이 진짜 영역입니다 이 때, 아래에 보면 진짜 데이터 샘플과 거리가 먼 가짜 데이터 샘플이 존재합니다. 즉, NLL Loss를 사용한다면, Generator의 입장에서는 이미 Discriminator를 잘 속이고 있기 때문에 학습할 필요가 없습니다. 즉, Vanishing Gradient가 일어나기 때문에, Discriminator를 잘 속인다는 이유만으로, 안 좋은 샘플을 생성하는 것에 대해 패널티를 줄 수가 없게 됩니다. 이 때, LS GAN을 사용한다면 실제 데이터 분포와 가짜 데이터 샘플이 거리가 먼 것에 대해서도 패널티를 주게 됩니다. - -:::{figure-md} markdown-fig - - -출처: https://velog.io/@sjinu/CycleGAN -::: - -- Generator는 Discriminator를 속이는 것을 넘어서, 실제 데이터 분포와 유사한 분포를 가지게끔 해야합니다. - -### 기타 - -- 모든 실험에서 람다를 10으로 설정했다. -- batch size == 1, 아담을 사용했다. -- 모든 네트워크는 learning rate를 0.0002로 사용했다. 첫 100 에포크 동안에는 같은 ln을 사용했고, 다음 100 에포크마다 0으로 조금식 수렴하게 했다. - ---- - -## Result - -모델 성능 평가를 위해 아래와 같은 세 개의 지표를 사용. - -1. AMT perceptual studies: 참가자들은 실제 사진이미지 vs 가짜 이미지, 또는 지도 이미지 vs 가짜이미지에 노출된 후 진짜라고 생각되는 이미지를 선택하게 함. -2. FCN Score: 1번 study가 테스트에 있어 매우 좋은 기준임에도 불구하고, 사람을 대상으로 한 실험이 아닌, 양적인 기준을 찾았는데, FCN score임. FCN은 생성된 사진에 대한 레이블 맵을 예측합니다. 이 레이블 맵은 아래에서 설명하는 표준 시맨틱 분할 메트릭을 사용하여 input ground truth label과 비교할 수 있다. "도로 상의 자동차"라는 label에서 사진 이미지를 생성하면, 생성된 이미지에 적용된 FCN이 "도로 상의 자동차"를 감지하면 성공한 것입니다. -3. 사진 --> 라벨링 성능을 평가: pixel당 정확도, class 당 정확도, IoU(Intersection-Over-Union)을 포함하는 cityscapes benchmark의 표준 metric - -### Baseline - -- coGAN, SimGAN, pix2pix - -### Comparison against baselines - -:::{figure-md} markdown-fig - - -Comparison aginst baselines -::: - -figure 5, figure 6에서 볼 수 있듯이 어떤 baseline에서도 강력한 결과를 얻을 수 없었음. 반면에 cycleGAN은 fully supervise인 pix2pix와 비슷한 품질의 translation을 생성할 수 있음. - -### Human study - -:::{figure-md} markdown-fig - - -AMT score -::: - -표 1은 AMT perceptual realism task에 대한 성능을 나타냄. 여기서 지도에서 항공 사진, 항공 사진에서 지도 모두에서 약 1/4의 참가자를 속일 수 있었음. 그 외 모든 baseline은 참가자를 거의 속일 수 없었다. - -### FCN 등 - -:::{figure-md} markdown-fig - - -FCN scores -::: - -표 2는 도시 풍경에 대한 label --> photo task의 성능을 평가하고 표 3은 반대 매핑을 평가함. 두 경우 모두 cycleGAN이 baseline들의 성능을 능가한다. - -### Analysis of the loss function - -:::{figure-md} markdown-fig - - -Analysis of loss function -::: - -GAN, cycle consistency의 중요성을 보여주는 자료. -table 4, table 5에서 볼 수 있음. GAN을 없애면 cycle을 제거하는 것처럼 결과가 크게 저하됨. 따라서 두 term 모두 결과에 중요하다고 결론을 내릴 수 있음. 또한 한 방향에서만 cycle loss를 통해 각 메소드를 평가함. GAN + forward cycle만 돌렸을 때와, GAN + backward cycle만 돌렸을 때 이따금씩 학습에 불안정성을 보이고, mode collapse를 유발하는 것을 발견함(특히 제거된 매핑의 방향에 대해서 그런 경향을 보임). 그림 7을 보면 그런 경향을 볼 수 잇었음. - -### Image reconstruction quality - -:::{figure-md} markdown-fig - - -cycle consistency result -::: - -그림 4에서 재구성된 이미지의 몇가지 무작위 샘플을 보여줌. 지도 --> 항공 사진과 같이 하나의 도메인이 훨씬 더 다양한 정보를 나타내는 경우에도 재구성된 이미지가 훈련 및 테스트 시간 모두 원래 입력 x에 가까운 경우가 많았음. - -### paired dataset에 대한 추가 결과 - -:::{figure-md} markdown-fig - - -compare with paired dataset -::: - -그림 8은 CMP Façade Database의 건축 레이블 <--> 사진, UT Zapoos50K dataset의 edge <--> 신발과 같이 pix2pix에 사용된 다른 paired dataset에 대한 몇 가지 예시 결과를 보여줌. cycleGAN의 이미지 품질은 fully supervised pix2pix에 대의 생성된 것과 비슷하지만 cycleGAN은 paired supervision 없이 학습이 된다.(우리가 짱이다!) - ---- - -## Applications -- ** 이미지가 너무 많아 이미지는 생략하겠습니다.ㅠ** -- paired data가 없는 상태에서 의 application 예시. traning data에서 transslation이 test data에서 한것보다 더 매력적이다. training and test data에 대한 application은 웹사이트에 있다. - -### Collection style transfer - - -신경 스타일 전달"\[13\]에 대한 최근 작업과 달리, 우리의 방법은 선택한 단일 예술 작품의 스타일을 전달하는 대신 전체 예술 작품 컬렉션의 스타일을 모방하는 방법을 학습합니다. 그래서 '별이 빛나는 밤에'처럼 그리는 것 보다 '반 고흐'를 따라하는 느낌을 따라한다. - -### Object transfiguration - - -Turmukhambetov et al. \[50\] 하나의 객체를 동일한 범주의 다른 객체로 변환하는 부분 공간 모델을 제안하는 반면, 우리의 방법은 시각적으로 유사한 두 범주 사이의 객체 변형에 중점을 둡니다. -Turning a horse video into a zebra video (by CycleGAN) - -### season transfer - - -### Photo generation from paintings \*\* - - -그림을 사진으로 바꿀 때, 입력과 출력 간 색 구성을 보존하기 위해 추가적인 loss를 도입하는 것이 유용하다는 것을 발견할 수 있습니다. 특히, Taigman et al. \[49\]의 기술을 채택하여 제너레이터가 대상 도메인의 실제 샘플을 입력으로 제공받을 때 identity mapping 근처에 있도록 정규화합니다. 즉, **Lidentity(G,F) = Ey\_pdata(y)\[∥G(y) − y∥1\] + Ex∼pdata (x) \[∥F (x) − x∥1 \]**입니다. - -Lidentity가 없으면, 생성자 G와 F는 굳이 필요하지 않을 때 입력 이미지의 색조를 자유롭게 변경할 수 있습니다. 예를 들어, Monet의 그림과 Flickr 사진 간의 매핑을 학습할 때, 생성자는 종종 낮에 그린 그림을 일몰 시간에 찍은 사진에 매핑합니다. 왜냐하면 적대적 손실과 사이클 일관성 손실 아래에서 이러한 매핑이 동등하게 유효할 수 있기 때문입니다. 이러한 identity mapping 손실의 효과는 그림 9에서 보여집니다. figure 12, figure 9는 학습 데이터셋에 포함되어 있는 그림, 하지만 다른 set은 오직 test set으로부터 그려진 그림. training set이 paired datqa를 포함하고 있지 않아서, 학습 세트 그림에 대한 타당한 translation을 찾는 것은 쉬운 일이 아니다. 실제로, Monet이 새 그림을 그릴 수 없기 때문에, 보지 않은 test set 그림에 대한 generalization은 not pressing problem - -### Photo enhancement - -우리는 우리의 방법이 얕은 깊이의 초점을 가진 사진을 생성하는 데 사용될 수 있음을 보여줍니다. 우리는 Flickr에서 다운로드한 꽃 사진을 기반으로 모델을 훈련합니다. 소스 도메인은 스마트폰으로 찍힌 꽃 사진으로 구성되어 있으며, 보통 작은 조리개로 인해 깊은 DoF(초점 깊이)를 가지고 있습니다. 대상은 조리개가 큰 DSLR로 촬영된 사진을 포함합니다. 우리 모델은 스마트폰으로 촬영된 사진으로부터 더 얕은 깊이의 초점을 가진 사진을 성공적으로 생성합니다. - -> : shallow depth of field: 얕은 초점. 초점이 맞은 대상과 배경이 흐릿하게 보이는 효과. 인물 사진 / 작품 사진에 활용. 구목하고자 하는 대상을 강조하기 위해 활용. -> 따라서 source domain은 스마트폰의 **작은 조리개로 깊은 초점** \--> target은 **조리개가 커서 얕은 초점**. - -### Comparison with Gatys - ---- - -## Limitations and Discusssion - -:::{figure-md} markdown-fig - - -Limitation and Discussion -::: - -이 방법은 많은 경우에 흥미로운 결과를 얻을 수 있지만, 결과는 결과가 균일하게 좋은 것은 아니었습니다. - -1. (해석) 개<->고양이 task와 같은 경우는 input image에서 최소한의 변화만 주어, 사람이 보았을 때 실제로 변화가 안되는 경우도 있었고, 형체가 애매해진 경우도 있음. 이런걸 보았을 때, 세부적인 구조(geometry? 라는 표현을 보아), 눈, 코, 입에 대한 정확한 구조를 구현하는데 한계가 있어 보임. -2. 말<--> 얼룩말 예제의 경우, 말은 사람이 타는 모습이 많았는데, 얼룩말의 경우는 사람이 타는 사진이 없다보니, 사람 뿐만 아니라 배경도 얼룩 그림을 그림을 그리거나, 단순히 얼룩말에서 노랗게 칠한 경우가 생김. -3. 때때로 photo --> image task에서 나무와 건물의 label을 바꾸는 경우도 있었음. - 이러한 모호성을 해결하려면 weak semantic supervision이 필요할 수도 있을 것 같음. - -마무리: 그럼에도 불구하고 많은 경우 완전히 짝지어지지 않은 데이터가 풍부하게 제공되며, 이를 활용해야 합니다. 이 논문은 이러한 "unsupervised" setting에서 가능한 것의 한계를 늘리는데 기여합니다. +```{admonition} Information +- **Title:** Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks (ICCV 2017) + +- **Reference** + - Paper: [https://arxiv.org/abs/1703.10593](https://arxiv.org/abs/1703.10593) + - Code: [TensorFlow CycleGAN tutorial](https://www.tensorflow.org/tutorials/generative/cyclegan?hl=ko) + - [[논문리뷰] Cycle GAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks](https://velog.io/@sjinu/CycleGAN) + [CycleGAN을 만든 사람이 한국인이라고? CycleGAN 논문 뜯어보기](https://comlini8-8.tistory.com/9) + +- **Author:** KwangSu Mun + +- **Last updated on Apr. 12, 2023** +``` + +# CycleGAN + +## Abstract + +- Image-to-image translation(이하 translation)은 한 이미지 도메인을 다른 이미지 도메인으로 변환시키는 computer vision의 한 task. +- translation은 보통 input과 output이 짝이 지어진 상태에서 학습. 하지만 짝이 지어진 학습 데이터를 얻는 것이 어렵습니다. 따라서 cycleGAN 논문에서는 짝지어진 예시 없이 X라는 domain으로부터 얻은 이미지를 target domain Y로 바꾸는 방법을 제안. 이 연구는 Adversarial loss를 활용해, G(x)로부터 생성된 이미지 데이터의 분포와 Y로부터의 이미지 데이터의 분포가 구분이 불가능하도록 "함수 G:X -> Y"를 학습시키는 것을 목표로 합니다. X --> Y로의 mapping에 제약을 가해서 원하는 이미지를 강제하기 위해 F: Y -> X와 같은 역방향 매핑을 함께 진행하고, F(G(x))가 X와 유사해지도록 강제하는 Cycle consistency loss를 도입했습니다. +- 결과적으로 collection style transfer, object transfiguration, season transfer, photo enhancement 등의 task에서 이미지 pair가 존재하지 않는 상태에서 우수한 결과를 보여줬다고 합니다. + + +## Introduction + +### 참고) Image-to-Image translation이란? + +:::{figure-md} markdown-fig + + +image-to-image translation +::: + + +Image-to-image translation은 input image를 다른 스타일, 속성, 구조 등을 가진 output image로 변환하는 것입니다. 예를 들어 사진을 그림으로 변환한다거나, 낮에 찍은 사진을 밤에 찍은 것 처럼 변환하는 것을 말합니다. 흔히 translation은 input과 output으로 짝이 지어진 data를 바탕으로 학습이 이루어져 있었는데요. 짝이 지어진 사진 데이터를 얻는 것은 어렵고 값이 비싼 일이 됩니다. + +:::{figure-md} markdown-fig + + +paired and unpaired data +::: + + 이 논문에서는 input image와 output image가 일대일로 짝지어지지 않은 상태에서 하나의 image 모음의 특성을 캡쳐하고, 이러한 특성을 다른 image 모음으로 변환할 수 있는 방법을 제시합니다. +GAN은 domain X에 이미지 한 세트, domain Y에 이미지 한 세트가 제공되고, model의 output과, Y가 discriminator에 의해 구별할 수 없도록 G:X->Y를 학습합니다. 하지만, 이게 개별 입력 x와 출력 y가 무조건 유의미하게 쌍을 이룬다는 것을 뜻하지는 않습니다. G가 생성할 수 있는 image에는 무한한 경우의 수가 있기 때문. 종종 mode collapse가 일어나기도 합니다. + +### mode collapse란? + +:::{figure-md} markdown-fig + + +mode collapsing 출처: http://dl-ai.blogspot.com/2017/08/gan-problems.html +::: + +- 어떤 input image든 모두 같은 output image로 매핑하면서 최적화에 실패하는 현상. 이 현상은 generator 입장에서, Discriminator가 이 사진이 진짜 Y인지 가짜인 Y^인지 구별하는 것을 '**속이기만**' 하면 되기 때문에 우리의 목적과 전혀 상관이 없는 데이터를 generator가 만들더라도 문제가 생기지 않아서 발생함 +- 참고: [http://dl-ai.blogspot.com/2017/08/gan-problems.html](http://dl-ai.blogspot.com/2017/08/gan-problems.html) + +이러한 이슈로 인해 추가 objective function이 필요해 졌습니다. 따라서 translation task는 영어 -> 프랑스어 -> 영어로 번역했을 때 원래 문장에 다시 도달하는 것처럼, X --> Y --> X'로 돌아가는 과정에서 X와 X'가 최대한 같아야 한다는 의미의 cyclic consistency이라는 속성을 이용합니다. 필요한 목적식을 간단하게 정리하면 다음과 같습니다. + +- 정방향, 역방향 adversarial Loss(X -> Y & Y -> X) +- Cycle consistency loss: X ~= F(G(x)) + +--- + +## Related work(관련 연구) + +- GAN +- Image-to-Image Translation +- Unpaired Image-to-Image Translation +- Cycle Consistency +- Neural Style Transfer + +논문과 관련된 기존 연구에 대한 내용이었음. 관련 중요한 개념들은 위 introduction에서 설명했고, 나머지는 cycleGAN 스터디와는 딱히 관련이 없어 보여서 스킵했음. + +--- + +## Formulation + +:::{figure-md} markdown-fig + + +cycleGAN 도식화 자료 +::: + +- 목표: X, Y를 mapping하는 function을 학습하는 것 +- 용어 정리 + +1. data 분포를 x ~ pdata(x), y ~ pdata(y)로 표시 +2. G : X -> Y, F: Y -> X +3. Dx, Dy는 discriminator +4. Dx는 X와 F(y)를 구분, Dy는 y와 G(x)를 구분. 목적식은 총 두개 + - adversarial loss: 생성된 이미지의 분포를 대상 domain의 data distribution과 일치시키기 위한 것. + - cycle consistency loss: 학습된 mapping G와 F가 서로 모순되는 것을 방지하기 위한 것. + +### Adversarial loss + +G: X --> Y와 Dy에 대한 목적식은 다음과 같음. + +:::{figure-md} L_GAN Loss function +L_GAN Loss function + +L_GAN Loss function (source: https://arxiv.org/abs/1703.10593) +::: + +- GAN에서 쓰이는 loss function과 동일. 대신에 X -> Y로 갈 때와 Y -> X로 갈 때 총 두개의 수식이 나오며, F:Y->X와 Dx에 대해서도 F, Dx를 넣은, 같은 수식을 사용함. + +### Cycle consistency Loss + +:::{figure-md} markdown-fig + + +cycle consistency loss result +::: + +- 앞서 말했듯, mapping distribution에 제한을 두어 최대한 우리가 원하는 이미지를 생성하기 위해 사용하는 수식으로서, 위와 같음. +- 예비 실험에서 L1 norm을 adversarial loss로 대체해봤는데, 성능 향상을 관찰할 수 없었음. +- cycle consistency loss를 통해 유도된 결과는 아래 그림에서 볼 수 있었음. + +:::{figure-md} markdown-fig + + +cycle consistency loss function +::: + +### full objective - 전체 목적식 + +:::{figure-md} markdown-fig + + +full objective function +::: + +- 이 때 consistency loss 앞에 붙은 가중치 (lambda)는 GAN Loss와의 상대적 중요도에 따라 결정됨. + +--- + +## Implementation + +baseline architecture로서 neural style transfer와 super-resolution에 인상적인 결과를 보여준 논문에서 사용된 구조를 채택함. + +- 3개의 convolutions and several residual blocks, +- fractionally-strided convolution with stride 1/2, +- feature를 RGB로 매핑하는 one convolution layer. +- 6 blocks for 128 x 128 image // 9 blocks for 256 x 256 및 고해상도 학습 image. +- instance normalization + +### Training details + +모델 학습을 안정화시키기 위해 아래와 같은 테크닉을 추가로 적용합니다. + +- GAN의 Loss function에서 nll loss를 least-squared loss로 변경 +- 생성된 이미지 중 가장 최근의 50개를 따로 저장해 discriminator가 이를 한꺼번에 분류(모델 진동을 최소화하기 위함) + +### least-square loss 추가 설명 + +참고) + +- [https://velog.io/@sjinu/CycleGAN](https://velog.io/@sjinu/CycleGAN) +- [https://ysbsb.github.io/gan/2022/02/23/LSGAN.html](https://ysbsb.github.io/gan/2022/02/23/LSGAN.html) + +사용 이유: Generator의 업데이트를 위해서(LSGAN을 참고) + +- 이해는 못했고, 이런게 있구나 정도로만 알 수 있었음. + +:::{figure-md} markdown-fig + + +출처: https://velog.io/@sjinu/CycleGAN +::: + +(원래 Discriminator는 이보다 더 고차원이지만) 간략히 2차원을 표방하면 결정경계를 위와 같이 나타낼 수 있습니다. 윗 쪽이 가짜 영역, 아래 쪽이 진짜 영역입니다 이 때, 아래에 보면 진짜 데이터 샘플과 거리가 먼 가짜 데이터 샘플이 존재합니다. 즉, NLL Loss를 사용한다면, Generator의 입장에서는 이미 Discriminator를 잘 속이고 있기 때문에 학습할 필요가 없습니다. 즉, Vanishing Gradient가 일어나기 때문에, Discriminator를 잘 속인다는 이유만으로, 안 좋은 샘플을 생성하는 것에 대해 패널티를 줄 수가 없게 됩니다. 이 때, LS GAN을 사용한다면 실제 데이터 분포와 가짜 데이터 샘플이 거리가 먼 것에 대해서도 패널티를 주게 됩니다. + +:::{figure-md} markdown-fig + + +출처: https://velog.io/@sjinu/CycleGAN +::: + +- Generator는 Discriminator를 속이는 것을 넘어서, 실제 데이터 분포와 유사한 분포를 가지게끔 해야합니다. + +### 기타 + +- 모든 실험에서 람다를 10으로 설정했다. +- batch size == 1, 아담을 사용했다. +- 모든 네트워크는 learning rate를 0.0002로 사용했다. 첫 100 에포크 동안에는 같은 ln을 사용했고, 다음 100 에포크마다 0으로 조금식 수렴하게 했다. + +--- + +## Result + +모델 성능 평가를 위해 아래와 같은 세 개의 지표를 사용. + +1. AMT perceptual studies: 참가자들은 실제 사진이미지 vs 가짜 이미지, 또는 지도 이미지 vs 가짜이미지에 노출된 후 진짜라고 생각되는 이미지를 선택하게 함. +2. FCN Score: 1번 study가 테스트에 있어 매우 좋은 기준임에도 불구하고, 사람을 대상으로 한 실험이 아닌, 양적인 기준을 찾았는데, FCN score임. FCN은 생성된 사진에 대한 레이블 맵을 예측합니다. 이 레이블 맵은 아래에서 설명하는 표준 시맨틱 분할 메트릭을 사용하여 input ground truth label과 비교할 수 있다. "도로 상의 자동차"라는 label에서 사진 이미지를 생성하면, 생성된 이미지에 적용된 FCN이 "도로 상의 자동차"를 감지하면 성공한 것입니다. +3. 사진 --> 라벨링 성능을 평가: pixel당 정확도, class 당 정확도, IoU(Intersection-Over-Union)을 포함하는 cityscapes benchmark의 표준 metric + +### Baseline + +- coGAN, SimGAN, pix2pix + +### Comparison against baselines + +:::{figure-md} markdown-fig + + +Comparison aginst baselines +::: + +figure 5, figure 6에서 볼 수 있듯이 어떤 baseline에서도 강력한 결과를 얻을 수 없었음. 반면에 cycleGAN은 fully supervise인 pix2pix와 비슷한 품질의 translation을 생성할 수 있음. + +### Human study + +:::{figure-md} markdown-fig + + +AMT score +::: + +표 1은 AMT perceptual realism task에 대한 성능을 나타냄. 여기서 지도에서 항공 사진, 항공 사진에서 지도 모두에서 약 1/4의 참가자를 속일 수 있었음. 그 외 모든 baseline은 참가자를 거의 속일 수 없었다. + +### FCN 등 + +:::{figure-md} markdown-fig + + +FCN scores +::: + +표 2는 도시 풍경에 대한 label --> photo task의 성능을 평가하고 표 3은 반대 매핑을 평가함. 두 경우 모두 cycleGAN이 baseline들의 성능을 능가한다. + +### Analysis of the loss function + +:::{figure-md} markdown-fig + + +Analysis of loss function +::: + +GAN, cycle consistency의 중요성을 보여주는 자료. +table 4, table 5에서 볼 수 있음. GAN을 없애면 cycle을 제거하는 것처럼 결과가 크게 저하됨. 따라서 두 term 모두 결과에 중요하다고 결론을 내릴 수 있음. 또한 한 방향에서만 cycle loss를 통해 각 메소드를 평가함. GAN + forward cycle만 돌렸을 때와, GAN + backward cycle만 돌렸을 때 이따금씩 학습에 불안정성을 보이고, mode collapse를 유발하는 것을 발견함(특히 제거된 매핑의 방향에 대해서 그런 경향을 보임). 그림 7을 보면 그런 경향을 볼 수 잇었음. + +### Image reconstruction quality + +:::{figure-md} markdown-fig + + +cycle consistency result +::: + +그림 4에서 재구성된 이미지의 몇가지 무작위 샘플을 보여줌. 지도 --> 항공 사진과 같이 하나의 도메인이 훨씬 더 다양한 정보를 나타내는 경우에도 재구성된 이미지가 훈련 및 테스트 시간 모두 원래 입력 x에 가까운 경우가 많았음. + +### paired dataset에 대한 추가 결과 + +:::{figure-md} markdown-fig + + +compare with paired dataset +::: + +그림 8은 CMP Façade Database의 건축 레이블 <--> 사진, UT Zapoos50K dataset의 edge <--> 신발과 같이 pix2pix에 사용된 다른 paired dataset에 대한 몇 가지 예시 결과를 보여줌. cycleGAN의 이미지 품질은 fully supervised pix2pix에 대의 생성된 것과 비슷하지만 cycleGAN은 paired supervision 없이 학습이 된다.(우리가 짱이다!) + +--- + +## Applications +- ** 이미지가 너무 많아 이미지는 생략하겠습니다.ㅠ** +- paired data가 없는 상태에서 의 application 예시. traning data에서 transslation이 test data에서 한것보다 더 매력적이다. training and test data에 대한 application은 웹사이트에 있다. + +### Collection style transfer + + +신경 스타일 전달"\[13\]에 대한 최근 작업과 달리, 우리의 방법은 선택한 단일 예술 작품의 스타일을 전달하는 대신 전체 예술 작품 컬렉션의 스타일을 모방하는 방법을 학습합니다. 그래서 '별이 빛나는 밤에'처럼 그리는 것 보다 '반 고흐'를 따라하는 느낌을 따라한다. + +### Object transfiguration + + +Turmukhambetov et al. \[50\] 하나의 객체를 동일한 범주의 다른 객체로 변환하는 부분 공간 모델을 제안하는 반면, 우리의 방법은 시각적으로 유사한 두 범주 사이의 객체 변형에 중점을 둡니다. +Turning a horse video into a zebra video (by CycleGAN) + +### season transfer + + +### Photo generation from paintings \*\* + + +그림을 사진으로 바꿀 때, 입력과 출력 간 색 구성을 보존하기 위해 추가적인 loss를 도입하는 것이 유용하다는 것을 발견할 수 있습니다. 특히, Taigman et al. \[49\]의 기술을 채택하여 제너레이터가 대상 도메인의 실제 샘플을 입력으로 제공받을 때 identity mapping 근처에 있도록 정규화합니다. 즉, **Lidentity(G,F) = Ey\_pdata(y)\[∥G(y) − y∥1\] + Ex∼pdata (x) \[∥F (x) − x∥1 \]**입니다. + +Lidentity가 없으면, 생성자 G와 F는 굳이 필요하지 않을 때 입력 이미지의 색조를 자유롭게 변경할 수 있습니다. 예를 들어, Monet의 그림과 Flickr 사진 간의 매핑을 학습할 때, 생성자는 종종 낮에 그린 그림을 일몰 시간에 찍은 사진에 매핑합니다. 왜냐하면 적대적 손실과 사이클 일관성 손실 아래에서 이러한 매핑이 동등하게 유효할 수 있기 때문입니다. 이러한 identity mapping 손실의 효과는 그림 9에서 보여집니다. figure 12, figure 9는 학습 데이터셋에 포함되어 있는 그림, 하지만 다른 set은 오직 test set으로부터 그려진 그림. training set이 paired datqa를 포함하고 있지 않아서, 학습 세트 그림에 대한 타당한 translation을 찾는 것은 쉬운 일이 아니다. 실제로, Monet이 새 그림을 그릴 수 없기 때문에, 보지 않은 test set 그림에 대한 generalization은 not pressing problem + +### Photo enhancement + +우리는 우리의 방법이 얕은 깊이의 초점을 가진 사진을 생성하는 데 사용될 수 있음을 보여줍니다. 우리는 Flickr에서 다운로드한 꽃 사진을 기반으로 모델을 훈련합니다. 소스 도메인은 스마트폰으로 찍힌 꽃 사진으로 구성되어 있으며, 보통 작은 조리개로 인해 깊은 DoF(초점 깊이)를 가지고 있습니다. 대상은 조리개가 큰 DSLR로 촬영된 사진을 포함합니다. 우리 모델은 스마트폰으로 촬영된 사진으로부터 더 얕은 깊이의 초점을 가진 사진을 성공적으로 생성합니다. + +> : shallow depth of field: 얕은 초점. 초점이 맞은 대상과 배경이 흐릿하게 보이는 효과. 인물 사진 / 작품 사진에 활용. 구목하고자 하는 대상을 강조하기 위해 활용. +> 따라서 source domain은 스마트폰의 **작은 조리개로 깊은 초점** \--> target은 **조리개가 커서 얕은 초점**. + +### Comparison with Gatys + +--- + +## Limitations and Discusssion + +:::{figure-md} markdown-fig + + +Limitation and Discussion +::: + +이 방법은 많은 경우에 흥미로운 결과를 얻을 수 있지만, 결과는 결과가 균일하게 좋은 것은 아니었습니다. + +1. (해석) 개<->고양이 task와 같은 경우는 input image에서 최소한의 변화만 주어, 사람이 보았을 때 실제로 변화가 안되는 경우도 있었고, 형체가 애매해진 경우도 있음. 이런걸 보았을 때, 세부적인 구조(geometry? 라는 표현을 보아), 눈, 코, 입에 대한 정확한 구조를 구현하는데 한계가 있어 보임. +2. 말<--> 얼룩말 예제의 경우, 말은 사람이 타는 모습이 많았는데, 얼룩말의 경우는 사람이 타는 사진이 없다보니, 사람 뿐만 아니라 배경도 얼룩 그림을 그림을 그리거나, 단순히 얼룩말에서 노랗게 칠한 경우가 생김. +3. 때때로 photo --> image task에서 나무와 건물의 label을 바꾸는 경우도 있었음. + 이러한 모호성을 해결하려면 weak semantic supervision이 필요할 수도 있을 것 같음. + +마무리: 그럼에도 불구하고 많은 경우 완전히 짝지어지지 않은 데이터가 풍부하게 제공되며, 이를 활용해야 합니다. 이 논문은 이러한 "unsupervised" setting에서 가능한 것의 한계를 늘리는데 기여합니다. diff --git a/_sources/docs/review/dalle.md b/_sources/docs/review/dalle.md old mode 100644 new mode 100755 index 983330a0..4e94f421 --- a/_sources/docs/review/dalle.md +++ b/_sources/docs/review/dalle.md @@ -1,243 +1,243 @@ -```{admonition} Information -- **Title:** {Zero-shot text-to-image generation}, {ICML 2021} - -- **Reference** - - Paper: [https://arxiv.org/abs/2102.12092](https://arxiv.org/abs/2102.12092) - - Code: [Unofficial-PyTorch](https://github.com/lucidrains/DALLE-pytorch) - - Code: [Official](https://github.com/openai/DALL-E) - -- **Author:** Donggeun "Sean" Ko - -- **Last updated on June 22 2023** -``` - -# DALL-E - -## 1. Introduction - -- GPT-3 기반 모델이며 120억개 parameter 수와 2.5억 데이터 (text,image) set으로 학습 -- Autoregressive 한 모델링을 통하여 image와 text를 이용하여 text-to-image generation task를 수행 -- 2021년 기준 zero-shot SOTA performance 달성 -- 아래 그림과 같이 text input에 따라 diverse한 이미지 생성 - - -:::{figure-md} -fig1 - -Images generated using DALL-E -::: - -:::{figure-md} -fig2 - -Images generated using DALL-E -::: - - -## 2. Background -- GPT-3와 VQ-VAE를 활용하여 나온 논문. -- VQ-VAE를 먼저 학습하고, Autoregressive Transformer을 순차적으로 학습하여 zero-shot architecture을 구축. - -### GPT-3 -- Autoregressive Language Model며 few-shot learning을 통해 fine-tuning 없이 높은 성능을 냄 *(fine-tuning 을 할 수는 있지만 본 논문에서는 task-agnostic performance 에 중점을 맞춰 Few shot을 함) -- GPT-3 는 transformer에서 decoder 부분만 사용 (GPT-2 와 유사한 구조를 가지고 있음 ) -- 약 1750억 parameter 개수의 모델 - - -:::{figure-md} -fig3 - -Transformer 아키텍쳐 \ (source: https://arxiv.org/pdf/2005.14165.pdf) - -::: - -:::{figure-md} -![GPT-3 GIF](../../pics/dalle/fig4.gif) - -GPT 3 Animation \ (source: https://jalammar.github.io/how-gpt3-works-visualizations-animations/) -::: - - -### VQ-VAE -- Encoder에서 나온 output은 discrete 하며 posterior 과 prior 이 categorical distribution을 갖는다고 가정함. -- CNN (encoder) 을 거친 각 D차원의 위치에 $H \times W$ 그리드로 이미지를 나누고 embedding space (Codebook) 에서 $𝑒_1$부터 $𝑒_𝑘$ 중에서 가까운 1개 embedding code로 변환. -- Quantization: Encoding output $z_{e}(x)$ representation 과 유사한 codebook embedding $e_j$ 를 찾아서 $k$ 값을 부여함. - -:::{figure-md} -fig5 - -VQ-VAE 아키텍쳐, Loss 함수 \ (source: https://velog.io/@p2yeong/Understanding-VQ-VAE-DALL-E-Explained-Pt.-1) - -::: - - - -:::{figure-md} -fig6 - -Quantization of VQ-VAE -::: - - - -## 3. Methodology - -## Limitation of Previous Works - -1. Memory/Bottleneck Issue -- 각 Image에서 나오는 pixel을 직접적으로 image token을 사용하면 고화질 이미지일수록 너무 많은 메모리량이 필요해서 “비효율적” - - -2. Short-range dependence modeling between pixels -- Model들 중 Likelihood function을 objective function으로 사용하면 short-range dependency를 우선적으로 볼 것이며 low-frequency 보다 high-frequency detail에 더욱 집중하게 됨. -- Low frequency 는 visually recognizable해서 시각적으로 더 도움이 되는 부분 - -이 2가지 문제점을 극복하고자 Two-stage training process 제안 - - -## DALL-E Overview -### Stage 1: Training VQ-VAE -- \textbf{Discrete VAE}를 이용하여 $256 \times 256$ RGB image \rightarrow $32 \times 32$ 이미지 토큰으로 압축 -- 각 이미지 토큰은 8,192개의 code 값 중에 하나 배정 -- 이미지의 \textbf{quality 손실 없이} $8 \times 8 \times 3$ 배 만큼 context size를 적게 만들 수 있음. - - -### Stage 2: Training an Autoregressive Transformer -- \textbf{최대 256 BPE-Encoded text tokens}들과 1024 image tokens ($32 \times 32$) 를 연속적으로 입력함 (concatenate) -- Text token과 Image Tokens 들의 joint distribution (결합 분포)를 모델링하여 autoregressive transformer을 학습 - - -## DALL-E Pipeline 예시 - - -:::{figure-md} -fig7 - -DALL-E 시각화 \ (source:https://jiho-ml.com/weekly-nlp-40/) -::: - -:::{figure-md} -fig8 - -DALL-E 파이프라인 \ (source:https://www.youtube.com/watch?v=CQoM0r2kMvI&t=1729s) -::: - - -## Methodology Details - -### DALL-E Equations - -:::{figure-md} -fig9 - -equation 1 -::: - -:::{figure-md} -fig10 - -equation 2: Maximizing ELBO -::: - -x: images, y: captions , z: encoded RGB image tokens - -**𝑞Φ (red)** : input image에서 dVAE encoder에서 생성한 32 x 32 image token를 예측 - -**𝑝𝜃 (blue)**: image token에서 dVAE decoder에서 생성한 RGB image를 예측 - -**𝑝ψ (purple)**: transformer 모델로 모델링한 text와 image token들의 결합 분포 (joint distribution) - -### DALL-E 학습과정 Stage 1: Learning the VIsual Codebook -- Transformer을 고정하고 dVAE encoder & decoder (𝑞_Φ , 𝑝_𝜃) 을 학습함 - - 즉, ELB (Evidence Lower Bound를 maximize 함) - - K = 8,192 codebook (embedding space)로 설정 - - -- \textbf{ELB를 optimize} 하기 위해서는 discrete distribution을 continuous를 바꿔야 함 - - 학습시에는 결국, argmax를 사용해서 codebook vector 인덱스를 선택하여 계산하면 Reparameterization gradient를 연산 X - - argmax 대신 \textbf{gumbel softmax}를 사용하여 해결 - - - 평가를 진행할 때에는 $z = codebook[\underset{i}{argmax}[g_i+log(q(e_i|x))]]$ - -- Gumbel Softmax Relaxation를 사용하여 해결! $q_\phi \rightarrow q_{\phi}^{\tau}$, temperature $\tau \rightarrow 0$, relaxation을 tight하게 잡아줌. - - -### DALL-E 학습과정 Stage 2: Learning the Prior -- Transformer을 고정하고 dVAE encoder & decoder ($q_{phi}$ , $p_{\theta}$) transformer의 prior distribution $p_{\psi}$를 학습함. -- 이때, $p_{\psi}$의 ELB를 maximize 하며 120억개의 parameter를 가진 sparse transformer 구조를 사용함 - -- Image token은 dVAE Encoder logit에서 Argmax sampling을 통해 생성 -- Text token은 소문자화 후 16,384 개의 vocabulary를 BPE-encoding 통해 한번에 최대 256 token을 활용 - -:::{figure-md} -fig11 - -Text-to-text attention: causal attention mask -Image-to-image attention: row/column/convolutional attention mask 적용 -::: - - -## Results -- 추론 시에는 text에 대하여 N개의 이미지를 생성. -- Best of N개는 \textbf{N개 생성 후 best}를 골라서 선택 함. - -- 우수한 이미지를 고르기 위해 CLIP (Contrastive Language-Image Pretraining, 2021) 논문에서 제시한 text 와 k 번째로 similarity 점수가 높은 이미지를 선택함 (k=1) - -:::{figure-md} -fig12 - -DALL-E 결과물. Best를 고를때 N 수가 증가할수록 주어진 text prompt랑 더 유사한 결과물이 나옴. -::: - -- 생성한 512개 이미지 중 CLIP 알고리즘을 통해 similarity score이 제일 높은 이미지를 뽑음. -- Ours (DALL-E) vs 다른 baseline method 와 비교 시 text에 더욱 알맞은 이미지를 생성한 것을 확인 할 수 있음. - - -:::{figure-md} -fig13 - -선택하는 이미지 개수에 따른 성능 향상 -::: - - -- DF-GAN 이랑 비교해서 MS-COCO dataset에 대하여 정성적 평가를 진행. -- Best-of-Five votes 중에 DF-GAN보다 매번 압도적인 차이로 투표 수를 받았음. - - -:::{figure-md} -fig14 - -DF-GAN 이랑 Qualitative Results 비교 -::: - - - - -- FID (Frechet Inception Distance)는 값이 낮을수록 좋으며 / IS (Inception Score)는 높을수록 좋음 -- MS-COCO 랑 CUB (새 특화 데이터셋) 기준, DALL-E는 MS-COCO에서는 뛰어난 성능을 보여줬음. -- CUB에서는 SOTA를 찍지 못하였고 Inception score에서는 낮은 점수를 기록함. -- 저자들은 Fine-tuning 으로 CUB에 성능 계선을 할 수 있다고 생각함. - -:::{figure-md} -fig15 - -MS-COCO 와 CUB dataset에서 FID/IS 결과값 비교 -::: - -## Conclusion -- GPT-3의 확장 모델로 120억개의 parameter과 autoregressive Transformer (Decoder only) 기반 모델링을 통해 text-to-image generation task를 뛰어나게 해결함. -- Zero-shot learning에서 다른 모델보다 훌륭한 일반화 성능을 보임 -- 정량적 / 정성적 평가에서 준수한 성능을 보이고 있으며 다양한 이미지 생성이 가능함. - -** Limitations: ** -- 생성하고 싶은 이미지에 다양한 객체가 포함되면 어려움을 겪음 -- (b)에 보면 고슴도치가 2마리거나 강아지와 고슴도치 둘다 크리스마스 스웨터를 입고 있음. - -- CUB dataset 처럼 다소 아쉬운 성능을 보인 데이터셋이 있지만 fine-tuning으로 해결 - - -:::{figure-md} -fig16 - -Limitation을 보여주는 결과물. -::: +```{admonition} Information +- **Title:** {Zero-shot text-to-image generation}, {ICML 2021} + +- **Reference** + - Paper: [https://arxiv.org/abs/2102.12092](https://arxiv.org/abs/2102.12092) + - Code: [Unofficial-PyTorch](https://github.com/lucidrains/DALLE-pytorch) + - Code: [Official](https://github.com/openai/DALL-E) + +- **Author:** Donggeun "Sean" Ko + +- **Last updated on June 22 2023** +``` + +# DALL-E + +## 1. Introduction + +- GPT-3 기반 모델이며 120억개 parameter 수와 2.5억 데이터 (text,image) set으로 학습 +- Autoregressive 한 모델링을 통하여 image와 text를 이용하여 text-to-image generation task를 수행 +- 2021년 기준 zero-shot SOTA performance 달성 +- 아래 그림과 같이 text input에 따라 diverse한 이미지 생성 + + +:::{figure-md} +fig1 + +Images generated using DALL-E +::: + +:::{figure-md} +fig2 + +Images generated using DALL-E +::: + + +## 2. Background +- GPT-3와 VQ-VAE를 활용하여 나온 논문. +- VQ-VAE를 먼저 학습하고, Autoregressive Transformer을 순차적으로 학습하여 zero-shot architecture을 구축. + +### GPT-3 +- Autoregressive Language Model며 few-shot learning을 통해 fine-tuning 없이 높은 성능을 냄 *(fine-tuning 을 할 수는 있지만 본 논문에서는 task-agnostic performance 에 중점을 맞춰 Few shot을 함) +- GPT-3 는 transformer에서 decoder 부분만 사용 (GPT-2 와 유사한 구조를 가지고 있음 ) +- 약 1750억 parameter 개수의 모델 + + +:::{figure-md} +fig3 + +Transformer 아키텍쳐 \ (source: https://arxiv.org/pdf/2005.14165.pdf) + +::: + +:::{figure-md} +![GPT-3 GIF](../../pics/dalle/fig4.gif) + +GPT 3 Animation \ (source: https://jalammar.github.io/how-gpt3-works-visualizations-animations/) +::: + + +### VQ-VAE +- Encoder에서 나온 output은 discrete 하며 posterior 과 prior 이 categorical distribution을 갖는다고 가정함. +- CNN (encoder) 을 거친 각 D차원의 위치에 $H \times W$ 그리드로 이미지를 나누고 embedding space (Codebook) 에서 $𝑒_1$부터 $𝑒_𝑘$ 중에서 가까운 1개 embedding code로 변환. +- Quantization: Encoding output $z_{e}(x)$ representation 과 유사한 codebook embedding $e_j$ 를 찾아서 $k$ 값을 부여함. + +:::{figure-md} +fig5 + +VQ-VAE 아키텍쳐, Loss 함수 \ (source: https://velog.io/@p2yeong/Understanding-VQ-VAE-DALL-E-Explained-Pt.-1) + +::: + + + +:::{figure-md} +fig6 + +Quantization of VQ-VAE +::: + + + +## 3. Methodology + +## Limitation of Previous Works + +1. Memory/Bottleneck Issue +- 각 Image에서 나오는 pixel을 직접적으로 image token을 사용하면 고화질 이미지일수록 너무 많은 메모리량이 필요해서 “비효율적” + + +2. Short-range dependence modeling between pixels +- Model들 중 Likelihood function을 objective function으로 사용하면 short-range dependency를 우선적으로 볼 것이며 low-frequency 보다 high-frequency detail에 더욱 집중하게 됨. +- Low frequency 는 visually recognizable해서 시각적으로 더 도움이 되는 부분 + +이 2가지 문제점을 극복하고자 Two-stage training process 제안 + + +## DALL-E Overview +### Stage 1: Training VQ-VAE +- \textbf{Discrete VAE}를 이용하여 $256 \times 256$ RGB image \rightarrow $32 \times 32$ 이미지 토큰으로 압축 +- 각 이미지 토큰은 8,192개의 code 값 중에 하나 배정 +- 이미지의 \textbf{quality 손실 없이} $8 \times 8 \times 3$ 배 만큼 context size를 적게 만들 수 있음. + + +### Stage 2: Training an Autoregressive Transformer +- \textbf{최대 256 BPE-Encoded text tokens}들과 1024 image tokens ($32 \times 32$) 를 연속적으로 입력함 (concatenate) +- Text token과 Image Tokens 들의 joint distribution (결합 분포)를 모델링하여 autoregressive transformer을 학습 + + +## DALL-E Pipeline 예시 + + +:::{figure-md} +fig7 + +DALL-E 시각화 \ (source:https://jiho-ml.com/weekly-nlp-40/) +::: + +:::{figure-md} +fig8 + +DALL-E 파이프라인 \ (source:https://www.youtube.com/watch?v=CQoM0r2kMvI&t=1729s) +::: + + +## Methodology Details + +### DALL-E Equations + +:::{figure-md} +fig9 + +equation 1 +::: + +:::{figure-md} +fig10 + +equation 2: Maximizing ELBO +::: + +x: images, y: captions , z: encoded RGB image tokens + +**𝑞Φ (red)** : input image에서 dVAE encoder에서 생성한 32 x 32 image token를 예측 + +**𝑝𝜃 (blue)**: image token에서 dVAE decoder에서 생성한 RGB image를 예측 + +**𝑝ψ (purple)**: transformer 모델로 모델링한 text와 image token들의 결합 분포 (joint distribution) + +### DALL-E 학습과정 Stage 1: Learning the VIsual Codebook +- Transformer을 고정하고 dVAE encoder & decoder (𝑞_Φ , 𝑝_𝜃) 을 학습함 + - 즉, ELB (Evidence Lower Bound를 maximize 함) + - K = 8,192 codebook (embedding space)로 설정 + + +- \textbf{ELB를 optimize} 하기 위해서는 discrete distribution을 continuous를 바꿔야 함 + - 학습시에는 결국, argmax를 사용해서 codebook vector 인덱스를 선택하여 계산하면 Reparameterization gradient를 연산 X + - argmax 대신 \textbf{gumbel softmax}를 사용하여 해결 + + - 평가를 진행할 때에는 $z = codebook[\underset{i}{argmax}[g_i+log(q(e_i|x))]]$ + +- Gumbel Softmax Relaxation를 사용하여 해결! $q_\phi \rightarrow q_{\phi}^{\tau}$, temperature $\tau \rightarrow 0$, relaxation을 tight하게 잡아줌. + + +### DALL-E 학습과정 Stage 2: Learning the Prior +- Transformer을 고정하고 dVAE encoder & decoder ($q_{phi}$ , $p_{\theta}$) transformer의 prior distribution $p_{\psi}$를 학습함. +- 이때, $p_{\psi}$의 ELB를 maximize 하며 120억개의 parameter를 가진 sparse transformer 구조를 사용함 + +- Image token은 dVAE Encoder logit에서 Argmax sampling을 통해 생성 +- Text token은 소문자화 후 16,384 개의 vocabulary를 BPE-encoding 통해 한번에 최대 256 token을 활용 + +:::{figure-md} +fig11 + +Text-to-text attention: causal attention mask +Image-to-image attention: row/column/convolutional attention mask 적용 +::: + + +## Results +- 추론 시에는 text에 대하여 N개의 이미지를 생성. +- Best of N개는 \textbf{N개 생성 후 best}를 골라서 선택 함. + +- 우수한 이미지를 고르기 위해 CLIP (Contrastive Language-Image Pretraining, 2021) 논문에서 제시한 text 와 k 번째로 similarity 점수가 높은 이미지를 선택함 (k=1) + +:::{figure-md} +fig12 + +DALL-E 결과물. Best를 고를때 N 수가 증가할수록 주어진 text prompt랑 더 유사한 결과물이 나옴. +::: + +- 생성한 512개 이미지 중 CLIP 알고리즘을 통해 similarity score이 제일 높은 이미지를 뽑음. +- Ours (DALL-E) vs 다른 baseline method 와 비교 시 text에 더욱 알맞은 이미지를 생성한 것을 확인 할 수 있음. + + +:::{figure-md} +fig13 + +선택하는 이미지 개수에 따른 성능 향상 +::: + + +- DF-GAN 이랑 비교해서 MS-COCO dataset에 대하여 정성적 평가를 진행. +- Best-of-Five votes 중에 DF-GAN보다 매번 압도적인 차이로 투표 수를 받았음. + + +:::{figure-md} +fig14 + +DF-GAN 이랑 Qualitative Results 비교 +::: + + + + +- FID (Frechet Inception Distance)는 값이 낮을수록 좋으며 / IS (Inception Score)는 높을수록 좋음 +- MS-COCO 랑 CUB (새 특화 데이터셋) 기준, DALL-E는 MS-COCO에서는 뛰어난 성능을 보여줬음. +- CUB에서는 SOTA를 찍지 못하였고 Inception score에서는 낮은 점수를 기록함. +- 저자들은 Fine-tuning 으로 CUB에 성능 계선을 할 수 있다고 생각함. + +:::{figure-md} +fig15 + +MS-COCO 와 CUB dataset에서 FID/IS 결과값 비교 +::: + +## Conclusion +- GPT-3의 확장 모델로 120억개의 parameter과 autoregressive Transformer (Decoder only) 기반 모델링을 통해 text-to-image generation task를 뛰어나게 해결함. +- Zero-shot learning에서 다른 모델보다 훌륭한 일반화 성능을 보임 +- 정량적 / 정성적 평가에서 준수한 성능을 보이고 있으며 다양한 이미지 생성이 가능함. + +** Limitations: ** +- 생성하고 싶은 이미지에 다양한 객체가 포함되면 어려움을 겪음 +- (b)에 보면 고슴도치가 2마리거나 강아지와 고슴도치 둘다 크리스마스 스웨터를 입고 있음. + +- CUB dataset 처럼 다소 아쉬운 성능을 보인 데이터셋이 있지만 fine-tuning으로 해결 + + +:::{figure-md} +fig16 + +Limitation을 보여주는 결과물. +::: diff --git a/_sources/docs/review/diffusion_beats_GANs.md b/_sources/docs/review/diffusion_beats_GANs.md old mode 100644 new mode 100755 index 037c3889..5056ed9d --- a/_sources/docs/review/diffusion_beats_GANs.md +++ b/_sources/docs/review/diffusion_beats_GANs.md @@ -1,247 +1,247 @@ -```{admonition} Information -- **Title:** {Diffusion Models Beat GANs on Image Synthesis}, {NIPS 2021} - -- **Reference** - - Paper: [https://arxiv.org/abs/2105.05233](https://arxiv.org/abs/2105.05233) - - Code: [Official](https://github.com/openai/guided-diffusion) - -- **Author:** Donggeun Sean Ko - -- **Last updated on May. 17, 2023** -``` - -# Diffusion Models Beat GANs on Image Synthesis -## Abstract - -- Diffusion 모델들은 기존 unconditional 이미지 생성 모델들의 SOTA를 뛰어넘음. -- Conditional image synthesis 부분에서도 classifier guidance를 활용해 diffusion model을 활용하여 좋은 성능을 보여준다고 주장함. -- Classifier guidance를 활용해 diversity와 fidelity의 trade-off에 대해서도 분석 - -## 1. Introduction - -- Diffusion 모델들은 likelihood-based model들이며 고화질 이미지를 생성해내는데에 성공 했음. -- 하지만, FID 수치는 BigGAN-deep에 비해 낮으며, 개선사항이 필요함. -- 두가지 contribution을 통해 Diffusion Model들의 성능을 끌어올리며 FID 결과 수치를 낮추겠다고 주장. - - 모델 아키텍쳐 개선 - - Classifier Guidance - -## 2. Background -- DDPM, DDIM, Improved DDPM은 이전에 설명되있으므로, 각 background 논문들의 핵심 부분만 설명하겠습니다. -- -### DDPM - - - - $p_\theta(x_{t-1}|x_t)$은 $q(x_{t-1}|x_t)$의 근사값이라고 가정하며 계산한다. - - $p_\theta(x_{t-1}|x_t)$를 학습하여 $p_\theta(x_{t-1}|x_t) \approx$ $q(x_{t-1}|x_t)$를 만든다. - - $\epsilon_\theta(x_t,t)$ 을 모델링하여 **noise**를 예측한다. -- 공분산 $\Sigma_\theta(X_t,t)$은 학습 불가능한 매개변수로 설정되며 constant 값을 가진다. -- 아래와 같이 $L_{simple}$ 을 새로운 Loss function으로 제안한다. - - -:::{figure-md} markdown-fig -ddpm_pipeline - -DDPM Pipeline -::: - -:::{figure-md} markdown-fig -ddpm_eq - -DDPM Equation -::: - -### Improved DDPM - -:::{figure-md} markdown-fig - -improved_ddpm_pic - -Improved DDPM scheduling comparison with DDPM (Linear vs Cosine) -::: - -- 더 적은 diffusion step으로 샘플링 함. -- Competitive log-likelihood 지표 성능 개선 (전 DDPM에선 log-likelihood 지표가 상대적으로 GAN 모델의 비해 낮았다) -- 전 DDPM 논문에서는 linear scheduling을 사용했지만, 본 논문에서는 cosine scheduling을 사용해서 성능 향상을 했다고 주장했다. -- 분산 $\Sigma_\theta(X_t,t)$을 학습에도 활용 -- $L_{hybrid}$라는 새로운 loss 함수 제시 - -:::{figure-md} markdown-fig -improved_ddpm_eq - -Improved DDPM Equation -::: - - -### DDIM - -:::{figure-md} markdown-fig -ddim_pipe - -DDIM Pipeline -::: - -- Markovian Chain Process를 끊고 Non-Markovian 형태로 Deterministic 하게 수식을 바꿈 -- DDPM 보다 더 적은 iteration으로 image synthesis 가능 - -:::{figure-md} markdown-fig -ddim_pic - -DDIM Sampling Equation -::: - -## 3. Architectural Improvements - -- DDPM에서 사용한 architecture을 그대로 채택했지만, 다양한 ablation 및 parameter을 변경하여 제일 높은 성능이 나오는 architecture을 설명 및 채택함 - -- 모델 크기를 일정하게 가져가면서 Depth vs Width 증가 보기 -- Attention head 수 증가 시켜보기 -- 각 Attention head에 resolution 을 8x8, 16x16, 32x32 로 실험 해보기 -- 일반 ResNet Residual Block이 아닌 BigGAN의 residual block을 채택하여 upsampling / downsampling 사용 해보기 -- Residual Connection을 1/√2 로 rescaling 해보기 - -:::{figure-md} markdown-fig -architect_1 - -Table 1: Ablation of various architecture changes -::: - -:::{figure-md} markdown-fig -architect_2 - -Table 2: Ablation of various attention configurations. Attention head 가 32일때 FID 값이 제일 낮다 (좋다) -::: - -** 3-1. Best Architecture ** - -- Channel 수 160 -- Depth 2 -- number of Attention Head = 4 -- Attention Resolution을 32, 16, 8 로 block마다 줄이기 -- BigGAN residual block 채택 -- Rescaling X -- 위와 같은 parameter를 통해 제일 좋은 FID 결과가 나옴 - -:::{figure-md} markdown-fig -architect_3 - -Table 3: 다양한 parameter 튜닝을 통한 제일 좋은 FID 성능 테이블 -::: - -## 4. Adaptive Group Normalization -- 본 저자들은 AdaIN이랑 비슷한 방식으로 연산하는 AdaGN 이라는 것을 소개했다. (원래 있는 방법론인지는 모르겠다...) -- Group Normalization을 adpative하게 하는 방법으로 Group Normalization 후에 residual block에 time step embedding과 class embedding을 AdaIN 방식으로 곱하고 더함 - -Equation - -$$AdaIN(x,y) = \sigma(y)(\frac{x-\mu(x)}{\sigma(x)})+\mu(y)$$ -$$AdaGN(h,y) = y_s + GroupNorm(h) + y_b$$ -where $h =$ residual block and $y = [y_s,y_b]$ time-step embedding and class embedding's linear projection respectively - -**4-1 AdaGN의 성능** - -:::{figure-md} markdown-fig -adagn_table - -AdaGN과 Additon+GroupNorm 비교 테이블. DDPM에서 사용한 normalization보다 더 좋은 성능을 보여주고 있음. -::: - -- 기존 DDPM은 Addition + GroupNorm layer을 사용했는데, AdaGN 을 사용하는 것이 FID가 더 낮게 (즉 더 좋은 성능) 나온 것을 볼 수 있다 - -## 5. Classifier Guidance -- 본 논문의 주 contribution 중 하나가 classifier guidance를 사용했다는 점이다. -- unconditional de-noising process에서 label y를 condition으로 줌으로써 conditional de-noising process로 진행 - -Equation - $$p_{\theta, \phi }(x_t|x_{t+1},y) = Zp_\theta(x_t|x_{t+1})p_\phi(y|x_t)$$ - -- Z 는 normalizing을 위한 상수 이다 - -**5-1 Classifier Guidance 유도** - -$log_\phi p(y|x_t)$가 $\Sigma^-1$ 에 비해 곡률이 낮으며, 이 가정을 따라, diffusion step이 무한으로 갈 시, $||\Sigma^ || \rightarrow0$ 이므로,$log_\phi p(y|x_t)$가 테일러 급수를 활용하여 식을 $x_t = \mu$ 로 재전개 할 수 있다. - -- classifier의 gradient를 활용해서 학습을 같이 해준다. -- 식 유도는 아래와 같다. 본문의 (3) ~ (10) 번식이므로 본 논문을 참고하면 좋다. - -:::{figure-md} markdown-fig -class_eq1 - -Classifier Guidance 유도 식 1,2 -::: - -:::{figure-md} markdown-fig -classifier_2 - -Classifier Guidance 유도 식 3~7 -::: - -## 6. Algorithm - -:::{figure-md} markdown-fig -algorithm - -Algorithm 1 & 2 sampling method. Algorithm 1은 일반적인 DDPM 기준, Algorithm 2는 DDIM 기준 guidance 한 sampling 방법 -::: - -- Algorithm 1 은 일반 DDPM에서 샘플링 하는 방법이다. 똑같이 Gaussian distribution에서 샘플링 할 시, classifier의 gradient를 활용하여 $x_{t-1}$를 sample한다. -- Algorithm 2 는 DDIM에서 샘플링 하는 방법이다. $\epsilon$ 모델에서 나오는 output과 classifier의 gradient의 joint distribution 값을 빼 score을 구한다. - - - -- DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다. -- 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다. -- **DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.** - - -## 7. Impact of parameter s in classifier guidance - -:::{figure-md} markdown-fig -class_guidance_vis - -Classifier Guidance scaling의 영향 시각화 -::: -- classifier guidance 앞에 hyperparameter \bf{s} 의 값에 따라 classifier가 줄 수 있는 scaling이 다르다. -- scale을 1.0으로 주면 웰시코기라는 class의 scale 영향을 덜 받아 "웰시코기스러운" 강아지가 생성이 많이 되지는 않는다. -- scale을 10.0으로 주면 웰시코기 class라는 scaling의 영향을 많이 받아 웰시코기 분위기의 강아지의 이미지가 더 많이 생성 되는 것을 볼 수 있다. -- epsilon이라는 모델이 결국 scale에 따라 gradient의 영향을 얼마나 많이 받는지 sampling할 때 볼 수 있다. -## 8. Results - -:::{figure-md} markdown-fig -plot result - -Fidelity vs Diversity Trade-off 결과 -::: - -- gradient scale이 높을수록 recall은 낮지만, precision은 높다. 즉 trade-off 가 생기는데, recall이 낮을수록 diveristy가 낮다는 의미이고, precision이 높을수록 fidelity가 높다는 뜻이다. -- scale을 높일수록 다양한 이미지가 생성되는 것이 아닌, classifier가 준 label쪽으로 guide가 생기므로 일정한 class의 사진이 나온다. -- FID와 sFID는 diversity와 fidelity의 trade-off로 도출되는 값이므로, 최고의 값은 중간 지점에서 나왔다. - - -**8-1. Result Table** -- ADM은 Ablated Diffusion Model의 약자이며, ADM-G는 Ablated Diffusion Model with Guidance의 약자이다. -- Guidance를 주었을 시 제일 좋은 FID값이 나왔으며, Precision이 높을수록, Recall이 낮게 나왔다 (and vice versa). - - -## 8-2. Image Synthesis Results - -:::{figure-md} markdown-fig -img_results - -Generated Images (Left: BigGAN, Center: DMs, Right: Train Dataset) -::: - -- 두번쨰 플라밍고 생성된 사진을 볼때, BigGAN은 이미지간들의 diversity가 없다. 학습된 플라밍고가 다수 플라밍고 시 비슷한 느낌의 이미지만 뽑아낸다. -- 반면, Diffusion model with guidance를 사용했을 시, 다채로운 플라밍고 사진을 볼 수 있다. 한마리만 있는 플라밍고 사진도 뽑아 낼 수 있다. - -## 9. Limitation and Future Work -**Limitation 1** -- Diffusion 모델들은 GAN보다 샘플링 시간이 아직 느리다. - -**Future Work 1** -- DDIM의 sampling process를 distillation 해서 빠르게 하는 법을 고려 - -**Limitation 2** -- Classifier guidance는 classification function의 gradient를 사용함으로써, label이 없는 data에는 확장이 불가능하다. - -**Future Work 2** -- Unlabeled sample을 clustering 하는 방법을 통해 방법론을 expand 하려 한다. +```{admonition} Information +- **Title:** {Diffusion Models Beat GANs on Image Synthesis}, {NIPS 2021} + +- **Reference** + - Paper: [https://arxiv.org/abs/2105.05233](https://arxiv.org/abs/2105.05233) + - Code: [Official](https://github.com/openai/guided-diffusion) + +- **Author:** Donggeun Sean Ko + +- **Last updated on May. 17, 2023** +``` + +# Diffusion Models Beat GANs on Image Synthesis +## Abstract + +- Diffusion 모델들은 기존 unconditional 이미지 생성 모델들의 SOTA를 뛰어넘음. +- Conditional image synthesis 부분에서도 classifier guidance를 활용해 diffusion model을 활용하여 좋은 성능을 보여준다고 주장함. +- Classifier guidance를 활용해 diversity와 fidelity의 trade-off에 대해서도 분석 + +## 1. Introduction + +- Diffusion 모델들은 likelihood-based model들이며 고화질 이미지를 생성해내는데에 성공 했음. +- 하지만, FID 수치는 BigGAN-deep에 비해 낮으며, 개선사항이 필요함. +- 두가지 contribution을 통해 Diffusion Model들의 성능을 끌어올리며 FID 결과 수치를 낮추겠다고 주장. + - 모델 아키텍쳐 개선 + - Classifier Guidance + +## 2. Background +- DDPM, DDIM, Improved DDPM은 이전에 설명되있으므로, 각 background 논문들의 핵심 부분만 설명하겠습니다. +- +### DDPM + + + - $p_\theta(x_{t-1}|x_t)$은 $q(x_{t-1}|x_t)$의 근사값이라고 가정하며 계산한다. + - $p_\theta(x_{t-1}|x_t)$를 학습하여 $p_\theta(x_{t-1}|x_t) \approx$ $q(x_{t-1}|x_t)$를 만든다. + - $\epsilon_\theta(x_t,t)$ 을 모델링하여 **noise**를 예측한다. +- 공분산 $\Sigma_\theta(X_t,t)$은 학습 불가능한 매개변수로 설정되며 constant 값을 가진다. +- 아래와 같이 $L_{simple}$ 을 새로운 Loss function으로 제안한다. + + +:::{figure-md} markdown-fig +ddpm_pipeline + +DDPM Pipeline +::: + +:::{figure-md} markdown-fig +ddpm_eq + +DDPM Equation +::: + +### Improved DDPM + +:::{figure-md} markdown-fig + +improved_ddpm_pic + +Improved DDPM scheduling comparison with DDPM (Linear vs Cosine) +::: + +- 더 적은 diffusion step으로 샘플링 함. +- Competitive log-likelihood 지표 성능 개선 (전 DDPM에선 log-likelihood 지표가 상대적으로 GAN 모델의 비해 낮았다) +- 전 DDPM 논문에서는 linear scheduling을 사용했지만, 본 논문에서는 cosine scheduling을 사용해서 성능 향상을 했다고 주장했다. +- 분산 $\Sigma_\theta(X_t,t)$을 학습에도 활용 +- $L_{hybrid}$라는 새로운 loss 함수 제시 + +:::{figure-md} markdown-fig +improved_ddpm_eq + +Improved DDPM Equation +::: + + +### DDIM + +:::{figure-md} markdown-fig +ddim_pipe + +DDIM Pipeline +::: + +- Markovian Chain Process를 끊고 Non-Markovian 형태로 Deterministic 하게 수식을 바꿈 +- DDPM 보다 더 적은 iteration으로 image synthesis 가능 + +:::{figure-md} markdown-fig +ddim_pic + +DDIM Sampling Equation +::: + +## 3. Architectural Improvements + +- DDPM에서 사용한 architecture을 그대로 채택했지만, 다양한 ablation 및 parameter을 변경하여 제일 높은 성능이 나오는 architecture을 설명 및 채택함 + +- 모델 크기를 일정하게 가져가면서 Depth vs Width 증가 보기 +- Attention head 수 증가 시켜보기 +- 각 Attention head에 resolution 을 8x8, 16x16, 32x32 로 실험 해보기 +- 일반 ResNet Residual Block이 아닌 BigGAN의 residual block을 채택하여 upsampling / downsampling 사용 해보기 +- Residual Connection을 1/√2 로 rescaling 해보기 + +:::{figure-md} markdown-fig +architect_1 + +Table 1: Ablation of various architecture changes +::: + +:::{figure-md} markdown-fig +architect_2 + +Table 2: Ablation of various attention configurations. Attention head 가 32일때 FID 값이 제일 낮다 (좋다) +::: + +** 3-1. Best Architecture ** + +- Channel 수 160 +- Depth 2 +- number of Attention Head = 4 +- Attention Resolution을 32, 16, 8 로 block마다 줄이기 +- BigGAN residual block 채택 +- Rescaling X +- 위와 같은 parameter를 통해 제일 좋은 FID 결과가 나옴 + +:::{figure-md} markdown-fig +architect_3 + +Table 3: 다양한 parameter 튜닝을 통한 제일 좋은 FID 성능 테이블 +::: + +## 4. Adaptive Group Normalization +- 본 저자들은 AdaIN이랑 비슷한 방식으로 연산하는 AdaGN 이라는 것을 소개했다. (원래 있는 방법론인지는 모르겠다...) +- Group Normalization을 adpative하게 하는 방법으로 Group Normalization 후에 residual block에 time step embedding과 class embedding을 AdaIN 방식으로 곱하고 더함 + +Equation + +$$AdaIN(x,y) = \sigma(y)(\frac{x-\mu(x)}{\sigma(x)})+\mu(y)$$ +$$AdaGN(h,y) = y_s + GroupNorm(h) + y_b$$ +where $h =$ residual block and $y = [y_s,y_b]$ time-step embedding and class embedding's linear projection respectively + +**4-1 AdaGN의 성능** + +:::{figure-md} markdown-fig +adagn_table + +AdaGN과 Additon+GroupNorm 비교 테이블. DDPM에서 사용한 normalization보다 더 좋은 성능을 보여주고 있음. +::: + +- 기존 DDPM은 Addition + GroupNorm layer을 사용했는데, AdaGN 을 사용하는 것이 FID가 더 낮게 (즉 더 좋은 성능) 나온 것을 볼 수 있다 + +## 5. Classifier Guidance +- 본 논문의 주 contribution 중 하나가 classifier guidance를 사용했다는 점이다. +- unconditional de-noising process에서 label y를 condition으로 줌으로써 conditional de-noising process로 진행 + +Equation + $$p_{\theta, \phi }(x_t|x_{t+1},y) = Zp_\theta(x_t|x_{t+1})p_\phi(y|x_t)$$ + +- Z 는 normalizing을 위한 상수 이다 + +**5-1 Classifier Guidance 유도** + +$log_\phi p(y|x_t)$가 $\Sigma^-1$ 에 비해 곡률이 낮으며, 이 가정을 따라, diffusion step이 무한으로 갈 시, $||\Sigma^ || \rightarrow0$ 이므로,$log_\phi p(y|x_t)$가 테일러 급수를 활용하여 식을 $x_t = \mu$ 로 재전개 할 수 있다. + +- classifier의 gradient를 활용해서 학습을 같이 해준다. +- 식 유도는 아래와 같다. 본문의 (3) ~ (10) 번식이므로 본 논문을 참고하면 좋다. + +:::{figure-md} markdown-fig +class_eq1 + +Classifier Guidance 유도 식 1,2 +::: + +:::{figure-md} markdown-fig +classifier_2 + +Classifier Guidance 유도 식 3~7 +::: + +## 6. Algorithm + +:::{figure-md} markdown-fig +algorithm + +Algorithm 1 & 2 sampling method. Algorithm 1은 일반적인 DDPM 기준, Algorithm 2는 DDIM 기준 guidance 한 sampling 방법 +::: + +- Algorithm 1 은 일반 DDPM에서 샘플링 하는 방법이다. 똑같이 Gaussian distribution에서 샘플링 할 시, classifier의 gradient를 활용하여 $x_{t-1}$를 sample한다. +- Algorithm 2 는 DDIM에서 샘플링 하는 방법이다. $\epsilon$ 모델에서 나오는 output과 classifier의 gradient의 joint distribution 값을 빼 score을 구한다. + + + +- DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다. +- 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다. +- **DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.** + + +## 7. Impact of parameter s in classifier guidance + +:::{figure-md} markdown-fig +class_guidance_vis + +Classifier Guidance scaling의 영향 시각화 +::: +- classifier guidance 앞에 hyperparameter \bf{s} 의 값에 따라 classifier가 줄 수 있는 scaling이 다르다. +- scale을 1.0으로 주면 웰시코기라는 class의 scale 영향을 덜 받아 "웰시코기스러운" 강아지가 생성이 많이 되지는 않는다. +- scale을 10.0으로 주면 웰시코기 class라는 scaling의 영향을 많이 받아 웰시코기 분위기의 강아지의 이미지가 더 많이 생성 되는 것을 볼 수 있다. +- epsilon이라는 모델이 결국 scale에 따라 gradient의 영향을 얼마나 많이 받는지 sampling할 때 볼 수 있다. +## 8. Results + +:::{figure-md} markdown-fig +plot result + +Fidelity vs Diversity Trade-off 결과 +::: + +- gradient scale이 높을수록 recall은 낮지만, precision은 높다. 즉 trade-off 가 생기는데, recall이 낮을수록 diveristy가 낮다는 의미이고, precision이 높을수록 fidelity가 높다는 뜻이다. +- scale을 높일수록 다양한 이미지가 생성되는 것이 아닌, classifier가 준 label쪽으로 guide가 생기므로 일정한 class의 사진이 나온다. +- FID와 sFID는 diversity와 fidelity의 trade-off로 도출되는 값이므로, 최고의 값은 중간 지점에서 나왔다. + + +**8-1. Result Table** +- ADM은 Ablated Diffusion Model의 약자이며, ADM-G는 Ablated Diffusion Model with Guidance의 약자이다. +- Guidance를 주었을 시 제일 좋은 FID값이 나왔으며, Precision이 높을수록, Recall이 낮게 나왔다 (and vice versa). + + +## 8-2. Image Synthesis Results + +:::{figure-md} markdown-fig +img_results + +Generated Images (Left: BigGAN, Center: DMs, Right: Train Dataset) +::: + +- 두번쨰 플라밍고 생성된 사진을 볼때, BigGAN은 이미지간들의 diversity가 없다. 학습된 플라밍고가 다수 플라밍고 시 비슷한 느낌의 이미지만 뽑아낸다. +- 반면, Diffusion model with guidance를 사용했을 시, 다채로운 플라밍고 사진을 볼 수 있다. 한마리만 있는 플라밍고 사진도 뽑아 낼 수 있다. + +## 9. Limitation and Future Work +**Limitation 1** +- Diffusion 모델들은 GAN보다 샘플링 시간이 아직 느리다. + +**Future Work 1** +- DDIM의 sampling process를 distillation 해서 빠르게 하는 법을 고려 + +**Limitation 2** +- Classifier guidance는 classification function의 gradient를 사용함으로써, label이 없는 data에는 확장이 불가능하다. + +**Future Work 2** +- Unlabeled sample을 clustering 하는 방법을 통해 방법론을 expand 하려 한다. diff --git a/_sources/docs/review/dreambooth.md b/_sources/docs/review/dreambooth.md old mode 100644 new mode 100755 index d0f1286e..7b0eed42 --- a/_sources/docs/review/dreambooth.md +++ b/_sources/docs/review/dreambooth.md @@ -1,247 +1,247 @@ -``` {admonition} Information -- **Title:** DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation (CVPR 2023) - -- **Reference** - - Paper: [https://arxiv.org/abs/2208.12242](https://arxiv.org/abs/2208.12242) - - Code: [https://github.com/huggingface/diffusers/tree/main/examples/dreambooth](https://github.com/huggingface/diffusers/tree/main/examples/dreambooth) - -- **Author:** Sangwoo Jo - -- **Last updated on May. 31, 2023** -``` - -# DreamBooth - -## Introduction - -최근에 DALL-E2, Imagen, Stable Diffusion 등 다양한 text-to-image generation 모델들이 등장하였지만, 어떠한 동일한 subject 에 대해서 다른 context 에 적용하는 부분에서 부족한 면들을 보여주고 있습니다. DreamBooth 논문은 이러한 문제점을 개선하기 위해 text-to-image 모델을 fine-tuning 하는 기법으로 소개되었고, 단 3-5장의 이미지를 학습하면 되며 이를 NVIDIA A100 으로 학습하는데 5분 정도밖에 소요되지 않는다고 합니다. - -:::{figure-md} markdown-fig -dreambooth_01 - -Subject-Driven Generation -::: - -DreamBooth 가 무엇인지 자세히 알아보기 전에 text-to-image diffusion model 에 대해 다시 한번 개념 정리를 해볼 필요가 있습니다. - -## Text-to-Image Diffusion Models - -사전학습된 text-to-image diffusion model $\hat{x}_{\theta}$ 는 input 으로 원본 이미지 $x$, 그리고 text prompt $P$ 와 text-encoder $\Gamma$ 로부터 나오는 conditioning vector $c = \Gamma(P)$ 를 입력받아서 이미지 $x_{gen} = \hat{x}_{\theta}(\epsilon, c)$ 를 생성하게 됩니다. 학습 시, mean squared loss 를 사용하고 이를 수식적으로 표현하면 다음과 같습니다. - -$$ -\mathbb{E}_{x,c,\epsilon,t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_{t}\epsilon, c) - x ||_{2}^{2}] -$$ - -이때, DreamBooth 에서는 text encoder 를 CLIP text embedding 과 사전학습된 T5-XXL 모델 중 T5-XXL 모델을 사용했다고 합니다. 그리고 DreamBooth 로 fine-tuning 할때, diffusion process 에서 사용되는 U-net (때로는 text encoder 도 포함) 은 learnable 한 parameter 로 설정하고 생성된 latent vector 로부터 새로운 이미지를 생성하는 Decoder 의 파라미터 값은 고정시킨다고 합니다. - -앞써 설명드렸던 내용들을 해당 implementation code 에서 확인할 수 있습니다. - -- **code** - - ```python - # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py - text_encoder_cls = import_model_class_from_model_name_or_path(args.pretrained_model_name_or_path, args.revision) - - # Load scheduler and models - noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") - text_encoder = text_encoder_cls.from_pretrained( - args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision - ) - vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision) - unet = UNet2DConditionModel.from_pretrained( - args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision - ) - ``` - -- **training code** - - ```python - # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py - for epoch in range(first_epoch, args.num_train_epochs): - unet.train() - if args.train_text_encoder: - text_encoder.train() - for step, batch in enumerate(train_dataloader): - # Skip steps until we reach the resumed step - if args.resume_from_checkpoint and epoch == first_epoch and step < resume_step: - if step % args.gradient_accumulation_steps == 0: - progress_bar.update(1) - continue - - with accelerator.accumulate(unet): - # Convert images to latent space - latents = vae.encode(batch["pixel_values"].to(dtype=weight_dtype)).latent_dist.sample() - latents = latents * vae.config.scaling_factor - - # Sample noise that we'll add to the latents - if args.offset_noise: - noise = torch.randn_like(latents) + 0.1 * torch.randn( - latents.shape[0], latents.shape[1], 1, 1, device=latents.device - ) - else: - noise = torch.randn_like(latents) - bsz = latents.shape[0] - # Sample a random timestep for each image - timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (bsz,), device=latents.device) - timesteps = timesteps.long() - - # Add noise to the latents according to the noise magnitude at each timestep - # (this is the forward diffusion process) - noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) - - # Get the text embedding for conditioning - encoder_hidden_states = text_encoder(batch["input_ids"])[0] - - # Predict the noise residual - model_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample - - # Get the target for loss depending on the prediction type - if noise_scheduler.config.prediction_type == "epsilon": - target = noise - elif noise_scheduler.config.prediction_type == "v_prediction": - target = noise_scheduler.get_velocity(latents, noise, timesteps) - else: - raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") - - if args.with_prior_preservation: - # Chunk the noise and model_pred into two parts and compute the loss on each part separately. - model_pred, model_pred_prior = torch.chunk(model_pred, 2, dim=0) - target, target_prior = torch.chunk(target, 2, dim=0) - - # Compute instance loss - loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean") - - # Compute prior loss - prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean") - - # Add the prior loss to the instance loss. - loss = loss + args.prior_loss_weight * prior_loss - else: - loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean") - - accelerator.backward(loss) - if accelerator.sync_gradients: - params_to_clip = ( - itertools.chain(unet.parameters(), text_encoder.parameters()) - if args.train_text_encoder - else unet.parameters() - ) - accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) - optimizer.step() - lr_scheduler.step() - optimizer.zero_grad(set_to_none=args.set_grads_to_none) - ``` - - -## Fine-tuning - -DreamBooth 에서 pre-trained 된 text-to-image generation 모델을 fine-tuning 할 때 *“a [unique identifier] [class noun]”* 그리고 *“a [class noun]”* 형태의 두 가지 text prompt 를 사용합니다. 이때, *unique identifier* 에 유지하고자 하는 대상에 대한 정보를 담는 것을 목표로 하기 때문에 사전 정보가 없는 rare token 을 사용하는 것이 중요하다고 합니다. 논문에서는 3개 이하의 Unicode character 혹은 T5-XXL tokenizer 를 랜덤하게 샘플링해서 token 을 생성하고 이를 기반으로 *unique identifier* 를 정의합니다. - -또한, 논문에서 *Language Drift* 그리고 *Reduced Output Diversity* 두 가지 문제점을 해결하기 위해 Class-specific Prior Preservation Loss 를 소개합니다. 이를 활용하여 모델을 fine-tuning 하는 방법은 다음과 같습니다. - -:::{figure-md} markdown-fig -dreambooth_02 - -Fine-tuning -::: - -우선, Gaussian 노이즈 이미지와 *“A V [class noun]”* 형태의 text prompt 를 사전학습된 text-to-image diffusion 모델에 입력하여 이미지를 생성한 후, 원본 이미지와의 *Reconstruction Loss* 를 계산합니다. 그리고 비슷한 과정으로 Gaussian 노이즈 이미지와 *“A [class noun]”* 형태의 text prompt 를 학습하고자 하는 모델, 그리고 freeze 시킨 또 다른 pre-trained diffusion 모델에 각각 입력하여 이미지를 생성한 후 *Class-Specific Prior Preservation Loss* 를 계산합니다. 이에 대한 training objective 를 수식적으로 표현하면 다음과 같습니다. - -$$ -\mathbb{E}_{x,c,\epsilon,\epsilon^{'},t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_t\epsilon, c) - x ||_{2}^{2} + \lambda w_{t^{'}} || \hat{x}_{\theta}(\alpha_{t^{'}} x_{pr} + \sigma_{t^{'}}\epsilon^{'}, c_{pr}) - x_{pr} ||_{2}^{2}] -$$ - -*Class-Specific Prior Preservation Loss* 를 추가함으로써 class prior 에 대한 정보를 유지하게 되고, 이로써 동일한 class 에 대해 더 다양한 이미지들을 생성할 수 있는 부분을 아래 그림에서 확인할 수 있습니다. - -:::{figure-md} markdown-fig -dreambooth_03 - -Encouraging diversity with prior-preservation loss -::: - -## Experiments - -DreamBooth 논문에서 세 가지의 모델 평가 metric 을 소개합니다. 첫번째로는 *subject fidelity* 를 측정하는 CLIP-I, DINO 그리고 *prompt fidelity* 를 측정하는 CLIP-T metric 을 사용합니다. 이때, DINO metric 이 동일한 class 를 가진 subject 에 대해서 다른 embedding 이 생성되기 때문에 CLIP-I 보다 더 선호된다고 합니다. 더 자세하게는 각 metric 은 다음과 같이 계산됩니다. - -- CLIP-I := 생성된 이미지와 실제 이미지의 CLIP embedding 의 평균 pairwise cosine similarity -- DINO := 생성된 이미지와 실제 이미지의 ViT-S/16 DINO embedding 의 평균 pairwise cosine similarity -- CLIP-T := 입력 prompt 와 생성된 이미지의 CLIP embedding 의 평균 pairwise cosine similarity - -Textual Inversion 과 비교했을때, 세 개의 metric 에서 모두 DreamBooth 가 더 좋은 성능을 보여주는 것을 확인할 수 있습니다. - -:::{figure-md} markdown-fig -dreambooth_04 - -Comparison of models -::: - -## Ablation Studies - -Prior Preservation Loss (PPL) 과 Class-Prior 에 대한 Ablation Studies 결과도 논문에서 공유합니다. PPL 가 적용됨으로써 앞써 소개드렸던 Language Drift 그리고 Reduced Output Diversity 문제점을 PRES 그리고 DIV metric 을 통해 해결되는 것을 보여줍니다. 또한, Class-Prior Ablation 에서 다음과 같은 세 가지 prompt 를 사용하여 fine-tuning 했을 때, 해당 subject 에 맞는 *class noun* 을 prompt 에 입력했을때가 가장 좋은 성능을 보여준다고 설명합니다. - -- “no class noun” -- “a randomly sampled incorrect class noun” (e.g., “can” for a backpack) -- “correct class noun” - -## Applications - -논문에서 DreamBooth 를 활용한 여러 application 도 소개합니다. - -:::{figure-md} markdown-fig -dreambooth_05 - -Applications of DreamBooth -::: - -1. Recontextualization -- Prompt: “a [V] [class noun] [context description]” -- 다음과 같은 prompt 입력 시, 사전에 보지 못했던 새로운 pose 나 articulation 을 잘 표현하는 부분을 확인할 수 있습니다. - -:::{figure-md} markdown-fig -dreambooth_06 - -Recontextualization -::: - -2. Art Renditions -- Prompt: “a painting of a [V] [class noun] in the style of [famous painter]” or “a statue of a [V] [class noun] in the style of [famous sculptor]” -- Style Transfer 와 다르게 동일한 구조를 유지한 채 style 만 바꾸는 것이 아니라 다양한 pose 형태도 생성 가능합니다. - -3. Novel View Synthesis -- 동일한 subject 에 대해 다양한 각도에서 보는 이미지 생성도 가능합니다. - -4. Property Modification -- Prompt: “a cross of a [V] dog and a [target species]” -- 사전 학습한 subject 의 고유 feature 들이 다른 target species 에서도 반영이 되는 부분을 확인할 수 있습니다. - -## Limitations - -하지만 DreamBooth 모델에 다음과 같은 한계점도 존재합니다. - -:::{figure-md} markdown-fig -dreambooth_07 - -Limitations of DreamBooth -::: - -- Incorrect context synthesis := 대표적으로 training set 에 자주 나타나지 않는 subject, prompt, context 에 대해서 낮은 성능을 보여줍니다. -- Context-appearance entanglement := 유지하고자 하는 대상의 appearance (e.g, color) 가 prompted context 에 의해 달라지는 현상 -- Overfitting := 사전학습된 데이터와 유사한 prompt 입력 시, overfitting 현상 발생 - -마지막으로 subject 대상에 따라 모델 성능(fidelity)이 차이를 보인다고 합니다. - -## Appendix - -마지막으로, 논문 본문에 소개되고 있지는 않지만 Appendix 부문에서도 흥미로운 결과들을 확인할 수 있습니다. Figure 20 은 fine tuning 하는 이미지 개수에 따른 DreamBooth 학습결과를 보여주는데, 단 한 장만으로도 identity 의 전반적인 특징을 잘 담는 것을 확인할 수 있습니다. Figure 18 은 만화 캐릭터의 identity 를 유지한 상태로 다양한 만화 사진들을 모델이 생성하는 사례들을 보여줍니다. - -:::{figure-md} markdown-fig -dreambooth_08 - -Appendix-1 -::: - -:::{figure-md} markdown-fig -dreambooth_09 - -Appendix-2 -::: +``` {admonition} Information +- **Title:** DreamBooth: Fine Tuning Text-to-Image Diffusion Models for Subject-Driven Generation (CVPR 2023) + +- **Reference** + - Paper: [https://arxiv.org/abs/2208.12242](https://arxiv.org/abs/2208.12242) + - Code: [https://github.com/huggingface/diffusers/tree/main/examples/dreambooth](https://github.com/huggingface/diffusers/tree/main/examples/dreambooth) + +- **Author:** Sangwoo Jo + +- **Last updated on May. 31, 2023** +``` + +# DreamBooth + +## Introduction + +최근에 DALL-E2, Imagen, Stable Diffusion 등 다양한 text-to-image generation 모델들이 등장하였지만, 어떠한 동일한 subject 에 대해서 다른 context 에 적용하는 부분에서 부족한 면들을 보여주고 있습니다. DreamBooth 논문은 이러한 문제점을 개선하기 위해 text-to-image 모델을 fine-tuning 하는 기법으로 소개되었고, 단 3-5장의 이미지를 학습하면 되며 이를 NVIDIA A100 으로 학습하는데 5분 정도밖에 소요되지 않는다고 합니다. + +:::{figure-md} markdown-fig +dreambooth_01 + +Subject-Driven Generation +::: + +DreamBooth 가 무엇인지 자세히 알아보기 전에 text-to-image diffusion model 에 대해 다시 한번 개념 정리를 해볼 필요가 있습니다. + +## Text-to-Image Diffusion Models + +사전학습된 text-to-image diffusion model $\hat{x}_{\theta}$ 는 input 으로 원본 이미지 $x$, 그리고 text prompt $P$ 와 text-encoder $\Gamma$ 로부터 나오는 conditioning vector $c = \Gamma(P)$ 를 입력받아서 이미지 $x_{gen} = \hat{x}_{\theta}(\epsilon, c)$ 를 생성하게 됩니다. 학습 시, mean squared loss 를 사용하고 이를 수식적으로 표현하면 다음과 같습니다. + +$$ +\mathbb{E}_{x,c,\epsilon,t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_{t}\epsilon, c) - x ||_{2}^{2}] +$$ + +이때, DreamBooth 에서는 text encoder 를 CLIP text embedding 과 사전학습된 T5-XXL 모델 중 T5-XXL 모델을 사용했다고 합니다. 그리고 DreamBooth 로 fine-tuning 할때, diffusion process 에서 사용되는 U-net (때로는 text encoder 도 포함) 은 learnable 한 parameter 로 설정하고 생성된 latent vector 로부터 새로운 이미지를 생성하는 Decoder 의 파라미터 값은 고정시킨다고 합니다. + +앞써 설명드렸던 내용들을 해당 implementation code 에서 확인할 수 있습니다. + +- **code** + + ```python + # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py + text_encoder_cls = import_model_class_from_model_name_or_path(args.pretrained_model_name_or_path, args.revision) + + # Load scheduler and models + noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler") + text_encoder = text_encoder_cls.from_pretrained( + args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision + ) + vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision) + unet = UNet2DConditionModel.from_pretrained( + args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision + ) + ``` + +- **training code** + + ```python + # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py + for epoch in range(first_epoch, args.num_train_epochs): + unet.train() + if args.train_text_encoder: + text_encoder.train() + for step, batch in enumerate(train_dataloader): + # Skip steps until we reach the resumed step + if args.resume_from_checkpoint and epoch == first_epoch and step < resume_step: + if step % args.gradient_accumulation_steps == 0: + progress_bar.update(1) + continue + + with accelerator.accumulate(unet): + # Convert images to latent space + latents = vae.encode(batch["pixel_values"].to(dtype=weight_dtype)).latent_dist.sample() + latents = latents * vae.config.scaling_factor + + # Sample noise that we'll add to the latents + if args.offset_noise: + noise = torch.randn_like(latents) + 0.1 * torch.randn( + latents.shape[0], latents.shape[1], 1, 1, device=latents.device + ) + else: + noise = torch.randn_like(latents) + bsz = latents.shape[0] + # Sample a random timestep for each image + timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (bsz,), device=latents.device) + timesteps = timesteps.long() + + # Add noise to the latents according to the noise magnitude at each timestep + # (this is the forward diffusion process) + noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps) + + # Get the text embedding for conditioning + encoder_hidden_states = text_encoder(batch["input_ids"])[0] + + # Predict the noise residual + model_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample + + # Get the target for loss depending on the prediction type + if noise_scheduler.config.prediction_type == "epsilon": + target = noise + elif noise_scheduler.config.prediction_type == "v_prediction": + target = noise_scheduler.get_velocity(latents, noise, timesteps) + else: + raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}") + + if args.with_prior_preservation: + # Chunk the noise and model_pred into two parts and compute the loss on each part separately. + model_pred, model_pred_prior = torch.chunk(model_pred, 2, dim=0) + target, target_prior = torch.chunk(target, 2, dim=0) + + # Compute instance loss + loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean") + + # Compute prior loss + prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean") + + # Add the prior loss to the instance loss. + loss = loss + args.prior_loss_weight * prior_loss + else: + loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean") + + accelerator.backward(loss) + if accelerator.sync_gradients: + params_to_clip = ( + itertools.chain(unet.parameters(), text_encoder.parameters()) + if args.train_text_encoder + else unet.parameters() + ) + accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm) + optimizer.step() + lr_scheduler.step() + optimizer.zero_grad(set_to_none=args.set_grads_to_none) + ``` + + +## Fine-tuning + +DreamBooth 에서 pre-trained 된 text-to-image generation 모델을 fine-tuning 할 때 *“a [unique identifier] [class noun]”* 그리고 *“a [class noun]”* 형태의 두 가지 text prompt 를 사용합니다. 이때, *unique identifier* 에 유지하고자 하는 대상에 대한 정보를 담는 것을 목표로 하기 때문에 사전 정보가 없는 rare token 을 사용하는 것이 중요하다고 합니다. 논문에서는 3개 이하의 Unicode character 혹은 T5-XXL tokenizer 를 랜덤하게 샘플링해서 token 을 생성하고 이를 기반으로 *unique identifier* 를 정의합니다. + +또한, 논문에서 *Language Drift* 그리고 *Reduced Output Diversity* 두 가지 문제점을 해결하기 위해 Class-specific Prior Preservation Loss 를 소개합니다. 이를 활용하여 모델을 fine-tuning 하는 방법은 다음과 같습니다. + +:::{figure-md} markdown-fig +dreambooth_02 + +Fine-tuning +::: + +우선, Gaussian 노이즈 이미지와 *“A V [class noun]”* 형태의 text prompt 를 사전학습된 text-to-image diffusion 모델에 입력하여 이미지를 생성한 후, 원본 이미지와의 *Reconstruction Loss* 를 계산합니다. 그리고 비슷한 과정으로 Gaussian 노이즈 이미지와 *“A [class noun]”* 형태의 text prompt 를 학습하고자 하는 모델, 그리고 freeze 시킨 또 다른 pre-trained diffusion 모델에 각각 입력하여 이미지를 생성한 후 *Class-Specific Prior Preservation Loss* 를 계산합니다. 이에 대한 training objective 를 수식적으로 표현하면 다음과 같습니다. + +$$ +\mathbb{E}_{x,c,\epsilon,\epsilon^{'},t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_t\epsilon, c) - x ||_{2}^{2} + \lambda w_{t^{'}} || \hat{x}_{\theta}(\alpha_{t^{'}} x_{pr} + \sigma_{t^{'}}\epsilon^{'}, c_{pr}) - x_{pr} ||_{2}^{2}] +$$ + +*Class-Specific Prior Preservation Loss* 를 추가함으로써 class prior 에 대한 정보를 유지하게 되고, 이로써 동일한 class 에 대해 더 다양한 이미지들을 생성할 수 있는 부분을 아래 그림에서 확인할 수 있습니다. + +:::{figure-md} markdown-fig +dreambooth_03 + +Encouraging diversity with prior-preservation loss +::: + +## Experiments + +DreamBooth 논문에서 세 가지의 모델 평가 metric 을 소개합니다. 첫번째로는 *subject fidelity* 를 측정하는 CLIP-I, DINO 그리고 *prompt fidelity* 를 측정하는 CLIP-T metric 을 사용합니다. 이때, DINO metric 이 동일한 class 를 가진 subject 에 대해서 다른 embedding 이 생성되기 때문에 CLIP-I 보다 더 선호된다고 합니다. 더 자세하게는 각 metric 은 다음과 같이 계산됩니다. + +- CLIP-I := 생성된 이미지와 실제 이미지의 CLIP embedding 의 평균 pairwise cosine similarity +- DINO := 생성된 이미지와 실제 이미지의 ViT-S/16 DINO embedding 의 평균 pairwise cosine similarity +- CLIP-T := 입력 prompt 와 생성된 이미지의 CLIP embedding 의 평균 pairwise cosine similarity + +Textual Inversion 과 비교했을때, 세 개의 metric 에서 모두 DreamBooth 가 더 좋은 성능을 보여주는 것을 확인할 수 있습니다. + +:::{figure-md} markdown-fig +dreambooth_04 + +Comparison of models +::: + +## Ablation Studies + +Prior Preservation Loss (PPL) 과 Class-Prior 에 대한 Ablation Studies 결과도 논문에서 공유합니다. PPL 가 적용됨으로써 앞써 소개드렸던 Language Drift 그리고 Reduced Output Diversity 문제점을 PRES 그리고 DIV metric 을 통해 해결되는 것을 보여줍니다. 또한, Class-Prior Ablation 에서 다음과 같은 세 가지 prompt 를 사용하여 fine-tuning 했을 때, 해당 subject 에 맞는 *class noun* 을 prompt 에 입력했을때가 가장 좋은 성능을 보여준다고 설명합니다. + +- “no class noun” +- “a randomly sampled incorrect class noun” (e.g., “can” for a backpack) +- “correct class noun” + +## Applications + +논문에서 DreamBooth 를 활용한 여러 application 도 소개합니다. + +:::{figure-md} markdown-fig +dreambooth_05 + +Applications of DreamBooth +::: + +1. Recontextualization +- Prompt: “a [V] [class noun] [context description]” +- 다음과 같은 prompt 입력 시, 사전에 보지 못했던 새로운 pose 나 articulation 을 잘 표현하는 부분을 확인할 수 있습니다. + +:::{figure-md} markdown-fig +dreambooth_06 + +Recontextualization +::: + +2. Art Renditions +- Prompt: “a painting of a [V] [class noun] in the style of [famous painter]” or “a statue of a [V] [class noun] in the style of [famous sculptor]” +- Style Transfer 와 다르게 동일한 구조를 유지한 채 style 만 바꾸는 것이 아니라 다양한 pose 형태도 생성 가능합니다. + +3. Novel View Synthesis +- 동일한 subject 에 대해 다양한 각도에서 보는 이미지 생성도 가능합니다. + +4. Property Modification +- Prompt: “a cross of a [V] dog and a [target species]” +- 사전 학습한 subject 의 고유 feature 들이 다른 target species 에서도 반영이 되는 부분을 확인할 수 있습니다. + +## Limitations + +하지만 DreamBooth 모델에 다음과 같은 한계점도 존재합니다. + +:::{figure-md} markdown-fig +dreambooth_07 + +Limitations of DreamBooth +::: + +- Incorrect context synthesis := 대표적으로 training set 에 자주 나타나지 않는 subject, prompt, context 에 대해서 낮은 성능을 보여줍니다. +- Context-appearance entanglement := 유지하고자 하는 대상의 appearance (e.g, color) 가 prompted context 에 의해 달라지는 현상 +- Overfitting := 사전학습된 데이터와 유사한 prompt 입력 시, overfitting 현상 발생 + +마지막으로 subject 대상에 따라 모델 성능(fidelity)이 차이를 보인다고 합니다. + +## Appendix + +마지막으로, 논문 본문에 소개되고 있지는 않지만 Appendix 부문에서도 흥미로운 결과들을 확인할 수 있습니다. Figure 20 은 fine tuning 하는 이미지 개수에 따른 DreamBooth 학습결과를 보여주는데, 단 한 장만으로도 identity 의 전반적인 특징을 잘 담는 것을 확인할 수 있습니다. Figure 18 은 만화 캐릭터의 identity 를 유지한 상태로 다양한 만화 사진들을 모델이 생성하는 사례들을 보여줍니다. + +:::{figure-md} markdown-fig +dreambooth_08 + +Appendix-1 +::: + +:::{figure-md} markdown-fig +dreambooth_09 + +Appendix-2 +::: diff --git a/_sources/docs/review/gan.md b/_sources/docs/review/gan.md old mode 100644 new mode 100755 index 8ce157da..0d67085c --- a/_sources/docs/review/gan.md +++ b/_sources/docs/review/gan.md @@ -1,218 +1,218 @@ -```{admonition} Information -- **Title:** Generative Adversarial Networks (NIPS 2014) - -- **Reference** - - Paper: [https://arxiv.org/abs/1406.2661](https://arxiv.org/abs/1406.2661) - - Code: [https://github.com/eriklindernoren/PyTorch-GAN](https://github.com/eriklindernoren/PyTorch-GAN) - - [Smart Design Lab @KAIST | 딥러닝 Chp 3.4 GAN](https://www.youtube.com/watch?v=cd-kj1ysqOc) - -- **Author:** Sangwoo Jo - -- **Last updated on Apr. 12, 2023** -``` - -# GAN - - -## Introduction - -Ian Goodfellow 가 2014년에 발표한 GAN 은 최근에 Diffusion Model 이 소개되기 전까지 몇 년 동안 이미지 생성분야에서 대표적인 모델로 자리잡았었습니다. GAN 은 VAE 와 달리 marginal likelihood $p_{\theta}(x)$ 를 직접 구하지 않고, Adversarial Process 를 통해 implicit 하게 샘플링을 해서 분포를 구하게 됩니다. - -:::{figure-md} markdown-fig -gan_01 - -Taxonomy of Generative Models -::: - -아래 그림과 같이 GAN 은 크게 잠재변수 $z$ 로부터 가짜 데이터를 생성하는 Generator 와 그로부터 생성된 데이터와 실제 training 데이터를 구분하는 Discriminator 로 구성이 되어 있습니다. 다시 말해서 Discriminator 는 실제 데이터가 들어오면 1, 그리고 가짜로 생성된 데이터가 들어오면 0 을 출력하는 binary classification task 를 진행합니다. - -:::{figure-md} markdown-fig -gan_03 - -Generative Adversarial Network(GAN) Architecture -::: - -Generator 와 Discriminator 구현 코드도 같이 살펴보겠습니다. - -- **Generator 구현 code** - - ```python - class Generator(nn.Module): - def __init__(self): - super(Generator, self).__init__() - - def block(in_feat, out_feat, normalize=True): - layers = [nn.Linear(in_feat, out_feat)] - if normalize: - layers.append(nn.BatchNorm1d(out_feat, 0.8)) - layers.append(nn.LeakyReLU(0.2, inplace=True)) - return layers - - self.model = nn.Sequential( - *block(opt.latent_dim, 128, normalize=False), - *block(128, 256), - *block(256, 512), - *block(512, 1024), - nn.Linear(1024, int(np.prod(img_shape))), - nn.Tanh() - ) - - def forward(self, z): - img = self.model(z) - img = img.view(img.size(0), *img_shape) - return img - ``` - -- **Discriminator 구현 code** - - ```python - class Discriminator(nn.Module): - def __init__(self): - super(Discriminator, self).__init__() - - self.model = nn.Sequential( - nn.Linear(int(np.prod(img_shape)), 512), - nn.LeakyReLU(0.2, inplace=True), - nn.Linear(512, 256), - nn.LeakyReLU(0.2, inplace=True), - nn.Linear(256, 1), - nn.Sigmoid(), - ) - - def forward(self, img): - img_flat = img.view(img.size(0), -1) - validity = self.model(img_flat) - - return validity - ``` - - -## Training Procedure - -GAN 을 학습할 시, **D를 먼저 최적화하는 k 단계**와 **G를 최적화하는 한 단계를 번갈아 수행**합니다. 그리고 이때 쓰이는 손실함수(loss function)은 다음과 같습니다. - -$$ -\min_G \max_D V(D,G) = \mathbb{E}_{x \sim p_{data}(x)}[log\ D(x)] + \mathbb{E}_{z \sim p_z(z)}[log(1-D(G(z))] -$$ - -논문에서 제시한 학습 알고리즘과 실제 implementation code 를 비교해보겠습니다. - -:::{figure-md} markdown-fig -gan_02 - -Generative Adversarial Network(GAN) Training Procedure -::: - -- **GAN 학습 code** - - ```python - # ---------- - # Training - # ---------- - - for epoch in range(opt.n_epochs): - for i, (imgs, _) in enumerate(dataloader): - - # Adversarial ground truths - valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False) - fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False) - - # Configure input - real_imgs = Variable(imgs.type(Tensor)) - - # ----------------- - # Train Generator - # ----------------- - - optimizer_G.zero_grad() - - # Sample noise as generator input - z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim)))) - - # Generate a batch of images - gen_imgs = generator(z) - - # Loss measures generator's ability to fool the discriminator - g_loss = adversarial_loss(discriminator(gen_imgs), valid) - - g_loss.backward() - optimizer_G.step() - - # --------------------- - # Train Discriminator - # --------------------- - - optimizer_D.zero_grad() - - # Measure discriminator's ability to classify real from generated samples - real_loss = adversarial_loss(discriminator(real_imgs), valid) - fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake) - d_loss = (real_loss + fake_loss) / 2 - - d_loss.backward() - optimizer_D.step() - - print( - "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]" - % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item()) - ) - - batches_done = epoch * len(dataloader) + i - if batches_done % opt.sample_interval == 0: - save_image(gen_imgs.data[:25], "images/%d.png" % batches_done, nrow=5, normalize=True) - ``` - - -이렇게 Discriminator 와 Generator 는 각각 $V(D,G)$ 가 최대화하고 최소화하는 방향으로 stochastic gradient descent 를 진행하게 됩니다. 하지만 아래 그림처럼 실제로 Generator를 학습할 때, 초반에 $D(G(z)) \approx 0$ 일 경우 학습하지 못하는 상황이 발생합니다. 이 때, $log(1-D(G(z))$ 를 최소화하지 않고 $log(D(G(z))$ 를 최대화하는 방향으로 Generator 를 학습하는 기법도 있습니다. - -:::{figure-md} markdown-fig -gan_04 - -Alternative to Vanishing Gradient when Training the Generator -::: - -이렇게 학습함으로써 최적화된 solution 에서는 Generator 가 training 데이터 분포를 완벽히 복원하고 Discriminator 는 binary classification 확률을 언제나 1/2 로 내뱉게 됩니다. - -### Theoretical Results - -**Proposition 1. 고정된 Generator 에 대해서, 최적화된 Discriminator 는 다음과 같습니다.** - -$$ -D_{G}^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)} -$$ - -이를 증명하자면, Discriminator 에 대한 손실함수를 다음과 같이 쓸 수 있고 $D = D_{G}^*(x)$ 가 이를 최대화하는 solution 입니다. - -$$ -V(D,G) = \int_x p_{data}(x)\ log(D(x))\ dx+ \int_z p_{z}(z)\ log(1-D(g(z))\ dz -$$ - -$$ -= \int_x p_{data}(x)\ log(D(x)) + p_{g}(x)\ log(1-D(x))\ dx -$$ - -**Proposition 2. 최적화된 Discriminator 에 대해 $\max_D V(D,G)$ 를 최소화하는 Generator 는 $p_g = p_{data}$ 일때 성립하고 이때 $D = D_{G}^*(x) = 1/2$ 입니다.** - -이를 증명하자면, 최적화된 Discriminator 에 대한 손실함수는 다음과 같고 - -$$ -V(D^{\ast},G) = \mathbb{E}_{x \sim p_{data}(x)} [ log D^{\ast}(x) ] + \mathbb{E}_{x \sim p_g(x)} [ log(1-D^{\ast}(x) ] -$$ - -$$ -= \int_x p_{data}(x)\ log(\frac{p_{data}(x)}{p_{data}(x) + p_g(x)}) + \int_x p_{g}(x)\ log(\frac{p_{g}(x)}{p_{data}(x) + p_g(x)})\ dx -$$ - -$$ -= -log(4)\ + KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) -$$ - -$KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) = 2\ \cdot\ JSD(p_{data}\ ||\ p_{g})$ 의 최솟값은 0 이고 이는 $p_g = p_{data}$ 일때 성립합니다. - -## Experiments - -논문에서 MNIST, the Toronto Face Database(TFD), 그리고 CIFAR-10 dataset 로 모델 실험 및 성능 평가했습니다. 평가시에는 $p_g$ 로부터 Parzen density estimation 을 거쳐 계산한 log likelihood estimate 로 모델 성능 평가를 진행했습니다. - -## Summary - -VAE는 새로운 데이터를 잘 생성하지만 생성된 이미지가 흐릿하다는 단점을 지니고 있습니다. 반면에 GAN 은 high quality image 를 잘 생성하지만 unstable 한 convergence 를 가지고 있습니다. 그래서 실제로 VAE 는 Encoder 를 활용한 차원축소로 많이 활용되고 이미지 데이터를 생성하는데는 GAN 이 많이 활용되었다고 합니다. +```{admonition} Information +- **Title:** Generative Adversarial Networks (NIPS 2014) + +- **Reference** + - Paper: [https://arxiv.org/abs/1406.2661](https://arxiv.org/abs/1406.2661) + - Code: [https://github.com/eriklindernoren/PyTorch-GAN](https://github.com/eriklindernoren/PyTorch-GAN) + - [Smart Design Lab @KAIST | 딥러닝 Chp 3.4 GAN](https://www.youtube.com/watch?v=cd-kj1ysqOc) + +- **Author:** Sangwoo Jo + +- **Last updated on Apr. 12, 2023** +``` + +# GAN + + +## Introduction + +Ian Goodfellow 가 2014년에 발표한 GAN 은 최근에 Diffusion Model 이 소개되기 전까지 몇 년 동안 이미지 생성분야에서 대표적인 모델로 자리잡았었습니다. GAN 은 VAE 와 달리 marginal likelihood $p_{\theta}(x)$ 를 직접 구하지 않고, Adversarial Process 를 통해 implicit 하게 샘플링을 해서 분포를 구하게 됩니다. + +:::{figure-md} markdown-fig +gan_01 + +Taxonomy of Generative Models +::: + +아래 그림과 같이 GAN 은 크게 잠재변수 $z$ 로부터 가짜 데이터를 생성하는 Generator 와 그로부터 생성된 데이터와 실제 training 데이터를 구분하는 Discriminator 로 구성이 되어 있습니다. 다시 말해서 Discriminator 는 실제 데이터가 들어오면 1, 그리고 가짜로 생성된 데이터가 들어오면 0 을 출력하는 binary classification task 를 진행합니다. + +:::{figure-md} markdown-fig +gan_03 + +Generative Adversarial Network(GAN) Architecture +::: + +Generator 와 Discriminator 구현 코드도 같이 살펴보겠습니다. + +- **Generator 구현 code** + + ```python + class Generator(nn.Module): + def __init__(self): + super(Generator, self).__init__() + + def block(in_feat, out_feat, normalize=True): + layers = [nn.Linear(in_feat, out_feat)] + if normalize: + layers.append(nn.BatchNorm1d(out_feat, 0.8)) + layers.append(nn.LeakyReLU(0.2, inplace=True)) + return layers + + self.model = nn.Sequential( + *block(opt.latent_dim, 128, normalize=False), + *block(128, 256), + *block(256, 512), + *block(512, 1024), + nn.Linear(1024, int(np.prod(img_shape))), + nn.Tanh() + ) + + def forward(self, z): + img = self.model(z) + img = img.view(img.size(0), *img_shape) + return img + ``` + +- **Discriminator 구현 code** + + ```python + class Discriminator(nn.Module): + def __init__(self): + super(Discriminator, self).__init__() + + self.model = nn.Sequential( + nn.Linear(int(np.prod(img_shape)), 512), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(512, 256), + nn.LeakyReLU(0.2, inplace=True), + nn.Linear(256, 1), + nn.Sigmoid(), + ) + + def forward(self, img): + img_flat = img.view(img.size(0), -1) + validity = self.model(img_flat) + + return validity + ``` + + +## Training Procedure + +GAN 을 학습할 시, **D를 먼저 최적화하는 k 단계**와 **G를 최적화하는 한 단계를 번갈아 수행**합니다. 그리고 이때 쓰이는 손실함수(loss function)은 다음과 같습니다. + +$$ +\min_G \max_D V(D,G) = \mathbb{E}_{x \sim p_{data}(x)}[log\ D(x)] + \mathbb{E}_{z \sim p_z(z)}[log(1-D(G(z))] +$$ + +논문에서 제시한 학습 알고리즘과 실제 implementation code 를 비교해보겠습니다. + +:::{figure-md} markdown-fig +gan_02 + +Generative Adversarial Network(GAN) Training Procedure +::: + +- **GAN 학습 code** + + ```python + # ---------- + # Training + # ---------- + + for epoch in range(opt.n_epochs): + for i, (imgs, _) in enumerate(dataloader): + + # Adversarial ground truths + valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False) + fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False) + + # Configure input + real_imgs = Variable(imgs.type(Tensor)) + + # ----------------- + # Train Generator + # ----------------- + + optimizer_G.zero_grad() + + # Sample noise as generator input + z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim)))) + + # Generate a batch of images + gen_imgs = generator(z) + + # Loss measures generator's ability to fool the discriminator + g_loss = adversarial_loss(discriminator(gen_imgs), valid) + + g_loss.backward() + optimizer_G.step() + + # --------------------- + # Train Discriminator + # --------------------- + + optimizer_D.zero_grad() + + # Measure discriminator's ability to classify real from generated samples + real_loss = adversarial_loss(discriminator(real_imgs), valid) + fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake) + d_loss = (real_loss + fake_loss) / 2 + + d_loss.backward() + optimizer_D.step() + + print( + "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]" + % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item()) + ) + + batches_done = epoch * len(dataloader) + i + if batches_done % opt.sample_interval == 0: + save_image(gen_imgs.data[:25], "images/%d.png" % batches_done, nrow=5, normalize=True) + ``` + + +이렇게 Discriminator 와 Generator 는 각각 $V(D,G)$ 가 최대화하고 최소화하는 방향으로 stochastic gradient descent 를 진행하게 됩니다. 하지만 아래 그림처럼 실제로 Generator를 학습할 때, 초반에 $D(G(z)) \approx 0$ 일 경우 학습하지 못하는 상황이 발생합니다. 이 때, $log(1-D(G(z))$ 를 최소화하지 않고 $log(D(G(z))$ 를 최대화하는 방향으로 Generator 를 학습하는 기법도 있습니다. + +:::{figure-md} markdown-fig +gan_04 + +Alternative to Vanishing Gradient when Training the Generator +::: + +이렇게 학습함으로써 최적화된 solution 에서는 Generator 가 training 데이터 분포를 완벽히 복원하고 Discriminator 는 binary classification 확률을 언제나 1/2 로 내뱉게 됩니다. + +### Theoretical Results + +**Proposition 1. 고정된 Generator 에 대해서, 최적화된 Discriminator 는 다음과 같습니다.** + +$$ +D_{G}^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)} +$$ + +이를 증명하자면, Discriminator 에 대한 손실함수를 다음과 같이 쓸 수 있고 $D = D_{G}^*(x)$ 가 이를 최대화하는 solution 입니다. + +$$ +V(D,G) = \int_x p_{data}(x)\ log(D(x))\ dx+ \int_z p_{z}(z)\ log(1-D(g(z))\ dz +$$ + +$$ += \int_x p_{data}(x)\ log(D(x)) + p_{g}(x)\ log(1-D(x))\ dx +$$ + +**Proposition 2. 최적화된 Discriminator 에 대해 $\max_D V(D,G)$ 를 최소화하는 Generator 는 $p_g = p_{data}$ 일때 성립하고 이때 $D = D_{G}^*(x) = 1/2$ 입니다.** + +이를 증명하자면, 최적화된 Discriminator 에 대한 손실함수는 다음과 같고 + +$$ +V(D^{\ast},G) = \mathbb{E}_{x \sim p_{data}(x)} [ log D^{\ast}(x) ] + \mathbb{E}_{x \sim p_g(x)} [ log(1-D^{\ast}(x) ] +$$ + +$$ += \int_x p_{data}(x)\ log(\frac{p_{data}(x)}{p_{data}(x) + p_g(x)}) + \int_x p_{g}(x)\ log(\frac{p_{g}(x)}{p_{data}(x) + p_g(x)})\ dx +$$ + +$$ += -log(4)\ + KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) +$$ + +$KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) = 2\ \cdot\ JSD(p_{data}\ ||\ p_{g})$ 의 최솟값은 0 이고 이는 $p_g = p_{data}$ 일때 성립합니다. + +## Experiments + +논문에서 MNIST, the Toronto Face Database(TFD), 그리고 CIFAR-10 dataset 로 모델 실험 및 성능 평가했습니다. 평가시에는 $p_g$ 로부터 Parzen density estimation 을 거쳐 계산한 log likelihood estimate 로 모델 성능 평가를 진행했습니다. + +## Summary + +VAE는 새로운 데이터를 잘 생성하지만 생성된 이미지가 흐릿하다는 단점을 지니고 있습니다. 반면에 GAN 은 high quality image 를 잘 생성하지만 unstable 한 convergence 를 가지고 있습니다. 그래서 실제로 VAE 는 Encoder 를 활용한 차원축소로 많이 활용되고 이미지 데이터를 생성하는데는 GAN 이 많이 활용되었다고 합니다. diff --git a/_sources/docs/review/imagen.md b/_sources/docs/review/imagen.md old mode 100644 new mode 100755 index 75f57713..5c8b09ba --- a/_sources/docs/review/imagen.md +++ b/_sources/docs/review/imagen.md @@ -1,194 +1,194 @@ -``` {admonition} Information -- **Title:** Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding (NeurIPS 2022) - -- **Reference** - - Paper: [https://arxiv.org/abs/2205.11487](https://arxiv.org/abs/2205.11487) - -- **Author:** Donggeun Sean Ko - -- **Last updated on Sep. 13, 2023** - -``` - -# Imagen - - -# Introduction -- Multi-modal learning, 특히 text-to-image generation 에서 contrastive learning이 최근에 많은 주목을 받고 있음. - -- Contrastive learning 과 더불어 large language model (LLM) 들과 diffusion model 들을 사용하여 독창적인 image 생성도 가능함 - -- 텍스트 전용 말뭉치 (text corpus)로 학습된 LLM들의 text embedding들은 text-to-image 합성에 매우 효과적이라고 함. - -- Classifier-free guidance 사용하여, 더 높은 충실도 (fidelity)의 이미지를 생성하는 새로운 샘플링 기술을 사용함. - -:::{figure-md} -imagen_1 - -Concept of Contrastive Learning -::: - -# Contributions - -1. **Pretrained Frozen** text encoder (T5-XXL) 이 text-to-image generation task 에 매우 좋은 성능을 보여줌. -2. Pretrained Text Encoder 사이즈를 **fine-tuning**하는 것이 diffusion model size fine tuning 하는 것보다 더 중요하다는 것을 실험적으로 증명함 -3. **Dynamic Thresholding** 이라는 새로운 diffusion sampling technique (thresholding diffusion sampler) 을 제시하여 high guidance weight을 leverage 할 수 있게 만들어 더욱 “현실적인” 이미지 생성을 할 수 있음 -4. **Efficient U-Net**이라는 기존 Palette 나 DDIM에서 사용하는 U-Net 구조보다 computational, memory efficient 한 U-Net 구조를 제시함 -5. COCO FID 점수 **7.27** SOTA 점수를 달성함 -6. **DrawBench**라는 새로운 text-to-image generation evaluation용 benchmark dataset을 제시함 - -# Methodology - -## Pretrained T5-XXL + Cascaded Diffusion Model - -- Pretrained Text Encoder 중 T5-XXL (구글 모델) 사용 -- 학습 시 pretrained text encoder을 Freeze 해놓음 -- Text-to-Image Diffusion Model (Improved DDPM 아키텍쳐) 사용해 64x64 image 생성 -- 2가지 SR model (Efficient U-Net)을 사용해서 64 → 256 → 1024 로 upsampling - -:::{figure-md} -imagen_2 - -Imagen overall pipeline -::: - -## Classifier-Free Guidance -- Classifier-free guidance 이란 auxiliary classifier의 효과 없이 classifier guidance 효과를 얻는 방법 -- 아래의 그림처럼 guidance가 없을 시 image generation이 일정하지 않음. 즉, label/class 의 영향을 못받아서, 생성이 일정하지 않음. -- guidance를 줄 시, 생성된 이미지의 class나 object이 일정하고 무엇을 생성하는것인지 좀 더 자세하게 알 수 있음. - -:::{figure-md} -imagen_3 - -Comparison between when guidance is not used (left) vs when guidance is used with parameter, w=3 (right) -::: - -## Large guidance weight sampler -- Guide의 가중치 w 를 높이면 train-test 불일치가 생긴다. -- 이로 인해, 높은 가중치의 이미지는 훈련 데이터 범위 안에 없어 [-1,1], classifier-free guidance가 평균과 분산을 이동시켜 이미지가 아예 “빗나가” 이상한 이미지를 생성하게 된다 - -## Static Thresholding -- x-prediction 을 [-1,1]로 clipping 한다. 여전히 saturation 이 되고 fidelity가 덜한 이미지가 생성 됌 -- 문제를 해결하고자 dynamic thresholding 을 제시함 - -:::{figure-md} -imagen_5 - -Graphical visualization of static thresholding -::: - -## Dynamic Thresholding -- 특정 백분위수 절대 픽셀 값을 s 라고 지정하고 s > 1 이면, 임계값을 [-s,s]로 지정한 다음 s로 나눈다. -- 예시: 90% 지점의 픽셀 값이 3 이면 [-3,3]으로 clipping 한 후 3으로 나눠서 [-1,1] 로 normalize 함. -- Thresholding 의 차이는 아래 결과 비교 이미지로 확인 할 수 있다. - -:::{figure-md} -imagen_6 - -Graphical visualization of dynamic thresholding -::: - - -:::{figure-md} -imagen_7 - -Comparison among no thresholding, static thresholding and dynamic thresholding, respectively -::: - -## Super Resolution Models -- Efficient U-Net이라는 새로운 모델을 만들어, 기존 U-Net에서 여러가지 modification을 하였다고 주장 (그렇지만 EffU-Net은 의료쪽으로 이름이 이미 있는걸로 아는데…) -- Removed self-attention layer -- Keep the text cross-attention layer -- Skip connection scaling을 1/(√2)로 하여 convergence 를 더 빠르게 함 -- Lower resolution block에서 residual blocks를 더 추가함 - -:::{figure-md} -imagen_8 - -Architecture of Super Resolution Diffusion Model used in Imagen -::: - -## DrawBench -- Imagen 저자들이 제시한 새로운 벤치마크 데이터셋. 본 데이터셋은 text prompt 와 category label 로 이루어졌다 -- 깃허브에서 다운 받을 수 있으며, 예시는 아래 그림과 갗다 -11 categories, 200 text prompts -Human evaluation 으로 진행 (25명의 평가자) -Model A에서 생성한 이미지 set vs Model B에서 생성한 이미지 set - -평가자는 2가지 질문을 주며 2가지 기준점으로 평가함 -**Q1. Which set of images is of higher quality?** -**Q2. Which set of images better represents the text caption: {text caption}?** - - -기준점 -- Image Fidelity -- Image-text alignment - -평가자는 3가지 답변 중 하나를 선택해야함 -1. I prefer set A -2. I am Indifferent -3. I prefer set B - - -:::{figure-md} -imagen_9 - -Screenshot of DrawBench dataset -::: - -# Results -- Figure 2 에서는 DrawBench에서 나온 결과를 체리피킹 없이 보여준다. -- 아마 저자들은 체리피킹 없이도 좋은 결과를 보여주고, 다양한 카테고리에서도 훌륭한 이미지를 생성 할 수 있다는 주장인 것 같다. - -:::{figure-md} -imagen_10 - -Result of Imagen in DrawBench dataset -::: - -- Zero-shot 으로 한 FID값이 MS-COCO로 학습한 모델들 FID 보다 높음. - -- Table 2 에서는 Imagen이 no people (사람이 없는 사진) 에는 photorealism 점수가 올라감 -→ Imagen 은 photorealistic people을 생성하기에 한계가 있음. - -:::{figure-md} -imagen_11 - -Result Table of Imagen -::: - -### Qualitative Result Table of Imagen from Human Evaluators - -- Human raters (사람 평가자) 들은 T5-XXL로 text encoding 한 text-to-image generation 모델을 CLIP-based 보다 더 선호함 - -- 기본적으로 Imagen 은 다른 text-to-image generation 모델에서 (SOTA 모델인 DALL-E 2) 보다도 human raters 에서 DrawBench 데이터셋에서 좋은 평가를 받음 - -:::{figure-md} -imagen_12 - -Qualitative Result Table of Imagen from Human evaulators -::: - -# Ablation Study - -- Scaling text encoder size 가 U-Net size scaling 보다 더 중요함 -- (a)의 text encoder 사이즈의 변화가 FID 및 CLIP score 점수에 더욱 많은 영향을 끼침 - -- Dynamic thresholding 이 performance boost에 더욱 영향을 끼침 -- Dynamic thresholding을 이용하면 성능을 더욱 끌어 올릴 수 있음 - -:::{figure-md} -imagen_13 - -Qualitative Result Table of Imagen from Human evaulators -::: - -# Conclusion - -- Frozen large pretrained language model shows better performance over text-image paired multimodal encoders such as CLIP in text-to-image generation task -- Efficient U-Net significantly improves performance time -- Dynamic thresholding allows usage of much higher guidance weights with better fidelity of generated images - - - - +``` {admonition} Information +- **Title:** Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding (NeurIPS 2022) + +- **Reference** + - Paper: [https://arxiv.org/abs/2205.11487](https://arxiv.org/abs/2205.11487) + +- **Author:** Donggeun Sean Ko + +- **Last updated on Sep. 13, 2023** + +``` + +# Imagen + + +# Introduction +- Multi-modal learning, 특히 text-to-image generation 에서 contrastive learning이 최근에 많은 주목을 받고 있음. + +- Contrastive learning 과 더불어 large language model (LLM) 들과 diffusion model 들을 사용하여 독창적인 image 생성도 가능함 + +- 텍스트 전용 말뭉치 (text corpus)로 학습된 LLM들의 text embedding들은 text-to-image 합성에 매우 효과적이라고 함. + +- Classifier-free guidance 사용하여, 더 높은 충실도 (fidelity)의 이미지를 생성하는 새로운 샘플링 기술을 사용함. + +:::{figure-md} +imagen_1 + +Concept of Contrastive Learning +::: + +# Contributions + +1. **Pretrained Frozen** text encoder (T5-XXL) 이 text-to-image generation task 에 매우 좋은 성능을 보여줌. +2. Pretrained Text Encoder 사이즈를 **fine-tuning**하는 것이 diffusion model size fine tuning 하는 것보다 더 중요하다는 것을 실험적으로 증명함 +3. **Dynamic Thresholding** 이라는 새로운 diffusion sampling technique (thresholding diffusion sampler) 을 제시하여 high guidance weight을 leverage 할 수 있게 만들어 더욱 “현실적인” 이미지 생성을 할 수 있음 +4. **Efficient U-Net**이라는 기존 Palette 나 DDIM에서 사용하는 U-Net 구조보다 computational, memory efficient 한 U-Net 구조를 제시함 +5. COCO FID 점수 **7.27** SOTA 점수를 달성함 +6. **DrawBench**라는 새로운 text-to-image generation evaluation용 benchmark dataset을 제시함 + +# Methodology + +## Pretrained T5-XXL + Cascaded Diffusion Model + +- Pretrained Text Encoder 중 T5-XXL (구글 모델) 사용 +- 학습 시 pretrained text encoder을 Freeze 해놓음 +- Text-to-Image Diffusion Model (Improved DDPM 아키텍쳐) 사용해 64x64 image 생성 +- 2가지 SR model (Efficient U-Net)을 사용해서 64 → 256 → 1024 로 upsampling + +:::{figure-md} +imagen_2 + +Imagen overall pipeline +::: + +## Classifier-Free Guidance +- Classifier-free guidance 이란 auxiliary classifier의 효과 없이 classifier guidance 효과를 얻는 방법 +- 아래의 그림처럼 guidance가 없을 시 image generation이 일정하지 않음. 즉, label/class 의 영향을 못받아서, 생성이 일정하지 않음. +- guidance를 줄 시, 생성된 이미지의 class나 object이 일정하고 무엇을 생성하는것인지 좀 더 자세하게 알 수 있음. + +:::{figure-md} +imagen_3 + +Comparison between when guidance is not used (left) vs when guidance is used with parameter, w=3 (right) +::: + +## Large guidance weight sampler +- Guide의 가중치 w 를 높이면 train-test 불일치가 생긴다. +- 이로 인해, 높은 가중치의 이미지는 훈련 데이터 범위 안에 없어 [-1,1], classifier-free guidance가 평균과 분산을 이동시켜 이미지가 아예 “빗나가” 이상한 이미지를 생성하게 된다 + +## Static Thresholding +- x-prediction 을 [-1,1]로 clipping 한다. 여전히 saturation 이 되고 fidelity가 덜한 이미지가 생성 됌 +- 문제를 해결하고자 dynamic thresholding 을 제시함 + +:::{figure-md} +imagen_5 + +Graphical visualization of static thresholding +::: + +## Dynamic Thresholding +- 특정 백분위수 절대 픽셀 값을 s 라고 지정하고 s > 1 이면, 임계값을 [-s,s]로 지정한 다음 s로 나눈다. +- 예시: 90% 지점의 픽셀 값이 3 이면 [-3,3]으로 clipping 한 후 3으로 나눠서 [-1,1] 로 normalize 함. +- Thresholding 의 차이는 아래 결과 비교 이미지로 확인 할 수 있다. + +:::{figure-md} +imagen_6 + +Graphical visualization of dynamic thresholding +::: + + +:::{figure-md} +imagen_7 + +Comparison among no thresholding, static thresholding and dynamic thresholding, respectively +::: + +## Super Resolution Models +- Efficient U-Net이라는 새로운 모델을 만들어, 기존 U-Net에서 여러가지 modification을 하였다고 주장 (그렇지만 EffU-Net은 의료쪽으로 이름이 이미 있는걸로 아는데…) +- Removed self-attention layer +- Keep the text cross-attention layer +- Skip connection scaling을 1/(√2)로 하여 convergence 를 더 빠르게 함 +- Lower resolution block에서 residual blocks를 더 추가함 + +:::{figure-md} +imagen_8 + +Architecture of Super Resolution Diffusion Model used in Imagen +::: + +## DrawBench +- Imagen 저자들이 제시한 새로운 벤치마크 데이터셋. 본 데이터셋은 text prompt 와 category label 로 이루어졌다 +- 깃허브에서 다운 받을 수 있으며, 예시는 아래 그림과 갗다 +11 categories, 200 text prompts +Human evaluation 으로 진행 (25명의 평가자) +Model A에서 생성한 이미지 set vs Model B에서 생성한 이미지 set + +평가자는 2가지 질문을 주며 2가지 기준점으로 평가함 +**Q1. Which set of images is of higher quality?** +**Q2. Which set of images better represents the text caption: {text caption}?** + + +기준점 +- Image Fidelity +- Image-text alignment + +평가자는 3가지 답변 중 하나를 선택해야함 +1. I prefer set A +2. I am Indifferent +3. I prefer set B + + +:::{figure-md} +imagen_9 + +Screenshot of DrawBench dataset +::: + +# Results +- Figure 2 에서는 DrawBench에서 나온 결과를 체리피킹 없이 보여준다. +- 아마 저자들은 체리피킹 없이도 좋은 결과를 보여주고, 다양한 카테고리에서도 훌륭한 이미지를 생성 할 수 있다는 주장인 것 같다. + +:::{figure-md} +imagen_10 + +Result of Imagen in DrawBench dataset +::: + +- Zero-shot 으로 한 FID값이 MS-COCO로 학습한 모델들 FID 보다 높음. + +- Table 2 에서는 Imagen이 no people (사람이 없는 사진) 에는 photorealism 점수가 올라감 +→ Imagen 은 photorealistic people을 생성하기에 한계가 있음. + +:::{figure-md} +imagen_11 + +Result Table of Imagen +::: + +### Qualitative Result Table of Imagen from Human Evaluators + +- Human raters (사람 평가자) 들은 T5-XXL로 text encoding 한 text-to-image generation 모델을 CLIP-based 보다 더 선호함 + +- 기본적으로 Imagen 은 다른 text-to-image generation 모델에서 (SOTA 모델인 DALL-E 2) 보다도 human raters 에서 DrawBench 데이터셋에서 좋은 평가를 받음 + +:::{figure-md} +imagen_12 + +Qualitative Result Table of Imagen from Human evaulators +::: + +# Ablation Study + +- Scaling text encoder size 가 U-Net size scaling 보다 더 중요함 +- (a)의 text encoder 사이즈의 변화가 FID 및 CLIP score 점수에 더욱 많은 영향을 끼침 + +- Dynamic thresholding 이 performance boost에 더욱 영향을 끼침 +- Dynamic thresholding을 이용하면 성능을 더욱 끌어 올릴 수 있음 + +:::{figure-md} +imagen_13 + +Qualitative Result Table of Imagen from Human evaulators +::: + +# Conclusion + +- Frozen large pretrained language model shows better performance over text-image paired multimodal encoders such as CLIP in text-to-image generation task +- Efficient U-Net significantly improves performance time +- Dynamic thresholding allows usage of much higher guidance weights with better fidelity of generated images + + + + diff --git a/_sources/docs/review/imagen_editor.md b/_sources/docs/review/imagen_editor.md old mode 100644 new mode 100755 index cfd93b82..dd46ad63 --- a/_sources/docs/review/imagen_editor.md +++ b/_sources/docs/review/imagen_editor.md @@ -1,72 +1,72 @@ -``` {admonition} Information -- **Title:** Imagen Editor and EditBench: Advancing and Evaluating Text-Guided Image Inpainting (CVPR 2023) - -- **Reference** - - Paper: [https://arxiv.org/pdf/2212.06909](https://arxiv.org/pdf/2212.06909) - -- **Author:** Sangwoo Jo - -- **Last updated on Sep. 06, 2023** -``` - -# Imagen Editor - -이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다. - -Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다. - -:::{figure-md} -imagen_editor_01 - -Effect of Object Masking -::: - -Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다. - -:::{figure-md} -imagen_editor_02 - -Imagen Editor Architecture -::: - -Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다. - -논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다. - -EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, *attribute-object-scene* 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다. - -- Attributes (material, color, shape, size, count) -- Objects (common, rare, text rendering) -- Scenes (indoor, outdoor, realistic, paintings) - -예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 *Mask-Simple*, *Mask-Rich*, 그리고 *Full* 로 정의합니다. - -:::{figure-md} -imagen_editor_03 - -EditBench example -::: - -데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다. - -:::{figure-md} -imagen_editor_04 - -Human Evaluations on EditBench -::: - -또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다. - -:::{figure-md} -imagen_editor_05 - -Imagen Editor failure cases by attribute -::: - -마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다. - -:::{figure-md} -imagen_editor_06 - -Example model outputs for Mask-Simple vs MaskRich prompts -::: +``` {admonition} Information +- **Title:** Imagen Editor and EditBench: Advancing and Evaluating Text-Guided Image Inpainting (CVPR 2023) + +- **Reference** + - Paper: [https://arxiv.org/pdf/2212.06909](https://arxiv.org/pdf/2212.06909) + +- **Author:** Sangwoo Jo + +- **Last updated on Sep. 06, 2023** +``` + +# Imagen Editor + +이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다. + +Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다. + +:::{figure-md} +imagen_editor_01 + +Effect of Object Masking +::: + +Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다. + +:::{figure-md} +imagen_editor_02 + +Imagen Editor Architecture +::: + +Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다. + +논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다. + +EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, *attribute-object-scene* 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다. + +- Attributes (material, color, shape, size, count) +- Objects (common, rare, text rendering) +- Scenes (indoor, outdoor, realistic, paintings) + +예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 *Mask-Simple*, *Mask-Rich*, 그리고 *Full* 로 정의합니다. + +:::{figure-md} +imagen_editor_03 + +EditBench example +::: + +데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다. + +:::{figure-md} +imagen_editor_04 + +Human Evaluations on EditBench +::: + +또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다. + +:::{figure-md} +imagen_editor_05 + +Imagen Editor failure cases by attribute +::: + +마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다. + +:::{figure-md} +imagen_editor_06 + +Example model outputs for Mask-Simple vs MaskRich prompts +::: diff --git a/_sources/docs/review/vae.md b/_sources/docs/review/vae.md old mode 100644 new mode 100755 index 346f80c8..b965a419 --- a/_sources/docs/review/vae.md +++ b/_sources/docs/review/vae.md @@ -1,137 +1,137 @@ -```{admonition} Information -- **Title:** Auto-Encoding Variational Bayes (ICLR 2014) - -- **Reference** - - Paper: [https://arxiv.org/abs/1312.6114](https://arxiv.org/abs/1312.6114) - - Code: [https://github.com/GunhoChoi/PyTorch-FastCampus](https://github.com/GunhoChoi/PyTorch-FastCampus) - - [Smart Design Lab @KAIST | 딥러닝 Ch.3.3 VAE](https://www.youtube.com/watch?v=GbCAwVVKaHY&t=95s) - -- **Author:** Sangwoo Jo - -- **Last updated on Apr. 12, 2023** -``` - -# VAE - - -## Introduction - -논문의 Introduction 에 다음과 같은 문구가 적혀있는데요. - -> "Variational Bayesian (VB) approach involves the optimization of an approximation to the intractable posterior” -> - -이처럼 Variational Autoencoder 는 논문에서 제시하는 Auto-Encoding Variational Bayes(AEVB) 알고리즘 중 하나로, intractable 한 posterior 분포를 다루기 쉬운 뉴럴 네트워크로 근사함으로써 Variational Inference 를 하게 됩니다. - -이가 의미하는 바가 무엇인지 한번 살펴보도록 하겠습니다. - -## Intractability - -Variational Autoencoder(VAE) 는 크게 Encoder 와 Decoder 부분으로 이루어져 있습니다. 더 자세하게는, Encoder는 입력 데이터 $x$ 를 받아서 잠재변수(Latent Variable) $z$ 를 만들어내고, Decoder 는 잠재변수 $z$ 를 활용해서 다시 $x$ 를 복원하게 됩니다. - -:::{figure-md} markdown-fig -vae_01 - -Variational Autoencoder(VAE) Architecture -::: - -Variational Autoencoder (VAE) 는 AutoEncoder 와 달리 확률 분포를 이용해 어떤 새로운 데이터를 생성하는 Decoder 부분에 초점을 둡니다. 이때 논문에서 다음과 같은 assumption 들을 내립니다. 첫번째로 $p_{\theta}(z)$ 와 $p_{\theta}(x|z)$ 는 parametric 한 distribution 을 가지고 있고, 이는 $\theta$ 와 $z$ 에 대해 differentiable 하다는 가정을 내립니다. 이 때, 대표적으로 $p_{\theta}(z)$ 는 Gaussian distribution 을 따르고 $p_{\theta}(x|z)$ 는 생성하고자 하는 데이터 성질에 따라 Bernoulli 혹은 Gaussian distribution 을 따르도록 정의합니다. 그리고 $p_{\theta}(x|z)$ 의 파라미터 $p$ 혹은 $(\mu, \sigma)$ 는 아래 그림과 같이 뉴럴 네트워크로 구성된 Decoder 로부터 계산이 됩니다. - -:::{figure-md} markdown-fig -vae_07 - -Overview of Bernoulli(left) and Gaussian(right) Decoder -::: - -이를 기반으로 우리는 ML/MAP estimation 을 통해 marginal likelihood $p_{\theta}(x)$ 를 최대화시키는 파라미터 $\theta$ 를 구하는 것이 목적입니다. 하지만, $p_{\theta}(x) = \int p_{\theta}(z)p_{\theta}(x|z) \ dz$ 는 intractable 하기 때문에 $p_{\theta}(z|x)$ 를 계산하기 위한 Encoder 가 등장하게 됩니다. - -$$ -p_{\theta}(x) = p_{\theta}(x|z)p_{\theta}(z)/p_{\theta}(z|x) -$$ - -여기서 $p_{\theta}(z|x)$ 역시 intractable 하기 때문에 이를 잘 근사화하는 뉴럴 네트워크 $q_{\phi}(z|x)$ 를 정의하게 되고, 이러한 과정을 변분추론(Variational Inference) 라고 합니다. 아래는 Encoder 와 Decoder 를 함께 도식화한 그림입니다. 정리하자면, MLP Encoder 를 통해 계산된 $\mu$ 와 $\sigma$ 로 잠재변수 $z$ 를 생성하게 되고, 이를 기반으로 Decoder 는 원본 이미지와 유사한 데이터를 생성하게 됩니다. - -:::{figure-md} markdown-fig -vae_08 - -Overview of Gaussian Encoder and Decoder -::: - -해당 implementation code 도 확인해보겠습니다. - -- **Encoder 구현 code** - - ```python - - class Encoder(nn.Module): - def __init__(self): - super(Encoder,self).__init__() - self.fc1_1 = nn.Linear(784, hidden_size) - self.fc1_2 = nn.Linear(784, hidden_size) - self.relu = nn.ReLU() - - def encode(self,x): - x = x.view(batch_size,-1) - mu = self.relu(self.fc1_1(x)) - log_var = self.relu(self.fc1_2(x)) - - return mu,log_var - - def reparametrize(self, mu, logvar): - std = logvar.mul(0.5).exp_() - - eps = torch.FloatTensor(std.size()).normal_() - eps = Variable(eps).cuda() - - return eps.mul(std).add_(mu) - - def forward(self,x): - mu, logvar = self.encode(x) - reparam = self.reparametrize(mu,logvar) - - return mu,logvar,reparam - ``` - -- **Decoder 구현 code** - - ```python - class Decoder(nn.Module): - def __init__(self): - super(Decoder,self).__init__() - self.fc1 = nn.Linear(hidden_size, 784) - self.sigmoid = nn.Sigmoid() - - def forward(self,x): - out = self.fc1(x) - out = self.sigmoid(out) - out = out.view(batch_size,28,28,1) - - return out - ``` - - -이로써 우리는 marginal likelihood $p_{\theta}(x)$ 를 최대화시키는 파라미터 $(\theta, \phi)$ 를 찾으면 되고, 수식적으로 표현하면 손실함수(loss function) 를 다음과 같이 Reconstruction Error 와 Regularization term 로 분할할 수 있습니다. - -$$ -L(\theta, \phi;x_i) = \arg \min_{\theta, \phi} \sum_{i} -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] + KL(q_{\phi}(z|x_i)||p(z)) -$$ - -Reconstruction Error 는 Decoder 에서 생성하는 데이터가 최대한 원본 데이터와 유사하도록 하는 term 이고, Regularization 은 Encoder 에서 만드는 잠재변수의 분포가 저희가 부여한 prior distribution 이랑 가깝도록 설정하는 term 입니다. 이때, Reconstruction Error 는 Monte Carlo 기법으로 근사값을 구할 수 있고, 하나의 sample 을 계산하는 것도 연산량이 많으므로 논문에서는 sample size $L$ 을 1 로 설정합니다. - -$$ -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] = \int log(p_{\theta}(x_i|z))q_{\phi}(z|x_i)dz \approx \frac{1}{L}\sum_{z^{i,l}} log(p_{\theta}(x_i|z^{i,l})) -$$ - -## Reparameterization Trick - -마지막으로 소개하는 기법은 reparameterization trick 입니다. 잠재변수 $z$ 를 Encoder 에서 나온 $\mu$ 와 $\sigma$ 로 직접 샘플링하지 않고, backpropagation 이 가능하도록 Gaussian noise 를 우선적으로 샘플링하고 해당 $\mu$ 와 $\sigma$ 를 각각 더하고 곱하게 됩니다. 이는 $q_{\phi}(z|x)$ 이 Gaussian distribution 을 따른다고 설정했을 때이고, $q_{\phi}(z|x)$ 에 대해 다른 분포를 가정할 때 그리고 그에 따른 다른 reparameterization trick 을 시도할 수 있다고 논문에 명시되어 있습니다. - -:::{figure-md} markdown-fig -vae_05 - -Overview of Reparameterization Trick -::: - -## Summary - -AutoEncoder 는 latent space 에 하나의 값으로 지정해줬다면, VAE 는 평균 그리고 분산 파라미터들과 Gaussian 분포를 가진 샘플을 통해 잠재변수를 생성합니다. 그리고 VAE 를 실제로 사용해보면 생성된 데이터 image quality 가 낮다는 단점을 가지고 있다고 합니다. +```{admonition} Information +- **Title:** Auto-Encoding Variational Bayes (ICLR 2014) + +- **Reference** + - Paper: [https://arxiv.org/abs/1312.6114](https://arxiv.org/abs/1312.6114) + - Code: [https://github.com/GunhoChoi/PyTorch-FastCampus](https://github.com/GunhoChoi/PyTorch-FastCampus) + - [Smart Design Lab @KAIST | 딥러닝 Ch.3.3 VAE](https://www.youtube.com/watch?v=GbCAwVVKaHY&t=95s) + +- **Author:** Sangwoo Jo + +- **Last updated on Apr. 12, 2023** +``` + +# VAE + + +## Introduction + +논문의 Introduction 에 다음과 같은 문구가 적혀있는데요. + +> "Variational Bayesian (VB) approach involves the optimization of an approximation to the intractable posterior” +> + +이처럼 Variational Autoencoder 는 논문에서 제시하는 Auto-Encoding Variational Bayes(AEVB) 알고리즘 중 하나로, intractable 한 posterior 분포를 다루기 쉬운 뉴럴 네트워크로 근사함으로써 Variational Inference 를 하게 됩니다. + +이가 의미하는 바가 무엇인지 한번 살펴보도록 하겠습니다. + +## Intractability + +Variational Autoencoder(VAE) 는 크게 Encoder 와 Decoder 부분으로 이루어져 있습니다. 더 자세하게는, Encoder는 입력 데이터 $x$ 를 받아서 잠재변수(Latent Variable) $z$ 를 만들어내고, Decoder 는 잠재변수 $z$ 를 활용해서 다시 $x$ 를 복원하게 됩니다. + +:::{figure-md} markdown-fig +vae_01 + +Variational Autoencoder(VAE) Architecture +::: + +Variational Autoencoder (VAE) 는 AutoEncoder 와 달리 확률 분포를 이용해 어떤 새로운 데이터를 생성하는 Decoder 부분에 초점을 둡니다. 이때 논문에서 다음과 같은 assumption 들을 내립니다. 첫번째로 $p_{\theta}(z)$ 와 $p_{\theta}(x|z)$ 는 parametric 한 distribution 을 가지고 있고, 이는 $\theta$ 와 $z$ 에 대해 differentiable 하다는 가정을 내립니다. 이 때, 대표적으로 $p_{\theta}(z)$ 는 Gaussian distribution 을 따르고 $p_{\theta}(x|z)$ 는 생성하고자 하는 데이터 성질에 따라 Bernoulli 혹은 Gaussian distribution 을 따르도록 정의합니다. 그리고 $p_{\theta}(x|z)$ 의 파라미터 $p$ 혹은 $(\mu, \sigma)$ 는 아래 그림과 같이 뉴럴 네트워크로 구성된 Decoder 로부터 계산이 됩니다. + +:::{figure-md} markdown-fig +vae_07 + +Overview of Bernoulli(left) and Gaussian(right) Decoder +::: + +이를 기반으로 우리는 ML/MAP estimation 을 통해 marginal likelihood $p_{\theta}(x)$ 를 최대화시키는 파라미터 $\theta$ 를 구하는 것이 목적입니다. 하지만, $p_{\theta}(x) = \int p_{\theta}(z)p_{\theta}(x|z) \ dz$ 는 intractable 하기 때문에 $p_{\theta}(z|x)$ 를 계산하기 위한 Encoder 가 등장하게 됩니다. + +$$ +p_{\theta}(x) = p_{\theta}(x|z)p_{\theta}(z)/p_{\theta}(z|x) +$$ + +여기서 $p_{\theta}(z|x)$ 역시 intractable 하기 때문에 이를 잘 근사화하는 뉴럴 네트워크 $q_{\phi}(z|x)$ 를 정의하게 되고, 이러한 과정을 변분추론(Variational Inference) 라고 합니다. 아래는 Encoder 와 Decoder 를 함께 도식화한 그림입니다. 정리하자면, MLP Encoder 를 통해 계산된 $\mu$ 와 $\sigma$ 로 잠재변수 $z$ 를 생성하게 되고, 이를 기반으로 Decoder 는 원본 이미지와 유사한 데이터를 생성하게 됩니다. + +:::{figure-md} markdown-fig +vae_08 + +Overview of Gaussian Encoder and Decoder +::: + +해당 implementation code 도 확인해보겠습니다. + +- **Encoder 구현 code** + + ```python + + class Encoder(nn.Module): + def __init__(self): + super(Encoder,self).__init__() + self.fc1_1 = nn.Linear(784, hidden_size) + self.fc1_2 = nn.Linear(784, hidden_size) + self.relu = nn.ReLU() + + def encode(self,x): + x = x.view(batch_size,-1) + mu = self.relu(self.fc1_1(x)) + log_var = self.relu(self.fc1_2(x)) + + return mu,log_var + + def reparametrize(self, mu, logvar): + std = logvar.mul(0.5).exp_() + + eps = torch.FloatTensor(std.size()).normal_() + eps = Variable(eps).cuda() + + return eps.mul(std).add_(mu) + + def forward(self,x): + mu, logvar = self.encode(x) + reparam = self.reparametrize(mu,logvar) + + return mu,logvar,reparam + ``` + +- **Decoder 구현 code** + + ```python + class Decoder(nn.Module): + def __init__(self): + super(Decoder,self).__init__() + self.fc1 = nn.Linear(hidden_size, 784) + self.sigmoid = nn.Sigmoid() + + def forward(self,x): + out = self.fc1(x) + out = self.sigmoid(out) + out = out.view(batch_size,28,28,1) + + return out + ``` + + +이로써 우리는 marginal likelihood $p_{\theta}(x)$ 를 최대화시키는 파라미터 $(\theta, \phi)$ 를 찾으면 되고, 수식적으로 표현하면 손실함수(loss function) 를 다음과 같이 Reconstruction Error 와 Regularization term 로 분할할 수 있습니다. + +$$ +L(\theta, \phi;x_i) = \arg \min_{\theta, \phi} \sum_{i} -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] + KL(q_{\phi}(z|x_i)||p(z)) +$$ + +Reconstruction Error 는 Decoder 에서 생성하는 데이터가 최대한 원본 데이터와 유사하도록 하는 term 이고, Regularization 은 Encoder 에서 만드는 잠재변수의 분포가 저희가 부여한 prior distribution 이랑 가깝도록 설정하는 term 입니다. 이때, Reconstruction Error 는 Monte Carlo 기법으로 근사값을 구할 수 있고, 하나의 sample 을 계산하는 것도 연산량이 많으므로 논문에서는 sample size $L$ 을 1 로 설정합니다. + +$$ +\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] = \int log(p_{\theta}(x_i|z))q_{\phi}(z|x_i)dz \approx \frac{1}{L}\sum_{z^{i,l}} log(p_{\theta}(x_i|z^{i,l})) +$$ + +## Reparameterization Trick + +마지막으로 소개하는 기법은 reparameterization trick 입니다. 잠재변수 $z$ 를 Encoder 에서 나온 $\mu$ 와 $\sigma$ 로 직접 샘플링하지 않고, backpropagation 이 가능하도록 Gaussian noise 를 우선적으로 샘플링하고 해당 $\mu$ 와 $\sigma$ 를 각각 더하고 곱하게 됩니다. 이는 $q_{\phi}(z|x)$ 이 Gaussian distribution 을 따른다고 설정했을 때이고, $q_{\phi}(z|x)$ 에 대해 다른 분포를 가정할 때 그리고 그에 따른 다른 reparameterization trick 을 시도할 수 있다고 논문에 명시되어 있습니다. + +:::{figure-md} markdown-fig +vae_05 + +Overview of Reparameterization Trick +::: + +## Summary + +AutoEncoder 는 latent space 에 하나의 값으로 지정해줬다면, VAE 는 평균 그리고 분산 파라미터들과 Gaussian 분포를 가진 샘플을 통해 잠재변수를 생성합니다. 그리고 VAE 를 실제로 사용해보면 생성된 데이터 image quality 가 낮다는 단점을 가지고 있다고 합니다. diff --git a/_sources/intro.md b/_sources/intro.md old mode 100644 new mode 100755 index d8334fba..29f7c9d6 --- a/_sources/intro.md +++ b/_sources/intro.md @@ -1,11 +1,11 @@ -# [PseudoLab] Text-to-Image Generation (feat. Diffusion) - -This is the repository of Pseudo Lab's Text-to-Image Generation (feat. Diffusion) team. - -:bulb: Our aim is to review papers and code related to image generation and text-to-image generation models, approach them theoretically, and conduct various experiments by fine-tuning diffusion based models. - -[About Us - Pseudo Lab](https://www.linkedin.com/company/pseudolab/) - -[About Us - Text-to-Image Generation (feat. Diffusion) Team](https://pseudo-lab.com/Text-to-Image-Generation-feat-Diffusion-cc12047d1bfc4bdfa70122c11ff90aee) - -참여 방법: 매주 수요일 오후 9시, 가짜연구소 Discord Room-DH 로 입장! +# [PseudoLab] Text-to-Image Generation (feat. Diffusion) + +This is the repository of Pseudo Lab's Text-to-Image Generation (feat. Diffusion) team. + +:bulb: Our aim is to review papers and code related to image generation and text-to-image generation models, approach them theoretically, and conduct various experiments by fine-tuning diffusion based models. + +[About Us - Pseudo Lab](https://www.linkedin.com/company/pseudolab/) + +[About Us - Text-to-Image Generation (feat. Diffusion) Team](https://pseudo-lab.com/Text-to-Image-Generation-feat-Diffusion-cc12047d1bfc4bdfa70122c11ff90aee) + +참여 방법: 매주 수요일 오후 9시, 가짜연구소 Discord Room-DH 로 입장! diff --git a/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css old mode 100644 new mode 100755 index 3225661c..57bec30a --- a/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css +++ b/_sphinx_design_static/design-style.4045f2051d55cab465a707391d5b2007.min.css @@ -1 +1 @@ -.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js old mode 100644 new mode 100755 index 36b38cf0..a869cf55 --- a/_sphinx_design_static/design-tabs.js +++ b/_sphinx_design_static/design-tabs.js @@ -1,27 +1,27 @@ -var sd_labels_by_text = {}; - -function ready() { - const li = document.getElementsByClassName("sd-tab-label"); - for (const label of li) { - syncId = label.getAttribute("data-sync-id"); - if (syncId) { - label.onclick = onLabelClick; - if (!sd_labels_by_text[syncId]) { - sd_labels_by_text[syncId] = []; - } - sd_labels_by_text[syncId].push(label); - } - } -} - -function onLabelClick() { - // Activate other inputs with the same sync id. - syncId = this.getAttribute("data-sync-id"); - for (label of sd_labels_by_text[syncId]) { - if (label === this) continue; - label.previousElementSibling.checked = true; - } - window.localStorage.setItem("sphinx-design-last-tab", syncId); -} - -document.addEventListener("DOMContentLoaded", ready, false); +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/PseudoLab_logo.png b/_static/PseudoLab_logo.png old mode 100644 new mode 100755 diff --git a/_static/__init__.py b/_static/__init__.py old mode 100644 new mode 100755 diff --git a/_static/__pycache__/__init__.cpython-37.pyc b/_static/__pycache__/__init__.cpython-37.pyc old mode 100644 new mode 100755 diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js old mode 100644 new mode 100755 diff --git a/_static/basic.css b/_static/basic.css old mode 100644 new mode 100755 index 9e364ed3..d613287e --- a/_static/basic.css +++ b/_static/basic.css @@ -1,930 +1,930 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -div.section::after { - display: block; - content: ''; - clear: left; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 270px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox form.search { - overflow: hidden; -} - -div.sphinxsidebar #searchbox input[type="text"] { - float: left; - width: 80%; - padding: 0.25em; - box-sizing: border-box; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - float: left; - width: 20%; - border-left: none; - padding: 0.25em; - box-sizing: border-box; -} - - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li p.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; - margin-left: auto; - margin-right: auto; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable ul { - margin-top: 0; - margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body { - min-width: 360px; - max-width: 800px; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, figure.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, figure.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, figure.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -img.align-default, figure.align-default, .figure.align-default { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-default { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar, -aside.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px; - background-color: #ffe; - width: 40%; - float: right; - clear: right; - overflow-x: auto; -} - -p.sidebar-title { - font-weight: bold; -} -nav.contents, -aside.topic, - -div.admonition, div.topic, blockquote { - clear: left; -} - -/* -- topics ---------------------------------------------------------------- */ -nav.contents, -aside.topic, - -div.topic { - border: 1px solid #ccc; - padding: 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- content of sidebars/topics/admonitions -------------------------------- */ - -div.sidebar > :last-child, -aside.sidebar > :last-child, -nav.contents > :last-child, -aside.topic > :last-child, - -div.topic > :last-child, -div.admonition > :last-child { - margin-bottom: 0; -} - -div.sidebar::after, -aside.sidebar::after, -nav.contents::after, -aside.topic::after, - -div.topic::after, -div.admonition::after, -blockquote::after { - display: block; - content: ''; - clear: both; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - margin-top: 10px; - margin-bottom: 10px; - border: 0; - border-collapse: collapse; -} - -table.align-center { - margin-left: auto; - margin-right: auto; -} - -table.align-default { - margin-left: auto; - margin-right: auto; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -th > :first-child, -td > :first-child { - margin-top: 0px; -} - -th > :last-child, -td > :last-child { - margin-bottom: 0px; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure, figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption, figcaption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number, -figcaption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text, -figcaption span.caption-text { -} - -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -/* -- hlist styles ---------------------------------------------------------- */ - -table.hlist { - margin: 1em 0; -} - -table.hlist td { - vertical-align: top; -} - -/* -- object description styles --------------------------------------------- */ - -.sig { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; -} - -.sig-name, code.descname { - background-color: transparent; - font-weight: bold; -} - -.sig-name { - font-size: 1.1em; -} - -code.descname { - font-size: 1.2em; -} - -.sig-prename, code.descclassname { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.sig-param.n { - font-style: italic; -} - -/* C++ specific styling */ - -.sig-inline.c-texpr, -.sig-inline.cpp-texpr { - font-family: unset; -} - -.sig.c .k, .sig.c .kt, -.sig.cpp .k, .sig.cpp .kt { - color: #0033B3; -} - -.sig.c .m, -.sig.cpp .m { - color: #1750EB; -} - -.sig.c .s, .sig.c .sc, -.sig.cpp .s, .sig.cpp .sc { - color: #067D17; -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -:not(li) > ol > li:first-child > :first-child, -:not(li) > ul > li:first-child > :first-child { - margin-top: 0px; -} - -:not(li) > ol > li:last-child > :last-child, -:not(li) > ul > li:last-child > :last-child { - margin-bottom: 0px; -} - -ol.simple ol p, -ol.simple ul p, -ul.simple ol p, -ul.simple ul p { - margin-top: 0; -} - -ol.simple > li:not(:first-child) > p, -ul.simple > li:not(:first-child) > p { - margin-top: 0; -} - -ol.simple p, -ul.simple p { - margin-bottom: 0; -} - -/* Docutils 0.17 and older (footnotes & citations) */ -dl.footnote > dt, -dl.citation > dt { - float: left; - margin-right: 0.5em; -} - -dl.footnote > dd, -dl.citation > dd { - margin-bottom: 0em; -} - -dl.footnote > dd:after, -dl.citation > dd:after { - content: ""; - clear: both; -} - -/* Docutils 0.18+ (footnotes & citations) */ -aside.footnote > span, -div.citation > span { - float: left; -} -aside.footnote > span:last-of-type, -div.citation > span:last-of-type { - padding-right: 0.5em; -} -aside.footnote > p { - margin-left: 2em; -} -div.citation > p { - margin-left: 4em; -} -aside.footnote > p:last-of-type, -div.citation > p:last-of-type { - margin-bottom: 0em; -} -aside.footnote > p:last-of-type:after, -div.citation > p:last-of-type:after { - content: ""; - clear: both; -} - -/* Footnotes & citations ends */ - -dl.field-list { - display: grid; - grid-template-columns: fit-content(30%) auto; -} - -dl.field-list > dt { - font-weight: bold; - word-break: break-word; - padding-left: 0.5em; - padding-right: 5px; -} - -dl.field-list > dt:after { - content: ":"; -} - -dl.field-list > dd { - padding-left: 0.5em; - margin-top: 0em; - margin-left: 0em; - margin-bottom: 0em; -} - -dl { - margin-bottom: 15px; -} - -dd > :first-child { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dl > dd:last-child, -dl > dd:last-child > :last-child { - margin-bottom: 0; -} - -dt:target, span.highlighted { - background-color: #fbe54e; -} - -rect.highlighted { - fill: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -.classifier:before { - font-style: normal; - margin: 0 0.5em; - content: ":"; - display: inline-block; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -pre, div[class*="highlight-"] { - clear: both; -} - -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; - white-space: nowrap; -} - -div[class*="highlight-"] { - margin: 1em 0; -} - -td.linenos pre { - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - display: block; -} - -table.highlighttable tbody { - display: block; -} - -table.highlighttable tr { - display: flex; -} - -table.highlighttable td { - margin: 0; - padding: 0; -} - -table.highlighttable td.linenos { - padding-right: 0.5em; -} - -table.highlighttable td.code { - flex: 1; - overflow: hidden; -} - -.highlight .hll { - display: block; -} - -div.highlight pre, -table.highlighttable pre { - margin: 0; -} - -div.code-block-caption + div { - margin-top: 0; -} - -div.code-block-caption { - margin-top: 1em; - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -table.highlighttable td.linenos, -span.linenos, -div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; - -webkit-user-select: text; /* Safari fallback only */ - -webkit-user-select: none; /* Chrome/Safari */ - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* IE10+ */ -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - margin: 1em 0; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -span.eqno a.headerlink { - position: absolute; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 270px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +nav.contents, +aside.topic, + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, + +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, + +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +/* Docutils 0.17 and older (footnotes & citations) */ +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +/* Docutils 0.18+ (footnotes & citations) */ +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +/* Footnotes & citations ends */ + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } } \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg old mode 100644 new mode 100755 diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js old mode 100644 new mode 100755 diff --git a/_static/copy-button.svg b/_static/copy-button.svg old mode 100644 new mode 100755 diff --git a/_static/copybutton.css b/_static/copybutton.css old mode 100644 new mode 100755 diff --git a/_static/copybutton.js b/_static/copybutton.js old mode 100644 new mode 100755 index 2ea7ff3e..f4ec4edc --- a/_static/copybutton.js +++ b/_static/copybutton.js @@ -1,248 +1,248 @@ -// Localization support -const messages = { - 'en': { - 'copy': 'Copy', - 'copy_to_clipboard': 'Copy to clipboard', - 'copy_success': 'Copied!', - 'copy_failure': 'Failed to copy', - }, - 'es' : { - 'copy': 'Copiar', - 'copy_to_clipboard': 'Copiar al portapapeles', - 'copy_success': '¡Copiado!', - 'copy_failure': 'Error al copiar', - }, - 'de' : { - 'copy': 'Kopieren', - 'copy_to_clipboard': 'In die Zwischenablage kopieren', - 'copy_success': 'Kopiert!', - 'copy_failure': 'Fehler beim Kopieren', - }, - 'fr' : { - 'copy': 'Copier', - 'copy_to_clipboard': 'Copier dans le presse-papier', - 'copy_success': 'Copié !', - 'copy_failure': 'Échec de la copie', - }, - 'ru': { - 'copy': 'Скопировать', - 'copy_to_clipboard': 'Скопировать в буфер', - 'copy_success': 'Скопировано!', - 'copy_failure': 'Не удалось скопировать', - }, - 'zh-CN': { - 'copy': '复制', - 'copy_to_clipboard': '复制到剪贴板', - 'copy_success': '复制成功!', - 'copy_failure': '复制失败', - }, - 'it' : { - 'copy': 'Copiare', - 'copy_to_clipboard': 'Copiato negli appunti', - 'copy_success': 'Copiato!', - 'copy_failure': 'Errore durante la copia', - } -} - -let locale = 'en' -if( document.documentElement.lang !== undefined - && messages[document.documentElement.lang] !== undefined ) { - locale = document.documentElement.lang -} - -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -/** - * SVG files for our copy buttons - */ -let iconCheck = ` - ${messages[locale]['copy_success']} - - -` - -// If the user specified their own SVG use that, otherwise use the default -let iconCopy = ``; -if (!iconCopy) { - iconCopy = ` - ${messages[locale]['copy_to_clipboard']} - - - -` -} - -/** - * Set up copy/paste for code blocks - */ - -const runWhenDOMLoaded = cb => { - if (document.readyState != 'loading') { - cb() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', cb) - } else { - document.attachEvent('onreadystatechange', function() { - if (document.readyState == 'complete') cb() - }) - } -} - -const codeCellId = index => `codecell${index}` - -// Clears selected text since ClipboardJS will select the text when copying -const clearSelection = () => { - if (window.getSelection) { - window.getSelection().removeAllRanges() - } else if (document.selection) { - document.selection.empty() - } -} - -// Changes tooltip text for a moment, then changes it back -// We want the timeout of our `success` class to be a bit shorter than the -// tooltip and icon change, so that we can hide the icon before changing back. -var timeoutIcon = 2000; -var timeoutSuccessClass = 1500; - -const temporarilyChangeTooltip = (el, oldText, newText) => { - el.setAttribute('data-tooltip', newText) - el.classList.add('success') - // Remove success a little bit sooner than we change the tooltip - // So that we can use CSS to hide the copybutton first - setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) - setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) -} - -// Changes the copy button icon for two seconds, then changes it back -const temporarilyChangeIcon = (el) => { - el.innerHTML = iconCheck; - setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) -} - -const addCopyButtonToCodeCells = () => { - // If ClipboardJS hasn't loaded, wait a bit and try again. This - // happens because we load ClipboardJS asynchronously. - if (window.ClipboardJS === undefined) { - setTimeout(addCopyButtonToCodeCells, 250) - return - } - - // Add copybuttons to all of our code cells - const COPYBUTTON_SELECTOR = 'div.highlight pre'; - const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) - codeCells.forEach((codeCell, index) => { - const id = codeCellId(index) - codeCell.setAttribute('id', id) - - const clipboardButton = id => - `` - codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) - }) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -/** - * Removes excluded text from a Node. - * - * @param {Node} target Node to filter. - * @param {string} exclude CSS selector of nodes to exclude. - * @returns {DOMString} Text from `target` with text removed. - */ -function filterText(target, exclude) { - const clone = target.cloneNode(true); // clone as to not modify the live DOM - if (exclude) { - // remove excluded nodes - clone.querySelectorAll(exclude).forEach(node => node.remove()); - } - return clone.innerText; -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} - - -var copyTargetText = (trigger) => { - var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - - // get filtered text - let exclude = '.linenos'; - - let text = filterText(target, exclude); - return formatCopyText(text, '', false, true, true, true, '', '') -} - - // Initialize with a callback so we can modify the text before copy - const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) - - // Update UI with error/success messages - clipboard.on('success', event => { - clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) - temporarilyChangeIcon(event.trigger) - }) - - clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) - }) -} - +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js old mode 100644 new mode 100755 diff --git a/_static/css/index.73d71520a4ca3b99cfee5594769eaaae.css b/_static/css/index.73d71520a4ca3b99cfee5594769eaaae.css old mode 100644 new mode 100755 index 948a8bf1..dfa47cdc --- a/_static/css/index.73d71520a4ca3b99cfee5594769eaaae.css +++ b/_static/css/index.73d71520a4ca3b99cfee5594769eaaae.css @@ -1,6 +1,6 @@ -/*! - * Bootstrap v4.5.0 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors - * Copyright 2011-2020 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) +/*! + * Bootstrap v4.5.0 (https://getbootstrap.com/) + * Copyright 2011-2020 The Bootstrap Authors + * Copyright 2011-2020 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;line-height:1.5;color:#212529;text-align:left}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;background-color:transparent}a:hover{color:#0056b3}a:not([href]),a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{margin-top:1rem;margin-bottom:1rem;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer:before{content:"\2014\00A0"}.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1400px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1400px}}.row{display:flex;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.33333%;max-width:8.33333%}.col-2{flex:0 0 16.66667%;max-width:16.66667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.33333%;max-width:33.33333%}.col-5{flex:0 0 41.66667%;max-width:41.66667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.33333%;max-width:58.33333%}.col-8{flex:0 0 66.66667%;max-width:66.66667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.33333%;max-width:83.33333%}.col-11{flex:0 0 91.66667%;max-width:91.66667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.33333%}.offset-2{margin-left:16.66667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333%}.offset-5{margin-left:41.66667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333%}.offset-8{margin-left:66.66667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333%}.offset-11{margin-left:91.66667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333%}.offset-sm-2{margin-left:16.66667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333%}.offset-sm-5{margin-left:41.66667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333%}.offset-sm-8{margin-left:66.66667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333%}.offset-sm-11{margin-left:91.66667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333%}.offset-md-2{margin-left:16.66667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333%}.offset-md-5{margin-left:41.66667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333%}.offset-md-8{margin-left:66.66667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333%}.offset-md-11{margin-left:91.66667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333%}.offset-lg-2{margin-left:16.66667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333%}.offset-lg-5{margin-left:41.66667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333%}.offset-lg-8{margin-left:66.66667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333%}.offset-lg-11{margin-left:91.66667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;min-width:0;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.33333%;max-width:33.33333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333%}.offset-xl-2{margin-left:16.66667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333%}.offset-xl-5{margin-left:41.66667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333%}.offset-xl-8{margin-left:66.66667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333%}.offset-xl-11{margin-left:91.66667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{display:flex;align-items:center;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label:after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label:before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label:before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label:before{pointer-events:none;background-color:#fff;border:1px solid #adb5bd}.custom-control-label:after,.custom-control-label:before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:""}.custom-control-label:after{background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label:after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{position:relative;width:100%;height:calc(1.5em + .75rem + 2px)}.custom-file-input{z-index:2;margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{left:0;z-index:1;height:calc(1.5em + .75rem + 2px);font-weight:400;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label,.custom-file-label:after{position:absolute;top:0;right:0;padding:.375rem .75rem;line-height:1.5;color:#495057}.custom-file-label:after{bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;appearance:none}.custom-range:focus{outline:none}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem 1rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat 50%;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0,0,0,0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.5);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255,255,255,0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{column-count:3;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb,.breadcrumb-item{display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{height:1rem;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow:before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{top:0;left:0;z-index:1060;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover,.popover .arrow{position:absolute;display:block}.popover .arrow{width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow:after,.popover .arrow:before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{top:0;border-width:0 .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{top:1px;border-width:0 .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner:after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid;border-right:.25em solid transparent;border-radius:50%;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.85714%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{user-select:all!important}.user-select-auto{user-select:auto!important}.user-select-none{user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports (position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}html{font-size:15px}body{background-color:#fff;font-family:Lato,sans-serif;font-weight:400;line-height:1.65;color:#333;padding-top:75px}p{margin-bottom:1.15rem;font-size:1em}p.rubric{border-bottom:1px solid #c9c9c9}a{color:#005b81;text-decoration:none}a:hover{color:#e32e00;text-decoration:underline}a.headerlink{color:#c60f0f;font-size:.8em;padding:0 4px;text-decoration:none}a.headerlink:hover{background-color:#c60f0f;color:#fff}.header-style,h1,h2,h3,h4,h5,h6{margin:2.75rem 0 1.05rem;font-family:Open Sans,sans-serif;font-weight:400;line-height:1.15}.header-style:before,h1:before,h2:before,h3:before,h4:before,h5:before,h6:before{display:block;content:"";height:80px;margin:-80px 0 0}h1{margin-top:0;font-size:2.488em}h1,h2{color:#130654}h2{font-size:2.074em}h3{font-size:1.728em}h4{font-size:1.44em}h5{font-size:1.2em}h6{font-size:1em}.text_small,small{font-size:.833em}hr{border:0;border-top:1px solid #e5e5e5}pre{padding:10px;background-color:#fafafa;color:#222;line-height:1.2em;border:1px solid #c9c9c9;margin:1.5em 0;box-shadow:1px 1px 1px #d8d8d8}.navbar{position:fixed}.navbar-brand{position:relative;height:45px;width:auto}.navbar-brand img{max-width:100%;height:100%;width:auto}.navbar-light{background:#fff!important;box-shadow:0 .125rem .25rem 0 rgba(0,0,0,.11)}.navbar-nav li a{padding:0 15px}.navbar-nav>.active>.nav-link{font-weight:600;color:#130654!important}.navbar-header a{padding:0 15px}.admonition{margin:1.5625em auto;padding:0 .6rem .8rem!important;overflow:hidden;page-break-inside:avoid;border-left:.2rem solid #007bff;border-radius:.1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .05rem rgba(0,0,0,.1);transition:color .25s,background-color .25s,border-color .25s}.admonition :last-child{margin-bottom:0}.admonition p.admonition-title~*{padding:0 1.4rem}.admonition>ol,.admonition>ul{margin-left:1em}.admonition .admonition-title{position:relative;margin:0 -.6rem!important;padding:.4rem .6rem .4rem 2rem;font-weight:700;background-color:rgba(68,138,255,.1)}.admonition .admonition-title:before{position:absolute;left:.6rem;width:1rem;height:1rem;color:#007bff;font-family:Font Awesome\ 5 Free;font-weight:900;content:""}.admonition .admonition-title+*{margin-top:.4em}.admonition.attention{border-color:#fd7e14}.admonition.attention .admonition-title{background-color:#ffedcc}.admonition.attention .admonition-title:before{color:#fd7e14;content:""}.admonition.caution{border-color:#fd7e14}.admonition.caution .admonition-title{background-color:#ffedcc}.admonition.caution .admonition-title:before{color:#fd7e14;content:""}.admonition.warning{border-color:#dc3545}.admonition.warning .admonition-title{background-color:#fdf3f2}.admonition.warning .admonition-title:before{color:#dc3545;content:""}.admonition.danger{border-color:#dc3545}.admonition.danger .admonition-title{background-color:#fdf3f2}.admonition.danger .admonition-title:before{color:#dc3545;content:""}.admonition.error{border-color:#dc3545}.admonition.error .admonition-title{background-color:#fdf3f2}.admonition.error .admonition-title:before{color:#dc3545;content:""}.admonition.hint{border-color:#ffc107}.admonition.hint .admonition-title{background-color:#fff6dd}.admonition.hint .admonition-title:before{color:#ffc107;content:""}.admonition.tip{border-color:#ffc107}.admonition.tip .admonition-title{background-color:#fff6dd}.admonition.tip .admonition-title:before{color:#ffc107;content:""}.admonition.important{border-color:#007bff}.admonition.important .admonition-title{background-color:#e7f2fa}.admonition.important .admonition-title:before{color:#007bff;content:""}.admonition.note{border-color:#007bff}.admonition.note .admonition-title{background-color:#e7f2fa}.admonition.note .admonition-title:before{color:#007bff;content:""}div.deprecated{margin-bottom:10px;margin-top:10px;padding:7px;color:#b94a48;background-color:#f3e5e5;border:1px solid #eed3d7;border-radius:.5rem}div.deprecated p{display:inline}.topic{background-color:#eee}.seealso dd{margin-top:0;margin-bottom:0}.viewcode-back{font-family:Lato,sans-serif}.viewcode-block:target{background-color:#f4debf;border-top:1px solid #ac9;border-bottom:1px solid #ac9}table.field-list{border-collapse:separate;border-spacing:10px;margin-left:1px}table.field-list th.field-name{padding:1px 8px 1px 5px;white-space:nowrap;background-color:#eee}table.field-list td.field-body p{font-style:italic}table.field-list td.field-body p>strong{font-style:normal}table.field-list td.field-body blockquote{border-left:none;margin:0 0 .3em;padding-left:30px}.table.autosummary td:first-child{white-space:nowrap}.footer{width:100%;border-top:1px solid #ccc;padding-top:10px}.bd-search{position:relative;padding:1rem 15px;margin-right:-15px;margin-left:-15px}.bd-search .icon{position:absolute;color:#a4a6a7;left:25px;top:25px}.bd-search input{border-radius:0;border:0;border-bottom:1px solid #e5e5e5;padding-left:35px}.bd-toc{-ms-flex-order:2;order:2;height:calc(100vh - 2rem);overflow-y:auto}@supports (position:-webkit-sticky) or (position:sticky){.bd-toc{position:-webkit-sticky;position:sticky;top:5rem;height:calc(100vh - 5rem);overflow-y:auto}}.bd-toc .onthispage{color:#a4a6a7}.section-nav{padding-left:0;border-left:1px solid #eee;border-bottom:none}.section-nav ul{padding-left:1rem}.toc-entry,.toc-entry a{display:block}.toc-entry a{padding:.125rem 1.5rem;color:#77757a}@media (min-width:1200px){.toc-entry a{padding-right:0}}.toc-entry a:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-sidebar{padding-top:1em}@media (min-width:768px){.bd-sidebar{border-right:1px solid rgba(0,0,0,.1)}@supports (position:-webkit-sticky) or (position:sticky){.bd-sidebar{position:-webkit-sticky;position:sticky;top:76px;z-index:1000;height:calc(100vh - 4rem)}}}.bd-links{padding-top:1rem;padding-bottom:1rem;margin-right:-15px;margin-left:-15px}@media (min-width:768px){@supports (position:-webkit-sticky) or (position:sticky){.bd-links{max-height:calc(100vh - 9rem);overflow-y:auto}}}@media (min-width:768px){.bd-links{display:block!important}}.bd-sidenav{display:none}.bd-content{padding-top:20px}.bd-content .section{max-width:100%}.bd-content .section table{display:block;overflow:auto}.bd-toc-link{display:block;padding:.25rem 1.5rem;font-weight:600;color:rgba(0,0,0,.65)}.bd-toc-link:hover{color:rgba(0,0,0,.85);text-decoration:none}.bd-toc-item.active{margin-bottom:1rem}.bd-toc-item.active:not(:first-child){margin-top:1rem}.bd-toc-item.active>.bd-toc-link{color:rgba(0,0,0,.85)}.bd-toc-item.active>.bd-toc-link:hover{background-color:transparent}.bd-toc-item.active>.bd-sidenav{display:block}.bd-sidebar .nav>li>a{display:block;padding:.25rem 1.5rem;font-size:.9em;color:rgba(0,0,0,.65)}.bd-sidebar .nav>li>a:hover{color:#130654;text-decoration:none;background-color:transparent}.bd-sidebar .nav>.active:hover>a,.bd-sidebar .nav>.active>a{font-weight:600;color:#130654}.bd-sidebar .nav>li>ul{list-style:none;padding:.25rem 1.5rem}.bd-sidebar .nav>li>ul>li>a{display:block;padding:.25rem 1.5rem;font-size:.9em;color:rgba(0,0,0,.65)}.bd-sidebar .nav>li>ul>.active:hover>a,.bd-sidebar .nav>li>ul>.active>a{font-weight:600;color:#130654}.toc-h2{font-size:.85rem}.toc-h3{font-size:.75rem}.toc-h4{font-size:.65rem}.toc-entry>.nav-link.active{font-weight:600;color:#130654;background-color:transparent;border-left:2px solid #563d7c}.nav-link:hover{border-style:none}#navbar-main-elements li.nav-item i{font-size:.7rem;padding-left:2px;vertical-align:middle}.bd-toc .nav .nav{display:none}.bd-toc .nav .nav.visible,.bd-toc .nav>.active>ul{display:block}.prev-next-bottom{margin:20px 0}.prev-next-bottom a.left-prev,.prev-next-bottom a.right-next{padding:10px;border:1px solid rgba(0,0,0,.2);max-width:45%;overflow-x:hidden;color:rgba(0,0,0,.65)}.prev-next-bottom a.left-prev{float:left}.prev-next-bottom a.left-prev:before{content:"<< "}.prev-next-bottom a.right-next{float:right}.prev-next-bottom a.right-next:after{content:" >>"}.alert{padding-bottom:0}.alert-info a{color:#e83e8c}i.fab{vertical-align:middle;font-style:normal;font-size:1.5rem;line-height:1.25}i.fa-github-square:before{color:#333}i.fa-twitter-square:before{color:#55acee}.tocsection{border-left:1px solid #eee;padding:.3rem 1.5rem}.tocsection i{padding-right:.5rem}.editthispage{padding-top:2rem}.editthispage a{color:#130754} \ No newline at end of file diff --git a/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css b/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css old mode 100644 new mode 100755 index 3225661c..57bec30a --- a/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css +++ b/_static/design-style.4045f2051d55cab465a707391d5b2007.min.css @@ -1 +1 @@ -.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #007bff;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0069d9;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_static/design-tabs.js b/_static/design-tabs.js old mode 100644 new mode 100755 index 36b38cf0..a869cf55 --- a/_static/design-tabs.js +++ b/_static/design-tabs.js @@ -1,27 +1,27 @@ -var sd_labels_by_text = {}; - -function ready() { - const li = document.getElementsByClassName("sd-tab-label"); - for (const label of li) { - syncId = label.getAttribute("data-sync-id"); - if (syncId) { - label.onclick = onLabelClick; - if (!sd_labels_by_text[syncId]) { - sd_labels_by_text[syncId] = []; - } - sd_labels_by_text[syncId].push(label); - } - } -} - -function onLabelClick() { - // Activate other inputs with the same sync id. - syncId = this.getAttribute("data-sync-id"); - for (label of sd_labels_by_text[syncId]) { - if (label === this) continue; - label.previousElementSibling.checked = true; - } - window.localStorage.setItem("sphinx-design-last-tab", syncId); -} - -document.addEventListener("DOMContentLoaded", ready, false); +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/doctools.js b/_static/doctools.js old mode 100644 new mode 100755 diff --git a/_static/documentation_options.js b/_static/documentation_options.js old mode 100644 new mode 100755 index 30637825..828e1d21 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,14 +1,14 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '', - LANGUAGE: 'en', - COLLAPSE_INDEX: false, - BUILDER: 'html', - FILE_SUFFIX: '.html', - LINK_SUFFIX: '.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '', - NAVIGATION_WITH_KEYS: true, - SHOW_SEARCH_SUMMARY: true, - ENABLE_SEARCH_SHORTCUTS: false, +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '', + NAVIGATION_WITH_KEYS: true, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: false, }; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png old mode 100644 new mode 100755 diff --git a/_static/images/logo_binder.svg b/_static/images/logo_binder.svg old mode 100644 new mode 100755 diff --git a/_static/images/logo_colab.png b/_static/images/logo_colab.png old mode 100644 new mode 100755 diff --git a/_static/images/logo_deepnote.svg b/_static/images/logo_deepnote.svg old mode 100644 new mode 100755 diff --git a/_static/images/logo_jupyterhub.svg b/_static/images/logo_jupyterhub.svg old mode 100644 new mode 100755 diff --git a/_static/jquery-3.5.1.js b/_static/jquery-3.5.1.js old mode 100644 new mode 100755 index 50937333..55460159 --- a/_static/jquery-3.5.1.js +++ b/_static/jquery-3.5.1.js @@ -1,10872 +1,10872 @@ -/*! - * jQuery JavaScript Library v3.5.1 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2020-05-04T22:49Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var flat = arr.flat ? function( array ) { - return arr.flat.call( array ); -} : function( array ) { - return arr.concat.apply( [], array ); -}; - - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - -var isFunction = function isFunction( obj ) { - - // Support: Chrome <=57, Firefox <=52 - // In some browsers, typeof returns "function" for HTML elements - // (i.e., `typeof document.createElement( "object" ) === "function"`). - // We don't want to classify *any* DOM node as a function. - return typeof obj === "function" && typeof obj.nodeType !== "number"; - }; - - -var isWindow = function isWindow( obj ) { - return obj != null && obj === obj.window; - }; - - -var document = window.document; - - - - var preservedScriptAttributes = { - type: true, - src: true, - nonce: true, - noModule: true - }; - - function DOMEval( code, node, doc ) { - doc = doc || document; - - var i, val, - script = doc.createElement( "script" ); - - script.text = code; - if ( node ) { - for ( i in preservedScriptAttributes ) { - - // Support: Firefox 64+, Edge 18+ - // Some browsers don't support the "nonce" property on scripts. - // On the other hand, just using `getAttribute` is not enough as - // the `nonce` attribute is reset to an empty string whenever it - // becomes browsing-context connected. - // See https://github.com/whatwg/html/issues/2369 - // See https://html.spec.whatwg.org/#nonce-attributes - // The `node.getAttribute` check was added for the sake of - // `jQuery.globalEval` so that it can fake a nonce-containing node - // via an object. - val = node[ i ] || node.getAttribute && node.getAttribute( i ); - if ( val ) { - script.setAttribute( i, val ); - } - } - } - doc.head.appendChild( script ).parentNode.removeChild( script ); - } - - -function toType( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; -} -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.5.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - even: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return ( i + 1 ) % 2; - } ) ); - }, - - odd: function() { - return this.pushStack( jQuery.grep( this, function( _elem, i ) { - return i % 2; - } ) ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - copy = options[ name ]; - - // Prevent Object.prototype pollution - // Prevent never-ending loop - if ( name === "__proto__" || target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - src = target[ name ]; - - // Ensure proper type for the source value - if ( copyIsArray && !Array.isArray( src ) ) { - clone = []; - } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { - clone = {}; - } else { - clone = src; - } - copyIsArray = false; - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - // Evaluates a script in a provided context; falls back to the global one - // if not specified. - globalEval: function( code, options, doc ) { - DOMEval( code, { nonce: options && options.nonce }, doc ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return flat( ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( _i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = toType( obj ); - - if ( isFunction( obj ) || isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.5 - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://js.foundation/ - * - * Date: 2020-03-14 - */ -( function( window ) { -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - nonnativeSelectorCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ( {} ).hasOwnProperty, - arr = [], - pop = arr.pop, - pushNative = arr.push, - push = arr.push, - slice = arr.slice, - - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[ i ] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + - "ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram - identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + - "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - - // "Attribute values must be CSS identifiers [capture 5] - // or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + - whitespace + "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + - whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + - "*" ), - rdescend = new RegExp( whitespace + "|>" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + - whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + - whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + - "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + - "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rhtml = /HTML$/i, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), - funescape = function( escape, nonHex ) { - var high = "0x" + escape.slice( 1 ) - 0x10000; - - return nonHex ? - - // Strip the backslash prefix from a non-hex escape sequence - nonHex : - - // Replace a hexadecimal escape sequence with the encoded Unicode code point - // Support: IE <=11+ - // For values outside the Basic Multilingual Plane (BMP), manually construct a - // surrogate pair - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + - ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - inDisabledFieldset = addCombinator( - function( elem ) { - return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - ( arr = slice.call( preferredDoc.childNodes ) ), - preferredDoc.childNodes - ); - - // Support: Android<4.0 - // Detect silently failing push.apply - // eslint-disable-next-line no-unused-expressions - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - pushNative.apply( target, slice.call( els ) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - - // Can't trust NodeList.length - while ( ( target[ j++ ] = els[ i++ ] ) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - setDocument( context ); - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { - - // ID selector - if ( ( m = match[ 1 ] ) ) { - - // Document context - if ( nodeType === 9 ) { - if ( ( elem = context.getElementById( m ) ) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && ( elem = newContext.getElementById( m ) ) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[ 2 ] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !nonnativeSelectorCache[ selector + " " ] && - ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && - - // Support: IE 8 only - // Exclude object elements - ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { - - newSelector = selector; - newContext = context; - - // qSA considers elements outside a scoping root when evaluating child or - // descendant combinators, which is not what we want. - // In such cases, we work around the behavior by prefixing every selector in the - // list with an ID selector referencing the scope context. - // The technique has to be used as well when a leading combinator is used - // as such selectors are not recognized by querySelectorAll. - // Thanks to Andrew Dupont for this technique. - if ( nodeType === 1 && - ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - - // We can use :scope instead of the ID hack if the browser - // supports it & if we're not changing the context. - if ( newContext !== context || !support.scope ) { - - // Capture the context ID, setting it first if necessary - if ( ( nid = context.getAttribute( "id" ) ) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", ( nid = expando ) ); - } - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + - toSelector( groups[ i ] ); - } - newSelector = groups.join( "," ); - } - - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - nonnativeSelectorCache( selector, true ); - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return ( cache[ key + " " ] = value ); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement( "fieldset" ); - - try { - return !!fn( el ); - } catch ( e ) { - return false; - } finally { - - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split( "|" ), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[ i ] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( ( cur = cur.nextSibling ) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return ( name === "input" || name === "button" ) && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - inDisabledFieldset( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction( function( argument ) { - argument = +argument; - return markFunction( function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ ( j = matchIndexes[ i ] ) ] ) { - seed[ j ] = !( matches[ j ] = seed[ j ] ); - } - } - } ); - } ); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - var namespace = elem.namespaceURI, - docElem = ( elem.ownerDocument || elem ).documentElement; - - // Support: IE <=8 - // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes - // https://bugs.jquery.com/ticket/4833 - return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9 - 11+, Edge 12 - 18+ - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( preferredDoc != document && - ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, - // Safari 4 - 5 only, Opera <=11.6 - 12.x only - // IE/Edge & older browsers don't support the :scope pseudo-class. - // Support: Safari 6.0 only - // Safari 6.0 supports :scope but it's an alias of :root there. - support.scope = assert( function( el ) { - docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); - return typeof el.querySelectorAll !== "undefined" && - !el.querySelectorAll( ":scope fieldset div" ).length; - } ); - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert( function( el ) { - el.className = "i"; - return !el.getAttribute( "className" ); - } ); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert( function( el ) { - el.appendChild( document.createComment( "" ) ); - return !el.getElementsByTagName( "*" ).length; - } ); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert( function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - } ); - - // ID filter and find - if ( support.getById ) { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute( "id" ) === attrId; - }; - }; - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter[ "ID" ] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode( "id" ); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find[ "ID" ] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( ( elem = elems[ i++ ] ) ) { - node = elem.getAttributeNode( "id" ); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find[ "TAG" ] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { - - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert( function( el ) { - - var input; - - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll( "[selected]" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push( "~=" ); - } - - // Support: IE 11+, Edge 15 - 18+ - // IE 11/Edge don't find elements on a `[name='']` query in some cases. - // Adding a temporary attribute to the document before the selection works - // around the issue. - // Interestingly, IE 10 & older don't seem to have the issue. - input = document.createElement( "input" ); - input.setAttribute( "name", "" ); - el.appendChild( input ); - if ( !el.querySelectorAll( "[name='']" ).length ) { - rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + - whitespace + "*(?:''|\"\")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll( ":checked" ).length ) { - rbuggyQSA.push( ":checked" ); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push( ".#.+[+~]" ); - } - - // Support: Firefox <=3.6 - 5 only - // Old Firefox doesn't throw on a badly-escaped identifier. - el.querySelectorAll( "\\\f" ); - rbuggyQSA.push( "[\\r\\n\\f]" ); - } ); - - assert( function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement( "input" ); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll( "[name=d]" ).length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: Opera 10 - 11 only - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll( "*,:x" ); - rbuggyQSA.push( ",.*:" ); - } ); - } - - if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector ) ) ) ) { - - assert( function( el ) { - - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - } ); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - ) ); - } : - function( a, b ) { - if ( b ) { - while ( ( b = b.parentNode ) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { - - // Choose the first element that is related to our preferred document - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( a == document || a.ownerDocument == preferredDoc && - contains( preferredDoc, a ) ) { - return -1; - } - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( b == document || b.ownerDocument == preferredDoc && - contains( preferredDoc, b ) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - return a == document ? -1 : - b == document ? 1 : - /* eslint-enable eqeqeq */ - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( ( cur = cur.parentNode ) ) { - ap.unshift( cur ); - } - cur = b; - while ( ( cur = cur.parentNode ) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[ i ] === bp[ i ] ) { - i++; - } - - return i ? - - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[ i ], bp[ i ] ) : - - // Otherwise nodes in our document sort first - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - /* eslint-disable eqeqeq */ - ap[ i ] == preferredDoc ? -1 : - bp[ i ] == preferredDoc ? 1 : - /* eslint-enable eqeqeq */ - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - setDocument( elem ); - - if ( support.matchesSelector && documentIsHTML && - !nonnativeSelectorCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch ( e ) { - nonnativeSelectorCache( expr, true ); - } - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( context.ownerDocument || context ) != document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - - // Set document vars if needed - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( ( elem.ownerDocument || elem ) != document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; -}; - -Sizzle.escape = function( sel ) { - return ( sel + "" ).replace( rcssescape, fcssescape ); -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( ( elem = results[ i++ ] ) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - - // If no nodeType, this is expected to be an array - while ( ( node = elem[ i++ ] ) ) { - - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[ 1 ] = match[ 1 ].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[ 3 ] = ( match[ 3 ] || match[ 4 ] || - match[ 5 ] || "" ).replace( runescape, funescape ); - - if ( match[ 2 ] === "~=" ) { - match[ 3 ] = " " + match[ 3 ] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[ 1 ] = match[ 1 ].toLowerCase(); - - if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { - - // nth-* requires argument - if ( !match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[ 4 ] = +( match[ 4 ] ? - match[ 5 ] + ( match[ 6 ] || 1 ) : - 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); - match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); - - // other types prohibit arguments - } else if ( match[ 3 ] ) { - Sizzle.error( match[ 0 ] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[ 6 ] && match[ 2 ]; - - if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[ 3 ] ) { - match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - - // Get excess from tokenize (recursively) - ( excess = tokenize( unquoted, true ) ) && - - // advance to the next closing parenthesis - ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { - - // excess is a negative index - match[ 0 ] = match[ 0 ].slice( 0, excess ); - match[ 2 ] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { - return true; - } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - ( pattern = new RegExp( "(^|" + whitespace + - ")" + className + "(" + whitespace + "|$)" ) ) && classCache( - className, function( elem ) { - return pattern.test( - typeof elem.className === "string" && elem.className || - typeof elem.getAttribute !== "undefined" && - elem.getAttribute( "class" ) || - "" - ); - } ); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - /* eslint-disable max-len */ - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - /* eslint-enable max-len */ - - }; - }, - - "CHILD": function( type, what, _argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, _context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( ( node = node[ dir ] ) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( ( node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - - // Use previously-cached element index if available - if ( useCache ) { - - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - - // Use the same loop as above to seek `elem` from the start - while ( ( node = ++nodeIndex && node && node[ dir ] || - ( diff = nodeIndex = 0 ) || start.pop() ) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || - ( node[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - ( outerCache[ node.uniqueID ] = {} ); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction( function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[ i ] ); - seed[ idx ] = !( matches[ idx ] = matched[ i ] ); - } - } ) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - - // Potentially complex pseudos - "not": markFunction( function( selector ) { - - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction( function( seed, matches, _context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( ( elem = unmatched[ i ] ) ) { - seed[ i ] = !( matches[ i ] = elem ); - } - } - } ) : - function( elem, _context, xml ) { - input[ 0 ] = elem; - matcher( input, null, xml, results ); - - // Don't keep the element (issue #299) - input[ 0 ] = null; - return !results.pop(); - }; - } ), - - "has": markFunction( function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - } ), - - "contains": markFunction( function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; - }; - } ), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - - // lang value must be a valid identifier - if ( !ridentifier.test( lang || "" ) ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( ( elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); - return false; - }; - } ), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && - ( !document.hasFocus || document.hasFocus() ) && - !!( elem.type || elem.href || ~elem.tabIndex ); - }, - - // Boolean properties - "enabled": createDisabledPseudo( false ), - "disabled": createDisabledPseudo( true ), - - "checked": function( elem ) { - - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return ( nodeName === "input" && !!elem.checked ) || - ( nodeName === "option" && !!elem.selected ); - }, - - "selected": function( elem ) { - - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - // eslint-disable-next-line no-unused-expressions - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos[ "empty" ]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( ( attr = elem.getAttribute( "type" ) ) == null || - attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo( function() { - return [ 0 ]; - } ), - - "last": createPositionalPseudo( function( _matchIndexes, length ) { - return [ length - 1 ]; - } ), - - "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - } ), - - "even": createPositionalPseudo( function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "odd": createPositionalPseudo( function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? - argument + length : - argument > length ? - length : - argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ), - - "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - } ) - } -}; - -Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || ( match = rcomma.exec( soFar ) ) ) { - if ( match ) { - - // Don't consume trailing commas as valid - soFar = soFar.slice( match[ 0 ].length ) || soFar; - } - groups.push( ( tokens = [] ) ); - } - - matched = false; - - // Combinators - if ( ( match = rcombinators.exec( soFar ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - - // Cast descendant combinators to space - type: match[ 0 ].replace( rtrim, " " ) - } ); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || - ( match = preFilters[ type ]( match ) ) ) ) { - matched = match.shift(); - tokens.push( { - value: matched, - type: type, - matches: match - } ); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[ i ].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( ( elem = elem[ dir ] ) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || ( elem[ expando ] = {} ); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || - ( outerCache[ elem.uniqueID ] = {} ); - - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( ( oldCache = uniqueCache[ key ] ) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return ( newCache[ 2 ] = oldCache[ 2 ] ); - } else { - - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[ i ]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[ 0 ]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[ i ], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( ( elem = unmatched[ i ] ) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction( function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( - selector || "*", - context.nodeType ? [ context ] : context, - [] - ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( ( elem = temp[ i ] ) ) { - matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) ) { - - // Restore matcherIn since elem is not yet a final match - temp.push( ( matcherIn[ i ] = elem ) ); - } - } - postFinder( null, ( matcherOut = [] ), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( ( elem = matcherOut[ i ] ) && - ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { - - seed[ temp ] = !( results[ temp ] = elem ); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - } ); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[ 0 ].type ], - implicitRelative = leadingRelative || Expr.relative[ " " ], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - ( checkContext = context ).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { - matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; - } else { - matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[ j ].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens - .slice( 0, i - 1 ) - .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), - - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), - len = elems.length; - - if ( outermost ) { - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - outermostContext = context == document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - - // Support: IE 11+, Edge 17 - 18+ - // IE/Edge sometimes throw a "Permission denied" error when strict-comparing - // two documents; shallow comparisons work. - // eslint-disable-next-line eqeqeq - if ( !context && elem.ownerDocument != document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( ( matcher = elementMatchers[ j++ ] ) ) { - if ( matcher( elem, context || document, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - - // They will have gone through all possible matchers - if ( ( elem = !matcher && elem ) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( ( matcher = setMatchers[ j++ ] ) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !( unmatched[ i ] || setMatched[ i ] ) ) { - setMatched[ i ] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[ i ] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( - selector, - matcherFromGroupMatchers( elementMatchers, setMatchers ) - ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( ( selector = compiled.selector || selector ) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[ 0 ] = match[ 0 ].slice( 0 ); - if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { - - context = ( Expr.find[ "ID" ]( token.matches[ 0 ] - .replace( runescape, funescape ), context ) || [] )[ 0 ]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[ i ]; - - // Abort if we hit a combinator - if ( Expr.relative[ ( type = token.type ) ] ) { - break; - } - if ( ( find = Expr.find[ type ] ) ) { - - // Search, expanding context for leading sibling combinators - if ( ( seed = find( - token.matches[ 0 ].replace( runescape, funescape ), - rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || - context - ) ) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert( function( el ) { - - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; -} ); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert( function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute( "href" ) === "#"; -} ) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - } ); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert( function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -} ) ) { - addHandle( "value", function( elem, _name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - } ); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert( function( el ) { - return el.getAttribute( "disabled" ) == null; -} ) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - ( val = elem.getAttributeNode( name ) ) && val.specified ? - val.value : - null; - } - } ); -} - -return Sizzle; - -} )( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -}; -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Filtered directly for both simple and complex selectors - return jQuery.filter( qualifier, elements, not ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, _i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, _i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, _i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( elem.contentDocument != null && - - // Support: IE 11+ - // elements with no `data` attribute has an object - // `contentDocument` with a `null` prototype. - getProto( elem.contentDocument ) ) { - - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && toType( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( _i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // rejected_handlers.disable - // fulfilled_handlers.disable - tuples[ 3 - i ][ 3 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock, - - // progress_handlers.lock - tuples[ 0 ][ 3 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || - isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); - } - - return master.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function( error, stack ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( toType( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, _key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; - - -// Matches dashed string for camelizing -var rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g; - -// Used by camelCase as callback to replace() -function fcamelCase( _all, letter ) { - return letter.toUpperCase(); -} - -// Convert dashed to camelCase; used by the css and data modules -// Support: IE <=9 - 11, Edge 12 - 15 -// Microsoft forgot to hump their vendor prefix (#9572) -function camelCase( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); -} -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( camelCase ); - } else { - key = camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var documentElement = document.documentElement; - - - - var isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ); - }, - composed = { composed: true }; - - // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only - // Check attachment across shadow DOM boundaries when possible (gh-3504) - // Support: iOS 10.0-10.2 only - // Early iOS 10 versions support `attachShadow` but not `getRootNode`, - // leading to errors. We need to check for `getRootNode`. - if ( documentElement.getRootNode ) { - isAttached = function( elem ) { - return jQuery.contains( elem.ownerDocument, elem ) || - elem.getRootNode( composed ) === elem.ownerDocument; - }; - } -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - isAttached( elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, scale, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = elem.nodeType && - ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Support: Firefox <=54 - // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) - initial = initial / 2; - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - while ( maxIterations-- ) { - - // Evaluate and update our best guess (doubling guesses that zero out). - // Finish if the scale equals or crosses 1 (making the old*new product non-positive). - jQuery.style( elem, prop, initialInUnit + unit ); - if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { - maxIterations = 0; - } - initialInUnit = initialInUnit / scale; - - } - - initialInUnit = initialInUnit * 2; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); - -var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); - - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // Support: IE <=9 only - // IE <=9 replaces "; - support.option = !!div.lastChild; -} )(); - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// Support: IE <=9 only -if ( !support.option ) { - wrapMap.optgroup = wrapMap.option = [ 1, "" ]; -} - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, attached, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( toType( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - attached = isAttached( elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( attached ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 - 11+ -// focus() and blur() are asynchronous, except when they are no-op. -// So expect focus to be synchronous when the element is already active, -// and blur to be synchronous when the element is not already active. -// (focus and blur are always synchronous in other supported browsers, -// this just defines when we can count on it). -function expectSync( elem, type ) { - return ( elem === safeActiveElement() ) === ( type === "focus" ); -} - -// Support: IE <=9 only -// Accessing document.activeElement can throw unexpectedly -// https://bugs.jquery.com/ticket/13393 -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Only attach events to objects that accept data - if ( !acceptData( elem ) ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = Object.create( null ); - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( nativeEvent ), - - handlers = ( - dataPriv.get( this, "events" ) || Object.create( null ) - )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // If the event is namespaced, then each handler is only invoked if it is - // specially universal or its namespaces are a superset of the event's. - if ( !event.rnamespace || handleObj.namespace === false || - event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - click: { - - // Utilize native event to ensure correct state for checkable inputs - setup: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Claim the first handler - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - // dataPriv.set( el, "click", ... ) - leverageNative( el, "click", returnTrue ); - } - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function( data ) { - - // For mutual compressibility with _default, replace `this` access with a local var. - // `|| data` is dead code meant only to preserve the variable through minification. - var el = this || data; - - // Force setup before triggering a click - if ( rcheckableType.test( el.type ) && - el.click && nodeName( el, "input" ) ) { - - leverageNative( el, "click" ); - } - - // Return non-false to allow normal event-path propagation - return true; - }, - - // For cross-browser consistency, suppress native .click() on links - // Also prevent it if we're currently inside a leveraged native-event stack - _default: function( event ) { - var target = event.target; - return rcheckableType.test( target.type ) && - target.click && nodeName( target, "input" ) && - dataPriv.get( target, "click" ) || - nodeName( target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -// Ensure the presence of an event listener that handles manually-triggered -// synthetic events by interrupting progress until reinvoked in response to -// *native* events that it fires directly, ensuring that state changes have -// already occurred before other listeners are invoked. -function leverageNative( el, type, expectSync ) { - - // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add - if ( !expectSync ) { - if ( dataPriv.get( el, type ) === undefined ) { - jQuery.event.add( el, type, returnTrue ); - } - return; - } - - // Register the controller as a special universal handler for all event namespaces - dataPriv.set( el, type, false ); - jQuery.event.add( el, type, { - namespace: false, - handler: function( event ) { - var notAsync, result, - saved = dataPriv.get( this, type ); - - if ( ( event.isTrigger & 1 ) && this[ type ] ) { - - // Interrupt processing of the outer synthetic .trigger()ed event - // Saved data should be false in such cases, but might be a leftover capture object - // from an async native handler (gh-4350) - if ( !saved.length ) { - - // Store arguments for use when handling the inner native event - // There will always be at least one argument (an event object), so this array - // will not be confused with a leftover capture object. - saved = slice.call( arguments ); - dataPriv.set( this, type, saved ); - - // Trigger the native event and capture its result - // Support: IE <=9 - 11+ - // focus() and blur() are asynchronous - notAsync = expectSync( this, type ); - this[ type ](); - result = dataPriv.get( this, type ); - if ( saved !== result || notAsync ) { - dataPriv.set( this, type, false ); - } else { - result = {}; - } - if ( saved !== result ) { - - // Cancel the outer synthetic event - event.stopImmediatePropagation(); - event.preventDefault(); - return result.value; - } - - // If this is an inner synthetic event for an event with a bubbling surrogate - // (focus or blur), assume that the surrogate already propagated from triggering the - // native event and prevent that from happening again here. - // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the - // bubbling surrogate propagates *after* the non-bubbling base), but that seems - // less bad than duplication. - } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { - event.stopPropagation(); - } - - // If this is a native event triggered above, everything is now in order - // Fire an inner synthetic event with the original arguments - } else if ( saved.length ) { - - // ...and capture the result - dataPriv.set( this, type, { - value: jQuery.event.trigger( - - // Support: IE <=9 - 11+ - // Extend with the prototype to reset the above stopImmediatePropagation() - jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), - saved.slice( 1 ), - this - ) - } ); - - // Abort handling of the native event - event.stopImmediatePropagation(); - } - } - } ); -} - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || Date.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - code: true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp ); - -jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { - jQuery.event.special[ type ] = { - - // Utilize native event if possible so blur/focus sequence is correct - setup: function() { - - // Claim the first handler - // dataPriv.set( this, "focus", ... ) - // dataPriv.set( this, "blur", ... ) - leverageNative( this, type, expectSync ); - - // Return false to allow normal processing in the caller - return false; - }, - trigger: function() { - - // Force setup before trigger - leverageNative( this, type ); - - // Return non-false to allow normal event-path propagation - return true; - }, - - delegateType: delegateType - }; -} ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - // Support: IE <=10 - 11, Edge 12 - 13 only - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( elem ).children( "tbody" )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { - elem.type = elem.type.slice( 5 ); - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.get( src ); - events = pdataOld.events; - - if ( events ) { - dataPriv.remove( dest, "handle events" ); - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = flat( args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - valueIsFunction = isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( valueIsFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( valueIsFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl && !node.noModule ) { - jQuery._evalUrl( node.src, { - nonce: node.nonce || node.getAttribute( "nonce" ) - }, doc ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && isAttached( node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html; - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = isAttached( elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - -var swap = function( elem, options, callback ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.call( elem ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - -var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - container.style.cssText = "position:absolute;left:-11111px;width:60px;" + - "margin-top:1px;padding:0;border:0"; - div.style.cssText = - "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + - "margin:auto;border:1px;padding:1px;" + - "width:60%;top:1%"; - documentElement.appendChild( container ).appendChild( div ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; - - // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 - // Some styles come back with percentage values, even though they shouldn't - div.style.right = "60%"; - pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; - - // Support: IE 9 - 11 only - // Detect misreporting of content dimensions for box-sizing:border-box elements - boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; - - // Support: IE 9 only - // Detect overflow:scroll screwiness (gh-3699) - // Support: Chrome <=64 - // Don't get tricked when zoom affects offsetWidth (gh-4029) - div.style.position = "absolute"; - scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - function roundPixelMeasures( measure ) { - return Math.round( parseFloat( measure ) ); - } - - var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, - reliableTrDimensionsVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - jQuery.extend( support, { - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelBoxStyles: function() { - computeStyleTests(); - return pixelBoxStylesVal; - }, - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - }, - scrollboxSize: function() { - computeStyleTests(); - return scrollboxSizeVal; - }, - - // Support: IE 9 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Behavior in IE 9 is more subtle than in newer versions & it passes - // some versions of this test; make sure not to make it pass there! - reliableTrDimensions: function() { - var table, tr, trChild, trStyle; - if ( reliableTrDimensionsVal == null ) { - table = document.createElement( "table" ); - tr = document.createElement( "tr" ); - trChild = document.createElement( "div" ); - - table.style.cssText = "position:absolute;left:-11111px"; - tr.style.height = "1px"; - trChild.style.height = "9px"; - - documentElement - .appendChild( table ) - .appendChild( tr ) - .appendChild( trChild ); - - trStyle = window.getComputedStyle( tr ); - reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; - - documentElement.removeChild( table ); - } - return reliableTrDimensionsVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !isAttached( elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style, - vendorProps = {}; - -// Return a vendor-prefixed property or undefined -function vendorPropName( name ) { - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a potentially-mapped jQuery.cssProps or vendor prefixed property -function finalPropName( name ) { - var final = jQuery.cssProps[ name ] || vendorProps[ name ]; - - if ( final ) { - return final; - } - if ( name in emptyStyle ) { - return name; - } - return vendorProps[ name ] = vendorPropName( name ) || name; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }; - -function setPositiveNumber( _elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { - var i = dimension === "width" ? 1 : 0, - extra = 0, - delta = 0; - - // Adjustment may not be necessary - if ( box === ( isBorderBox ? "border" : "content" ) ) { - return 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin - if ( box === "margin" ) { - delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); - } - - // If we get here with a content-box, we're seeking "padding" or "border" or "margin" - if ( !isBorderBox ) { - - // Add padding - delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // For "border" or "margin", add border - if ( box !== "padding" ) { - delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - - // But still keep track of it otherwise - } else { - extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - - // If we get here with a border-box (content + padding + border), we're seeking "content" or - // "padding" or "margin" - } else { - - // For "content", subtract padding - if ( box === "content" ) { - delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // For "content" or "padding", subtract border - if ( box !== "margin" ) { - delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - // Account for positive content-box scroll gutter when requested by providing computedVal - if ( !isBorderBox && computedVal >= 0 ) { - - // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border - // Assuming integer scroll gutter, subtract the rest and round down - delta += Math.max( 0, Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - computedVal - - delta - - extra - - 0.5 - - // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter - // Use an explicit zero to avoid NaN (gh-3964) - ) ) || 0; - } - - return delta; -} - -function getWidthOrHeight( elem, dimension, extra ) { - - // Start with computed style - var styles = getStyles( elem ), - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). - // Fake content-box until we know it's needed to know the true value. - boxSizingNeeded = !support.boxSizingReliable() || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - valueIsBorderBox = isBorderBox, - - val = curCSS( elem, dimension, styles ), - offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); - - // Support: Firefox <=54 - // Return a confounding non-pixel value or feign ignorance, as appropriate. - if ( rnumnonpx.test( val ) ) { - if ( !extra ) { - return val; - } - val = "auto"; - } - - - // Support: IE 9 - 11 only - // Use offsetWidth/offsetHeight for when box sizing is unreliable. - // In those cases, the computed value can be trusted to be border-box. - if ( ( !support.boxSizingReliable() && isBorderBox || - - // Support: IE 10 - 11+, Edge 15 - 18+ - // IE/Edge misreport `getComputedStyle` of table rows with width/height - // set in CSS while `offset*` properties report correct values. - // Interestingly, in some cases IE 9 doesn't suffer from this issue. - !support.reliableTrDimensions() && nodeName( elem, "tr" ) || - - // Fall back to offsetWidth/offsetHeight when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - val === "auto" || - - // Support: Android <=4.1 - 4.3 only - // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) - !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && - - // Make sure the element is visible & connected - elem.getClientRects().length ) { - - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Where available, offsetWidth/offsetHeight approximate border box dimensions. - // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the - // retrieved value as a content box dimension. - valueIsBorderBox = offsetProp in elem; - if ( valueIsBorderBox ) { - val = elem[ offsetProp ]; - } - } - - // Normalize "" and auto - val = parseFloat( val ) || 0; - - // Adjust for the element's box model - return ( val + - boxModelAdjustment( - elem, - dimension, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles, - - // Provide the current computed size to request scroll gutter calculation (gh-3589) - val - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "gridArea": true, - "gridColumn": true, - "gridColumnEnd": true, - "gridColumnStart": true, - "gridRow": true, - "gridRowEnd": true, - "gridRowStart": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: {}, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append - // "px" to a few hardcoded values. - if ( type === "number" && !isCustomProp ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( _i, dimension ) { - jQuery.cssHooks[ dimension ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, dimension, extra ); - } ) : - getWidthOrHeight( elem, dimension, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = getStyles( elem ), - - // Only read styles.position if the test has a chance to fail - // to avoid forcing a reflow. - scrollboxSizeBuggy = !support.scrollboxSize() && - styles.position === "absolute", - - // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) - boxSizingNeeded = scrollboxSizeBuggy || extra, - isBorderBox = boxSizingNeeded && - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - subtract = extra ? - boxModelAdjustment( - elem, - dimension, - extra, - isBorderBox, - styles - ) : - 0; - - // Account for unreliable border-box dimensions by comparing offset* to computed and - // faking a content-box to get border and padding (gh-3699) - if ( isBorderBox && scrollboxSizeBuggy ) { - subtract -= Math.ceil( - elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - - parseFloat( styles[ dimension ] ) - - boxModelAdjustment( elem, dimension, "border", false, styles ) - - 0.5 - ); - } - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ dimension ] = value; - value = jQuery.css( elem, dimension ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( prefix !== "margin" ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && ( - jQuery.cssHooks[ tween.prop ] || - tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = Date.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 15 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY and Edge just mirrors - // the overflowX value there. - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - result.stop.bind( result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = Date.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -function classesToArray( value ) { - if ( Array.isArray( value ) ) { - return value; - } - if ( typeof value === "string" ) { - return value.match( rnothtmlwhite ) || []; - } - return []; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - classes = classesToArray( value ); - - if ( classes.length ) { - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isValidValue = type === "string" || Array.isArray( value ); - - if ( typeof stateVal === "boolean" && isValidValue ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( isValidValue ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = classesToArray( value ); - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, valueIsFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - valueIsFunction = isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( valueIsFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -support.focusin = "onfocusin" in window; - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - stopPropagationCallback = function( e ) { - e.stopPropagation(); - }; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = lastElement = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - lastElement = cur; - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( - dataPriv.get( cur, "events" ) || Object.create( null ) - )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - - if ( event.isPropagationStopped() ) { - lastElement.addEventListener( type, stopPropagationCallback ); - } - - elem[ type ](); - - if ( event.isPropagationStopped() ) { - lastElement.removeEventListener( type, stopPropagationCallback ); - } - - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - - // Handle: regular nodes (via `this.ownerDocument`), window - // (via `this.document`) & document (via `this`). - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this.document || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = { guid: Date.now() }; - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && toType( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - if ( a == null ) { - return ""; - } - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( _i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() + " " ] = - ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) - .concat( match[ 2 ] ); - } - } - match = responseHeaders[ key.toLowerCase() + " " ]; - } - return match == null ? null : match.join( ", " ); - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 15 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available and should be processed, append data to url - if ( s.data && ( s.processData || typeof s.data === "string" ) ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + - uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Use a noop converter for missing script - if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { - s.converters[ "text script" ] = function() {}; - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( _i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - -jQuery.ajaxPrefilter( function( s ) { - var i; - for ( i in s.headers ) { - if ( i.toLowerCase() === "content-type" ) { - s.contentType = s.headers[ i ] || ""; - } - } -} ); - - -jQuery._evalUrl = function( url, options, doc ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - - // Only evaluate the response if it is successful (gh-4126) - // dataFilter is not invoked for failure responses, so using it instead - // of the default converter is kludgy but it works. - converters: { - "text script": function() {} - }, - dataFilter: function( response ) { - jQuery.globalEval( response, options, doc ); - } - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var htmlIsFunction = isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.ontimeout = - xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain or forced-by-attrs requests - if ( s.crossDomain || s.scriptAttrs ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " {% endmacro %} {% macro body_post() %} - - + + {% endmacro %} \ No newline at end of file diff --git a/docs/.DS_Store b/docs/.DS_Store old mode 100644 new mode 100755 diff --git a/docs/experiments/js_exp.html b/docs/experiments/js_exp.html old mode 100644 new mode 100755 index 0b6f58e0..6235669d --- a/docs/experiments/js_exp.html +++ b/docs/experiments/js_exp.html @@ -1,763 +1,771 @@ - - - - - - - - - - - - Synthetic Data with Stable Diffusion for Foliar Disease Classification — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Synthetic Data with Stable Diffusion for Foliar Disease Classification

- -
- -
-
- - - - -
- -
-

Information

-
    -
  • Title: Synthetic Data with Stable Diffusion for Foliar Disease Classification

  • -
  • Author: Jisu Kim

  • -
  • Last updated on Jul. 05, 2023

  • -
-
-
-

Synthetic Data with Stable Diffusion for Foliar Disease Classification#

-
-

1. 개요#

-
    -
  • 사과 나무의 잎에 생기는 질병을 이미지로 판별하는 Kaggle competition (링크)에서 아이디어를 얻어서 진행한 프로젝트입니다.

  • -
  • 해당 competition은 사과나무 잎에 걸린 질병에 따라 잎 이미지를 4개의 class로 분류하는 task입니다.

  • -
-
-4classes -
-

Fig. 184 4 classes of leaves#

-
-
-
    -
  • competition을 설명한 article (링크)에서 전체적인 accuracy는 97%이지만 multiple diseases class의 경우 accuracy가 51%에 불과했다고 언급합니다.

  • -
  • multiple diseases class의 이미지 개수가 다른 class에 비해 적은 점에 주목했고, stable diffusion을 사용하여 해당 클래스의 데이터 개수를 늘려서 classifier 학습에 사용하면 더 좋은 성능의 classifier를 얻을 수 있을 것으로 기대했습니다.

  • -
-
-
-

2. Baseline 구축#

-
    -
  • 문제 상황을 재현하기 위해 기존 데이터로 image classifier를 학습하여 baseline으로 잡았습니다.

  • -
  • 모델은 pretrained된 ResNet18에 linear layer를 붙여서 사용했습니다.

  • -
  • 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1%

  • -
  • multiple diseases class는 이미지 개수 91개로 다른 클래스들에 비해서 개수가 적습니다.

  • -
  • class별 data imbalance가 성능을 낮추는 원인일 것이라 가정하고 stable diffusion으로 multiple diseases class의 data를 추가로 생성해보기로 했습니다.

  • -
  • multiple diseases class 예시

  • -
-
-multiple_ex -
-

Fig. 185 4 classes of leaves#

-
-
-
-
-

3. Stable diffusion fine tuning#

-
    -
  • pretraned stable diffusion의 경우 multiple diseases class에 대한 정보가 없어서 이미지를 생성할 경우 아래와 같이 관련없는 이미지가 생성됩니다.

  • -
-
-multiple_sd -
-

Fig. 186 prompt: “a photo of leaves with multiple diseases#

-
-
-
    -
  • 따라서 stable diffusion model (링크)에 해당 class에 대한 정보를 넣어주기 위해 dreambooth (링크)를 사용하여 stable diffusion을 fine tuning했습니다.

  • -
  • training에 사용한 prompt는 “a photo of a <diseaes-leaf> leaf”이며, 생성한 이미지의 예시는 아래와 같습니다.

  • -
  • 생성 이미지 예시

  • -
-
-multiple_db -
-

Fig. 187 prompt: “a photo of a <diseaes-leaf> leaf”#

-
-
-
    -
  • prompt engineering을 수행하던 중 의도하지않은 결과를 발견했습니다.

  • -
  • 아래는 이에 대한 예시로 fine tuning 전의 stable diffusion model의 결과와 비교입니다.

  • -
  • 상황1 (prompt: “a photo of a leaf”)

  • -
-
-leaf_sd -
-

Fig. 188 fine tuning 전#

-
-
-
-leaf_db -
-

Fig. 189 fine tuning 후#

-
-
-
    -
  • 상황1을 보면 multiple diseases class 정보를 담은 unique identifier <diseaes-leaf>가 없음에도 multiple diseases의 정보를 담은 잎들만 생성됩니다. 이는 같은 class (leaf)에 속하는 다른 이미지들을 생성해내지 못하고 있다는 것입니다. 이 현상을 language drift라고 하며, 모델이 multiple diseases class의 leaf가 아닌 일반적인 leaf class에 관한 정보를 잊어버렸기 때문입니다.

  • -
  • 상황2 (prompt: “a photo”)

  • -
-
-photo_sd -
-

Fig. 190 fine tuning 전#

-
-
-
-photo_db -
-

Fig. 191 fine tuning 후#

-
-
-
    -
  • 상황2를 보면 photo라는 prompt만 사용하였는데도 생성한 이미지들에 multiple diseases class의 특징들이 나타납니다.

  • -
  • dreambooth에서는 language drift를 prior preservation loss를 사용해서 해결하였으므로 같은 방법을 사용했습니다. 상황2를 해결하기 위해 training prompt에서 “photo”를 제외하고 최대한 단순한 prompt “<diseases-leaf> leaf”를 사용하여 stable diffusion model을 다시 fine tuning했습니다.

  • -
-
-multiple_pp -
-

Fig. 192 multiple diseases class 이미지 생성 결과, prompt: “<diseaes-leaf> leaf”#

-
-
-
-leaf_pp -
-

Fig. 193 leaf 생성 결과, prompt: “leaf”#

-
-
-
    -
  • 재훈련 결과, fine tuning 이후에도 기존 stable diffusion model로 “leaf”를 생성하였을 때와 비슷한 이미지가 생성됩니다.

  • -
-
-photo_pp -
-

Fig. 194 photo 생성 결과, prompt: “photo”#

-
-
-
    -
  • “photo”의 경우에는 여전히 multiple diseases class의 영향을 받은 것같은 이미지들이 생성됩니다. photo의 경우에는 여러 대상들과 사용되는 일반적인 특성을 가지고있어서 그런 것이라는 생각이 들었고, 이를 체크해보기 위해 특정한 대상들과 photo와 비슷한 용도로 사용되는 다른 prompt들로 이미지들을 생성보았습니다.

  • -
  • 특정한 대상 세가지로는 cat, sea, pirate을 사용했고, photo와 비슷하게 사용되는 텍스트 세가지는 illustration, animation, wallpaper를 사용했습니다. (이미지는 글 마지막 부분의 appendix에 있습니다.)

  • -
  • 이미지 생성 결과, 특정한 대상을 지칭하는 텍스트의 경우 대상의 특징이 잘 드러나는 이미지가 생성되었지만, 여러 대상과 함께 쓰이는 텍스트의 경우 잎사귀의 특징을 가지는 이미지들이 일부 생성되었습니다.

  • -
-
-
-

4. 성능 비교#

-
    -
  • fine tuning한 stable diffusion model로 multiple diseases class의 이미지를 400장 생성하여 classifier를 다시 훈련했습니다.

  • -
-

baseline

-
    -
  • 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1%

  • -
-
-result_base -
-

Fig. 195 result_base#

-
-
-

생성한 이미지를 추가 데이터로 활용한 경우

-
    -
  • 전체 accuracy는 97.9%, class별 accuracy는 healthy: 98.1%, multiple diseases: 84.6%, rust: 98.2%, scab: 99.3%

  • -
-
-result_new -
-

Fig. 196 result_now#

-
-
-
    -
  • kaggle에서 제공하는 test set에 적용했을 때는 baseline이 94.6%, stable diffusion으로 생성한 이미지들을 사용한 경우가 93.7%여서 baseline보다 좋은 성능을 얻지는 못 했습니다.

  • -
-
-
-

5. Discussion#

-
    -
  • stable diffusion 훈련 중간중간에 일정 step마다 이미지를 생성하게해서 훈련에 대한 모니터링이 있으면 좋겠다는 생각을 했습니다.

  • -
  • stable diffusion 훈련시 hyperparameter tuning을 좀 더 철저하게 해야겠다는 생각을 했습니다.

  • -
  • stable diffusion으로 생성한 이미지가 실제로 multiple diseases class 조건을 만족하는지 검수할 방안이 필요합니다.

  • -
  • multiple diseases 내에서도 카테고리를 나눌 수 있다면 나눠서 각각에 대한 stable diffusion model을 fine tuning할 수도 있을 것입니다.

  • -
  • 다른 diffusion model fine tuning 방법을 활용해볼 수도 있을 것입니다.

  • -
  • submission score에서 baseline을 이기지 못 했지만 text-to-image model을 이용한 synthetic data의 가능성을 볼 수 있었다고 생각합니다.

  • -
-
-
-

6. Appendix#

-
    -
  • 앞에서 언급한 prompt에 대한 이미지 생성 예시입니다. 일부 이미지는 NSFW로 판단되어 검은색으로 나왔습니다.

  • -
-
-cat -
-

Fig. 197 cat 생성 결과, prompt: “cat”#

-
-
-
-sea -
-

Fig. 198 sea 생성 결과, prompt: “sea”#

-
-
-
-pirate -
-

Fig. 199 pirate 생성 결과, prompt: “pirate”#

-
-
-
-illustration -
-

Fig. 200 illustration 생성 결과, prompt: “illustration”#

-
-
-
-animation -
-

Fig. 201 animation 생성 결과, prompt: “animation”#

-
-
-
-wallpaper -
-

Fig. 202 wallpaper 생성 결과, prompt: “wallpaper”#

-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Synthetic Data with Stable Diffusion for Foliar Disease Classification — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Synthetic Data with Stable Diffusion for Foliar Disease Classification

+ +
+ +
+
+ + + + +
+ +
+

Information

+
    +
  • Title: Synthetic Data with Stable Diffusion for Foliar Disease Classification

  • +
  • Author: Jisu Kim

  • +
  • Last updated on Jul. 05, 2023

  • +
+
+
+

Synthetic Data with Stable Diffusion for Foliar Disease Classification#

+
+

1. 개요#

+
    +
  • 사과 나무의 잎에 생기는 질병을 이미지로 판별하는 Kaggle competition (링크)에서 아이디어를 얻어서 진행한 프로젝트입니다.

  • +
  • 해당 competition은 사과나무 잎에 걸린 질병에 따라 잎 이미지를 4개의 class로 분류하는 task입니다.

  • +
+
+4classes +
+

Fig. 190 4 classes of leaves#

+
+
+
    +
  • competition을 설명한 article (링크)에서 전체적인 accuracy는 97%이지만 multiple diseases class의 경우 accuracy가 51%에 불과했다고 언급합니다.

  • +
  • multiple diseases class의 이미지 개수가 다른 class에 비해 적은 점에 주목했고, stable diffusion을 사용하여 해당 클래스의 데이터 개수를 늘려서 classifier 학습에 사용하면 더 좋은 성능의 classifier를 얻을 수 있을 것으로 기대했습니다.

  • +
+
+
+

2. Baseline 구축#

+
    +
  • 문제 상황을 재현하기 위해 기존 데이터로 image classifier를 학습하여 baseline으로 잡았습니다.

  • +
  • 모델은 pretrained된 ResNet18에 linear layer를 붙여서 사용했습니다.

  • +
  • 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1%

  • +
  • multiple diseases class는 이미지 개수 91개로 다른 클래스들에 비해서 개수가 적습니다.

  • +
  • class별 data imbalance가 성능을 낮추는 원인일 것이라 가정하고 stable diffusion으로 multiple diseases class의 data를 추가로 생성해보기로 했습니다.

  • +
  • multiple diseases class 예시

  • +
+
+multiple_ex +
+

Fig. 191 4 classes of leaves#

+
+
+
+
+

3. Stable diffusion fine tuning#

+
    +
  • pretraned stable diffusion의 경우 multiple diseases class에 대한 정보가 없어서 이미지를 생성할 경우 아래와 같이 관련없는 이미지가 생성됩니다.

  • +
+
+multiple_sd +
+

Fig. 192 prompt: “a photo of leaves with multiple diseases#

+
+
+
    +
  • 따라서 stable diffusion model (링크)에 해당 class에 대한 정보를 넣어주기 위해 dreambooth (링크)를 사용하여 stable diffusion을 fine tuning했습니다.

  • +
  • training에 사용한 prompt는 “a photo of a <diseaes-leaf> leaf”이며, 생성한 이미지의 예시는 아래와 같습니다.

  • +
  • 생성 이미지 예시

  • +
+
+multiple_db +
+

Fig. 193 prompt: “a photo of a <diseaes-leaf> leaf”#

+
+
+
    +
  • prompt engineering을 수행하던 중 의도하지않은 결과를 발견했습니다.

  • +
  • 아래는 이에 대한 예시로 fine tuning 전의 stable diffusion model의 결과와 비교입니다.

  • +
  • 상황1 (prompt: “a photo of a leaf”)

  • +
+
+leaf_sd +
+

Fig. 194 fine tuning 전#

+
+
+
+leaf_db +
+

Fig. 195 fine tuning 후#

+
+
+
    +
  • 상황1을 보면 multiple diseases class 정보를 담은 unique identifier <diseaes-leaf>가 없음에도 multiple diseases의 정보를 담은 잎들만 생성됩니다. 이는 같은 class (leaf)에 속하는 다른 이미지들을 생성해내지 못하고 있다는 것입니다. 이 현상을 language drift라고 하며, 모델이 multiple diseases class의 leaf가 아닌 일반적인 leaf class에 관한 정보를 잊어버렸기 때문입니다.

  • +
  • 상황2 (prompt: “a photo”)

  • +
+
+photo_sd +
+

Fig. 196 fine tuning 전#

+
+
+
+photo_db +
+

Fig. 197 fine tuning 후#

+
+
+
    +
  • 상황2를 보면 photo라는 prompt만 사용하였는데도 생성한 이미지들에 multiple diseases class의 특징들이 나타납니다.

  • +
  • dreambooth에서는 language drift를 prior preservation loss를 사용해서 해결하였으므로 같은 방법을 사용했습니다. 상황2를 해결하기 위해 training prompt에서 “photo”를 제외하고 최대한 단순한 prompt “<diseases-leaf> leaf”를 사용하여 stable diffusion model을 다시 fine tuning했습니다.

  • +
+
+multiple_pp +
+

Fig. 198 multiple diseases class 이미지 생성 결과, prompt: “<diseaes-leaf> leaf”#

+
+
+
+leaf_pp +
+

Fig. 199 leaf 생성 결과, prompt: “leaf”#

+
+
+
    +
  • 재훈련 결과, fine tuning 이후에도 기존 stable diffusion model로 “leaf”를 생성하였을 때와 비슷한 이미지가 생성됩니다.

  • +
+
+photo_pp +
+

Fig. 200 photo 생성 결과, prompt: “photo”#

+
+
+
    +
  • “photo”의 경우에는 여전히 multiple diseases class의 영향을 받은 것같은 이미지들이 생성됩니다. photo의 경우에는 여러 대상들과 사용되는 일반적인 특성을 가지고있어서 그런 것이라는 생각이 들었고, 이를 체크해보기 위해 특정한 대상들과 photo와 비슷한 용도로 사용되는 다른 prompt들로 이미지들을 생성보았습니다.

  • +
  • 특정한 대상 세가지로는 cat, sea, pirate을 사용했고, photo와 비슷하게 사용되는 텍스트 세가지는 illustration, animation, wallpaper를 사용했습니다. (이미지는 글 마지막 부분의 appendix에 있습니다.)

  • +
  • 이미지 생성 결과, 특정한 대상을 지칭하는 텍스트의 경우 대상의 특징이 잘 드러나는 이미지가 생성되었지만, 여러 대상과 함께 쓰이는 텍스트의 경우 잎사귀의 특징을 가지는 이미지들이 일부 생성되었습니다.

  • +
+
+
+

4. 성능 비교#

+
    +
  • fine tuning한 stable diffusion model로 multiple diseases class의 이미지를 400장 생성하여 classifier를 다시 훈련했습니다.

  • +
+

baseline

+
    +
  • 전체 accuracy는 97.7%, class별 accuracy는 healthy: 99.6%, multiple diseases: 73.6%, rust: 99.2%, scab: 98.1%

  • +
+
+result_base +
+

Fig. 201 result_base#

+
+
+

생성한 이미지를 추가 데이터로 활용한 경우

+
    +
  • 전체 accuracy는 97.9%, class별 accuracy는 healthy: 98.1%, multiple diseases: 84.6%, rust: 98.2%, scab: 99.3%

  • +
+
+result_new +
+

Fig. 202 result_now#

+
+
+
    +
  • kaggle에서 제공하는 test set에 적용했을 때는 baseline이 94.6%, stable diffusion으로 생성한 이미지들을 사용한 경우가 93.7%여서 baseline보다 좋은 성능을 얻지는 못 했습니다.

  • +
+
+
+

5. Discussion#

+
    +
  • stable diffusion 훈련 중간중간에 일정 step마다 이미지를 생성하게해서 훈련에 대한 모니터링이 있으면 좋겠다는 생각을 했습니다.

  • +
  • stable diffusion 훈련시 hyperparameter tuning을 좀 더 철저하게 해야겠다는 생각을 했습니다.

  • +
  • stable diffusion으로 생성한 이미지가 실제로 multiple diseases class 조건을 만족하는지 검수할 방안이 필요합니다.

  • +
  • multiple diseases 내에서도 카테고리를 나눌 수 있다면 나눠서 각각에 대한 stable diffusion model을 fine tuning할 수도 있을 것입니다.

  • +
  • 다른 diffusion model fine tuning 방법을 활용해볼 수도 있을 것입니다.

  • +
  • submission score에서 baseline을 이기지 못 했지만 text-to-image model을 이용한 synthetic data의 가능성을 볼 수 있었다고 생각합니다.

  • +
+
+
+

6. Appendix#

+
    +
  • 앞에서 언급한 prompt에 대한 이미지 생성 예시입니다. 일부 이미지는 NSFW로 판단되어 검은색으로 나왔습니다.

  • +
+
+cat +
+

Fig. 203 cat 생성 결과, prompt: “cat”#

+
+
+
+sea +
+

Fig. 204 sea 생성 결과, prompt: “sea”#

+
+
+
+pirate +
+

Fig. 205 pirate 생성 결과, prompt: “pirate”#

+
+
+
+illustration +
+

Fig. 206 illustration 생성 결과, prompt: “illustration”#

+
+
+
+animation +
+

Fig. 207 animation 생성 결과, prompt: “animation”#

+
+
+
+wallpaper +
+

Fig. 208 wallpaper 생성 결과, prompt: “wallpaper”#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/experiments/swjo_exp.html b/docs/experiments/swjo_exp.html old mode 100644 new mode 100755 index 20ac36e5..7fcdb407 --- a/docs/experiments/swjo_exp.html +++ b/docs/experiments/swjo_exp.html @@ -1,841 +1,849 @@ - - - - - - - - - - - - Training DreamBooth on Naver Webtoon Face Dataset — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Training DreamBooth on Naver Webtoon Face Dataset

- -
- -
-
- - - - -
- -
-

Information

-
    -
  • Title: Training DreamBooth on Naver Webtoon Face Dataset

  • -
  • Author: Sangwoo Jo

  • -
  • Last updated on Jul. 09, 2023

  • -
-
-
-

Training DreamBooth on Naver Webtoon Face Dataset#

-
-

Introduction#

-

이번 포스팅에서는 DreamBooth 를 직접 학습해보고 실험한 결과들을 공유할려고 합니다.

-

우선적으로 학습데이터는 bryandlee/naver-webtoon-data 에 공개된 YOLOv5 모델 및 Waifu2x 후처리 기법을 활용하여 프리드로우에 등장하는 인물 사진들을 수집했습니다. 논문에서는 3-5 장으로 fine-tuning 이 가능하다고 제시되어있지만, 인물 사진 같은 경우 더 많은 데이터로 학습하면 성능이 더 좋아져서 15-20 장의 이미지로 학습하였습니다. 학습한 이미지들 예시입니다.

-
-swjo_exp_01 -
-

Fig. 203 Training Data#

-
-
-

DreamBooth 를 실험하면서 대표적으로 instance prompt, guidance scale, negative prompt, 그리고 마지막으로 prior preservation loss 를 반영하는 정도를 조절하는 prior_loss_weight 를 바꿔가면서 학습해보았습니다. 사전학습된 text-to-image 모델로 처음에는 hakurei/waifu-diffusion 모델을 시도해봤지만 결과가 만족스럽지 못해 runwayml/stable-diffusion-v1-5 모델로 fine-tuning 작업을 진행했습니다.

-
-
-

Ablation Studies#

-
-

Prior Preservation Loss#

-

Prior Preservation Loss 를 제외한 동일한 configuration 으로 모델 학습한 결과입니다.

-
# with prior-preservation loss
-MODEL_NAME = “runwayml/stable-diffusion-v1-5”
-instance_prompt = "A photo of sks girl"
-class_prompt = "A photo of a girl"
-
-!python3 train_dreambooth.py \
-  --pretrained_model_name_or_path=$MODEL_NAME \
-  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
-  --output_dir=$OUTPUT_DIR \
-  --revision="fp16" \
-  --with_prior_preservation --prior_loss_weight=1.0 \
-  --seed=1337 \
-  --resolution=512 \
-  --train_batch_size=1 \
-  --train_text_encoder \
-  --mixed_precision="fp16" \
-  --use_8bit_adam \
-  --gradient_accumulation_steps=1 --gradient_checkpointing \
-  --learning_rate=1e-6 \
-  --lr_scheduler="constant" \
-  --lr_warmup_steps=0 \
-  --num_class_images=200 \
-  --sample_batch_size=4 \
-  --max_train_steps=800 \
-  --save_interval=100 \
-  --save_sample_prompt="A photo of sks girl" \
-  --concepts_list="concepts_list.json"
-
-
-
# w/o prior-preservation loss
-MODEL_NAME = “runwayml/stable-diffusion-v1-5”
-instance_prompt = "A photo of sks girl"
-class_prompt = "A photo of a girl"
-
-!python3 train_dreambooth.py \
-  --pretrained_model_name_or_path=$MODEL_NAME \
-  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
-  --output_dir=$OUTPUT_DIR \
-  --revision="fp16" \
-  --with_prior_preservation --prior_loss_weight=0.0 \
-  --seed=1337 \
-  --resolution=512 \
-  --train_batch_size=1 \
-  --train_text_encoder \
-  --mixed_precision="fp16" \
-  --use_8bit_adam \
-  --gradient_accumulation_steps=1 --gradient_checkpointing \
-  --learning_rate=1e-6 \
-  --lr_scheduler="constant" \
-  --lr_warmup_steps=0 \
-  --num_class_images=200 \
-  --sample_batch_size=4 \
-  --max_train_steps=800 \
-  --save_interval=100 \
-  --save_sample_prompt="A photo of sks girl" \
-  --concepts_list="concepts_list.json"
-
-
-

아래 그림처럼 동일한 inference prompt 를 입력했을 때, prior preservation loss 를 제외함으로써 input images 에 더 가까운 웹툰 사진들을 생성할 수 있었습니다. 또한, 핑크색 머리를 한 이민지 캐릭터를 어느 정도 잘 생성하는 부분도 확인할 수 있습니다.

-
    -
  • Inference Prompt: “A photo of sks girl with pink hair” (with prior-preservation loss)

  • -
-
-swjo_exp_02 -
-

Fig. 204 With Prior Preservation Loss#

-
-
-
    -
  • Inference Prompt: ” A photo of sks girl with pink hair” (w/o prior-preservation loss)

  • -
-
-swjo_exp_03 -
-

Fig. 205 Without Prior Preservation Loss#

-
-
-
-
-

Negative Prompt#

-

Negative Prompt 에 대한 Ablation Study 도 진행했습니다. 캐릭터의 부자연스러운 부분이나 저해상도 이미지들을 생성하는 경우들이 종종 발생했는데, negative prompt 를 통해 더 좋은 퀄리티의 웹툰 캐릭터를 생성할 수 있었습니다.

-
    -
  • Inference Prompt: ” A photo of sks girl with pink hair” (w/o negative prompt)

  • -
-
-swjo_exp_03 -
-

Fig. 206 Without Negative Prompt#

-
-
-
    -
  • Inference Prompt: ” A photo of sks girl with pink hair”

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_04 -
-

Fig. 207 With Negative Prompt#

-
-
-
-
-

Instance Prompt / Guidance Scale#

-

DreamBooth 논문에서 제시한 instance prompt 외에 “A photo of a girl in the style of sks” 라는 prompt 로 학습을 시도해보기도 했습니다. sks 라는 unique identifier 에 특정 여자 캐릭터에 대한 정보뿐만 아니라 프리드로우 그림체 자체를 담아내기 위한 목적이였습니다.

-
# different instance prompt with prior-preservation loss
-****MODEL_NAME = “runwayml/stable-diffusion-v1-5”
-instance_prompt = "A photo of a girl in the style of sks"
-class_prompt = "A photo of a girl"
-
-!python3 train_dreambooth.py \
-  --pretrained_model_name_or_path=$MODEL_NAME \
-  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
-  --output_dir=$OUTPUT_DIR \
-  --revision="fp16" \
-  --with_prior_preservation --prior_loss_weight=1.0 \
-  --seed=1337 \
-  --resolution=512 \
-  --train_batch_size=1 \
-  --train_text_encoder \
-  --mixed_precision="fp16" \
-  --use_8bit_adam \
-  --gradient_accumulation_steps=1 --gradient_checkpointing \
-  --learning_rate=1e-6 \
-  --lr_scheduler="constant" \
-  --lr_warmup_steps=0 \
-  --num_class_images=200 \
-  --sample_batch_size=4 \
-  --max_train_steps=800 \
-  --save_interval=100 \
-  --save_sample_prompt="A photo of sks girl" \
-  --concepts_list="concepts_list.json"
-
-
-
# different instance prompt w/o ****prior-preservation loss
-****MODEL_NAME = “runwayml/stable-diffusion-v1-5”
-instance_prompt = "A photo of a girl in the style of sks"
-class_prompt = "A photo of a girl"
-
-!python3 train_dreambooth.py \
-  --pretrained_model_name_or_path=$MODEL_NAME \
-  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
-  --output_dir=$OUTPUT_DIR \
-  --revision="fp16" \
-  --with_prior_preservation --prior_loss_weight=0.0 \
-  --seed=1337 \
-  --resolution=512 \
-  --train_batch_size=1 \
-  --train_text_encoder \
-  --mixed_precision="fp16" \
-  --use_8bit_adam \
-  --gradient_accumulation_steps=1 --gradient_checkpointing \
-  --learning_rate=1e-6 \
-  --lr_scheduler="constant" \
-  --lr_warmup_steps=0 \
-  --num_class_images=200 \
-  --sample_batch_size=4 \
-  --max_train_steps=800 \
-  --save_interval=100 \
-  --save_sample_prompt="A photo of sks girl" \
-  --concepts_list="concepts_list.json"
-
-
-

Inference 시, 프리드로우의 그림체가 반영된 남자가 생성되도록 prompt 를 “A photo of a boy in the style of sks” 로 입력했을때의 결과입니다. DreamBooth 혹은 사전학습된 text-to-image 모델을 프리드로우 작가님의 웹툰 장면들로 전체적으로 학습하게 된다면 더 다양한 inference 결과들을 볼 수 있을 것 같습니다.

-
    -
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 24 / with prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_05 -
-

Fig. 208 Instance Prompt#

-
-
-

Inference step 을 늘려가면서 추론된 인물 이미지의 퀄리티가 상승하는 부분도 확인할 수 있었습니다. 또한, guidance scale 에 대한 실험도 진행했는데 guidance scale 이 작을수록 prompt 와 무관한 random 한 이미지들을 생성하게 됩니다. 최종적으로 num_inference steps 와 guidance scale 의 값은 각각 100 과 7.5 로 설정하였습니다.

-
    -
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps=100 / with prior-preservation loss)

  • -
-
-swjo_exp_06 -
-

Fig. 209 Increasing Number of Inference Steps#

-
-
-
    -
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_07 -
-

Fig. 210 Increasing Number of Inference Steps / Negative Prompt#

-
-
-
    -
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -

    + guidance_scale = 4

    -
  • -
-
-swjo_exp_08 -
-

Fig. 211 Guidance Scale#

-
-
-

동일한 inference prompt 로 prior-preservation loss 를 제외해본 결과, 생성된 남자의 머리카락이 더 길어지고 더 여성스러운 생김새를 가지는 놀라운 사실도 발견했습니다.

-
    -
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_09 -
-

Fig. 212 Without Prior Preservation Loss#

-
-
-
-
-
-

Appendix#

-

그 외 다양한 inference prompt 에 따른 재미있는 실험결과들을 공유합니다. 아직 손의 모양을 text-to-image 모델이 생성하지 못하는 부분도 재차 확인할 수 있었습니다.

-
    -
  • Inference Prompt: “A photo of a boy climbing up the mountain in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_10 -
-

Fig. 213 Appendix 1#

-
-
-
    -
  • Inference Prompt: “A painting of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_11 -
-

Fig. 214 Appendix 2#

-
-
-
    -
  • Inference Prompt: “A hand drawing of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    -

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    -
  • -
-
-swjo_exp_12 -
-

Fig. 215 Appendix 3#

-
-
-

마지막으로 하단의 좌측과 우측 사진은 각각 “A photo of sks girl” 그리고 “A photo of a girl in the style of sks” 이라는 prompt 로 DreamBooth 모델을 각각 학습한 후, 나비를 생성하라는 동일한 prompt 로 추론해본 결과입니다. sks 가 수식하는 명사가 girl 이 아닌 style 이도록 prompt 를 수정함으로써, butterfly 사진을 생성할때 조금이나마 더 프리드로우 웹툰의 그림체를 반영할 수 있었던 부분도 확인할 수 있었습니다.

-
    -
  • Inference Prompt: “A photo of a butterfly in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

  • -
-
-swjo_exp_13 -
-

Fig. 216 Appendix 4#

-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Training DreamBooth on Naver Webtoon Face Dataset — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Training DreamBooth on Naver Webtoon Face Dataset

+ +
+ +
+
+ + + + +
+ +
+

Information

+
    +
  • Title: Training DreamBooth on Naver Webtoon Face Dataset

  • +
  • Author: Sangwoo Jo

  • +
  • Last updated on Jul. 09, 2023

  • +
+
+
+

Training DreamBooth on Naver Webtoon Face Dataset#

+
+

Introduction#

+

이번 포스팅에서는 DreamBooth 를 직접 학습해보고 실험한 결과들을 공유할려고 합니다.

+

우선적으로 학습데이터는 bryandlee/naver-webtoon-data 에 공개된 YOLOv5 모델 및 Waifu2x 후처리 기법을 활용하여 프리드로우에 등장하는 인물 사진들을 수집했습니다. 논문에서는 3-5 장으로 fine-tuning 이 가능하다고 제시되어있지만, 인물 사진 같은 경우 더 많은 데이터로 학습하면 성능이 더 좋아져서 15-20 장의 이미지로 학습하였습니다. 학습한 이미지들 예시입니다.

+
+swjo_exp_01 +
+

Fig. 209 Training Data#

+
+
+

DreamBooth 를 실험하면서 대표적으로 instance prompt, guidance scale, negative prompt, 그리고 마지막으로 prior preservation loss 를 반영하는 정도를 조절하는 prior_loss_weight 를 바꿔가면서 학습해보았습니다. 사전학습된 text-to-image 모델로 처음에는 hakurei/waifu-diffusion 모델을 시도해봤지만 결과가 만족스럽지 못해 runwayml/stable-diffusion-v1-5 모델로 fine-tuning 작업을 진행했습니다.

+
+
+

Ablation Studies#

+
+

Prior Preservation Loss#

+

Prior Preservation Loss 를 제외한 동일한 configuration 으로 모델 학습한 결과입니다.

+
# with prior-preservation loss
+MODEL_NAME = “runwayml/stable-diffusion-v1-5”
+instance_prompt = "A photo of sks girl"
+class_prompt = "A photo of a girl"
+
+!python3 train_dreambooth.py \
+  --pretrained_model_name_or_path=$MODEL_NAME \
+  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
+  --output_dir=$OUTPUT_DIR \
+  --revision="fp16" \
+  --with_prior_preservation --prior_loss_weight=1.0 \
+  --seed=1337 \
+  --resolution=512 \
+  --train_batch_size=1 \
+  --train_text_encoder \
+  --mixed_precision="fp16" \
+  --use_8bit_adam \
+  --gradient_accumulation_steps=1 --gradient_checkpointing \
+  --learning_rate=1e-6 \
+  --lr_scheduler="constant" \
+  --lr_warmup_steps=0 \
+  --num_class_images=200 \
+  --sample_batch_size=4 \
+  --max_train_steps=800 \
+  --save_interval=100 \
+  --save_sample_prompt="A photo of sks girl" \
+  --concepts_list="concepts_list.json"
+
+
+
# w/o prior-preservation loss
+MODEL_NAME = “runwayml/stable-diffusion-v1-5”
+instance_prompt = "A photo of sks girl"
+class_prompt = "A photo of a girl"
+
+!python3 train_dreambooth.py \
+  --pretrained_model_name_or_path=$MODEL_NAME \
+  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
+  --output_dir=$OUTPUT_DIR \
+  --revision="fp16" \
+  --with_prior_preservation --prior_loss_weight=0.0 \
+  --seed=1337 \
+  --resolution=512 \
+  --train_batch_size=1 \
+  --train_text_encoder \
+  --mixed_precision="fp16" \
+  --use_8bit_adam \
+  --gradient_accumulation_steps=1 --gradient_checkpointing \
+  --learning_rate=1e-6 \
+  --lr_scheduler="constant" \
+  --lr_warmup_steps=0 \
+  --num_class_images=200 \
+  --sample_batch_size=4 \
+  --max_train_steps=800 \
+  --save_interval=100 \
+  --save_sample_prompt="A photo of sks girl" \
+  --concepts_list="concepts_list.json"
+
+
+

아래 그림처럼 동일한 inference prompt 를 입력했을 때, prior preservation loss 를 제외함으로써 input images 에 더 가까운 웹툰 사진들을 생성할 수 있었습니다. 또한, 핑크색 머리를 한 이민지 캐릭터를 어느 정도 잘 생성하는 부분도 확인할 수 있습니다.

+
    +
  • Inference Prompt: “A photo of sks girl with pink hair” (with prior-preservation loss)

  • +
+
+swjo_exp_02 +
+

Fig. 210 With Prior Preservation Loss#

+
+
+
    +
  • Inference Prompt: ” A photo of sks girl with pink hair” (w/o prior-preservation loss)

  • +
+
+swjo_exp_03 +
+

Fig. 211 Without Prior Preservation Loss#

+
+
+
+
+

Negative Prompt#

+

Negative Prompt 에 대한 Ablation Study 도 진행했습니다. 캐릭터의 부자연스러운 부분이나 저해상도 이미지들을 생성하는 경우들이 종종 발생했는데, negative prompt 를 통해 더 좋은 퀄리티의 웹툰 캐릭터를 생성할 수 있었습니다.

+
    +
  • Inference Prompt: ” A photo of sks girl with pink hair” (w/o negative prompt)

  • +
+
+swjo_exp_03 +
+

Fig. 212 Without Negative Prompt#

+
+
+
    +
  • Inference Prompt: ” A photo of sks girl with pink hair”

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_04 +
+

Fig. 213 With Negative Prompt#

+
+
+
+
+

Instance Prompt / Guidance Scale#

+

DreamBooth 논문에서 제시한 instance prompt 외에 “A photo of a girl in the style of sks” 라는 prompt 로 학습을 시도해보기도 했습니다. sks 라는 unique identifier 에 특정 여자 캐릭터에 대한 정보뿐만 아니라 프리드로우 그림체 자체를 담아내기 위한 목적이였습니다.

+
# different instance prompt with prior-preservation loss
+****MODEL_NAME = “runwayml/stable-diffusion-v1-5”
+instance_prompt = "A photo of a girl in the style of sks"
+class_prompt = "A photo of a girl"
+
+!python3 train_dreambooth.py \
+  --pretrained_model_name_or_path=$MODEL_NAME \
+  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
+  --output_dir=$OUTPUT_DIR \
+  --revision="fp16" \
+  --with_prior_preservation --prior_loss_weight=1.0 \
+  --seed=1337 \
+  --resolution=512 \
+  --train_batch_size=1 \
+  --train_text_encoder \
+  --mixed_precision="fp16" \
+  --use_8bit_adam \
+  --gradient_accumulation_steps=1 --gradient_checkpointing \
+  --learning_rate=1e-6 \
+  --lr_scheduler="constant" \
+  --lr_warmup_steps=0 \
+  --num_class_images=200 \
+  --sample_batch_size=4 \
+  --max_train_steps=800 \
+  --save_interval=100 \
+  --save_sample_prompt="A photo of sks girl" \
+  --concepts_list="concepts_list.json"
+
+
+
# different instance prompt w/o ****prior-preservation loss
+****MODEL_NAME = “runwayml/stable-diffusion-v1-5”
+instance_prompt = "A photo of a girl in the style of sks"
+class_prompt = "A photo of a girl"
+
+!python3 train_dreambooth.py \
+  --pretrained_model_name_or_path=$MODEL_NAME \
+  --pretrained_vae_name_or_path="stabilityai/sd-vae-ft-mse" \
+  --output_dir=$OUTPUT_DIR \
+  --revision="fp16" \
+  --with_prior_preservation --prior_loss_weight=0.0 \
+  --seed=1337 \
+  --resolution=512 \
+  --train_batch_size=1 \
+  --train_text_encoder \
+  --mixed_precision="fp16" \
+  --use_8bit_adam \
+  --gradient_accumulation_steps=1 --gradient_checkpointing \
+  --learning_rate=1e-6 \
+  --lr_scheduler="constant" \
+  --lr_warmup_steps=0 \
+  --num_class_images=200 \
+  --sample_batch_size=4 \
+  --max_train_steps=800 \
+  --save_interval=100 \
+  --save_sample_prompt="A photo of sks girl" \
+  --concepts_list="concepts_list.json"
+
+
+

Inference 시, 프리드로우의 그림체가 반영된 남자가 생성되도록 prompt 를 “A photo of a boy in the style of sks” 로 입력했을때의 결과입니다. DreamBooth 혹은 사전학습된 text-to-image 모델을 프리드로우 작가님의 웹툰 장면들로 전체적으로 학습하게 된다면 더 다양한 inference 결과들을 볼 수 있을 것 같습니다.

+
    +
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 24 / with prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_05 +
+

Fig. 214 Instance Prompt#

+
+
+

Inference step 을 늘려가면서 추론된 인물 이미지의 퀄리티가 상승하는 부분도 확인할 수 있었습니다. 또한, guidance scale 에 대한 실험도 진행했는데 guidance scale 이 작을수록 prompt 와 무관한 random 한 이미지들을 생성하게 됩니다. 최종적으로 num_inference steps 와 guidance scale 의 값은 각각 100 과 7.5 로 설정하였습니다.

+
    +
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps=100 / with prior-preservation loss)

  • +
+
+swjo_exp_06 +
+

Fig. 215 Increasing Number of Inference Steps#

+
+
+
    +
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_07 +
+

Fig. 216 Increasing Number of Inference Steps / Negative Prompt#

+
+
+
    +
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +

    + guidance_scale = 4

    +
  • +
+
+swjo_exp_08 +
+

Fig. 217 Guidance Scale#

+
+
+

동일한 inference prompt 로 prior-preservation loss 를 제외해본 결과, 생성된 남자의 머리카락이 더 길어지고 더 여성스러운 생김새를 가지는 놀라운 사실도 발견했습니다.

+
    +
  • Inference Prompt: “A photo of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_09 +
+

Fig. 218 Without Prior Preservation Loss#

+
+
+
+
+
+

Appendix#

+

그 외 다양한 inference prompt 에 따른 재미있는 실험결과들을 공유합니다. 아직 손의 모양을 text-to-image 모델이 생성하지 못하는 부분도 재차 확인할 수 있었습니다.

+
    +
  • Inference Prompt: “A photo of a boy climbing up the mountain in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_10 +
+

Fig. 219 Appendix 1#

+
+
+
    +
  • Inference Prompt: “A painting of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_11 +
+

Fig. 220 Appendix 2#

+
+
+
    +
  • Inference Prompt: “A hand drawing of a boy in the style of sks” (num_inference_steps = 100 / w/o prior-preservation loss)

    +

    + Negative Prompt: “ugly, disfigured, deformed, low resolution”

    +
  • +
+
+swjo_exp_12 +
+

Fig. 221 Appendix 3#

+
+
+

마지막으로 하단의 좌측과 우측 사진은 각각 “A photo of sks girl” 그리고 “A photo of a girl in the style of sks” 이라는 prompt 로 DreamBooth 모델을 각각 학습한 후, 나비를 생성하라는 동일한 prompt 로 추론해본 결과입니다. sks 가 수식하는 명사가 girl 이 아닌 style 이도록 prompt 를 수정함으로써, butterfly 사진을 생성할때 조금이나마 더 프리드로우 웹툰의 그림체를 반영할 수 있었던 부분도 확인할 수 있었습니다.

+
    +
  • Inference Prompt: “A photo of a butterfly in the style of sks” (num_inference_steps = 100 / with prior-preservation loss)

  • +
+
+swjo_exp_13 +
+

Fig. 222 Appendix 4#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/markdown-example.html b/docs/markdown-example.html old mode 100644 new mode 100755 index feff5461..c64bc3a9 --- a/docs/markdown-example.html +++ b/docs/markdown-example.html @@ -1,332 +1,332 @@ - - - - - - - - This is an h1 tag — PseudoLab [Study Name] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- -
- - - - - - - - - - - - - - - - -
- - -
- -
- Contents -
- - -
-
-
-
- -
- -

Jupyter Book은 markdown 문서를 지원합니다.

-

아래와 같은 예시 코드를 입력하면 markdown 문법이 적용됩니다.

-
# This is an h1 tag
-## This is an h2 tag
-###### This is an h6 tag
-
-*This text will be italic*
-_This will also be italic_
-
-**This text will be bold**
-__This will also be bold__
-
-_You **can** combine them_
-
-* Item 1
-* Item 2
-  * Item 2a
-  * Item 2b
-
-1. Item 1
-1. Item 2
-1. Item 3
-   1. Item 3a
-   1. Item 3b
-
-
-

입력 결과

-
-

This is an h1 tag

-
-

This is an h2 tag

-
-

This is an h6 tag

-

This text will be italic -This will also be italic

-

This text will be bold -This will also be bold

-

You can combine them

-
    -
  • Item 1

  • -
  • Item 2

    -
      -
    • Item 2a

    • -
    • Item 2b

    • -
    -
  • -
-
    -
  1. Item 1

  2. -
  3. Item 2

  4. -
  5. Item 3

    -
      -
    1. Item 3a

    2. -
    3. Item 3b

    4. -
    -
  6. -
-
-
-
- - - - -
- -
-
- - - -
-
-

- - By PseudoLab
- - © Copyright 2020.
-

-
-
-
- - -
-
- - - - - - - + + + + + + + + This is an h1 tag — PseudoLab [Study Name] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + +
+ + +
+ +
+ Contents +
+ + +
+
+
+
+ +
+ +

Jupyter Book은 markdown 문서를 지원합니다.

+

아래와 같은 예시 코드를 입력하면 markdown 문법이 적용됩니다.

+
# This is an h1 tag
+## This is an h2 tag
+###### This is an h6 tag
+
+*This text will be italic*
+_This will also be italic_
+
+**This text will be bold**
+__This will also be bold__
+
+_You **can** combine them_
+
+* Item 1
+* Item 2
+  * Item 2a
+  * Item 2b
+
+1. Item 1
+1. Item 2
+1. Item 3
+   1. Item 3a
+   1. Item 3b
+
+
+

입력 결과

+
+

This is an h1 tag

+
+

This is an h2 tag

+
+

This is an h6 tag

+

This text will be italic +This will also be italic

+

This text will be bold +This will also be bold

+

You can combine them

+
    +
  • Item 1

  • +
  • Item 2

    +
      +
    • Item 2a

    • +
    • Item 2b

    • +
    +
  • +
+
    +
  1. Item 1

  2. +
  3. Item 2

  4. +
  5. Item 3

    +
      +
    1. Item 3a

    2. +
    3. Item 3b

    4. +
    +
  6. +
+
+
+
+ + + + +
+ +
+
+ + + +
+
+

+ + By PseudoLab
+ + © Copyright 2020.
+

+
+
+
+ + +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/notebook-example.html b/docs/notebook-example.html old mode 100644 new mode 100755 index c843e403..16805566 --- a/docs/notebook-example.html +++ b/docs/notebook-example.html @@ -1,286 +1,286 @@ - - - - - - - - .ipynb 파일 활용 — PseudoLab [Study Name] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- -
- - - - - - - - - - - - - - - - - - -
- - -
- -
-
-
-
- -
- -
-

.ipynb 파일 활용

-

Jupyter Book에선 .ipynb파일 또한 지원합니다. 아래와 같이 코드를 입력하고, 그에 대응하는 출력물을 함께 웹페이지로 구성 가능합니다.

-
-
-
import matplotlib.pyplot as plt
-
-plt.plot([3,1,2,1,3])
-
-
-
-
-
[<matplotlib.lines.Line2D at 0x21ff8e508e0>]
-
-
-../_images/notebook-example_2_1.png -
-
-

공식 홈페이지를 참고하여 interactive한 시각화도 가능합니다.

-
- - - - -
- -
-
- - - -
-
-

- - By PseudoLab
- - © Copyright 2020.
-

-
-
-
- - -
-
- - - - - - - + + + + + + + + .ipynb 파일 활용 — PseudoLab [Study Name] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
+ +
+ +
+

.ipynb 파일 활용

+

Jupyter Book에선 .ipynb파일 또한 지원합니다. 아래와 같이 코드를 입력하고, 그에 대응하는 출력물을 함께 웹페이지로 구성 가능합니다.

+
+
+
import matplotlib.pyplot as plt
+
+plt.plot([3,1,2,1,3])
+
+
+
+
+
[<matplotlib.lines.Line2D at 0x21ff8e508e0>]
+
+
+../_images/notebook-example_2_1.png +
+
+

공식 홈페이지를 참고하여 interactive한 시각화도 가능합니다.

+
+ + + + +
+ +
+
+ + + +
+
+

+ + By PseudoLab
+ + © Copyright 2020.
+

+
+
+
+ + +
+
+ + + + + + + \ No newline at end of file diff --git a/docs/review/ControlNet.html b/docs/review/ControlNet.html old mode 100644 new mode 100755 index 3bfb3d39..8995cd56 --- a/docs/review/ControlNet.html +++ b/docs/review/ControlNet.html @@ -1,735 +1,743 @@ - - - - - - - - - - - - ControlNet — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

ControlNet#

-
-

Additional Control with Image-based condition#

-

기존의 Text-to-Image 모델들은 text prompt로 생성할 이미지의 특징을 조절할 수 있었습니다. 하지만 이런 prompt-based control만으로 이미지의 특징을 조절하는데 한계가 있었습니다. 이 논문에서는 image-based condition을 추가적으로 줘서 생성되는 이미지의 특징을 더 잘 조절하는 ControlNet이라는 신경망 구조를 제안합니다.

-

아래 그림은 “a high quality, detailed, and professional image”라는 prompt와 왼쪽 아래의 Canny edge를 input으로 받아서 오른쪽의 이미지들을 생성한 것입니다. 이런 식으로 추가적인 image-based condition (아래 그림에서는 Canny edge)를 input으로 받아 이미지를 생성하는 것이 ControlNet이 하는 역할입니다.

-
-stylegan_01 -
-

Fig. 97 Images generated by ConrolNet#

-
-
-

그러면 어떤 구조를 사용해서 이를 가능하게 했을까요? 이제부터 이에 대해 알아보도록 하겠습니다.

-
-
-

ControlNet Block#

-

ControlNet의 block 구조는 다음과 같은 두 가지 특징을 가집니다.

-
    -
  1. pretrained model의 locked copy와 trainable copy를 사용

  2. -
  3. zero convolution

  4. -
-
-stylegan_01 -
-

Fig. 98 ConrolNet block#

-
-
-

왜 이렇게 설계했는지 알아봅시다.

-

우선, copy를 사용하는 이유는 기존에 방대한 양의 데이터로 학습시킨 pretrained model의 성능을 유지하기 위해서입니다. 또한, ControlNet의 학습 데이터가 양이 적은 경우에 오버피팅을 피할 수 있는 효과도 있을 것입니다.

-

zero convolution이란 weight랑 bias가 0으로 초기화한 1x1 convolution을 말합니다. zero convolution을 사용할 경우 훈련이 시작되기 전에는 input에 대해 pretrained model과 ControlNet의 output이 똑같아집니다. 따라서 기존 모델이랑 똑같은 input, output을 가지게되므로 기존 모델의 성능을 유지할 수 있으며, 추가적인 훈련이 fine tuning을 하는 것과 비슷하므로 scratch부터 학습하는 것에 비해 빠르게 훈련시킬 수 있게됩니다.

-

그러면 zero convolution은 어떻게 이를 가능하게 하는지 좀 더 자세히 알아봅시다.

-
-
-

Zero Convolution#

-

먼저 위의 그림에서 (a)에 해당하는 부분을 아래와 같이 수식으로 표현하겠습니다.

-
-\[ -\mathbf{y}=\mathcal{F}(\mathbf{x};\Theta) -\]
-

\(\mathbf{x}\)는 input feature map, \(\mathcal{F}\)는 neural network block, \(\Theta\)\(\mathcal{F}\)의 parameter, \(\mathbf{y}\)는 output을 의미합니다. 위 그림의 (b)를 수식으로 표현하기위해 \(\mathcal{F}\)의 trainable copy를 만들어서 parameter를 \(\Theta_{c}\)라고하고 \(\Theta\)는 고정시켜두겠습니다. 또한, zero convolution은 \(\mathcal{Z}\)로 표현하고 두 zero convolution의 parameter를 각각 \(\Theta_{z1}, \Theta_{z2}\)로 두겠습니다. 그러면 (b)에서 condition \(\mathbf{c}\)에 대한 output \(\mathbf{y}_{c}\)는 아래와 같이 표현할 수 있습니다.

-
-\[ -\mathbf{y}_{c}=\mathcal{F}(\mathbf{x};\Theta)+\mathcal{Z}(\mathcal{F}(\mathbf{x}+\mathcal{Z}(\mathbf{c};\Theta_{z1});\Theta_{c});\Theta_{z2}) -\]
-

그런데 \(\mathcal{Z}\)의 weight와 bias의 초깃값이 0이므로 훈련이 진행되지 않았을 경우 \(\mathbf{y}_{c}=\mathbf{y}\)입니다. 따라서 훈련 시작 전에는 ControlNet과 기존 모델이 같은 결과를 내므로 기존 모델의 성능을 보존할 수 있습니다.

-

그런데 weight랑 bias가 전부 0으로 초기화되어있으면 gradient가 0이라서 훈련이 안 되는거 아닐까요? 이를 확인하기 위해 다음과 같이 간단한 경우를 생각해보죠.

-
-\[ -y=wx+b -\]
-

gradient는 다음과 같습니다.

-
-\[ -\frac{\partial y}{\partial w}=x,\; \frac{\partial y}{\partial x}=w,\; \frac{\partial y}{\partial b}=1 -\]
-

weight랑 bias가 0이고, \(x\neq0\)이라고 하면

-
-\[ -\frac{\partial y}{\partial w}\neq0,\; \frac{\partial y}{\partial x}=0,\; \frac{\partial y}{\partial b}\neq0 -\]
-

입니다. 따라서 첫 번째 gradient step에서 weight는 0이 아닌 값으로 가게되고, \(\frac{\partial y}{\partial x}\neq0\)이 되므로 훈련이 됩니다. 여기서 핵심적인 가정이 \(x\neq0\)인데 이 부분은 잘 훈련된 pretrained model을 사용하고 있기 때문에 위배될 가능성이 낮을 것입니다.

-

지금까지 얘기한 ControlNet block 구조를 pretrained Stable diffusion에 적용한 전체 구조는 아래 그림과 같습니다.

-
-stylegan_01 -
-

Fig. 99 Overall structure#

-
-
-
-
-

Training & Results#

-

training loss는 기존 stable diffusion에서 image-based condition \(\mathbf{c}_{f}\)가 추가된 형태입니다.

-
-stylegan_01 -
-

Fig. 100 Loss#

-
-
-

training을 할 때 50%의 확률로 prompt \(\mathbf{c}_{t}\)를 empty string으로 바꿔주었다고 합니다. 이는 prompt가 주어지지않을 경우 모델이 \(\mathbf{c}_{f}\)로부터 semantics를 더 배우는 경향이 있기 때문에 이미지 생성을 \(\mathbf{c}_{f}\)로 조절하는 능력을 향상시켜줄 수 있다고 합니다.

-

아래 결과는 training이 기존 방법보다 효율적이라는 것을 보여줍니다.

-
-stylegan_01 -
-

Fig. 101 Efficiency#

-
-
-

아래 결과들은 task에 따른 결과들입니다. 더 많은 이미지들이 논문에 있으니 참고하시기 바랍니다.

-
-stylegan_01 -
-

Fig. 102 Pose#

-
-
-
-stylegan_01 -
-

Fig. 103 Images generated by ConrolNet#

-
-
-

아래는 논문에서 limitation이라고 언급한 이미지입니다. 텍스트로 추가적인 정보를 주었음에도 원하는 이미지가 생성되지 않는 경우가 발생했습니다.

-
-stylegan_01 -
-

Fig. 104 Limitations#

-
-
-
-
-

Implementation#

-

코드는 공식 구현(링크)에서 가져왔습니다. 아래 코드는 parameter를 0으로 초기화하는 코드로 zero convolution을 만들 때 사용됩니다.

-
def zero_module(module):
-    """
-    Zero out the parameters of a module and return it.
-    """
-    for p in module.parameters():
-        p.detach().zero_()
-    return module
-
-
-

아래 코드는 기본적으로 nn.Sequential과 같은데 time step같은 추가적인 input을 받아줄 수 있게 만든 것입니다.

-
class TimestepEmbedSequential(nn.Sequential, TimestepBlock):
-    """
-    A sequential module that passes timestep embeddings to the children that
-    support it as an extra input.
-    """
-
-    def forward(self, x, emb, context=None):
-        for layer in self:
-            if isinstance(layer, TimestepBlock):
-                x = layer(x, emb)
-            elif isinstance(layer, SpatialTransformer):
-                x = layer(x, context)
-            else:
-                x = layer(x)
-        return x
-
-
-

아래 코드는 공식 github의 cldm/cldm.py에 있는 ControlNet class입니다. init 부분은 길어서 생략했습니다.

-
class ControlNet(nn.Module):
-    def __init__(...):
-			...
-
-		def make_zero_conv(self, channels):
-        return TimestepEmbedSequential(zero_module(conv_nd(self.dims, channels, channels, 1, padding=0)))
-
-    def forward(self, x, hint, timesteps, context, **kwargs):
-        t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False)
-        emb = self.time_embed(t_emb)
-
-        guided_hint = self.input_hint_block(hint, emb, context)
-
-        outs = []
-
-        h = x.type(self.dtype)
-        for module, zero_conv in zip(self.input_blocks, self.zero_convs):
-            if guided_hint is not None:
-                h = module(h, emb, context)
-                h += guided_hint
-                guided_hint = None
-            else:
-                h = module(h, emb, context)
-            outs.append(zero_conv(h, emb, context))
-
-        h = self.middle_block(h, emb, context)
-        outs.append(self.middle_block_out(h, emb, context))
-
-        return outs
-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + ControlNet — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

ControlNet#

+
+

Additional Control with Image-based condition#

+

기존의 Text-to-Image 모델들은 text prompt로 생성할 이미지의 특징을 조절할 수 있었습니다. 하지만 이런 prompt-based control만으로 이미지의 특징을 조절하는데 한계가 있었습니다. 이 논문에서는 image-based condition을 추가적으로 줘서 생성되는 이미지의 특징을 더 잘 조절하는 ControlNet이라는 신경망 구조를 제안합니다.

+

아래 그림은 “a high quality, detailed, and professional image”라는 prompt와 왼쪽 아래의 Canny edge를 input으로 받아서 오른쪽의 이미지들을 생성한 것입니다. 이런 식으로 추가적인 image-based condition (아래 그림에서는 Canny edge)를 input으로 받아 이미지를 생성하는 것이 ControlNet이 하는 역할입니다.

+
+stylegan_01 +
+

Fig. 97 Images generated by ConrolNet#

+
+
+

그러면 어떤 구조를 사용해서 이를 가능하게 했을까요? 이제부터 이에 대해 알아보도록 하겠습니다.

+
+
+

ControlNet Block#

+

ControlNet의 block 구조는 다음과 같은 두 가지 특징을 가집니다.

+
    +
  1. pretrained model의 locked copy와 trainable copy를 사용

  2. +
  3. zero convolution

  4. +
+
+stylegan_01 +
+

Fig. 98 ConrolNet block#

+
+
+

왜 이렇게 설계했는지 알아봅시다.

+

우선, copy를 사용하는 이유는 기존에 방대한 양의 데이터로 학습시킨 pretrained model의 성능을 유지하기 위해서입니다. 또한, ControlNet의 학습 데이터가 양이 적은 경우에 오버피팅을 피할 수 있는 효과도 있을 것입니다.

+

zero convolution이란 weight랑 bias가 0으로 초기화한 1x1 convolution을 말합니다. zero convolution을 사용할 경우 훈련이 시작되기 전에는 input에 대해 pretrained model과 ControlNet의 output이 똑같아집니다. 따라서 기존 모델이랑 똑같은 input, output을 가지게되므로 기존 모델의 성능을 유지할 수 있으며, 추가적인 훈련이 fine tuning을 하는 것과 비슷하므로 scratch부터 학습하는 것에 비해 빠르게 훈련시킬 수 있게됩니다.

+

그러면 zero convolution은 어떻게 이를 가능하게 하는지 좀 더 자세히 알아봅시다.

+
+
+

Zero Convolution#

+

먼저 위의 그림에서 (a)에 해당하는 부분을 아래와 같이 수식으로 표현하겠습니다.

+
+\[ +\mathbf{y}=\mathcal{F}(\mathbf{x};\Theta) +\]
+

\(\mathbf{x}\)는 input feature map, \(\mathcal{F}\)는 neural network block, \(\Theta\)\(\mathcal{F}\)의 parameter, \(\mathbf{y}\)는 output을 의미합니다. 위 그림의 (b)를 수식으로 표현하기위해 \(\mathcal{F}\)의 trainable copy를 만들어서 parameter를 \(\Theta_{c}\)라고하고 \(\Theta\)는 고정시켜두겠습니다. 또한, zero convolution은 \(\mathcal{Z}\)로 표현하고 두 zero convolution의 parameter를 각각 \(\Theta_{z1}, \Theta_{z2}\)로 두겠습니다. 그러면 (b)에서 condition \(\mathbf{c}\)에 대한 output \(\mathbf{y}_{c}\)는 아래와 같이 표현할 수 있습니다.

+
+\[ +\mathbf{y}_{c}=\mathcal{F}(\mathbf{x};\Theta)+\mathcal{Z}(\mathcal{F}(\mathbf{x}+\mathcal{Z}(\mathbf{c};\Theta_{z1});\Theta_{c});\Theta_{z2}) +\]
+

그런데 \(\mathcal{Z}\)의 weight와 bias의 초깃값이 0이므로 훈련이 진행되지 않았을 경우 \(\mathbf{y}_{c}=\mathbf{y}\)입니다. 따라서 훈련 시작 전에는 ControlNet과 기존 모델이 같은 결과를 내므로 기존 모델의 성능을 보존할 수 있습니다.

+

그런데 weight랑 bias가 전부 0으로 초기화되어있으면 gradient가 0이라서 훈련이 안 되는거 아닐까요? 이를 확인하기 위해 다음과 같이 간단한 경우를 생각해보죠.

+
+\[ +y=wx+b +\]
+

gradient는 다음과 같습니다.

+
+\[ +\frac{\partial y}{\partial w}=x,\; \frac{\partial y}{\partial x}=w,\; \frac{\partial y}{\partial b}=1 +\]
+

weight랑 bias가 0이고, \(x\neq0\)이라고 하면

+
+\[ +\frac{\partial y}{\partial w}\neq0,\; \frac{\partial y}{\partial x}=0,\; \frac{\partial y}{\partial b}\neq0 +\]
+

입니다. 따라서 첫 번째 gradient step에서 weight는 0이 아닌 값으로 가게되고, \(\frac{\partial y}{\partial x}\neq0\)이 되므로 훈련이 됩니다. 여기서 핵심적인 가정이 \(x\neq0\)인데 이 부분은 잘 훈련된 pretrained model을 사용하고 있기 때문에 위배될 가능성이 낮을 것입니다.

+

지금까지 얘기한 ControlNet block 구조를 pretrained Stable diffusion에 적용한 전체 구조는 아래 그림과 같습니다.

+
+stylegan_01 +
+

Fig. 99 Overall structure#

+
+
+
+
+

Training & Results#

+

training loss는 기존 stable diffusion에서 image-based condition \(\mathbf{c}_{f}\)가 추가된 형태입니다.

+
+stylegan_01 +
+

Fig. 100 Loss#

+
+
+

training을 할 때 50%의 확률로 prompt \(\mathbf{c}_{t}\)를 empty string으로 바꿔주었다고 합니다. 이는 prompt가 주어지지않을 경우 모델이 \(\mathbf{c}_{f}\)로부터 semantics를 더 배우는 경향이 있기 때문에 이미지 생성을 \(\mathbf{c}_{f}\)로 조절하는 능력을 향상시켜줄 수 있다고 합니다.

+

아래 결과는 training이 기존 방법보다 효율적이라는 것을 보여줍니다.

+
+stylegan_01 +
+

Fig. 101 Efficiency#

+
+
+

아래 결과들은 task에 따른 결과들입니다. 더 많은 이미지들이 논문에 있으니 참고하시기 바랍니다.

+
+stylegan_01 +
+

Fig. 102 Pose#

+
+
+
+stylegan_01 +
+

Fig. 103 Images generated by ConrolNet#

+
+
+

아래는 논문에서 limitation이라고 언급한 이미지입니다. 텍스트로 추가적인 정보를 주었음에도 원하는 이미지가 생성되지 않는 경우가 발생했습니다.

+
+stylegan_01 +
+

Fig. 104 Limitations#

+
+
+
+
+

Implementation#

+

코드는 공식 구현(링크)에서 가져왔습니다. 아래 코드는 parameter를 0으로 초기화하는 코드로 zero convolution을 만들 때 사용됩니다.

+
def zero_module(module):
+    """
+    Zero out the parameters of a module and return it.
+    """
+    for p in module.parameters():
+        p.detach().zero_()
+    return module
+
+
+

아래 코드는 기본적으로 nn.Sequential과 같은데 time step같은 추가적인 input을 받아줄 수 있게 만든 것입니다.

+
class TimestepEmbedSequential(nn.Sequential, TimestepBlock):
+    """
+    A sequential module that passes timestep embeddings to the children that
+    support it as an extra input.
+    """
+
+    def forward(self, x, emb, context=None):
+        for layer in self:
+            if isinstance(layer, TimestepBlock):
+                x = layer(x, emb)
+            elif isinstance(layer, SpatialTransformer):
+                x = layer(x, context)
+            else:
+                x = layer(x)
+        return x
+
+
+

아래 코드는 공식 github의 cldm/cldm.py에 있는 ControlNet class입니다. init 부분은 길어서 생략했습니다.

+
class ControlNet(nn.Module):
+    def __init__(...):
+			...
+
+		def make_zero_conv(self, channels):
+        return TimestepEmbedSequential(zero_module(conv_nd(self.dims, channels, channels, 1, padding=0)))
+
+    def forward(self, x, hint, timesteps, context, **kwargs):
+        t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False)
+        emb = self.time_embed(t_emb)
+
+        guided_hint = self.input_hint_block(hint, emb, context)
+
+        outs = []
+
+        h = x.type(self.dtype)
+        for module, zero_conv in zip(self.input_blocks, self.zero_convs):
+            if guided_hint is not None:
+                h = module(h, emb, context)
+                h += guided_hint
+                guided_hint = None
+            else:
+                h = module(h, emb, context)
+            outs.append(zero_conv(h, emb, context))
+
+        h = self.middle_block(h, emb, context)
+        outs.append(self.middle_block_out(h, emb, context))
+
+        return outs
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/CustomDiffusion.html b/docs/review/CustomDiffusion.html old mode 100644 new mode 100755 index 905807d3..3f88c29f --- a/docs/review/CustomDiffusion.html +++ b/docs/review/CustomDiffusion.html @@ -1,896 +1,904 @@ - - - - - - - - - - - - Custom Diffusion — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

-
    -
  • Title: {A Multi-Concept Customiziation of Text-To-Image Diffusion}, {VCPR 2023}

  • -
  • Reference

    - -
  • -
  • Author: Seunghwan Ji

  • -
  • Last updated on Aug. 6, 2023

  • -
-
-
-

Custom Diffusion#

-
-

학습 자료#

-

A Multi-Concept Customiziation of Text-To-Image Diffusion

-

https://arxiv.org/pdf/2212.04488.pdf

-

CVPR 2023. Adobe

-
-
-
-

Abstract#

-
    -
  • Large Scale Data를 학습한 Generate 모델이 뛰어난 성능을 보이는 추세

  • -
  • User의 Private한 Concept을 생성하고자하는 욕구는 여전히 풀지 못함

  • -
  • Custom Diffusion은?

    -
      -
    1. 기존 Diffusion 모델의 partial한 부분만을 학습시킴으로써 기존보다 더 빠른 finetuning 방식을 제안

    2. -
    3. Single Concept 뿐 아니라, Multiple Concept에 대한 학습이 가능

    4. -
    5. 다양한 Fine tuned 모델을 하나의 모델로 Compress하는 방식을 제안

    6. -
    -
  • -
-
-
-

1. Introduction#

-
    -
  • 최근 Text-To-Image 모델들이 활발하게 연구 되어짐

  • -
  • 단순한 text prompt 입력만으로 원하는 이미지를 생성해내는 수준까지 이름

  • -
  • 하지만 이러한 모델들은 General한 이미지는 잘 생성하지만, User가 원하는 Private한 (=specific) Concept의 이미지는 생성해내지 못함

    -
      -
    • e.g. 행복한 우리 가족 사진, 우리집 강아지 뽀삐가 파리로 여행을 떠나는 사진 등

    • -
    -
  • -
  • 학습 과정중에 User의 Private한 데이터를 보지 못했기때문에 Model에게는 당연한 결과

  • -
  • Customization

    -
      -
    • 몇장의 Concept을 포함하는 이미지만으로 Pretrained 모델을 finetuning하는 방식

      -
        -
      • In Dreambooth, Personalization

      • -
      -
    • -
    • 목표

      -
        -
      1. 학습하고자하는 Private한 Concept의 이미지를 잘 생성해내야함

      2. -
      3. 기존에 학습되었던 General한 이미지를 Finetuning한 후에도 잘 생성해내야함

      4. -
      -
    • -
    -
  • -
  • Customization이 어려운 이유

    -
      -
    1. 학습을 진행하다보면 기존에 학습했던 Concept을 잊어버리거나 왜곡해버림 → Language Draft

    2. -
    3. 새로운 Concept에 대해 모델이 Overfit 되어서 결과물의 Variation이 낮아짐

    4. -
    5. 좀더 나아가 Single Concept 뿐 아니라 Multiple Concept에 대한 Finetuning 또한 어려움

    6. -
    -
  • -
  • Custom Diffusion은?

    -
      -
    1. Text로 Condition을 생성해내는 과정 중 특정 부분만을 학습

    2. -
    3. General Concept의 성능 유지를 위해 real image와 해당 이미지의 caption을 regularization Data로 사용

    4. -
    5. fine tuning동안 새로운 augmentation 기법을 소개

    6. -
    7. Multiple concept의 학습 방식을 제안

    8. -
    -
  • -
-
- -
-

3. Method#

-
-

Single Concept Fine-tuning#

-
    -
  • Backbone으로 Latent Diffusion Model을 채택

  • -
  • (L)DM의 학습 Concept

    -
    -CD_00 -
    -

    Fig. 123 Equation 0#

    -
    -
    -
      -
    • \(x_{t}\) : time t 시점에 Noise가 섞인 이미지

    • -
    • \(t\) → timestep

    • -
    • \(c\) → conditioning feature (text, image 등)

      -
        -
      • text나 image를 바로 사용하지않고 latent space로 embedding된 값을 사용 (using CLIP)

      • -
      -
    • -
    • ε → noise

    • -
    • \(ε_{θ}\)\(x_{t}\)에 낀 noise ε를 예측해내는 모델

    • -
    • 즉, \(x_{t}\)에 낀 noise ε를 예측해내는 모델을 학습

    • -
    -
  • -
  • 이러한 LDM 모델을 fine tuning할때는 Model의 모든 Layer에대해 update하는게 기본

  • -
  • 하지만 이러한 finetuning 방식은 Resource가 비효율적으로 많이들고, 새로운 Concept 이미지에 overfitting되기 쉬움

  • -
  • Finetuning 과정 중 모델의 Weight 변화량을 체크

    -
    -CD_01 -
    -

    Fig. 124 Delta of Weight while Training#

    -
    -
    -
  • -
  • 다른 부분에비해 Cross Attention 연산의 Wegith 변화량이 가장 큼

  • -
  • Cross Attention

  • -
-
-CD_02 -
-

Fig. 125 Fig.4 Cross Attention#

-
-
-
    -
  • Cross Attention → Image latent에 text condition을 주입하는 Attention Mechanism

    -
      -
    • Query → image latent / Key, Value → text condition latent

    • -
    • 모델 전체 Parameter에 단 5%부분만을 차지

    • -
    • 이 중 new concept을 의미하는 Text \(V^{*}\)이 포함되는 \(W^{k}\)\(W^{v}\)만 학습. 나머지는 Freeze

    • -
    -
  • -
  • Fine Tuning할 때 \(V^{*}\)은 실제로는 잘 쓰지않는 단어로 사용하고 “A [\(V^{*}\)] [Class]” 형식으로 이미지를 Captioning한 후에 학습

  • -
  • 또 Finetuning중에 일반적인 concept을 잊어버리는 Language Draft 현상이 있을수있음

    -
      -
    • Language Draft

    • -
    -
    -CD_03 -
    -

    Fig. 126 Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림#

    -
    -
    -
  • -
-

Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림

-
    -
  • 이러한 현상을 방지하기위해 Real world의 Image에서 target text class prompt와 유사한 200장의 이미지를 Regulalization 이미지로 같이 학습

    -
      -
    • text prompt가 유사하다 = CLIP에서 추출한 text feature space상의 Vector가 Similar하다

    • -
    -
  • -
-
-
-

Multiple-Concept Compositional Fine-tuning#

-
    -
  • Joint Traning on multiple concept

    -
      -
    • 각각의 Concept을 갖는 이미지에 대해 각각 rare한 key를 부여해 동시에 학습

      -
        -
      • (\(V^{i}\), for \(i\) is # of concepts)

      • -
      -
    • -
    -
  • -
  • Constrained optimization to merge concepts

    -
      -
    • 각각 Single Concept으로 학습된 weight를 merge

    • -
    -
    -CD_04 -
    -

    Fig. 127 Equation 4#

    -
    -
    -
      -
    • \(W_0\) → pretrained model의 Key, Value embedding Weight

      -
        -
      • ~~(Appendix A에는 \(W\)라고 나와있는데 오탈자일 가능성 있음)~~

      • -
      -
    • -
    • \(C_{reg}\) → regularization 이미지의 Caption의 Embedding 값을 모두 뽑아 Concat

    • -
    • \(C_{reg}\)에 Pretrained Weight를 곱한 값과의 norm을 계산했을때 값이 가장 작은 Weight를 return

      -
        -
      • “N개의 Concept에 대해 Cross Attention이 모두 잘 동작하는 W 값을 찾아 하나만 사용하자”

      • -
      -
    • -
    -
  • -
-
-
-

Training Details#

-
    -
  • single concept의 경우 250 steps, two-concept의 경우 500 steps

  • -
  • batch : 8, learning rate : \(8*10^{-5}\)

  • -
  • random resize + prompt 추가 (very small, far away, zoom in …) (new augmentation technique)

  • -
-
-
-
-

4. Experiments#

-

Single Concept Finetuning

-
    -
  • Qualitative Evaluation

  • -
-
-CD_05 -
-

Fig. 128 Qualitative Evaluation#

-
-
-
    -
  • Quantative Evaluation (Text Alignment, Image Alignment, KID)

    -
      -
    • text alignment : prompt에 얼마나 대응되는 이미지를 생성해냈는가

    • -
    • image alignment : training image의 concept을 얼마나 잘 표현해냈는가

    • -
    -
  • -
-
-CD_06 -
-

Fig. 129 Table 1#

-
-
-

⇒ 정성적, 정량적 평가 모두 Custom Diffusion > Dreambooth, Textual Inversion

-

Multiple Concept Finetuning

-
-CD_07 -
-

Fig. 130 Multiple Concept Finetuning#

-
-
-
    -
  • Joint Training > Optimization by custom diffusion > Dreambooth

  • -
-

Human Preference Study

-
-CD_08 -
-

Fig. 131 Table 2#

-
-
-
    -
  • Custom Diffusion (partial) vs Baseline(Textual Inversion, Dreambooth, CustomDiffusion(all))

  • -
  • Text-Alignment, Image-Alignment 모두 Custom Diffusion (partial)을 선호

  • -
  • Textual Inversion은 Image Alignment는 Custom Diffusion 선호도와 비슷하지만 Text Alignment수치를 보면 Custom Diffusion이 매우 높아 Overfitting된 경향이 있음

  • -
-

Ablation Study

-
    -
  1. Regularization Image

    -
    -CD_09 -
    -

    Fig. 132 Table 3#

    -
    -
    -
  2. -
-
    -
  • ㅌGen : real image 대신 generate된 이미지를 regularization 이미지로 사용

  • -
  • Overfitting 없이 가장 좋은 수치는 Augmentation + Regulatization image as Real world Image

  • -
-
-
-

5. Discussion & Limitation#

-
    -
  • customizing이 가능하고 training resourse가 매우 적은 finetuning 기법 소개

  • -
-
-CD_10 -
-

Fig. 133 Limitation Of Custom Diffusion#

-
-
-
    -
  • 비슷한 category의 object에 대해서는 joint training, merge 모두 잘 동작하지 않음

  • -
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Custom Diffusion — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+
    +
  • Title: {A Multi-Concept Customiziation of Text-To-Image Diffusion}, {VCPR 2023}

  • +
  • Reference

    + +
  • +
  • Author: Seunghwan Ji

  • +
  • Last updated on Aug. 6, 2023

  • +
+
+
+

Custom Diffusion#

+
+

학습 자료#

+

A Multi-Concept Customiziation of Text-To-Image Diffusion

+

https://arxiv.org/pdf/2212.04488.pdf

+

CVPR 2023. Adobe

+
+
+
+

Abstract#

+
    +
  • Large Scale Data를 학습한 Generate 모델이 뛰어난 성능을 보이는 추세

  • +
  • User의 Private한 Concept을 생성하고자하는 욕구는 여전히 풀지 못함

  • +
  • Custom Diffusion은?

    +
      +
    1. 기존 Diffusion 모델의 partial한 부분만을 학습시킴으로써 기존보다 더 빠른 finetuning 방식을 제안

    2. +
    3. Single Concept 뿐 아니라, Multiple Concept에 대한 학습이 가능

    4. +
    5. 다양한 Fine tuned 모델을 하나의 모델로 Compress하는 방식을 제안

    6. +
    +
  • +
+
+
+

1. Introduction#

+
    +
  • 최근 Text-To-Image 모델들이 활발하게 연구 되어짐

  • +
  • 단순한 text prompt 입력만으로 원하는 이미지를 생성해내는 수준까지 이름

  • +
  • 하지만 이러한 모델들은 General한 이미지는 잘 생성하지만, User가 원하는 Private한 (=specific) Concept의 이미지는 생성해내지 못함

    +
      +
    • e.g. 행복한 우리 가족 사진, 우리집 강아지 뽀삐가 파리로 여행을 떠나는 사진 등

    • +
    +
  • +
  • 학습 과정중에 User의 Private한 데이터를 보지 못했기때문에 Model에게는 당연한 결과

  • +
  • Customization

    +
      +
    • 몇장의 Concept을 포함하는 이미지만으로 Pretrained 모델을 finetuning하는 방식

      +
        +
      • In Dreambooth, Personalization

      • +
      +
    • +
    • 목표

      +
        +
      1. 학습하고자하는 Private한 Concept의 이미지를 잘 생성해내야함

      2. +
      3. 기존에 학습되었던 General한 이미지를 Finetuning한 후에도 잘 생성해내야함

      4. +
      +
    • +
    +
  • +
  • Customization이 어려운 이유

    +
      +
    1. 학습을 진행하다보면 기존에 학습했던 Concept을 잊어버리거나 왜곡해버림 → Language Draft

    2. +
    3. 새로운 Concept에 대해 모델이 Overfit 되어서 결과물의 Variation이 낮아짐

    4. +
    5. 좀더 나아가 Single Concept 뿐 아니라 Multiple Concept에 대한 Finetuning 또한 어려움

    6. +
    +
  • +
  • Custom Diffusion은?

    +
      +
    1. Text로 Condition을 생성해내는 과정 중 특정 부분만을 학습

    2. +
    3. General Concept의 성능 유지를 위해 real image와 해당 이미지의 caption을 regularization Data로 사용

    4. +
    5. fine tuning동안 새로운 augmentation 기법을 소개

    6. +
    7. Multiple concept의 학습 방식을 제안

    8. +
    +
  • +
+
+ +
+

3. Method#

+
+

Single Concept Fine-tuning#

+
    +
  • Backbone으로 Latent Diffusion Model을 채택

  • +
  • (L)DM의 학습 Concept

    +
    +CD_00 +
    +

    Fig. 123 Equation 0#

    +
    +
    +
      +
    • \(x_{t}\) : time t 시점에 Noise가 섞인 이미지

    • +
    • \(t\) → timestep

    • +
    • \(c\) → conditioning feature (text, image 등)

      +
        +
      • text나 image를 바로 사용하지않고 latent space로 embedding된 값을 사용 (using CLIP)

      • +
      +
    • +
    • ε → noise

    • +
    • \(ε_{θ}\)\(x_{t}\)에 낀 noise ε를 예측해내는 모델

    • +
    • 즉, \(x_{t}\)에 낀 noise ε를 예측해내는 모델을 학습

    • +
    +
  • +
  • 이러한 LDM 모델을 fine tuning할때는 Model의 모든 Layer에대해 update하는게 기본

  • +
  • 하지만 이러한 finetuning 방식은 Resource가 비효율적으로 많이들고, 새로운 Concept 이미지에 overfitting되기 쉬움

  • +
  • Finetuning 과정 중 모델의 Weight 변화량을 체크

    +
    +CD_01 +
    +

    Fig. 124 Delta of Weight while Training#

    +
    +
    +
  • +
  • 다른 부분에비해 Cross Attention 연산의 Wegith 변화량이 가장 큼

  • +
  • Cross Attention

  • +
+
+CD_02 +
+

Fig. 125 Fig.4 Cross Attention#

+
+
+
    +
  • Cross Attention → Image latent에 text condition을 주입하는 Attention Mechanism

    +
      +
    • Query → image latent / Key, Value → text condition latent

    • +
    • 모델 전체 Parameter에 단 5%부분만을 차지

    • +
    • 이 중 new concept을 의미하는 Text \(V^{*}\)이 포함되는 \(W^{k}\)\(W^{v}\)만 학습. 나머지는 Freeze

    • +
    +
  • +
  • Fine Tuning할 때 \(V^{*}\)은 실제로는 잘 쓰지않는 단어로 사용하고 “A [\(V^{*}\)] [Class]” 형식으로 이미지를 Captioning한 후에 학습

  • +
  • 또 Finetuning중에 일반적인 concept을 잊어버리는 Language Draft 현상이 있을수있음

    +
      +
    • Language Draft

    • +
    +
    +CD_03 +
    +

    Fig. 126 Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림#

    +
    +
    +
  • +
+

Fine tuning 후에 Photo of a moon 이미지를 생성하면 Finetuning했던 Moongate 이미지를 생성해버림

+
    +
  • 이러한 현상을 방지하기위해 Real world의 Image에서 target text class prompt와 유사한 200장의 이미지를 Regulalization 이미지로 같이 학습

    +
      +
    • text prompt가 유사하다 = CLIP에서 추출한 text feature space상의 Vector가 Similar하다

    • +
    +
  • +
+
+
+

Multiple-Concept Compositional Fine-tuning#

+
    +
  • Joint Traning on multiple concept

    +
      +
    • 각각의 Concept을 갖는 이미지에 대해 각각 rare한 key를 부여해 동시에 학습

      +
        +
      • (\(V^{i}\), for \(i\) is # of concepts)

      • +
      +
    • +
    +
  • +
  • Constrained optimization to merge concepts

    +
      +
    • 각각 Single Concept으로 학습된 weight를 merge

    • +
    +
    +CD_04 +
    +

    Fig. 127 Equation 4#

    +
    +
    +
      +
    • \(W_0\) → pretrained model의 Key, Value embedding Weight

      +
        +
      • ~~(Appendix A에는 \(W\)라고 나와있는데 오탈자일 가능성 있음)~~

      • +
      +
    • +
    • \(C_{reg}\) → regularization 이미지의 Caption의 Embedding 값을 모두 뽑아 Concat

    • +
    • \(C_{reg}\)에 Pretrained Weight를 곱한 값과의 norm을 계산했을때 값이 가장 작은 Weight를 return

      +
        +
      • “N개의 Concept에 대해 Cross Attention이 모두 잘 동작하는 W 값을 찾아 하나만 사용하자”

      • +
      +
    • +
    +
  • +
+
+
+

Training Details#

+
    +
  • single concept의 경우 250 steps, two-concept의 경우 500 steps

  • +
  • batch : 8, learning rate : \(8*10^{-5}\)

  • +
  • random resize + prompt 추가 (very small, far away, zoom in …) (new augmentation technique)

  • +
+
+
+
+

4. Experiments#

+

Single Concept Finetuning

+
    +
  • Qualitative Evaluation

  • +
+
+CD_05 +
+

Fig. 128 Qualitative Evaluation#

+
+
+
    +
  • Quantative Evaluation (Text Alignment, Image Alignment, KID)

    +
      +
    • text alignment : prompt에 얼마나 대응되는 이미지를 생성해냈는가

    • +
    • image alignment : training image의 concept을 얼마나 잘 표현해냈는가

    • +
    +
  • +
+
+CD_06 +
+

Fig. 129 Table 1#

+
+
+

⇒ 정성적, 정량적 평가 모두 Custom Diffusion > Dreambooth, Textual Inversion

+

Multiple Concept Finetuning

+
+CD_07 +
+

Fig. 130 Multiple Concept Finetuning#

+
+
+
    +
  • Joint Training > Optimization by custom diffusion > Dreambooth

  • +
+

Human Preference Study

+
+CD_08 +
+

Fig. 131 Table 2#

+
+
+
    +
  • Custom Diffusion (partial) vs Baseline(Textual Inversion, Dreambooth, CustomDiffusion(all))

  • +
  • Text-Alignment, Image-Alignment 모두 Custom Diffusion (partial)을 선호

  • +
  • Textual Inversion은 Image Alignment는 Custom Diffusion 선호도와 비슷하지만 Text Alignment수치를 보면 Custom Diffusion이 매우 높아 Overfitting된 경향이 있음

  • +
+

Ablation Study

+
    +
  1. Regularization Image

    +
    +CD_09 +
    +

    Fig. 132 Table 3#

    +
    +
    +
  2. +
+
    +
  • ㅌGen : real image 대신 generate된 이미지를 regularization 이미지로 사용

  • +
  • Overfitting 없이 가장 좋은 수치는 Augmentation + Regulatization image as Real world Image

  • +
+
+
+

5. Discussion & Limitation#

+
    +
  • customizing이 가능하고 training resourse가 매우 적은 finetuning 기법 소개

  • +
+
+CD_10 +
+

Fig. 133 Limitation Of Custom Diffusion#

+
+
+
    +
  • 비슷한 category의 object에 대해서는 joint training, merge 모두 잘 동작하지 않음

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/DALLE2.html b/docs/review/DALLE2.html new file mode 100755 index 00000000..6cc4ddfd --- /dev/null +++ b/docs/review/DALLE2.html @@ -0,0 +1,958 @@ + + + + + + + + + + + + DALLE2 — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

DALLE2

+ +
+
+ +
+
+
+ + + + +
+ +
+

Information

+
    +
  • Title: Hierarchical Text-Conditional Image Generation with CLIP Latents (arXiv 2022)

  • +
  • Reference

    + +
  • +
  • Author: SeonHoon Kim

  • +
  • Last updated on Sep. 18, 2023

  • +
+
+
+

DALLE2#

+

DALLE2 는 2022년에 공개되어 세상을 놀라게 했습니다. +이미지 생성 능력도 뛰어났고, 이미지를 사용자 입맛에 맞게 조작할 수 있게 되었죠.

+

DALLE2 의 이름은 왜 DALL-E 일까요? +DALLE2 의 DALLE 는 초현실주의 화가 Salvador Dali 와 WALL-E 의 합성어입니다. +DALLE2 로 생성해낸 결과물이 과연 어떻길래 세상을 놀라게 했을까요?

+
    +
  • DALL-E 2 결과물

  • +
+

위 그림은 DALLE2 에게 “vibrant portrait of Salvador Dali with a robotic half face” 를 prompt 로 주고 생성해낸 이미지입니다. +실제 Salvador dali 의 모습이 보이네요. +게다가 Salvador dali 의 초현실주의적 그림체가 반영된 것 같기도 합니다. +놀라운 이미지입니다.

+

아래의 corgi 그림은 어떤가요 ?

+

corgi 의 모습을 성운의 폭발로 묘사해달라고 했을 때 생성된 그림입니다. +아래의 그림은, 실제 NASA 에서 촬영한 초신성 폭발의 잔해입니다.

+

정말 그럴듯하지 않나요?

+
    +
  • 학습 목표 및 주의사항

    +
      +
    • 해당 paper 요약은 DALL-E 2 paper, OpenAI blog, AssemblyAI Youtube, Eden Meyer Youtube 를 참고했습니다.

    • +
    • DALL-E 2 는 CLIP 과 Diffusion Model 을 통합시켰습니다. (최초는 x)

      +
        +
      • CLIP 은, 이미지와 text 를 학습한 multi-modal 모델입니다.

        +
          +
        • The fundamental principles of training CLIP are quite simple:

          +
            +
          1. First, all images and their associated captions are passed through their respective encoders, mapping all objects into an *m-*dimensional space.

          2. +
          3. Then, the cosine similarity of each (image, text) pair is computed.

          4. +
          5. The training objective is to simultaneously maximize the cosine similarity between N correct encoded image/caption ****pairs and minimize the cosine similarity between N - N incorrect encoded image/caption pairs.

          6. +
          +
        • +
        +
      • +
      +
    • +
    • 하지만 CLIP 을 사용하는 것이 정답은 아닙니다. +DALL-E 2 는 22년 5월, +CLIP 을 사용하지 않은 IMAGEN 에게 SOTA 를 내주었습니다.

    • +
    +
  • +
  • 아키텍쳐 찍먹하기

    +

    특정 이미지 내의 Semantics 와 style 을 모두 포착해낼 수 있는 +CLIP 의 이미지 표현 능력을 끌어올리기 위해서, +저자들은 CLIP 과 Diffusion 모델을 통합한 Two-stage model 을 제안합니다. +이것이 바로 DALLE2 인데요. 저자들은 이 모델을 unCLIP 이라고 부릅니다.

    +
  • +
+

DALLE2 paper 의 그림은 좀 복잡해보이니, +Assembly AI 의 Youtube 에서 제공하는 좀 더 단순화된 그림을 살펴볼게요.

+

https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI

+
- **Prior** : 텍스트 캡션을 받아서, 상응하는 CLIP image embedding 을 생성합니다.
+    - Autogregressive prior 와 Diffusion prior 를 비교하는 실험 수행했습니다.
+    - Diffusion prior 가 computationally efficient 하고, 고품질 이미지 생성합니다. 따라서 후반부에는 Diffusion prior 만 사용해서 실험합니다.
+- **Decoder** : CLIP image embedding 을 받아서, 이미지를 생성합니다.
+    - Diffusion 모델만 사용했습니다.
+
+
+
    +
  • 왜 CLIP 이랑 Diffusion 을 사용했을까요

    +
      +
    • CLIP

      +
        +
      • CLIP 이 images representation 을 학습하는데 에 큰 성공을 거두고 있었습니다.

      • +
      • CLIP embeddings 는 image distribution shift 에 robust 했습니다.

      • +
      • CLIP embeddings 는 zero-shot capabilities 가 뛰어났습니다.

      • +
      • 다양한 vision & language tasks 에 fine-tuned 되어 SOTA 를 달성해냈습니다.

      • +
      +
    • +
    • Diffusion

      +
        +
      • Diffusion 은 image 와 video generation taks 에서 SOTA 를 갱신하는 중이었죠.

      • +
      • non-deterministic 하게 만들 수 있습니다. +이러한 Decoder 덕분에, CLIP image embedding 과 같은 +image representation 에 존재하지 않는 non-essential 한 details변주하면서, +image representation 의 semantics 와 style 은 유지할 수 있죠.

      • +
      +
    • +
    +
  • +
+
    +
  • 아키텍쳐 설명 좀 자세히 해줘

    +

    https://www.youtube.com/watch?v=F1X4fHzF4mQ&t=360s&ab_channel=AssemblyAI

    +
      +
    • Prior

      +
        +
      • input

        +
          +
        • Caption 그 자체의 embedding vector 입니다.

        • +
        • CLIP text embedding 입니다.

        • +
        +
      • +
      • output

        +
          +
        • Generated CLIP Image embedding 입니다.

        • +
        +
      • +
      • 설명

        +
          +
        • 사실 Prior 은 CLIP text embedding 만 조건으로 받는 것이 아니라 +Caption 자체도 받습니다. (물론 embedding vector 로 받을 것) +CLIP text embedding 과, 그 Caption 은 서로 1대1 대응되기 때문에, +Duel-conditioning 이 문제될 것은 없다고 저자들은 변론합니다.

        • +
        • 샘플 퀄리티를 높이기 위해서, +2개의 CLIP image embeddings 를 생성한 후 +주어진 CLIP text embedding 과 +더 높은 dot product 를 갖는 CLIP image embedding 을 사용했다고 합니다.

        • +
        +
      • +
      +
    • +
    • Decoder

      +
        +
      • Input

        +
          +
        • CLIP text embedding

        • +
        • Generated CLIP Image embedding

        • +
        +
      • +
      • Output

        +
          +
        • Generated Image

        • +
        +
      • +
      • 설명

        +
          +
        • modified GLIDE model 을 Decoder 로 사용했습니다. +→ 따라서, projected CLIP text embeddings 를 아키텍쳐에 통합시킬 수 있다고 주장합니다.

        • +
        +

        어떻게 통합시키냐하면,

        +
          +
        1. GLIDE timestep embedding 에 추가하고,

        2. +
        3. 4개의 extra context tokens 을 만들어서 GLIDE text encoder 의 output sequence 에 concat 하는거죠.

        4. +
        +

        이 방법으로 CLIP image embeddings 를 받아서, 원본 영상을 생성하는 것 입니다.

        +
          +
        • GLIDE 를 수정해 사용함으로써, GLIDE 가 가지고 있던 text-conditional photorealistic image generation capabilities 를 활용할 수 있다고 주장합니다.

        • +
        +
      • +
      +
    • +
    +
  • +
  • 그렇다면 왜 Prior 가 필요할까요?

    +
      +
    1. To obtain a full generative model of images, we combine the CLIP image embedding decoder with a prior model, which generates possible CLIP image embeddings from a given text caption

    2. +
    3. 아래 세 가지 아키텍쳐를 비교하는 실험 수행 +(1) GLIDE 모델처럼, text 의 token embeddings 만 조건으로 주어 실험 +(2) 추가적으로, CLIP text embeddings 를 조건으로 주어 실험 +(3) 추가적으로, CLIP image embeddings 를 생성해내는 Prior 를 갖추고 실험

    4. +
    +

    결과 (3) 이 가장 훌륭했습니다. 특히 image diversity 가 뛰어났습니다.

    +
      - 하지만.. **95% 의 학습 시간 동안, (3) 방식으로 학습한 Decoder 를, (1) 과 (2) 방식에 그대로 적용해 실험했습니다.** 따라서 공정한 실험이라고 보긴 어려울 것 같습니다.
    +  - 또한.. **Decoder 를 True CLIP Image embeddings 와 Generated CLIP Image embeddings 로 각각 학습시켰을 때의 성능 비교 실험은 없습니다.**
    +  - 개인적으로 저는 이러한 결과들을 보고, Prior 를 반드시 써야하는 근거에 대한 설득력이 조금 떨어진다고 생각했습니다.
    +
    +
    +
  • +
  • 왜 CLIP 을 써야할가요?

    +
      +
    1. CLIP 은 어떤 객체를 묘사한 텍스트와, 그 객체의 시각적 발현 사이의 의미론적 관계를 학습했습니다. 따라서 저자들은 이러한 CLIP 의 능력이 Text-to-Image task 에서 매우 중요하다고 주장합니다.

    2. +
    3. CLIP 을 활용한 덕분에 이미지를 Manipulation 할 수 있습니다.

      +

      Untitled

      +
    4. +
    +
  • +
  • 그래서? 이 모델 좋아?

    +
      +
    • Evaluation

      +
        +
      • 주어진 Caption 에 대한 GLIDE 의 생성물과 unCLIP 의 생성물을 +사람들에게 제시하고, +Photorealism, Caption Similarity, Diversity 에 대해서 평가하도록 함.

      • +
      +
        +
      1. GLIDE 에 비해서 Photorealism, Caption Similarity, 은 Comparable 하다. +~~(안 좋다)~~

      2. +
      3. 하지만, Diversity 는 훨씬 뛰어나다.

        +

        Untitled

        +

        Untitled

        +

        Untitled

        +
      4. +
      +
    • +
    • Image Manipulations

      +
        +
      • Bipartite Representation

        +
          +
        • unCLIP 구조 덕분에, 주어진 이미지 x 를 (z_i, x_T) 와 같은 bipartite latent representation 으로 인코딩 할 수 있음

        • +
        • 이 latent space 를 활용해서, Image manipulation 을 수행할 수 있다.

        • +
        • x_T 는 DDIM inversion 을 z_i 가 condition 된 x 에 적용해 얻으며, +Decoder 가 x 를 복원하는데 필요한 잔여 정보들을 지님

        • +
        +
      • +
      +
        +
      1. Variations

      2. +
      +

      Untitled

      +
        +
      • Non-essential details 를 변주하기 위해서, +bipartite representation 에 DDIM with η > 0 for sampling decoder 를 적용한다.

      • +
      • η = 0 일 때, decoder 는 deterministic 해지고 x 자체를 복원해낸다.

      • +
      • η 가 커질수록, sampling steps 에는 stochasticity 가 생기고, 원본 이미지 x 근처에서 perceptually “centereed” 된 variations 를 만들어낼 것이다.

      • +
      • η 를 키우면, 우리는 CLIP image embedding 에 어떤 정보가 존재하고 어떤 정보가 유실되었는지 탐색 가능 +→ CLIP latent space 를 탐색해낼 수 있다 !

      • +
      +
        +
      1. Interpolations

        +

        Untitled

        +
          +
        • input image 두 장의 CLIP image embeddings 를 interpolation 해서 +Decoder 에 준다면, interpolated image 를 생성할 수 있다.

        • +
        +
      2. +
      3. Text Diffs

        +

        Untitled

        +
          +
        • 어떤 이미지와 그 캡션이 주어져있을 때, +그 이미지를 우리가 원하는 target text prompt 에 맞게 +조작할 수도 있음

        • +
        • Method +z_t0 = current CLIP text embedding +z_t = target CLIP text embedding

          +

          Untitled

          +
        • +
        • 주어진 이미지의 CLIP image embdding z_i 를 바로 이 text diff vector 와 interpolate 해서 Decoding 하면 이미지가 조작된다.

        • +
        +
      4. +
      +
    • +
    • Robustness against typographic attaks

      +
        +
      • typographic attacks : 이미지 내 사물 위에, 글씨가 쓰여 있는 경우이다.

      • +
      • Multimodal 로 학습한 CLIP 은 텍스트에 있는 정보를 더 많이 활용해 +사물을 판단하는 경향이 있음

        +
          +
        1. unCLIP 의 Decoder 모델에 “iPod” 텍스트 종이가 붙은 사과를 보고 분류를 수행해보았다.

        2. +
        3. 역시, “Granny Smith” 의 예측 확률을 거의 0 에 가깝다고 판단했다.

        4. +
        5. 그럼에도 불구하고, 사과의 사진으로 recover 해낸다.

          +

          Untitled

          +
        6. +
        +
      • +
      +
    • +
    +
  • +
  • 이 모델, 단점은 없어?

    +
      +
    1. 객체(cubes)와 그들의 속성(colors) 을 매칭시키는 능력이 떨어짐

      +

      Untitled

      +
    2. +
    3. 텍스트를 일관성있게 생성하는 능력이 떨어짐

      +

      Untitled

      +
    4. +
    5. 복잡한 상황에서 디테일을 묘사하는 능력이 떨어짐

      +

      Untitled

      +
    6. +
    +
  • +
  • Method - Training

    +
      +
    • unCLIP 모델의 아키텍쳐에 대한 수학적 justify 를 하고 있음

    • +
    • Training 데이터셋의 이미지를 x 라 한다.

    • +
    • 그에 상응하는 text captions 을 y 라 한다.

    • +
    • 각각에 대한 embeddings 인 Z_i, Z_t 를 기존의 CLIP 으로 생성.

      +
        +
      • image x —CLIP Image encoder—> Z_i image embeddings

      • +
      • text caption y —CLIP text encoder—> Z_t text embeddings

      • +
      +
    • +
    • 저자의 주장

      +
        +
      • unCLIP 으로, text caption y 로부터 image x 를 샘플링할 수 있다.

        +

        Untitled

        +
      • +
      • The first equality holds because z_i is a deterministic function of x.

      • +
      • The second equality holds because of the chain rule.

      • +
      +
    • +
    • 내 부가 설명

      +
        +
      • z_t 도 y 의 deterministic function 이므로, 다음과 같이 쓸 수 있다.

        +
        +\[ + P(x|y) = P(x, z_i|y, z_t) = P(x|z_i, y, z_t)P(z_i|y, z_t) + \]
        +
      • +
      • Prior 를 사용해 Z_t 로부터 Z_i 를 샘플링하고, +Decoder 를 사용해 x 를 샘플링함으로써 +True conditional distribution 인 P(x|y) 샘플링이 가능해짐

      • +
      +
    • +
    +
  • +
  • DALL-E 2 Bias

    +

    openai/dalle-2-preview

    +
      +
    • 현재 OpenAI 가 DALL-E 2 의 Safety 를 위해 하고 있는 노력

      +
        +
      1. 학습 데이터에서 violent, hate, or adult images 를 제거함으로써 +이러한 이미지들에 DALL-E 2 가 노출되는 시간을 최소화함

      2. +
      3. Safety policies 를 위반한 text prompts 혹은 생성된 images 를 자정하는 시스템 보유

      4. +
      5. 신뢰할 수 있는 전문가들과 DALL-E 2 에 대한 사전 검토를 진행했음

      6. +
      +
    • +
    • DALL-EVAL : 이미지 생성형 AI 의 Bias 를 평가하는 방법 소개

      +

      https://arxiv.org/pdf/2202.04053.pdf

      +

      j-min/DallEval

      +
        +
      • Contribution

        +
          +
        • Text to Image Generation models 의 시각적 추론 능력 3가지를 평가하기 위한 데이터셋 제공

        • +
        • 최근의 모델들이 object recognition skill 은 상대적으로 뛰어나지만, object counting 및 spaial relation 이해 능력은 떨어짐을 발견

        • +
        • Text to Image Generation models 에 존재하는 gender 및 skin tone biases 를 측정하는 evaluation metrics 와 그 분석 결과를 제시한 최초의 논문

          +
            +
          • web 에서 image-text pairs 를 학습한 현재 T2I 생성 모델들은 특정한 gender/skin tone biases 를 학습했음을 보여줌

          • +
          +
        • +
        +

        Untitled

        +
      • +
      • Social Bias Evaluation 측정 방법 (Sec. 4.2.1 참고)

        +

        Untitled

        +
          +
        1. Diagnostic prompts 로 이미지들을 생성한다.

          +
            +
          1. ex) “a person who works as a nurse”

          2. +
          3. 총 252개의 Diagnostic prompts 제공

          4. +
          +
        2. +
        3. Gender, Skin tone, Attributes 를 생성된 이미지로부터 탐지

          +
            +
          1. using automated detection models and verify the reliability of detection models with human evaluation

          2. +
          3. Gender

            +
              +
            1. BLIP-2 라는 모델에 생성된 영상을 주면서 영상 내 사람의 성별을 맞추게 함. BLIP-2 의 답변을 기반으로 Gender Bias 측정

            2. +
            +
          4. +
          5. Skin tone

            +
              +
            1. 신경망으로 facial landmark 를 추출하고, illumination 을 측정

            2. +
            +
          6. +
          7. Attributes

            +
              +
            1. BLIP-2 라는 모델에 생성된 영상을 주면서 영상 내 사람의 복장을 맞추게 함. BLIP-2 의 답변을 기반으로 Attributes Bias 측정

            2. +
            +
          8. +
          +
        4. +
        5. 탐지된 Gender, Skin tone, Attributes 가 unbiased uniform distribution 으로부터 얼마나 skewed 되어있는지 측정한다.

        6. +
        +
      • +
      • 실험 결과

        +

        Untitled

        +

        Untitled

        +

        Untitled

        +
      • +
      +
    • +
    +
  • +
+

이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다.

+

Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다.

+
+img_01 +
+

Fig. 184 Effect of Object Masking#

+
+
+

Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다.

+
+img_02 +
+

Fig. 185 Imagen Editor Architecture#

+
+
+

Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다.

+

논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다.

+

EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, attribute-object-scene 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다.

+
    +
  • Attributes (material, color, shape, size, count)

  • +
  • Objects (common, rare, text rendering)

  • +
  • Scenes (indoor, outdoor, realistic, paintings)

  • +
+

예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 Mask-Simple, Mask-Rich, 그리고 Full 로 정의합니다.

+
+img_03 +
+

Fig. 186 EditBench example#

+
+
+

데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다.

+
+img_04 +
+

Fig. 187 Human Evaluations on EditBench#

+
+
+

또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다.

+
+img_05 +
+

Fig. 188 Imagen Editor failure cases by attribute#

+
+
+

마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다.

+
+img_06 +
+

Fig. 189 Example model outputs for Mask-Simple vs MaskRich prompts#

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/docs/review/DDIM.html b/docs/review/DDIM.html old mode 100644 new mode 100755 index 50a018d1..66df4045 --- a/docs/review/DDIM.html +++ b/docs/review/DDIM.html @@ -1,921 +1,929 @@ - - - - - - - - - - - - DDIM — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

DDIM#

-
-

Abstract#

-
    -
  • DDPM의 단점인 Markov Process를 Non markovian process로 정의함으로서 Time efficient, deterministic한 Sampling이 가능한 모델을 제안

    -
      -
    • Deterministic vs Stochastic

    • -
    -
  • -
-
-
-

1. Introduction#

-
    -
  • 생성 분야에서 GAN(Generative Adversarial Network)이 뛰어난 성능을 보여주고있다.

  • -
  • 하지만, GAN은 학습 과정에서 불안정성을 보이는 경우가 많다.

    -
      -
    • Generator와 Discriminator의 Imbalanced에 의한 Mode collapse

    • -
    -
  • -
  • 그러던 중, DDPM과 NCSN같은 adversarial training구조가 아닌 model들이 등장하였고 성공의 가능성을 보여주었다.

  • -
  • 이 중 DDPM은 Forward Process에서 Markov Process를 거치는데 이때문에 GAN에 비해 매우 느린 Performance를 보여준다.

    - - - - - - - - - - - - - - - - - -

    sampling

    GAN

    DDPM

    32 x 32 x 50k

    Less than 1 min

    About 20h

    256 x 256 x 50k

    -

    About 1000h

    -
  • -
  • DDIM은,

    -
      -
    1. Markov Chain에 기반한 Process를 Non Markovian Process로 대체하였고

    2. -
    3. 결국 좀더 빠르고 비교적 우수한 Quality의 결과를 생성해내고, (with accelate)

    4. -
    5. DDPM과는 다르게 Consistency한 학습 결과를 보여줌으로써 latent간의 Interpolation이 가능하다.

      -
        -
      • Consistency?

        -
          -
        • If x, y is equivalent, then f(x) = f(y)

        • -
        -
      • -
      -
    6. -
    -
  • -
-
-
-

2. Background#

-
-

DDPM#

-
-DDIM_00 -
-

Fig. 43 DDPM & DDIM Architectures#

-
-
-
    -
  • DDPM의 Forward Process는 Markov process로 동작한다.

    -
      -
    • Markov process

      -
        -
      • 미래 시점을 예측하기위해 현재 시점의 값을 이용한다.

      • -
      • 미래 시점은 과거 시점의 값에는 독립적인 값을 갖는다.

      • -
      -
    • -
    -
  • -
  • time step T는 DDPM에서 성능을 좌지우지하는 중요한 Hyper parameter이다. (대충 T=1000 정도?)

  • -
  • 하지만, Sampling 과정에서 DDPM은 결국 T 번의 inference 과정을 모두 Sequential하게 거쳐야하고 이는 다른 Method(GAN 등)보다 현저히 느린 속도를 보이는 요소가 된다.

  • -
-
-
-
-

3. Variational Inference For Non-Markovian Forward Process#

-

3.1. Non-Markovian Forward Processes

-
    -
  • Inference’s Distribution 정의

  • -
-
-DDIM_01 -
-

Fig. 44 Equation 1#

-
-
-
-DDIM_02 -
-

Fig. 45 Equation 2#

-
-
-
    -
  • t 시점의 값을 구하기위해 \(X_{t-1}\)의 값과 \(X_{0}\)의 값을 참조

    -
      -
    • DDPM은? \(X_{t-1}\)의 값만을 참조

    • -
    • σ는 Forward process의 stochastic한 정도를 조절하는 hyper parameter (chap 4 참조)

    • -
    -
  • -
-

3.2. Generative Process And Unified Variational Inference Objective (Reverse Process)

-
-DDIM_00 -
-

Fig. 46 Equation 3#

-
-
-
-DDIM_00 -
-

Fig. 47 Equation 4#

-
-
-
    -
  1. \(X_{t}\)을 통해 \(X_{0}\)의 값을 예측 (trainable)

  2. -
  3. 위의 식을 통해 \(X_{t}\)와, \(X_{0}\)의 값을 이용해 \(X_{t-1}\)을 샘플링

  4. -
-

실제로는

-
    -
  • noise(ε)와 \(X_{0}\), \(X_{t}\)의 관계

    -
    -DDIM_05 -
    -

    Fig. 48 Equation 5#

    -
    -
    -
  • -
-
    -
  1. \(X_{t}\)을 통해 \(X_{0}\)을 예측

    -
      -
    1. t 시점의 이미지를 통해 t 시점의 noise를 예측

    2. -
    3. t 시점의 이미지와 t 시점의 noise를 통해 0 시점의 이미지를 계산 (fixed)

    4. -
    -
  2. -
  3. 위의 식을 통해 t시점의 값과 예측한 0 시점의 값을 이용해 t-1 시점의 값을 샘플링

  4. -
-
-
-

4. Sampling From Generalized Generative Process#

-

4.1. Denoising Diffusion Implicit Models

-
    -
  1. If σ → 0

  2. -
-
-DDIM_06 -
-

Fig. 49 Equation 6#

-
-
-
    -
  1. σ가 특정 값을 가질 때 DDPM의 generative process의 수식과 동일하다.

  2. -
-
-DDIM_07 -
-

Fig. 50 Explanation of σ#

-
-
-

4.2. Accelerated Generation Processes

-
-DDIM_08 -
-

Fig. 51 Explanation of accelated method#

-
-
-
    -
  • DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다.

  • -
  • 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다.

  • -
  • DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.

  • -
-

4.3. Relevance To Neural ODEs

-
    -
  • DDIM은 Object(e.g. 이미지)의 Encoding이 가능한 식을 유도할 수 있다.

  • -
-
-
-

5. Experiments#

-
-DDIM_09 -
-

Fig. 52 Table1#

-
-
-
-DDIM_010 -
-

Fig. 53 Euqation 7#

-
-
-
    -
  • η → model을 simple하게 control하기위한 hyperparameter

    -
      -
    • η = 1 → Model is DDPM

    • -
    • η = 0 → Model is DDIM

    • -
    -
  • -
  • 모든 비교 모델이 S(sampling 횟수)의 값이 커질수록 더 낮은 FiD를 보여준다.

  • -
  • Fig.3의 DDIM은 다른 모델(η가 0이 아닌 모델)과 다르게 sampling step에 consistency한 결과를 보여준다.

  • -
-
-DDIM_011 -
-

Fig. 54 Figure 4, 5#

-
-
-
    -
  • Step과 Inference time이 linear한 관계를 갖는다.

  • -
  • 적은 sampling step에서도 어느정도의 object를 보여준다.

  • -
-
-DDIM_012 -
-

Fig. 55 Figure 6#

-
-
-
    -
  • T 시점의 이미지에 interpolation이 가능하다.

  • -
-
-
-

6. Code#

-
# https://keras.io/examples/generative/ddim/
-class DiffusionModel(keras.Model):
-    def __init__(self, image_size, widths, block_depth):
-        super().__init__()
-
-        self.normalizer = layers.Normalization()
-        self.network = get_network(image_size, widths, block_depth) # unet 구조
-
-    def denormalize(self, images):
-        # convert the pixel values back to 0-1 range
-        images = self.normalizer.mean + images * self.normalizer.variance**0.5
-        return tf.clip_by_value(images, 0.0, 1.0)
-
-    def diffusion_schedule(self, diffusion_times):
-        # diffusion times -> angles
-        start_angle = tf.acos(max_signal_rate)
-        end_angle = tf.acos(min_signal_rate)
-
-        diffusion_angles = start_angle + diffusion_times * (end_angle - start_angle)
-
-        # angles -> signal and noise rates
-        signal_rates = tf.cos(diffusion_angles)
-        noise_rates = tf.sin(diffusion_angles)
-        # note that their squared sum is always: sin^2(x) + cos^2(x) = 1
-
-        return noise_rates, signal_rates
-
-    def denoise(self, noisy_images, noise_rates, signal_rates, training):
-        # the exponential moving average weights are used at evaluation
-        if training:
-            network = self.network
-        else:
-            network = self.ema_network
-
-        # predict noise component and calculate the image component using it
-        pred_noises = network([noisy_images, noise_rates**2], training=training)
-        pred_images = (noisy_images - noise_rates * pred_noises) / signal_rates
-
-        return pred_noises, pred_images
-
-    
-
-    def train_step(self, images):
-        # normalize images to have standard deviation of 1, like the noises
-        images = self.normalizer(images, training=True)
-        noises = tf.random.normal(shape=(batch_size, image_size, image_size, 3))
-
-        # sample uniform random diffusion times
-        diffusion_times = tf.random.uniform(
-            shape=(batch_size, 1, 1, 1), minval=0.0, maxval=1.0
-        )
-        noise_rates, signal_rates = self.diffusion_schedule(diffusion_times)
-        # mix the images with noises accordingly
-        noisy_images = signal_rates * images + noise_rates * noises
-
-        with tf.GradientTape() as tape:
-            # train the network to separate noisy images to their components
-            pred_noises, pred_images = self.denoise(
-                noisy_images, noise_rates, signal_rates, training=True
-            )
-
-            noise_loss = self.loss(noises, pred_noises)  # used for training
-            image_loss = self.loss(images, pred_images)  # only used as metric
-
-        gradients = tape.gradient(noise_loss, self.network.trainable_weights)
-        self.optimizer.apply_gradients(zip(gradients, self.network.trainable_weights))
-
-        self.noise_loss_tracker.update_state(noise_loss)
-        self.image_loss_tracker.update_state(image_loss)
-
-        return {m.name: m.result() for m in self.metrics[:-1]}
-
-		def reverse_diffusion(self, initial_noise, diffusion_steps):
-        # reverse diffusion = sampling
-        num_images = initial_noise.shape[0]
-        step_size = 1.0 / diffusion_steps
-
-        # important line:
-        # at the first sampling step, the "noisy image" is pure noise
-        # but its signal rate is assumed to be nonzero (min_signal_rate)
-        next_noisy_images = initial_noise
-        for step in range(diffusion_steps):
-            noisy_images = next_noisy_images
-
-            # separate the current noisy image to its components
-            diffusion_times = tf.ones((num_images, 1, 1, 1)) - step * step_size
-            noise_rates, signal_rates = self.diffusion_schedule(diffusion_times)
-            pred_noises, pred_images = self.denoise(
-                noisy_images, noise_rates, signal_rates, training=False
-            )
-            # network used in eval mode
-
-            # remix the predicted components using the next signal and noise rates
-            next_diffusion_times = diffusion_times - step_size
-            next_noise_rates, next_signal_rates = self.diffusion_schedule(
-                next_diffusion_times
-            )
-            next_noisy_images = (
-                next_signal_rates * pred_images + next_noise_rates * pred_noises
-            )
-            # this new noisy image will be used in the next step
-
-        return pred_images
-
-    def generate(self, num_images, diffusion_steps):
-        # noise -> images -> denormalized images
-        initial_noise = tf.random.normal(shape=(num_images, image_size, image_size, 3))
-        generated_images = self.reverse_diffusion(initial_noise, diffusion_steps)
-        generated_images = self.denormalize(generated_images)
-        return generated_images
-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + DDIM — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

DDIM#

+
+

Abstract#

+
    +
  • DDPM의 단점인 Markov Process를 Non markovian process로 정의함으로서 Time efficient, deterministic한 Sampling이 가능한 모델을 제안

    +
      +
    • Deterministic vs Stochastic

    • +
    +
  • +
+
+
+

1. Introduction#

+
    +
  • 생성 분야에서 GAN(Generative Adversarial Network)이 뛰어난 성능을 보여주고있다.

  • +
  • 하지만, GAN은 학습 과정에서 불안정성을 보이는 경우가 많다.

    +
      +
    • Generator와 Discriminator의 Imbalanced에 의한 Mode collapse

    • +
    +
  • +
  • 그러던 중, DDPM과 NCSN같은 adversarial training구조가 아닌 model들이 등장하였고 성공의 가능성을 보여주었다.

  • +
  • 이 중 DDPM은 Forward Process에서 Markov Process를 거치는데 이때문에 GAN에 비해 매우 느린 Performance를 보여준다.

    + + + + + + + + + + + + + + + + + +

    sampling

    GAN

    DDPM

    32 x 32 x 50k

    Less than 1 min

    About 20h

    256 x 256 x 50k

    -

    About 1000h

    +
  • +
  • DDIM은,

    +
      +
    1. Markov Chain에 기반한 Process를 Non Markovian Process로 대체하였고

    2. +
    3. 결국 좀더 빠르고 비교적 우수한 Quality의 결과를 생성해내고, (with accelate)

    4. +
    5. DDPM과는 다르게 Consistency한 학습 결과를 보여줌으로써 latent간의 Interpolation이 가능하다.

      +
        +
      • Consistency?

        +
          +
        • If x, y is equivalent, then f(x) = f(y)

        • +
        +
      • +
      +
    6. +
    +
  • +
+
+
+

2. Background#

+
+

DDPM#

+
+DDIM_00 +
+

Fig. 43 DDPM & DDIM Architectures#

+
+
+
    +
  • DDPM의 Forward Process는 Markov process로 동작한다.

    +
      +
    • Markov process

      +
        +
      • 미래 시점을 예측하기위해 현재 시점의 값을 이용한다.

      • +
      • 미래 시점은 과거 시점의 값에는 독립적인 값을 갖는다.

      • +
      +
    • +
    +
  • +
  • time step T는 DDPM에서 성능을 좌지우지하는 중요한 Hyper parameter이다. (대충 T=1000 정도?)

  • +
  • 하지만, Sampling 과정에서 DDPM은 결국 T 번의 inference 과정을 모두 Sequential하게 거쳐야하고 이는 다른 Method(GAN 등)보다 현저히 느린 속도를 보이는 요소가 된다.

  • +
+
+
+
+

3. Variational Inference For Non-Markovian Forward Process#

+

3.1. Non-Markovian Forward Processes

+
    +
  • Inference’s Distribution 정의

  • +
+
+DDIM_01 +
+

Fig. 44 Equation 1#

+
+
+
+DDIM_02 +
+

Fig. 45 Equation 2#

+
+
+
    +
  • t 시점의 값을 구하기위해 \(X_{t-1}\)의 값과 \(X_{0}\)의 값을 참조

    +
      +
    • DDPM은? \(X_{t-1}\)의 값만을 참조

    • +
    • σ는 Forward process의 stochastic한 정도를 조절하는 hyper parameter (chap 4 참조)

    • +
    +
  • +
+

3.2. Generative Process And Unified Variational Inference Objective (Reverse Process)

+
+DDIM_00 +
+

Fig. 46 Equation 3#

+
+
+
+DDIM_00 +
+

Fig. 47 Equation 4#

+
+
+
    +
  1. \(X_{t}\)을 통해 \(X_{0}\)의 값을 예측 (trainable)

  2. +
  3. 위의 식을 통해 \(X_{t}\)와, \(X_{0}\)의 값을 이용해 \(X_{t-1}\)을 샘플링

  4. +
+

실제로는

+
    +
  • noise(ε)와 \(X_{0}\), \(X_{t}\)의 관계

    +
    +DDIM_05 +
    +

    Fig. 48 Equation 5#

    +
    +
    +
  • +
+
    +
  1. \(X_{t}\)을 통해 \(X_{0}\)을 예측

    +
      +
    1. t 시점의 이미지를 통해 t 시점의 noise를 예측

    2. +
    3. t 시점의 이미지와 t 시점의 noise를 통해 0 시점의 이미지를 계산 (fixed)

    4. +
    +
  2. +
  3. 위의 식을 통해 t시점의 값과 예측한 0 시점의 값을 이용해 t-1 시점의 값을 샘플링

  4. +
+
+
+

4. Sampling From Generalized Generative Process#

+

4.1. Denoising Diffusion Implicit Models

+
    +
  1. If σ → 0

  2. +
+
+DDIM_06 +
+

Fig. 49 Equation 6#

+
+
+
    +
  1. σ가 특정 값을 가질 때 DDPM의 generative process의 수식과 동일하다.

  2. +
+
+DDIM_07 +
+

Fig. 50 Explanation of σ#

+
+
+

4.2. Accelerated Generation Processes

+
+DDIM_08 +
+

Fig. 51 Explanation of accelated method#

+
+
+
    +
  • DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다.

  • +
  • 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다.

  • +
  • DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.

  • +
+

4.3. Relevance To Neural ODEs

+
    +
  • DDIM은 Object(e.g. 이미지)의 Encoding이 가능한 식을 유도할 수 있다.

  • +
+
+
+

5. Experiments#

+
+DDIM_09 +
+

Fig. 52 Table1#

+
+
+
+DDIM_010 +
+

Fig. 53 Euqation 7#

+
+
+
    +
  • η → model을 simple하게 control하기위한 hyperparameter

    +
      +
    • η = 1 → Model is DDPM

    • +
    • η = 0 → Model is DDIM

    • +
    +
  • +
  • 모든 비교 모델이 S(sampling 횟수)의 값이 커질수록 더 낮은 FiD를 보여준다.

  • +
  • Fig.3의 DDIM은 다른 모델(η가 0이 아닌 모델)과 다르게 sampling step에 consistency한 결과를 보여준다.

  • +
+
+DDIM_011 +
+

Fig. 54 Figure 4, 5#

+
+
+
    +
  • Step과 Inference time이 linear한 관계를 갖는다.

  • +
  • 적은 sampling step에서도 어느정도의 object를 보여준다.

  • +
+
+DDIM_012 +
+

Fig. 55 Figure 6#

+
+
+
    +
  • T 시점의 이미지에 interpolation이 가능하다.

  • +
+
+
+

6. Code#

+
# https://keras.io/examples/generative/ddim/
+class DiffusionModel(keras.Model):
+    def __init__(self, image_size, widths, block_depth):
+        super().__init__()
+
+        self.normalizer = layers.Normalization()
+        self.network = get_network(image_size, widths, block_depth) # unet 구조
+
+    def denormalize(self, images):
+        # convert the pixel values back to 0-1 range
+        images = self.normalizer.mean + images * self.normalizer.variance**0.5
+        return tf.clip_by_value(images, 0.0, 1.0)
+
+    def diffusion_schedule(self, diffusion_times):
+        # diffusion times -> angles
+        start_angle = tf.acos(max_signal_rate)
+        end_angle = tf.acos(min_signal_rate)
+
+        diffusion_angles = start_angle + diffusion_times * (end_angle - start_angle)
+
+        # angles -> signal and noise rates
+        signal_rates = tf.cos(diffusion_angles)
+        noise_rates = tf.sin(diffusion_angles)
+        # note that their squared sum is always: sin^2(x) + cos^2(x) = 1
+
+        return noise_rates, signal_rates
+
+    def denoise(self, noisy_images, noise_rates, signal_rates, training):
+        # the exponential moving average weights are used at evaluation
+        if training:
+            network = self.network
+        else:
+            network = self.ema_network
+
+        # predict noise component and calculate the image component using it
+        pred_noises = network([noisy_images, noise_rates**2], training=training)
+        pred_images = (noisy_images - noise_rates * pred_noises) / signal_rates
+
+        return pred_noises, pred_images
+
+    
+
+    def train_step(self, images):
+        # normalize images to have standard deviation of 1, like the noises
+        images = self.normalizer(images, training=True)
+        noises = tf.random.normal(shape=(batch_size, image_size, image_size, 3))
+
+        # sample uniform random diffusion times
+        diffusion_times = tf.random.uniform(
+            shape=(batch_size, 1, 1, 1), minval=0.0, maxval=1.0
+        )
+        noise_rates, signal_rates = self.diffusion_schedule(diffusion_times)
+        # mix the images with noises accordingly
+        noisy_images = signal_rates * images + noise_rates * noises
+
+        with tf.GradientTape() as tape:
+            # train the network to separate noisy images to their components
+            pred_noises, pred_images = self.denoise(
+                noisy_images, noise_rates, signal_rates, training=True
+            )
+
+            noise_loss = self.loss(noises, pred_noises)  # used for training
+            image_loss = self.loss(images, pred_images)  # only used as metric
+
+        gradients = tape.gradient(noise_loss, self.network.trainable_weights)
+        self.optimizer.apply_gradients(zip(gradients, self.network.trainable_weights))
+
+        self.noise_loss_tracker.update_state(noise_loss)
+        self.image_loss_tracker.update_state(image_loss)
+
+        return {m.name: m.result() for m in self.metrics[:-1]}
+
+		def reverse_diffusion(self, initial_noise, diffusion_steps):
+        # reverse diffusion = sampling
+        num_images = initial_noise.shape[0]
+        step_size = 1.0 / diffusion_steps
+
+        # important line:
+        # at the first sampling step, the "noisy image" is pure noise
+        # but its signal rate is assumed to be nonzero (min_signal_rate)
+        next_noisy_images = initial_noise
+        for step in range(diffusion_steps):
+            noisy_images = next_noisy_images
+
+            # separate the current noisy image to its components
+            diffusion_times = tf.ones((num_images, 1, 1, 1)) - step * step_size
+            noise_rates, signal_rates = self.diffusion_schedule(diffusion_times)
+            pred_noises, pred_images = self.denoise(
+                noisy_images, noise_rates, signal_rates, training=False
+            )
+            # network used in eval mode
+
+            # remix the predicted components using the next signal and noise rates
+            next_diffusion_times = diffusion_times - step_size
+            next_noise_rates, next_signal_rates = self.diffusion_schedule(
+                next_diffusion_times
+            )
+            next_noisy_images = (
+                next_signal_rates * pred_images + next_noise_rates * pred_noises
+            )
+            # this new noisy image will be used in the next step
+
+        return pred_images
+
+    def generate(self, num_images, diffusion_steps):
+        # noise -> images -> denormalized images
+        initial_noise = tf.random.normal(shape=(num_images, image_size, image_size, 3))
+        generated_images = self.reverse_diffusion(initial_noise, diffusion_steps)
+        generated_images = self.denormalize(generated_images)
+        return generated_images
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/DDPM.html b/docs/review/DDPM.html old mode 100644 new mode 100755 index 5c0ee615..6143cb63 --- a/docs/review/DDPM.html +++ b/docs/review/DDPM.html @@ -1,1093 +1,1101 @@ - - - - - - - - - - - - DDPM — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

DDPM#

-
-DDPM_01 -
-

Fig. 34 DDPM samples \ (source: https://arxiv.org/abs/2006.11239)#

-
-
-
-
-
-

1. Introduction#

-
-DDPM_02 -
-

Fig. 35 Diffusion models \ (source: https://velog.io/@yetsyl0705/What-are-Diffusion-Models)#

-
-
-

Diffusion modelvariational inference로 학습시켜 데이터를 생성하는 parameterized Markov chain. Diffusion model은 Markov가 데이터가 normal distribution의 형태를 할 때까지 noise를 더해가는 diffusion process이를 역으로 거치며 학습하는 reverse process로 구성됨.

-

Diffusion model은 정의하기 쉽고 학습시키는 것도 편리함. 또한 높은 품질의 sample(output)도 생성이 가능.

-
-
    -
  • Variational inference(변분추론): 사후확률(posterior) 분포 \(p(z -|x)\)를 다루기 쉬운 확률분포 \(q(z)\)로 근사(approximation)하는 것

  • -
  • Parameterize: 하나의 표현식에 대해 다른 parameter를 사용하여 다시 표현하는 과정. 이 과정에서 보통 parameter의 개수를 표현 식의 차수보다 적은 수로 선택(ex. 3차 표현식 –> 2개 parameter 사용)하므로, 낮은 차수로의 mapping 함수(ex. 3D –> 2D)가 생성

  • -
  • Markov chain: 어떤 상태에서 다른 상태로 넘어갈 때, 바로 전 단계의 상태에만 영향을 받는 확률 과정

  • -
-
-
-
-
-

2. Background#

-
-DDPM_03 -
-

Fig. 36 Graphical model of DDPM \ (source: https://arxiv.org/abs/2006.11239)#

-
-
-
-

2-1. Forward(diffusion) process \(q(\mathbf{x}_t|\mathbf{x}_{t-1})\)#

-
-\[ -q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right):=\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right), \quad q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right):=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{1-\beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I}\right) -\]
-

Markov chain으로 data에 noise를 추가하는 과정. Noise를 추가할 때 variance schedule \(\beta_1,,,\beta_T\)로 scaling을 한 후 더해준다.

-
    -
  • \(\beta_t = 1\)이면 mean인 \(\sqrt{1-\beta_t}\mathbf{x}_{t-1} = 0\). 이전 정보를 갖지 못하고 노이즈가 증가함

  • -
  • 단순히 noise만을 더해주는게 아니라 \(\sqrt{1-\beta_t}\)로 scaling하는 이유는 variance가 발산하는 것을 막기 위함

  • -
  • \(q(x_1|x_0)\): \(x_0\)에 noise를 추가해 \(x_1\)을 만드는 과정

  • -
  • \(x_T\)는 완전 destroy된 noise 상태 ~ \(N(x_T;0, I)\)

  • -
-
-
-

2-2. Reverse process \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\)#

-
-\[ -p_\theta\left(\mathbf{x}_{0: T}\right):=p\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right), \quad p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right):=\mathcal{N}\left(\mathbf{x}_{t-1} ; \boldsymbol{\mu}_\theta\left(\mathbf{x}_t, t\right), \boldsymbol{\Sigma}_\theta\left(\mathbf{x}_t, t\right)\right) -\]
-

Reverse process로 가우시안 노이즈를 사용하는 이유는 1994년 논문에 forward process가 가우시안이면 reverse process도 가우시안으로 쓰면 된다라는 증명이 있다고 함.

-

여기서 우리가 해야 할 것은 \(\mathbf{x}_t\)를 보고 \(\mathbf{x}_{t-1}\)의 평균 \(\mu_\theta\)과 분산 \(\Sigma_\theta\)을 예측해내는 것.

-
    -
  • Hierarachical VAE에서의 decoding 과정과 비슷함

  • -
  • \(\mu_\theta\)과 분산 \(\Sigma_\theta\)는 학습 가능한 parameter

  • -
-
-
-

2-3. Loss Function \(L\)#

-

Diffusion model의 목적은 **noise를 어떻게 제거할 것인가?**이다. \(x_t\)가 들어왔을 때 \(x_{t-1}\)을 예측할 수 있다면 \(x_0\) 또한 예측이 가능해짐.

-
-\[ -\mathbb{E}\left[-\log p_\theta\left(\mathbf{x}_0\right)\right] \leq \mathbb{E}_q\left[-\log \frac{p_\theta\left(\mathbf{x}_{0: T}\right)}{q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right)}\right]=\mathbb{E}_q\left[-\log p\left(\mathbf{x}_T\right)-\sum_{t \geq 1} \log \frac{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}\right]=: L -\]
-

본 논문에서는 negative log likelihood를 최소화하는 방향으로 진행. 위 수식을 ELBO(Evidence of Lower BOund)로 우항과 같이 정리하고 이를 풀어내면

-
-

ELBO의 역할은 우리가 관찰한 P(z|x)가 다루기 힘든 분포를 이루고 있을 때 이를 조금 더 다루기 쉬운 분포인 Q(x)로 대신 표현하려 하는 과정에서 두 분포 (P(z|x)와 Q(x))의 차이 (KL Divergence)를 최소화 하기 위해 사용된다.

-
-
-\[ -\mathbb{E}_q[\underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_T \mid \mathbf{x}_0\right) \| p\left(\mathbf{x}_T\right)\right)}_{L_T}+\sum_{t>1} \underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)\right)}_{L_{t-1}} \underbrace{-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}_{L_0}] -\]
-

와 같은 결과가 나온다.

-
    -
  • \(L_T\): Regularization term으로 \(\beta_t\)를 학습시킴

  • -
  • \(L_{t-1}\): Reconstruction term으로 매 단계에서 noise를 지우는 지움

  • -
  • \(L_0\): Reconstruction term으로 최종 단계에서 image를 생성

  • -
-
-
-
-
-

3. Diffusion models and denoising encoders#

-

DDPM에서는 inductive bias를 늘려 모델을 더 stable하고 성능도 개선할 수 있었음.

-
-

Inductive bias: 학습 모델이 지금까지 만나보지 못했던 상황에서 정확한 예측을 하기 위해 사용하는 추가적인 가정, 즉 우리가 풀려는 문제에 대한 정보를 모델에 적용하는 것

-
-
-

3-1. Forward process and \(L_T\)#

-

\(\beta_t\)를 고정했더니 학습이 잘됨. 10^-4 ~ 0.02로 linear하게 image에 가까울수록 noise를 적게 주는 방식으로 설정.

-

따라서 \(q\)에는 학습 가능한 parameter가 없어 \(L_T\)는 0이 되기 때문에 삭제할 수 있었음.

-
-
-

3-2. Reverse process and \(L_{1:T-1}\)#

-
-\[ -L_{t-1}=D_{K L}\left(q\left(x_{t-1} \mid x_t, x_0\right) \| p_\theta\left(x_{t-1} \mid x_t\right)\right) -\]
-
    -
  • \( -q\left(x_{t-1} \mid x_t, x_0\right)=N\left(x_{t-1} ; \tilde{\mu}\left(x_t, x_0\right), \tilde{\beta}_t \mathrm{I}\right) -\)

  • -
  • \( -p_\theta\left(x_{t-1} \mid x_t\right)=\mathcal{N}\left(x_{t-1} ; \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) -\)

  • -
-

\(L_{1:T-1}\)는 forward progress posterior를 예측하는 loss. \(\mathbf{x}_{t-1}\)에서 noise를 더해 \(\mathbf{x}_{t}\)를 만들었을때, 그 과정을 복원 \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\) 하는 과정을 학습.

-
-DDPM_08 -
-

Fig. 37 Loss Simplication \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

-
-
-
    -
  • \(\Sigma_\theta\): \(\beta\)를 상수로 가정했고 \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\)의 variance가 \(\beta\)에 영향을 받기 때문에 학습시키지 않아도 된다고 생각해 variance term을 제거함.

  • -
-
-DDPM_09 -
-

Fig. 38 Residual Estimation \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

-
-
-
    -
  • \(\mu_\theta\): DDPM에서는 \(\mu_\theta\)를 바로 구하지 않고 residual \(\epsilon_\theta\)만 구해 정확도를 높임.

  • -
-
-
-

3-3. Data scaling, reverse process decoder and \(L_0\)#

-
-\[\begin{split} -\begin{aligned} -p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right) & =\prod_{i=1}^D \int_{\delta_{-}\left(x_0^i\right)}^{\delta_{+}\left(x_0^i\right)} \mathcal{N}\left(x ; \mu_\theta^i\left(\mathbf{x}_1, 1\right), \sigma_1^2\right) d x \\ -\delta_{+}(x) & =\left\{\begin{array}{ll} -\infty & \text { if } x=1 \\ -x+\frac{1}{255} & \text { if } x<1 -\end{array} \quad \delta_{-}(x)= \begin{cases}-\infty & \text { if } x=-1 \\ -x-\frac{1}{255} & \text { if } x>-1\end{cases} \right. -\end{aligned} -\end{split}\]
-

[0, 255]의 image를 [-1,1] 사이로 linearly mapping. Sampling 마지막 단계에는 noise를 추가하지 않음.

-

\(L_0\)은 두 normal distribution 사이의 KL divergence를 나타냄.

-
    -
  • \(D\): Data dimensionality

  • -
  • \(i\): 좌표

  • -
-
-
-

3-4. Simplified training objective#

-
-DDPM_10 -
-

Fig. 39 Simplified training objective \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

-
-
-
-DDPM_11 -
-

Fig. 40 Final Loss \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

-
-
-

최종 loss는 위와 같이 나타난다. Ground truth - estimated output간 MSE loss를 줄이는 과정이 denoising과 비슷해 DDPM이라는 이름이 붙음.

-

Simplified objective을 통해 diffusion process를 학습하면 매우 작은 t 에서뿐만 아니라 큰 t에 대해서도 network 학습이 가능하기 때문에 매우 효과적.

-
-DDPM_12 -
-

Fig. 41 Psuedo code of training process \ (source: https://arxiv.org/abs/2006.11239)#

-
-
-
    -
  • Algorithm 1: Training

    -
      -
    • Noise를 더해나가는 과정, network(\(\epsilon_\theta\), \(p_\theta\))가 t step에서 noise(\(\epsilon\))가 얼마만큼 더해졌는지를 학습한다.

    • -
    • 학습 시에는 특정 step의 이미지가 얼마나 gaussian noise가 추가되었는지를 예측하도록 학습된다.

    • -
    • 코드에서는 랜덤 노이즈와 시간 단계 t로 노이즈가 추가된 이미지를 얻고 해당 이미지를 보고 모델이 노이즈를 예측

    • -
    -
  • -
-
def p_losses(self, x_start, t, noise = None):
-        b, c, h, w = x_start.shape
-        noise = default(noise, lambda: torch.randn_like(x_start))
-
-        # noise sample
-
-        x = self.q_sample(x_start = x_start, t = t, noise = noise)
-
-        # if doing self-conditioning, 50% of the time, predict x_start from current set of times
-        # and condition with unet with that
-        # this technique will slow down training by 25%, but seems to lower FID significantly
-
-        x_self_cond = None
-        if self.self_condition and random() < 0.5:
-            with torch.no_grad():
-                x_self_cond = self.model_predictions(x, t).pred_x_start
-                x_self_cond.detach_()
-
-        # predict and take gradient step
-
-        model_out = self.model(x, t, x_self_cond)
-
-        if self.objective == 'pred_noise':
-            target = noise
-        elif self.objective == 'pred_x0':
-            target = x_start
-        elif self.objective == 'pred_v':
-            v = self.predict_v(x_start, t, noise)
-            target = v
-        else:
-            raise ValueError(f'unknown objective {self.objective}')
-
-        loss = self.loss_fn(model_out, target, reduction = 'none')
-        loss = reduce(loss, 'b ... -> b (...)', 'mean')
-
-        loss = loss * extract(self.loss_weight, t, loss.shape)
-        return loss.mean()
-
-
-
    -
  • Algorithm 2: Sampling

    -
      -
    • Network를 학습하고 나면, gaussian noise에서 시작해서 순차적으로 denoising 하는 것이 가능하다. (by parameterized markovian chain)

    • -
    • 코드에서는 noise 제거 후 소량의 noise를 다시 추가하고 있음

    • -
    -
  • -
-
@torch.no_grad()
-def p_sample(self, x, t: int, x_self_cond = None):
-    b, *_, device = *x.shape, x.device
-    batched_times = torch.full((b,), t, device = x.device, dtype = torch.long)
-    model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = True)
-    noise = torch.randn_like(x) if t > 0 else 0. # no noise if t == 0
-    pred_img = model_mean + (0.5 * model_log_variance).exp() * noise
-    return pred_img, x_start
-
-
-
-
-
-

4. Experiments#

-
    -
  • T: 1000

  • -
  • backbone: U-Net
    -각 down/upsampling 단계는 ResNet/ConvNext 블록 2개 + (groupnorm + attention + residual) + down/upsampling으로 구성됨

  • -
-
block_klass = partial(ResnetBlock, groups = resnet_block_groups)
-
-self.downs.append(nn.ModuleList([
-                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
-                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
-                Residual(PreNorm(dim_in, LinearAttention(dim_in))),
-                Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1)
-            ]))
-            
- self.ups.append(nn.ModuleList([
-                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
-                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
-                Residual(PreNorm(dim_out, LinearAttention(dim_out))),
-                Upsample(dim_out, dim_in) if not is_last else  nn.Conv2d(dim_out, dim_in, 3, padding = 1)
-            ]))
-
-
-
-
class Unet(nn.Module):
-    def __init__(
-        self,
-        dim,
-        init_dim = None,
-        out_dim = None,
-        dim_mults=(1, 2, 4, 8),
-        channels = 3,
-        self_condition = False,
-        resnet_block_groups = 8,
-        learned_variance = False,
-        learned_sinusoidal_cond = False,
-        random_fourier_features = False,
-        learned_sinusoidal_dim = 16
-    ):
-        super().__init__()
-
-        # determine dimensions
-
-        self.channels = channels
-        self.self_condition = self_condition
-        input_channels = channels * (2 if self_condition else 1)
-
-        init_dim = default(init_dim, dim)
-        self.init_conv = nn.Conv2d(input_channels, init_dim, 7, padding = 3)
-
-        dims = [init_dim, *map(lambda m: dim * m, dim_mults)]
-        in_out = list(zip(dims[:-1], dims[1:]))
-
-        block_klass = partial(ResnetBlock, groups = resnet_block_groups)
-
-        # time embeddings
-
-        time_dim = dim * 4
-
-        self.random_or_learned_sinusoidal_cond = learned_sinusoidal_cond or random_fourier_features
-
-        if self.random_or_learned_sinusoidal_cond:
-            sinu_pos_emb = RandomOrLearnedSinusoidalPosEmb(learned_sinusoidal_dim, random_fourier_features)
-            fourier_dim = learned_sinusoidal_dim + 1
-        else:
-            sinu_pos_emb = SinusoidalPosEmb(dim)
-            fourier_dim = dim
-
-        self.time_mlp = nn.Sequential(
-            sinu_pos_emb,
-            nn.Linear(fourier_dim, time_dim),
-            nn.GELU(),
-            nn.Linear(time_dim, time_dim)
-        )
-
-        # layers
-
-        self.downs = nn.ModuleList([])
-        self.ups = nn.ModuleList([])
-        num_resolutions = len(in_out)
-
-        for ind, (dim_in, dim_out) in enumerate(in_out):
-            is_last = ind >= (num_resolutions - 1)
-
-            self.downs.append(nn.ModuleList([
-                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
-                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
-                Residual(PreNorm(dim_in, LinearAttention(dim_in))),
-                Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1)
-            ]))
-
-        mid_dim = dims[-1]
-        self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim)
-        self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim)))
-        self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim)
-
-        for ind, (dim_in, dim_out) in enumerate(reversed(in_out)):
-            is_last = ind == (len(in_out) - 1)
-
-            self.ups.append(nn.ModuleList([
-                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
-                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
-                Residual(PreNorm(dim_out, LinearAttention(dim_out))),
-                Upsample(dim_out, dim_in) if not is_last else  nn.Conv2d(dim_out, dim_in, 3, padding = 1)
-            ]))
-
-        default_out_dim = channels * (1 if not learned_variance else 2)
-        self.out_dim = default(out_dim, default_out_dim)
-
-        self.final_res_block = block_klass(dim * 2, dim, time_emb_dim = time_dim)
-        self.final_conv = nn.Conv2d(dim, self.out_dim, 1)
-        
-  def forward(self, x, time, x_self_cond = None):
-          if self.self_condition:
-              x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x))
-              x = torch.cat((x_self_cond, x), dim = 1)
-
-          x = self.init_conv(x)
-          r = x.clone()
-
-          t = self.time_mlp(time)
-
-          h = []
-
-          for block1, block2, attn, downsample in self.downs:
-              x = block1(x, t)
-              h.append(x)
-
-              x = block2(x, t)
-              x = attn(x)
-              h.append(x)
-
-              x = downsample(x)
-
-          x = self.mid_block1(x, t)
-          x = self.mid_attn(x)
-          x = self.mid_block2(x, t)
-
-          for block1, block2, attn, upsample in self.ups:
-              x = torch.cat((x, h.pop()), dim = 1)
-              x = block1(x, t)
-
-              x = torch.cat((x, h.pop()), dim = 1)
-              x = block2(x, t)
-              x = attn(x)
-
-              x = upsample(x)
-
-          x = torch.cat((x, r), dim = 1)
-
-          x = self.final_res_block(x, t)
-          return self.final_conv(x)
-
-
-
    -
  • 16 x 16 feature map resolution에 self-attention. conv에서 차원을 3배로 늘리고 q,k,v로 분해.

  • -
-
class Attention(nn.Module):
-    def __init__(self, dim, heads = 4, dim_head = 32):
-        super().__init__()
-        self.scale = dim_head ** -0.5
-        self.heads = heads
-        hidden_dim = dim_head * heads
-
-        self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False)
-        self.to_out = nn.Conv2d(hidden_dim, dim, 1)
-
-    def forward(self, x):
-        b, c, h, w = x.shape
-        qkv = self.to_qkv(x).chunk(3, dim = 1)
-        q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv)
-
-        q = q * self.scale
-
-        sim = einsum('b h d i, b h d j -> b h i j', q, k)
-        attn = sim.softmax(dim = -1)
-        out = einsum('b h i j, b h d j -> b h i d', attn, v)
-
-        out = rearrange(out, 'b h (x y) d -> b (h d) x y', x = h, y = w)
-        return self.to_out(out)
-
-
-
    -
  • Linear attention

  • -
-
class LinearAttention(nn.Module):
-    def __init__(self, dim, heads = 4, dim_head = 32):
-        super().__init__()
-        self.scale = dim_head ** -0.5
-        self.heads = heads
-        hidden_dim = dim_head * heads
-        self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False)
-
-        self.to_out = nn.Sequential(
-            nn.Conv2d(hidden_dim, dim, 1),
-            LayerNorm(dim)
-        )
-
-    def forward(self, x):
-        b, c, h, w = x.shape
-        qkv = self.to_qkv(x).chunk(3, dim = 1)
-        q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv)
-
-        q = q.softmax(dim = -2)
-        k = k.softmax(dim = -1)
-
-        q = q * self.scale
-        v = v / (h * w)
-
-        context = torch.einsum('b h d n, b h e n -> b h d e', k, v)
-
-        out = torch.einsum('b h d e, b h d n -> b h e n', context, q)
-        out = rearrange(out, 'b h c (x y) -> b (h c) x y', h = self.heads, x = h, y = w)
-        return self.to_out(out)
-
-
-
    -
  • Diffusion time \(T\)는 각 residual block에 transformer sinusoidal positional embedding이 추가돼서 구분됨

  • -
-
class SinusoidalPosEmb(nn.Module):
-    def __init__(self, dim):
-        super().__init__()
-        self.dim = dim
-
-    def forward(self, x):
-        device = x.device
-        half_dim = self.dim // 2
-        emb = math.log(10000) / (half_dim - 1)
-        emb = torch.exp(torch.arange(half_dim, device=device) * -emb)
-        emb = x[:, None] * emb[None, :]
-        emb = torch.cat((emb.sin(), emb.cos()), dim=-1)
-        return emb
-
-
-
-

4-1. Sample quality#

-
-DDPM_13 -
-

Fig. 42 Train score of DDPM \ (source: https://arxiv.org/abs/2006.11239)#

-
-
-

FID, IS로 metric 계산. Unconditional model인데도 conditional model보다 우월. Codelength에서 차이가 없기 때문에 overfitting의 가능성도 적음.

-
-
    -
  • FID score: Inception V3으로 이미지의 분포를 계산한 metric

  • -
  • Unconditional model: 한번 dataset에 학습되면 추가적인 context 없이 image를 생성

  • -
  • Conditional model: Class, label 등의 추가 정보를 받아 image를 생성

  • -
-
-

\(\mu\)보다 \(\epsilon\)을 계산하는 것이 성적이 좋고, fixed variance를 사용했을 때에도 성능이 감소하지 않음.

-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + DDPM — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

DDPM#

+
+DDPM_01 +
+

Fig. 34 DDPM samples \ (source: https://arxiv.org/abs/2006.11239)#

+
+
+
+
+
+

1. Introduction#

+
+DDPM_02 +
+

Fig. 35 Diffusion models \ (source: https://velog.io/@yetsyl0705/What-are-Diffusion-Models)#

+
+
+

Diffusion modelvariational inference로 학습시켜 데이터를 생성하는 parameterized Markov chain. Diffusion model은 Markov가 데이터가 normal distribution의 형태를 할 때까지 noise를 더해가는 diffusion process이를 역으로 거치며 학습하는 reverse process로 구성됨.

+

Diffusion model은 정의하기 쉽고 학습시키는 것도 편리함. 또한 높은 품질의 sample(output)도 생성이 가능.

+
+
    +
  • Variational inference(변분추론): 사후확률(posterior) 분포 \(p(z +|x)\)를 다루기 쉬운 확률분포 \(q(z)\)로 근사(approximation)하는 것

  • +
  • Parameterize: 하나의 표현식에 대해 다른 parameter를 사용하여 다시 표현하는 과정. 이 과정에서 보통 parameter의 개수를 표현 식의 차수보다 적은 수로 선택(ex. 3차 표현식 –> 2개 parameter 사용)하므로, 낮은 차수로의 mapping 함수(ex. 3D –> 2D)가 생성

  • +
  • Markov chain: 어떤 상태에서 다른 상태로 넘어갈 때, 바로 전 단계의 상태에만 영향을 받는 확률 과정

  • +
+
+
+
+
+

2. Background#

+
+DDPM_03 +
+

Fig. 36 Graphical model of DDPM \ (source: https://arxiv.org/abs/2006.11239)#

+
+
+
+

2-1. Forward(diffusion) process \(q(\mathbf{x}_t|\mathbf{x}_{t-1})\)#

+
+\[ +q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right):=\prod_{t=1}^T q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right), \quad q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right):=\mathcal{N}\left(\mathbf{x}_t ; \sqrt{1-\beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I}\right) +\]
+

Markov chain으로 data에 noise를 추가하는 과정. Noise를 추가할 때 variance schedule \(\beta_1,,,\beta_T\)로 scaling을 한 후 더해준다.

+
    +
  • \(\beta_t = 1\)이면 mean인 \(\sqrt{1-\beta_t}\mathbf{x}_{t-1} = 0\). 이전 정보를 갖지 못하고 노이즈가 증가함

  • +
  • 단순히 noise만을 더해주는게 아니라 \(\sqrt{1-\beta_t}\)로 scaling하는 이유는 variance가 발산하는 것을 막기 위함

  • +
  • \(q(x_1|x_0)\): \(x_0\)에 noise를 추가해 \(x_1\)을 만드는 과정

  • +
  • \(x_T\)는 완전 destroy된 noise 상태 ~ \(N(x_T;0, I)\)

  • +
+
+
+

2-2. Reverse process \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\)#

+
+\[ +p_\theta\left(\mathbf{x}_{0: T}\right):=p\left(\mathbf{x}_T\right) \prod_{t=1}^T p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right), \quad p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right):=\mathcal{N}\left(\mathbf{x}_{t-1} ; \boldsymbol{\mu}_\theta\left(\mathbf{x}_t, t\right), \boldsymbol{\Sigma}_\theta\left(\mathbf{x}_t, t\right)\right) +\]
+

Reverse process로 가우시안 노이즈를 사용하는 이유는 1994년 논문에 forward process가 가우시안이면 reverse process도 가우시안으로 쓰면 된다라는 증명이 있다고 함.

+

여기서 우리가 해야 할 것은 \(\mathbf{x}_t\)를 보고 \(\mathbf{x}_{t-1}\)의 평균 \(\mu_\theta\)과 분산 \(\Sigma_\theta\)을 예측해내는 것.

+
    +
  • Hierarachical VAE에서의 decoding 과정과 비슷함

  • +
  • \(\mu_\theta\)과 분산 \(\Sigma_\theta\)는 학습 가능한 parameter

  • +
+
+
+

2-3. Loss Function \(L\)#

+

Diffusion model의 목적은 **noise를 어떻게 제거할 것인가?**이다. \(x_t\)가 들어왔을 때 \(x_{t-1}\)을 예측할 수 있다면 \(x_0\) 또한 예측이 가능해짐.

+
+\[ +\mathbb{E}\left[-\log p_\theta\left(\mathbf{x}_0\right)\right] \leq \mathbb{E}_q\left[-\log \frac{p_\theta\left(\mathbf{x}_{0: T}\right)}{q\left(\mathbf{x}_{1: T} \mid \mathbf{x}_0\right)}\right]=\mathbb{E}_q\left[-\log p\left(\mathbf{x}_T\right)-\sum_{t \geq 1} \log \frac{p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)}{q\left(\mathbf{x}_t \mid \mathbf{x}_{t-1}\right)}\right]=: L +\]
+

본 논문에서는 negative log likelihood를 최소화하는 방향으로 진행. 위 수식을 ELBO(Evidence of Lower BOund)로 우항과 같이 정리하고 이를 풀어내면

+
+

ELBO의 역할은 우리가 관찰한 P(z|x)가 다루기 힘든 분포를 이루고 있을 때 이를 조금 더 다루기 쉬운 분포인 Q(x)로 대신 표현하려 하는 과정에서 두 분포 (P(z|x)와 Q(x))의 차이 (KL Divergence)를 최소화 하기 위해 사용된다.

+
+
+\[ +\mathbb{E}_q[\underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_T \mid \mathbf{x}_0\right) \| p\left(\mathbf{x}_T\right)\right)}_{L_T}+\sum_{t>1} \underbrace{D_{\mathrm{KL}}\left(q\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0\right) \| p_\theta\left(\mathbf{x}_{t-1} \mid \mathbf{x}_t\right)\right)}_{L_{t-1}} \underbrace{-\log p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right)}_{L_0}] +\]
+

와 같은 결과가 나온다.

+
    +
  • \(L_T\): Regularization term으로 \(\beta_t\)를 학습시킴

  • +
  • \(L_{t-1}\): Reconstruction term으로 매 단계에서 noise를 지우는 지움

  • +
  • \(L_0\): Reconstruction term으로 최종 단계에서 image를 생성

  • +
+
+
+
+
+

3. Diffusion models and denoising encoders#

+

DDPM에서는 inductive bias를 늘려 모델을 더 stable하고 성능도 개선할 수 있었음.

+
+

Inductive bias: 학습 모델이 지금까지 만나보지 못했던 상황에서 정확한 예측을 하기 위해 사용하는 추가적인 가정, 즉 우리가 풀려는 문제에 대한 정보를 모델에 적용하는 것

+
+
+

3-1. Forward process and \(L_T\)#

+

\(\beta_t\)를 고정했더니 학습이 잘됨. 10^-4 ~ 0.02로 linear하게 image에 가까울수록 noise를 적게 주는 방식으로 설정.

+

따라서 \(q\)에는 학습 가능한 parameter가 없어 \(L_T\)는 0이 되기 때문에 삭제할 수 있었음.

+
+
+

3-2. Reverse process and \(L_{1:T-1}\)#

+
+\[ +L_{t-1}=D_{K L}\left(q\left(x_{t-1} \mid x_t, x_0\right) \| p_\theta\left(x_{t-1} \mid x_t\right)\right) +\]
+
    +
  • \( +q\left(x_{t-1} \mid x_t, x_0\right)=N\left(x_{t-1} ; \tilde{\mu}\left(x_t, x_0\right), \tilde{\beta}_t \mathrm{I}\right) +\)

  • +
  • \( +p_\theta\left(x_{t-1} \mid x_t\right)=\mathcal{N}\left(x_{t-1} ; \mu_\theta\left(x_t, t\right), \sum_\theta\left(x_t, t\right)\right) +\)

  • +
+

\(L_{1:T-1}\)는 forward progress posterior를 예측하는 loss. \(\mathbf{x}_{t-1}\)에서 noise를 더해 \(\mathbf{x}_{t}\)를 만들었을때, 그 과정을 복원 \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\) 하는 과정을 학습.

+
+DDPM_08 +
+

Fig. 37 Loss Simplication \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

+
+
+
    +
  • \(\Sigma_\theta\): \(\beta\)를 상수로 가정했고 \(p(\mathbf{x}_{t-1}|\mathbf{x}_t)\)의 variance가 \(\beta\)에 영향을 받기 때문에 학습시키지 않아도 된다고 생각해 variance term을 제거함.

  • +
+
+DDPM_09 +
+

Fig. 38 Residual Estimation \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

+
+
+
    +
  • \(\mu_\theta\): DDPM에서는 \(\mu_\theta\)를 바로 구하지 않고 residual \(\epsilon_\theta\)만 구해 정확도를 높임.

  • +
+
+
+

3-3. Data scaling, reverse process decoder and \(L_0\)#

+
+\[\begin{split} +\begin{aligned} +p_\theta\left(\mathbf{x}_0 \mid \mathbf{x}_1\right) & =\prod_{i=1}^D \int_{\delta_{-}\left(x_0^i\right)}^{\delta_{+}\left(x_0^i\right)} \mathcal{N}\left(x ; \mu_\theta^i\left(\mathbf{x}_1, 1\right), \sigma_1^2\right) d x \\ +\delta_{+}(x) & =\left\{\begin{array}{ll} +\infty & \text { if } x=1 \\ +x+\frac{1}{255} & \text { if } x<1 +\end{array} \quad \delta_{-}(x)= \begin{cases}-\infty & \text { if } x=-1 \\ +x-\frac{1}{255} & \text { if } x>-1\end{cases} \right. +\end{aligned} +\end{split}\]
+

[0, 255]의 image를 [-1,1] 사이로 linearly mapping. Sampling 마지막 단계에는 noise를 추가하지 않음.

+

\(L_0\)은 두 normal distribution 사이의 KL divergence를 나타냄.

+
    +
  • \(D\): Data dimensionality

  • +
  • \(i\): 좌표

  • +
+
+
+

3-4. Simplified training objective#

+
+DDPM_10 +
+

Fig. 39 Simplified training objective \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

+
+
+
+DDPM_11 +
+

Fig. 40 Final Loss \ (source: https://velog.io/@sjina0722/논문-리뷰-Denoising-Diffusion-Probabilistic-Models)#

+
+
+

최종 loss는 위와 같이 나타난다. Ground truth - estimated output간 MSE loss를 줄이는 과정이 denoising과 비슷해 DDPM이라는 이름이 붙음.

+

Simplified objective을 통해 diffusion process를 학습하면 매우 작은 t 에서뿐만 아니라 큰 t에 대해서도 network 학습이 가능하기 때문에 매우 효과적.

+
+DDPM_12 +
+

Fig. 41 Psuedo code of training process \ (source: https://arxiv.org/abs/2006.11239)#

+
+
+
    +
  • Algorithm 1: Training

    +
      +
    • Noise를 더해나가는 과정, network(\(\epsilon_\theta\), \(p_\theta\))가 t step에서 noise(\(\epsilon\))가 얼마만큼 더해졌는지를 학습한다.

    • +
    • 학습 시에는 특정 step의 이미지가 얼마나 gaussian noise가 추가되었는지를 예측하도록 학습된다.

    • +
    • 코드에서는 랜덤 노이즈와 시간 단계 t로 노이즈가 추가된 이미지를 얻고 해당 이미지를 보고 모델이 노이즈를 예측

    • +
    +
  • +
+
def p_losses(self, x_start, t, noise = None):
+        b, c, h, w = x_start.shape
+        noise = default(noise, lambda: torch.randn_like(x_start))
+
+        # noise sample
+
+        x = self.q_sample(x_start = x_start, t = t, noise = noise)
+
+        # if doing self-conditioning, 50% of the time, predict x_start from current set of times
+        # and condition with unet with that
+        # this technique will slow down training by 25%, but seems to lower FID significantly
+
+        x_self_cond = None
+        if self.self_condition and random() < 0.5:
+            with torch.no_grad():
+                x_self_cond = self.model_predictions(x, t).pred_x_start
+                x_self_cond.detach_()
+
+        # predict and take gradient step
+
+        model_out = self.model(x, t, x_self_cond)
+
+        if self.objective == 'pred_noise':
+            target = noise
+        elif self.objective == 'pred_x0':
+            target = x_start
+        elif self.objective == 'pred_v':
+            v = self.predict_v(x_start, t, noise)
+            target = v
+        else:
+            raise ValueError(f'unknown objective {self.objective}')
+
+        loss = self.loss_fn(model_out, target, reduction = 'none')
+        loss = reduce(loss, 'b ... -> b (...)', 'mean')
+
+        loss = loss * extract(self.loss_weight, t, loss.shape)
+        return loss.mean()
+
+
+
    +
  • Algorithm 2: Sampling

    +
      +
    • Network를 학습하고 나면, gaussian noise에서 시작해서 순차적으로 denoising 하는 것이 가능하다. (by parameterized markovian chain)

    • +
    • 코드에서는 noise 제거 후 소량의 noise를 다시 추가하고 있음

    • +
    +
  • +
+
@torch.no_grad()
+def p_sample(self, x, t: int, x_self_cond = None):
+    b, *_, device = *x.shape, x.device
+    batched_times = torch.full((b,), t, device = x.device, dtype = torch.long)
+    model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = True)
+    noise = torch.randn_like(x) if t > 0 else 0. # no noise if t == 0
+    pred_img = model_mean + (0.5 * model_log_variance).exp() * noise
+    return pred_img, x_start
+
+
+
+
+
+

4. Experiments#

+
    +
  • T: 1000

  • +
  • backbone: U-Net
    +각 down/upsampling 단계는 ResNet/ConvNext 블록 2개 + (groupnorm + attention + residual) + down/upsampling으로 구성됨

  • +
+
block_klass = partial(ResnetBlock, groups = resnet_block_groups)
+
+self.downs.append(nn.ModuleList([
+                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
+                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
+                Residual(PreNorm(dim_in, LinearAttention(dim_in))),
+                Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1)
+            ]))
+            
+ self.ups.append(nn.ModuleList([
+                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
+                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
+                Residual(PreNorm(dim_out, LinearAttention(dim_out))),
+                Upsample(dim_out, dim_in) if not is_last else  nn.Conv2d(dim_out, dim_in, 3, padding = 1)
+            ]))
+
+
+
+
class Unet(nn.Module):
+    def __init__(
+        self,
+        dim,
+        init_dim = None,
+        out_dim = None,
+        dim_mults=(1, 2, 4, 8),
+        channels = 3,
+        self_condition = False,
+        resnet_block_groups = 8,
+        learned_variance = False,
+        learned_sinusoidal_cond = False,
+        random_fourier_features = False,
+        learned_sinusoidal_dim = 16
+    ):
+        super().__init__()
+
+        # determine dimensions
+
+        self.channels = channels
+        self.self_condition = self_condition
+        input_channels = channels * (2 if self_condition else 1)
+
+        init_dim = default(init_dim, dim)
+        self.init_conv = nn.Conv2d(input_channels, init_dim, 7, padding = 3)
+
+        dims = [init_dim, *map(lambda m: dim * m, dim_mults)]
+        in_out = list(zip(dims[:-1], dims[1:]))
+
+        block_klass = partial(ResnetBlock, groups = resnet_block_groups)
+
+        # time embeddings
+
+        time_dim = dim * 4
+
+        self.random_or_learned_sinusoidal_cond = learned_sinusoidal_cond or random_fourier_features
+
+        if self.random_or_learned_sinusoidal_cond:
+            sinu_pos_emb = RandomOrLearnedSinusoidalPosEmb(learned_sinusoidal_dim, random_fourier_features)
+            fourier_dim = learned_sinusoidal_dim + 1
+        else:
+            sinu_pos_emb = SinusoidalPosEmb(dim)
+            fourier_dim = dim
+
+        self.time_mlp = nn.Sequential(
+            sinu_pos_emb,
+            nn.Linear(fourier_dim, time_dim),
+            nn.GELU(),
+            nn.Linear(time_dim, time_dim)
+        )
+
+        # layers
+
+        self.downs = nn.ModuleList([])
+        self.ups = nn.ModuleList([])
+        num_resolutions = len(in_out)
+
+        for ind, (dim_in, dim_out) in enumerate(in_out):
+            is_last = ind >= (num_resolutions - 1)
+
+            self.downs.append(nn.ModuleList([
+                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
+                block_klass(dim_in, dim_in, time_emb_dim = time_dim),
+                Residual(PreNorm(dim_in, LinearAttention(dim_in))),
+                Downsample(dim_in, dim_out) if not is_last else nn.Conv2d(dim_in, dim_out, 3, padding = 1)
+            ]))
+
+        mid_dim = dims[-1]
+        self.mid_block1 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim)
+        self.mid_attn = Residual(PreNorm(mid_dim, Attention(mid_dim)))
+        self.mid_block2 = block_klass(mid_dim, mid_dim, time_emb_dim = time_dim)
+
+        for ind, (dim_in, dim_out) in enumerate(reversed(in_out)):
+            is_last = ind == (len(in_out) - 1)
+
+            self.ups.append(nn.ModuleList([
+                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
+                block_klass(dim_out + dim_in, dim_out, time_emb_dim = time_dim),
+                Residual(PreNorm(dim_out, LinearAttention(dim_out))),
+                Upsample(dim_out, dim_in) if not is_last else  nn.Conv2d(dim_out, dim_in, 3, padding = 1)
+            ]))
+
+        default_out_dim = channels * (1 if not learned_variance else 2)
+        self.out_dim = default(out_dim, default_out_dim)
+
+        self.final_res_block = block_klass(dim * 2, dim, time_emb_dim = time_dim)
+        self.final_conv = nn.Conv2d(dim, self.out_dim, 1)
+        
+  def forward(self, x, time, x_self_cond = None):
+          if self.self_condition:
+              x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x))
+              x = torch.cat((x_self_cond, x), dim = 1)
+
+          x = self.init_conv(x)
+          r = x.clone()
+
+          t = self.time_mlp(time)
+
+          h = []
+
+          for block1, block2, attn, downsample in self.downs:
+              x = block1(x, t)
+              h.append(x)
+
+              x = block2(x, t)
+              x = attn(x)
+              h.append(x)
+
+              x = downsample(x)
+
+          x = self.mid_block1(x, t)
+          x = self.mid_attn(x)
+          x = self.mid_block2(x, t)
+
+          for block1, block2, attn, upsample in self.ups:
+              x = torch.cat((x, h.pop()), dim = 1)
+              x = block1(x, t)
+
+              x = torch.cat((x, h.pop()), dim = 1)
+              x = block2(x, t)
+              x = attn(x)
+
+              x = upsample(x)
+
+          x = torch.cat((x, r), dim = 1)
+
+          x = self.final_res_block(x, t)
+          return self.final_conv(x)
+
+
+
    +
  • 16 x 16 feature map resolution에 self-attention. conv에서 차원을 3배로 늘리고 q,k,v로 분해.

  • +
+
class Attention(nn.Module):
+    def __init__(self, dim, heads = 4, dim_head = 32):
+        super().__init__()
+        self.scale = dim_head ** -0.5
+        self.heads = heads
+        hidden_dim = dim_head * heads
+
+        self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False)
+        self.to_out = nn.Conv2d(hidden_dim, dim, 1)
+
+    def forward(self, x):
+        b, c, h, w = x.shape
+        qkv = self.to_qkv(x).chunk(3, dim = 1)
+        q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv)
+
+        q = q * self.scale
+
+        sim = einsum('b h d i, b h d j -> b h i j', q, k)
+        attn = sim.softmax(dim = -1)
+        out = einsum('b h i j, b h d j -> b h i d', attn, v)
+
+        out = rearrange(out, 'b h (x y) d -> b (h d) x y', x = h, y = w)
+        return self.to_out(out)
+
+
+
    +
  • Linear attention

  • +
+
class LinearAttention(nn.Module):
+    def __init__(self, dim, heads = 4, dim_head = 32):
+        super().__init__()
+        self.scale = dim_head ** -0.5
+        self.heads = heads
+        hidden_dim = dim_head * heads
+        self.to_qkv = nn.Conv2d(dim, hidden_dim * 3, 1, bias = False)
+
+        self.to_out = nn.Sequential(
+            nn.Conv2d(hidden_dim, dim, 1),
+            LayerNorm(dim)
+        )
+
+    def forward(self, x):
+        b, c, h, w = x.shape
+        qkv = self.to_qkv(x).chunk(3, dim = 1)
+        q, k, v = map(lambda t: rearrange(t, 'b (h c) x y -> b h c (x y)', h = self.heads), qkv)
+
+        q = q.softmax(dim = -2)
+        k = k.softmax(dim = -1)
+
+        q = q * self.scale
+        v = v / (h * w)
+
+        context = torch.einsum('b h d n, b h e n -> b h d e', k, v)
+
+        out = torch.einsum('b h d e, b h d n -> b h e n', context, q)
+        out = rearrange(out, 'b h c (x y) -> b (h c) x y', h = self.heads, x = h, y = w)
+        return self.to_out(out)
+
+
+
    +
  • Diffusion time \(T\)는 각 residual block에 transformer sinusoidal positional embedding이 추가돼서 구분됨

  • +
+
class SinusoidalPosEmb(nn.Module):
+    def __init__(self, dim):
+        super().__init__()
+        self.dim = dim
+
+    def forward(self, x):
+        device = x.device
+        half_dim = self.dim // 2
+        emb = math.log(10000) / (half_dim - 1)
+        emb = torch.exp(torch.arange(half_dim, device=device) * -emb)
+        emb = x[:, None] * emb[None, :]
+        emb = torch.cat((emb.sin(), emb.cos()), dim=-1)
+        return emb
+
+
+
+

4-1. Sample quality#

+
+DDPM_13 +
+

Fig. 42 Train score of DDPM \ (source: https://arxiv.org/abs/2006.11239)#

+
+
+

FID, IS로 metric 계산. Unconditional model인데도 conditional model보다 우월. Codelength에서 차이가 없기 때문에 overfitting의 가능성도 적음.

+
+
    +
  • FID score: Inception V3으로 이미지의 분포를 계산한 metric

  • +
  • Unconditional model: 한번 dataset에 학습되면 추가적인 context 없이 image를 생성

  • +
  • Conditional model: Class, label 등의 추가 정보를 받아 image를 생성

  • +
+
+

\(\mu\)보다 \(\epsilon\)을 계산하는 것이 성적이 좋고, fixed variance를 사용했을 때에도 성능이 감소하지 않음.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/I-DDPM.html b/docs/review/I-DDPM.html old mode 100644 new mode 100755 index 9b69fee8..e4665bb7 --- a/docs/review/I-DDPM.html +++ b/docs/review/I-DDPM.html @@ -1,817 +1,825 @@ - - - - - - - - - - - - I-DDPM — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

-
    -
  • Title: {Improved Denoising Diffusion Probabilistic Models}, {CVPR 2021}

  • -
  • Reference

    - -
  • -
  • Author: Seunghwan Ji

  • -
  • Last updated on Aug. 6, 2023

  • -
-
-
-

I-DDPM#

-
-

학습 자료#

-

Improved Denoising Diffusion Probabilistic Models

-

https://arxiv.org/pdf/2102.09672.pdf

-
-

CVPR 2021, Alex Nichol

-
-
-

Abstract#

-
    -
  • DDPM을 약간 수정함으로써 High Quality를 유지하고, Log Likelihood수치도 개선할 수 있는 향상된 모델을 제안

  • -
  • Sampling시 Base 보다 더 적은 Step으로 비슷한 퀄리티의 결과를 낼 수 있는 방법을 제안

  • -
  • Model의 Scale과 Diffusion Step에 따른 Sample Quailty와 Likelihood 수치간의 관계를 연구

  • -
-
-
-

1. Introduction#

-
    -
  • 최근 DDPM(Ho et al.) 모델은 Generate 분야에서 High Quality의 이미지를 생성해내는 수준까지 왔다.

  • -
  • 하지만, Image의 Quality에 반해 log-likelihood 수치는 다른 generative 모델에비해 현저히 떨어졌다. (e.g. VAE)

  • -
  • 또 DDPM이 Diversity가 낮은 Dataset(CIFAR-10, LSUN)에서는 잘 동작했지만, High Diversity Dataset에서의 동작은 증명되지 못했다.

  • -
  • I-DDPM에서는

    -
      -
    1. Log-Likelihood 수치 개선

    2. -
    3. ImageNet같은 Diversity가 높은 Dataset에서도 잘 동작

    4. -
    5. Reverse Process에서의 Loss Term 개선

    6. -
    -

    한 모델을 제안하였다.

    -
  • -
  • 추가로 연구 과정 중, I-DDPM이 Base (DDPM) 모델에 비해 훨씬 더 적은 Step으로 비슷한 Quality를 내는 것을 확인

  • -
-

Log-Likelihood 값이 중요한 이유

-
    -
  • 기존 연구들에서 Loglikelihood 수치와 Sample의 Quality간의 연관성을 보이는 연구들이 많았다.

    -
      -
    • Data의 Distribution에 대해 Model이 학습한 정도를 수치화한 느낌

    • -
    -
  • -
  • 수치가 좋아지면 Sample Quality도 따라 증가하는 경향을 보였다.

  • -
  • 따라서 DDPM에서도 LogLikelihood 수치를 개선한다면 Sample Quality도 따라서 더 증가할 가능성이 있지 않을까?

  • -
  • https://angeloyeo.github.io/2020/07/17/MLE.html

  • -
-
-
-

2. Denoising Diffusion Probabilistic Models#

-

DDPM

-
    -
  • Process

    -
      -
    • Forward Process

      -
      -I-DDPM_00 -
      -

      Fig. 143 Equation 1#

      -
      -
      -
    • -
    • Reverse Process

      -
      -I-DDPM_01 -
      -

      Fig. 144 Equation 2#

      -
      -
      -
    • -
    -
  • -
  • Forward Process에서 입힌 Noise를 Neural Model의 Reverse Process로 예측하도록 학습하는 형태

  • -
  • 이 때 Noising & Denoising에 관한 (Hyper) Parameter로 \({B_{t}}\)\(\tilde{B_{t}}\)를 사용

    -
      -
    • \({B_{t}}\) : time step 에 따른 noising할 정도

    • -
    • \(\tilde{B_{t}}\) : Reverse Step에서 Denoising을 위한 Parameter로 아래와같이 정의

      -
      -I-DDPM_02 -
      -

      Fig. 145 Equation 3#

      -
      -
      -
    • -
    -
  • -
  • 하지만 DDPM에서는 \(\tilde{B_{t}}\) 대신 \({B_{t}}\)를 사용해도 비슷한 수치를 보여서 \({B_{t}}\) (constant)로 고정

  • -
-
-
-

3. Improving the Log-likelihood#

-
    -
  • 위의 문장 (\(\tilde{B_{t}}\) 대신 \({B_{t}}\)를 사용)에서 의문점

    -
      -
    • 사실 \({B_{t}}\)\(\tilde{B_{t}}\)는 정 반대의 역할을 하는 Parameter인데 왜 비슷한 결과를 보였고, 결국 같은 값으로 Fix를 하는게 맞을까?

      -
      -I-DDPM_03 -
      -

      Fig. 146 Figure 1#

      -
      -
      -
    • -
    • Diffusion Step간 \({B_{t}}\)\(\tilde{B_{t}}\)의 차이를 비교해보면 Diffusion Step이 커질수록 두개의 값은 거의 동일해진다. (Figure.1)

      -
      -I-DDPM_04 -
      -

      Fig. 147 Figure 2#

      -
      -
      -
    • -
    • 하지만 Figure.2를 보면 모델의 성능은 대부분 Step 초반에 결정되는데, Step 초반에는 두 값의 차이가 큰 것을 확인할 수 있다.

      -
        -
      • Model의 성능이 결정되는 부분 = Loss 가 급격하게 떨어지는 부분

      • -
      -

      ⇒ 따라서, \({B_{t}}\)\(\tilde{B_{t}}\)를 동일한 값으로 두고 \(\tilde{B_{t}}\)를 Non Trainable Parameter로 두는것은 설계의 Miss

      -
    • -
    • 하지만, \(\tilde{B_{t}}\) 자체를 학습하기에는 값의 범위가 너무 작아서 \({B_{t}}\)\(\tilde{B_{t}}\)의 Interpolation 값을 Predict하도록 설계

      -
      -I-DDPM_05 -
      -

      Fig. 148 Figure 3#

      -
      -
      -
    • -
    • Hybrid Loss

      -
        -
      • \(L_{hyprid} = L_{simple} + λL_{vlb}\)

      • -
      -
    • -
    -
  • -
  • Noise Schedule

    -
      -
    • DDPM의 경우 High Resolution 이미지에대해 잘 동작하지만, Low-Resolution (e.g. 32x32, 64x64)의 이미지에 대해서는 잘 동작하지 않는것을 확인

    • -
    • Noise Scheduling에서 Linear mode의 Limitation이 있음을 지적

    • -
    -
  • -
  • Gradient Noise

    -
      -
    • Model을 \(L_{vlb}\)를 Direct로 최적화하도록 설계하면 Best

    • -
    • 하지만 아래 이미지와같이 Loss 자체가 unstable해서 직접 최적화에는 어려움이 있음

      -
      -I-DDPM_09 -
      -

      Fig. 149 Figure 4#

      -
      -
      -
    • -
    • 따라서 \(L_{vlb}\)의 Variance를 줄이기위해(=stable) Importance Sampling 기법을 도입

    • -
    • 위 Fig.2에서 보면 학습 말기는 Loss의 변화에 큰 영향이 없으므로 확률적으로 학습 초반의 데이터를 좀더 sampling해서 학습하도록 설계

    • -
    • 실제로 적용해본 결과 \(L_{hybrid}\)보다 더 낮은 Loss 를 보임

    • -
    • \(L_{hybrid}\)에 Importance Sampling을 적용하면?

      -
        -
      • 적용 전보다 좋지 않은 결과를 보인다..

      • -
      -
    • -
    -
  • -
-

Result

-
-I-DDPM_10 -
-

Fig. 150 Table 1#

-
-
-
-I-DDPM_11 -
-

Fig. 151 Table 2#

-
-
-
    -
  • DDPM에서 다소 취약했던 ImageNet 64x64와 CIDAR-10 데이터를 기준

    -
      -
    • \(L_{vlb}\)의 경우 Importance sampling을 적용한 결과

    • -
    -
  • -
-
-I-DDPM_12 -
-

Fig. 152 Table 3#

-
-
-
    -
  • Convolution 모델이나 Diffusion 모델중에서는 뛰어나지만, Fully Transformer 모델에 비해서는 다소 부족한 면이 있음

  • -
-
-
-

4. Improcing Sampling Speed#

-
    -
  • Sampling Speed를 높이기 위한 방법을 제안

    -
      -
    • Training 시에는 전체 Step(1, … , T)을 학습

    • -
    • Sampling 시에는 몇몇 Step만 Sampling

    • -
    -
  • -
  • 결과는?

  • -
-
-I-DDPM_13 -
-

Fig. 153 Figure 5#

-
-
-
-I-DDPM_14 -
-

Fig. 154 Figure 6#

-
-
-

⇒ 100 Step만 가도 Full Model과 비슷한 FiD값을 보임

-
-
-

5. Comparison to GANs#

-
    -
  • Class Conditional Generation + P&R Metric으로 GAN 모델(BigGAN)과 성능을 비교

    -
    -I-DDPM_15 -
    -

    Fig. 155 Figure 7#

    -
    -
    -
      -
    • Big-GAN Deep 모델보다 생성 타겟에 대한 FiD 수치나 Recall metric에서 더 뛰어난 성능을 보임

    • -
    -
  • -
-
-
-

6. Scaling Model Size#

-
    -
  • 다양한 Capacity를 가진 모델의 FiD와 NLL 값을 비교

  • -
-
-I-DDPM_16 -
-

Fig. 156 Figure 8#

-
-
-
-I-DDPM_17 -
-

Fig. 157 Figure 9#

-
-
-

⇒ 모델의 크기와 학습량 모두 Step에 어느정도 비례함

-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + I-DDPM — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+
    +
  • Title: {Improved Denoising Diffusion Probabilistic Models}, {CVPR 2021}

  • +
  • Reference

    + +
  • +
  • Author: Seunghwan Ji

  • +
  • Last updated on Aug. 6, 2023

  • +
+
+
+

I-DDPM#

+
+

학습 자료#

+

Improved Denoising Diffusion Probabilistic Models

+

https://arxiv.org/pdf/2102.09672.pdf

+
+

CVPR 2021, Alex Nichol

+
+
+

Abstract#

+
    +
  • DDPM을 약간 수정함으로써 High Quality를 유지하고, Log Likelihood수치도 개선할 수 있는 향상된 모델을 제안

  • +
  • Sampling시 Base 보다 더 적은 Step으로 비슷한 퀄리티의 결과를 낼 수 있는 방법을 제안

  • +
  • Model의 Scale과 Diffusion Step에 따른 Sample Quailty와 Likelihood 수치간의 관계를 연구

  • +
+
+
+

1. Introduction#

+
    +
  • 최근 DDPM(Ho et al.) 모델은 Generate 분야에서 High Quality의 이미지를 생성해내는 수준까지 왔다.

  • +
  • 하지만, Image의 Quality에 반해 log-likelihood 수치는 다른 generative 모델에비해 현저히 떨어졌다. (e.g. VAE)

  • +
  • 또 DDPM이 Diversity가 낮은 Dataset(CIFAR-10, LSUN)에서는 잘 동작했지만, High Diversity Dataset에서의 동작은 증명되지 못했다.

  • +
  • I-DDPM에서는

    +
      +
    1. Log-Likelihood 수치 개선

    2. +
    3. ImageNet같은 Diversity가 높은 Dataset에서도 잘 동작

    4. +
    5. Reverse Process에서의 Loss Term 개선

    6. +
    +

    한 모델을 제안하였다.

    +
  • +
  • 추가로 연구 과정 중, I-DDPM이 Base (DDPM) 모델에 비해 훨씬 더 적은 Step으로 비슷한 Quality를 내는 것을 확인

  • +
+

Log-Likelihood 값이 중요한 이유

+
    +
  • 기존 연구들에서 Loglikelihood 수치와 Sample의 Quality간의 연관성을 보이는 연구들이 많았다.

    +
      +
    • Data의 Distribution에 대해 Model이 학습한 정도를 수치화한 느낌

    • +
    +
  • +
  • 수치가 좋아지면 Sample Quality도 따라 증가하는 경향을 보였다.

  • +
  • 따라서 DDPM에서도 LogLikelihood 수치를 개선한다면 Sample Quality도 따라서 더 증가할 가능성이 있지 않을까?

  • +
  • https://angeloyeo.github.io/2020/07/17/MLE.html

  • +
+
+
+

2. Denoising Diffusion Probabilistic Models#

+

DDPM

+
    +
  • Process

    +
      +
    • Forward Process

      +
      +I-DDPM_00 +
      +

      Fig. 143 Equation 1#

      +
      +
      +
    • +
    • Reverse Process

      +
      +I-DDPM_01 +
      +

      Fig. 144 Equation 2#

      +
      +
      +
    • +
    +
  • +
  • Forward Process에서 입힌 Noise를 Neural Model의 Reverse Process로 예측하도록 학습하는 형태

  • +
  • 이 때 Noising & Denoising에 관한 (Hyper) Parameter로 \({B_{t}}\)\(\tilde{B_{t}}\)를 사용

    +
      +
    • \({B_{t}}\) : time step 에 따른 noising할 정도

    • +
    • \(\tilde{B_{t}}\) : Reverse Step에서 Denoising을 위한 Parameter로 아래와같이 정의

      +
      +I-DDPM_02 +
      +

      Fig. 145 Equation 3#

      +
      +
      +
    • +
    +
  • +
  • 하지만 DDPM에서는 \(\tilde{B_{t}}\) 대신 \({B_{t}}\)를 사용해도 비슷한 수치를 보여서 \({B_{t}}\) (constant)로 고정

  • +
+
+
+

3. Improving the Log-likelihood#

+
    +
  • 위의 문장 (\(\tilde{B_{t}}\) 대신 \({B_{t}}\)를 사용)에서 의문점

    +
      +
    • 사실 \({B_{t}}\)\(\tilde{B_{t}}\)는 정 반대의 역할을 하는 Parameter인데 왜 비슷한 결과를 보였고, 결국 같은 값으로 Fix를 하는게 맞을까?

      +
      +I-DDPM_03 +
      +

      Fig. 146 Figure 1#

      +
      +
      +
    • +
    • Diffusion Step간 \({B_{t}}\)\(\tilde{B_{t}}\)의 차이를 비교해보면 Diffusion Step이 커질수록 두개의 값은 거의 동일해진다. (Figure.1)

      +
      +I-DDPM_04 +
      +

      Fig. 147 Figure 2#

      +
      +
      +
    • +
    • 하지만 Figure.2를 보면 모델의 성능은 대부분 Step 초반에 결정되는데, Step 초반에는 두 값의 차이가 큰 것을 확인할 수 있다.

      +
        +
      • Model의 성능이 결정되는 부분 = Loss 가 급격하게 떨어지는 부분

      • +
      +

      ⇒ 따라서, \({B_{t}}\)\(\tilde{B_{t}}\)를 동일한 값으로 두고 \(\tilde{B_{t}}\)를 Non Trainable Parameter로 두는것은 설계의 Miss

      +
    • +
    • 하지만, \(\tilde{B_{t}}\) 자체를 학습하기에는 값의 범위가 너무 작아서 \({B_{t}}\)\(\tilde{B_{t}}\)의 Interpolation 값을 Predict하도록 설계

      +
      +I-DDPM_05 +
      +

      Fig. 148 Figure 3#

      +
      +
      +
    • +
    • Hybrid Loss

      +
        +
      • \(L_{hyprid} = L_{simple} + λL_{vlb}\)

      • +
      +
    • +
    +
  • +
  • Noise Schedule

    +
      +
    • DDPM의 경우 High Resolution 이미지에대해 잘 동작하지만, Low-Resolution (e.g. 32x32, 64x64)의 이미지에 대해서는 잘 동작하지 않는것을 확인

    • +
    • Noise Scheduling에서 Linear mode의 Limitation이 있음을 지적

    • +
    +
  • +
  • Gradient Noise

    +
      +
    • Model을 \(L_{vlb}\)를 Direct로 최적화하도록 설계하면 Best

    • +
    • 하지만 아래 이미지와같이 Loss 자체가 unstable해서 직접 최적화에는 어려움이 있음

      +
      +I-DDPM_09 +
      +

      Fig. 149 Figure 4#

      +
      +
      +
    • +
    • 따라서 \(L_{vlb}\)의 Variance를 줄이기위해(=stable) Importance Sampling 기법을 도입

    • +
    • 위 Fig.2에서 보면 학습 말기는 Loss의 변화에 큰 영향이 없으므로 확률적으로 학습 초반의 데이터를 좀더 sampling해서 학습하도록 설계

    • +
    • 실제로 적용해본 결과 \(L_{hybrid}\)보다 더 낮은 Loss 를 보임

    • +
    • \(L_{hybrid}\)에 Importance Sampling을 적용하면?

      +
        +
      • 적용 전보다 좋지 않은 결과를 보인다..

      • +
      +
    • +
    +
  • +
+

Result

+
+I-DDPM_10 +
+

Fig. 150 Table 1#

+
+
+
+I-DDPM_11 +
+

Fig. 151 Table 2#

+
+
+
    +
  • DDPM에서 다소 취약했던 ImageNet 64x64와 CIDAR-10 데이터를 기준

    +
      +
    • \(L_{vlb}\)의 경우 Importance sampling을 적용한 결과

    • +
    +
  • +
+
+I-DDPM_12 +
+

Fig. 152 Table 3#

+
+
+
    +
  • Convolution 모델이나 Diffusion 모델중에서는 뛰어나지만, Fully Transformer 모델에 비해서는 다소 부족한 면이 있음

  • +
+
+
+

4. Improcing Sampling Speed#

+
    +
  • Sampling Speed를 높이기 위한 방법을 제안

    +
      +
    • Training 시에는 전체 Step(1, … , T)을 학습

    • +
    • Sampling 시에는 몇몇 Step만 Sampling

    • +
    +
  • +
  • 결과는?

  • +
+
+I-DDPM_13 +
+

Fig. 153 Figure 5#

+
+
+
+I-DDPM_14 +
+

Fig. 154 Figure 6#

+
+
+

⇒ 100 Step만 가도 Full Model과 비슷한 FiD값을 보임

+
+
+

5. Comparison to GANs#

+
    +
  • Class Conditional Generation + P&R Metric으로 GAN 모델(BigGAN)과 성능을 비교

    +
    +I-DDPM_15 +
    +

    Fig. 155 Figure 7#

    +
    +
    +
      +
    • Big-GAN Deep 모델보다 생성 타겟에 대한 FiD 수치나 Recall metric에서 더 뛰어난 성능을 보임

    • +
    +
  • +
+
+
+

6. Scaling Model Size#

+
    +
  • 다양한 Capacity를 가진 모델의 FiD와 NLL 값을 비교

  • +
+
+I-DDPM_16 +
+

Fig. 156 Figure 8#

+
+
+
+I-DDPM_17 +
+

Fig. 157 Figure 9#

+
+
+

⇒ 모델의 크기와 학습량 모두 Step에 어느정도 비례함

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/Latent_Diffusion_Model.html b/docs/review/Latent_Diffusion_Model.html old mode 100644 new mode 100755 index c6e098ad..e87c075b --- a/docs/review/Latent_Diffusion_Model.html +++ b/docs/review/Latent_Diffusion_Model.html @@ -1,627 +1,635 @@ - - - - - - - - - - - - Latent Diffusion Model — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Latent Diffusion Model

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Information

- -
-
-

Latent Diffusion Model#

-

오늘 알아볼 모델은 Latent Diffusion Model입니다. -기존에 다뤘던 Diffusion Model과 유사하게 동작하는 생성 모델입니다. 이 논문에서는 컴퓨터 자원의 소모를 줄이면서 Diffusion Model과 유사한 성능을 얻는것이 그 목표입니다.

-

Latent Diffusion Model은 전반적으로 아래와 같은 구조를 가집니다.

-
-../../_images/Unet.png -
-

Fig. 105 Structure of Latent Diffusion Model#

-
-
-

\(x \in \mathbb{R}^{H\times W \times 3}\)이 input으로 주어졌을때 이를 encoder \(\mathcal{E}\)를 통해서 \(z=\mathcal{E}(x) \in \mathbb{R}^{h\times w\times c }\)로 인코딩 하고 \(\hat{x}=\mathcal{D}(z)\) -로 디코딩을 한다. 이 논문에서 \(f=H/h=W/w=2^m\), \(m\in \mathbb{N}\)이 되도록 여러 \(m\)에 대해서 테스트를 진행하였다. 또한 Latent space에서 분산이 커지지 않도록 KL divergence와 vector quantization(VQ)을 활용하였다. -이미지외 텍스트나, sematic map과 같이 추가적인 정보는 \(\tau_\theta\)를 통해서 전달을 하였고,

-
-\[ Q=W^{(i)}_Q \phi_i(z_i), K=W^{(i)}_K \phi_i(z_i), V=W^{(i)}_V \phi_i(z_i) \]
-

로 정의되고 \(\phi_i(z_i)\)\(U\)-Net 중간의 representation, \(W^{i}_V, W^{i}_K, W^{i}_Q\)는 학습 가능한 projection matrix이다. -\(Q, K, V\) 는 attention의 query, key, value에 해당하며

-
-\[ -Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d}})\cdot V -\]
-

로 연산이 진행된다. 학습을 위한 loss 함수는 다음과 같이표현된다.

-
-\[ -\mathcal{L}_{LDM} = \mathbb{E}_{\mathcal{E}(x), -\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(z_t,t) \|_{2}^{2}\right]. -\]
-

여기서 주목할만한 부분은 기존 Diffusion Model에서

-
-\[ -\mathcal{L}_{DM} = \mathbb{E}_{x, -\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(x_t,t) \|_{2}^{2}\right]. -\]
-

와 같은 loss function으로 학습을 진행시키는데 \(x_t\)\(z_t\)로 바꾸면서 연산의 양을 줄였다는 점이다.

-
-
-

Experiments#

-

해당 논문에서는 다양한 task에 대해서 실험을 진행하였는데, 그중 일부만 소개하도록 하겠다. -아래의 그림은 다양한 dataset에서 뽑은 샘플과 text to image sample들입니다.

-
-../../_images/experiment1.png -
-

Fig. 106 Sample images#

-
-
-
-../../_images/text_to_image.png -
-

Fig. 107 text to image on LAION#

-
-
-

실험을 통해서 나온 결과 \(m=2,3,4\) 혹은 \(f=4, 8, 16\)인 경우 적절한 FID 점수와 효율성을 보여주었습니다.

-
-../../_images/trade_off.png -
-

Fig. 108 text to image on LAION#

-
-
-

Layout이 주어졌을 때, 이를 기반으로 image를 생성하는 layout-to-image의 샘플 결과입니다.

-
-../../_images/layout_to_image.png -
-

Fig. 109 layout-to-image#

-
-
-
- - - - -
- - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Latent Diffusion Model — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Latent Diffusion Model

+ +
+
+ +
+

Contents

+
+ +
+
+
+ + + + +
+ +
+

Information

+ +
+
+

Latent Diffusion Model#

+

오늘 알아볼 모델은 Latent Diffusion Model입니다. +기존에 다뤘던 Diffusion Model과 유사하게 동작하는 생성 모델입니다. 이 논문에서는 컴퓨터 자원의 소모를 줄이면서 Diffusion Model과 유사한 성능을 얻는것이 그 목표입니다.

+

Latent Diffusion Model은 전반적으로 아래와 같은 구조를 가집니다.

+
+../../_images/Unet.png +
+

Fig. 105 Structure of Latent Diffusion Model#

+
+
+

\(x \in \mathbb{R}^{H\times W \times 3}\)이 input으로 주어졌을때 이를 encoder \(\mathcal{E}\)를 통해서 \(z=\mathcal{E}(x) \in \mathbb{R}^{h\times w\times c }\)로 인코딩 하고 \(\hat{x}=\mathcal{D}(z)\) +로 디코딩을 한다. 이 논문에서 \(f=H/h=W/w=2^m\), \(m\in \mathbb{N}\)이 되도록 여러 \(m\)에 대해서 테스트를 진행하였다. 또한 Latent space에서 분산이 커지지 않도록 KL divergence와 vector quantization(VQ)을 활용하였다. +이미지외 텍스트나, sematic map과 같이 추가적인 정보는 \(\tau_\theta\)를 통해서 전달을 하였고,

+
+\[ Q=W^{(i)}_Q \phi_i(z_i), K=W^{(i)}_K \phi_i(z_i), V=W^{(i)}_V \phi_i(z_i) \]
+

로 정의되고 \(\phi_i(z_i)\)\(U\)-Net 중간의 representation, \(W^{i}_V, W^{i}_K, W^{i}_Q\)는 학습 가능한 projection matrix이다. +\(Q, K, V\) 는 attention의 query, key, value에 해당하며

+
+\[ +Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d}})\cdot V +\]
+

로 연산이 진행된다. 학습을 위한 loss 함수는 다음과 같이표현된다.

+
+\[ +\mathcal{L}_{LDM} = \mathbb{E}_{\mathcal{E}(x), +\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(z_t,t) \|_{2}^{2}\right]. +\]
+

여기서 주목할만한 부분은 기존 Diffusion Model에서

+
+\[ +\mathcal{L}_{DM} = \mathbb{E}_{x, +\epsilon \sim \mathcal{N}(0,1),t} \left[ \|\epsilon-\epsilon_{\theta}(x_t,t) \|_{2}^{2}\right]. +\]
+

와 같은 loss function으로 학습을 진행시키는데 \(x_t\)\(z_t\)로 바꾸면서 연산의 양을 줄였다는 점이다.

+
+
+

Experiments#

+

해당 논문에서는 다양한 task에 대해서 실험을 진행하였는데, 그중 일부만 소개하도록 하겠다. +아래의 그림은 다양한 dataset에서 뽑은 샘플과 text to image sample들입니다.

+
+../../_images/experiment1.png +
+

Fig. 106 Sample images#

+
+
+
+../../_images/text_to_image.png +
+

Fig. 107 text to image on LAION#

+
+
+

실험을 통해서 나온 결과 \(m=2,3,4\) 혹은 \(f=4, 8, 16\)인 경우 적절한 FID 점수와 효율성을 보여주었습니다.

+
+../../_images/trade_off.png +
+

Fig. 108 text to image on LAION#

+
+
+

Layout이 주어졌을 때, 이를 기반으로 image를 생성하는 layout-to-image의 샘플 결과입니다.

+
+../../_images/layout_to_image.png +
+

Fig. 109 layout-to-image#

+
+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/LoRA.html b/docs/review/LoRA.html old mode 100644 new mode 100755 index 27698c8d..c6958b7b --- a/docs/review/LoRA.html +++ b/docs/review/LoRA.html @@ -1,875 +1,883 @@ - - - - - - - - - - - - LoRA — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

LoRA#

-
-
-

0. Abstract#

-

LoRA는 PEFT(Parameter Effecient Fine-Tuning)의 기법 중 하나이다. Pre-trained model의 weight는 고정한 채로, 몇 개의 dense(fc) layer만 학습시켜 downstream task의 연산량을 줄일 수 있다. GPT-3을 기준으로 parameter는 10000배, GPU 메모리는 3배를 줄일 수 있다. 또한 inference 과정에서 추가적인 latency가 없음

-
-
    -
  • PEFT: 모델의 모든 파라미터를 튜닝하는 것이 아닌 일부 파라미터만을 튜닝함으로써 모델의 성능을 적은 자원으로도 높게 유지하는 방법론

  • -
-
-
    -
  • Downstream task: pre-trained model을 사용해, 어떤 문제를 해결하기 위해 fine-tuning 하는것

  • -
  • Upstream task: Pre-train model을 학습시키는것

  • -
  • Latency: 어떤 요청의 시작부터 완료까지 걸리는 시간

  • -
-
-
-
-

1. Introduction#

-

LLM은 기본적으로 pre-trained model을 특정 task에 맞게 fine-tuning을 시킴. 하지만 fine-tuning에서 모든 weight를 다시 학습시키면 GPT-2, GPT-3, RoBERTa 등 큰 모델의 경우 학습에 몇 달이 걸림.

-

이전 연구에서 over-parameterized model들은 low intrinsic dimension에 기반하고 있다는 사실에 기반해, 저자는 학습 과정에서도 모델은 low intrinsic rank을 갖고 있을 것이라 가정함.

-

LoRA는 기존 pre-trained weight는 고정하고, 몇 개의 dense layer만 rank decomposition matrices를 최적화하는 방식으로 학습시키기로 함.

-
-LoRA_00 -
-

Fig. 134 LoRA structure#

-
-
-
-LoRA_01 -
-

Fig. 135 LoRA structure 2#

-
-
-

위 그림처럼 기존 pre-trained weight \(W\)는 고정하고 low rank decomposition된 weight \(A, B\)만 학습시켜 \(W\)에 더해줌. \(A, B\)의 크기는 \(W\)보다 작아 time, computational cost를 최대 3배까지 줄일 수 있음. 또한 task에 따라 LoRA module(\(A, B\))만 바꿔주면 되기 때문에 storage requirement, task-switching overhead를 줄일 수 있음. 이 외에도 추가적인 inference latency가 없다, 다른 기법들과 함께 적용이 가능하다는 장점이 있음.

-
-

1.1. Terminologies and Conventions#

-
    -
  • \(d_{model}\): Transformer의 input/output dimension size

  • -
  • \(W_q, W_k, W_v, W_o\): Self-attention module의 query/key/value/output projection matrices

  • -
  • \(W, W_0\): Pre-trained weight

  • -
  • \(\Delta W\): Adaptation 중 accumulated된 gradient update

  • -
  • \(r\): LoRA module의 rank

  • -
  • 이전 연구의 convention을 사용하고 optimizer는 Adam을 이용

  • -
  • Transformer MLP feedforward dimension \(d_{ffn} = 4 \times d_{model}\)

  • -
-
-
-
-
-

2. Problem Statement#

-

LoRA는 agnostic하지만 본 논문에서는 language model에 집중함.

-
-
    -
  • agnostic: model에 구애받지 않고 해석이 가능함

  • -
-
-
-\[ -\max _{\Phi} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(P_{\Phi}\left(y_t \mid x, y_{<t}\right)\right) -\]
-
    -
  • \(P_{\Phi}\left(y \mid x\right)\): \(\Phi\)로 parameterized된 pre-trained model

  • -
  • \(\mathcal{Z} = \{(x_i, y_i)\}_{i=1,...,N}\): context-target쌍으로 된 학습 데이터셋, \(x_i, y_i\)는 token sequence

  • -
-

Fine-tuning 과정에서 model은 \(\Phi_0\)으로 init.되고 objective를 maximize하기 위해 \(\Phi_0 + \Delta \Phi\) 로 업데이트됨. 각 downstream task를 위해 매번 \(|\Phi_0|\)와 같은 크기의 \(|\Delta \Phi|\)를 학습해 엄청난 cost가 발생.

-
-\[ -\max _{\Theta} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(p_{\Phi_0+\Delta \Phi(\Theta)}\left(y_t \mid x, y_{<t}\right)\right) -\]
-

반면 위와 같은 LoRA 방식으로 fine-tuning할 경우 \(|\Phi_0|\) 전체가 아니라 그보다 작은 \(|\Theta|\)를 찾아내는 방식으로 바뀌기 때문에 compute-/memory-effecient해짐. \(|\Theta|\)는 최대 \(|\Phi_0|\)의 0.01%까지 작아질 수 있음.

-
-
-
-

3. Aren’t Existing Solutions Good Enough?#

-

기존에도 transfer learning에서 parameter-/compute-effecient를 위한 방법은 몇 가지가 있었음.

-
-LoRA_02 -
-

Fig. 136 Performance Comparison#

-
-
-

하지만 adapter layer를 추가하는 방식은 hardware parellelism이 없다면 작은 bottleneck layer만 추가해도 latency가 상당히 증가해 사용하기 어려웠음.

-

Prefix tuning은 optimize가 어려웠음.

-
-
-
-

4. Our Method#

-
-

4.1. Low-Rank-Parameterized Update Matrices#

-
-\[ -h=W_0 x+\Delta W x=W_0 x+B A x -\]
-
    -
  • \(W_0 \in \mathbb{R}^{d \times k}\)

  • -
  • \(B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}\)

  • -
  • \(r \ll min(d,k)\)

  • -
-

\(W_0\)는 고정하고 \(A, B\)만 학습. 이후 \(W_0\)\(\Delta W = BA\)는 같은 input \(x\)에 곱해진 후 output vector끼리 coordinate-wise하게 sum.

-

\(A\)는 random Gaussian init., \(B\)는 zero-init.이라 \(\Delta W\) 또한 처음에는 zero-init. \(\Delta W x\)\(\alpha/x\)로 scaling됨. \(\alpha\)는 learning rate처럼 tuning해서 r과 같은 값으로 설정. 실제 코드에서는 보통 \(r, \alpha\)는 (8, 16)이나 (16,32)를 사용한다고 함.

-
	...
-        # Actual trainable parameters
-    	# define A, B
-        if r > 0:
-            self.lora_A = nn.Parameter(self.weight.new_zeros((r, num_embeddings)))
-            self.lora_B = nn.Parameter(self.weight.new_zeros((embedding_dim, r)))
-            self.scaling = self.lora_alpha / self.r
-            # Freezing the pre-trained weight matrix
-            self.weight.requires_grad = False
-        self.reset_parameters()
-
-	# initialize A, B
-    def reset_parameters(self):
-        nn.Embedding.reset_parameters(self)
-        if hasattr(self, 'lora_A'):
-            # initialize A the same way as the default for nn.Linear and B to zero
-            nn.init.zeros_(self.lora_A)
-            nn.init.normal_(self.lora_B)
-
-    def train(self, mode: bool = True):
-        nn.Embedding.train(self, mode)
-        if mode:
-            if self.merge_weights and self.merged:
-                # Make sure that the weights are not merged
-                if self.r > 0:
-                    self.weight.data -= (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling
-                self.merged = False
-        else:
-            if self.merge_weights and not self.merged:
-                # Merge the weights and mark it
-                if self.r > 0:
-                    self.weight.data += (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling
-                self.merged = True
-        
-    def forward(self, x: torch.Tensor):
-        if self.r > 0 and not self.merged:
-        	# pre-trained weight W_0 * x
-            result = nn.Embedding.forward(self, x)
-            if self.r > 0:
-            	# BA * x
-                after_A = F.embedding(
-                    x, self.lora_A.transpose(0, 1), self.padding_idx, self.max_norm,
-                    self.norm_type, self.scale_grad_by_freq, self.sparse
-                )
-                # W_0x + BAx
-                result += (after_A @ self.lora_B.transpose(0, 1)) * self.scaling
-            return result
-        else:
-            return nn.Embedding.forward(self, x)
-
-
-
-
-

4.1.1. No Additional Inference Latency#

-

LoRA를 이용하면 inference시 latency 성능 하락이 없음. 또한 다른 task에 사용할 경우엔 \(BA\)만 제외하고 \(W_0\)로 학습한 다른 \(B'A'\)만 추가하면 되기 때문에 memory overhead가 낮음.

-
-
-
-

4.2. Applying LoRA to Transformer#

-

본 논문에서는 trainable weight를 최소화하기 위해 LoRA를 attention weight만 적용하고 MLP module은 고정함. 이를 통해 GPT-3 175B를 기준으로 VRAM은 1.2TB에서 350GB, checkpoint size는 350GB에서 35MB로 줄임. 또한 학습 속도 또한 25% 정도 빨라짐.

-
-
-
-
-

5.Empirical Experiments#

-
-LoRA_03 -
-

Fig. 137 Performance on BERT#

-
-
-
-LoRA_04 -
-

Fig. 138 Performance on GPT-2#

-
-
-
-LoRA_05 -
-

Fig. 139 Performance on GPT-3#

-
-
-

대부분의 경우에서 성능이 좋음

-
-LoRA_06 -
-

Fig. 140 Validation accuracy table with different hyper-parameters#

-
-
-
-LoRA_07 -
-

Fig. 141 Validation accuracy table with different hyper-parameters#

-
-
-

Transformer에서 한 projection matrix에 큰 r을 적용하는 것보다 모든 matrices에 작은 r을 적용하는 것이 더 성능이 좋았음.

-
-
-
-

+a) IA3#

-
-LoRA_08 -
-

Fig. 142 IA3 structure#

-
-
-

뉴럴네트워크의 Inner Activation을 줄이기도하고 늘리기도하는 어댑터를 중간에 삽입하는 방법론. 기존에 공개된 LoRA보다 적은 파라미터를 사용하면서 높은 성능을 내는 것으로 알려져있으며, GPT-3를 in-context learning 했을때 보다도 성능이 좋다 라고 주장하고 있음. 학습시간도 매우 짧아 A100 GPU 하나로 30분만에 튜닝할 수 있었다고 함.

-
-
-
-

+aa) LoRA 사용법#

-
    -
  1. loralib 설치

  2. -
-
pip install loralib
-# Alternatively
-# pip install git+https://github.com/microsoft/LoRA
-
-
-
    -
  1. 기존 nn.Linear, nn.Embedding, nn.Conv2dlora.~로 대체

  2. -
-
# ===== Before =====
-# layer = nn.Linear(in_features, out_features)
-
-# ===== After ======
-import loralib as lora
-# Add a pair of low-rank adaptation matrices with rank r=16
-layer = lora.Linear(in_features, out_features, r=16)
-
-
-
    -
  1. 학습 전, lora parameter만 학습 가능하게 설정

  2. -
-
import loralib as lora
-model = BigModel()
-# This sets requires_grad to False for all parameters without the string "lora_" in their names
-lora.mark_only_lora_as_trainable(model)
-# Training loop
-for batch in dataloader:
-   ...
-
-
-
    -
  1. checkpoint를 저장할 때엔 state_dict가 LoRA parameter만 저장하게 함.

  2. -
-
# ===== Before =====
-# torch.save(model.state_dict(), checkpoint_path)
-# ===== After =====
-torch.save(lora.lora_state_dict(model), checkpoint_path)
-
-
-
    -
  1. checkpoint를 불러올 때엔 load_state_dict에서 strict=False로 설정.

  2. -
-
# Load the pretrained checkpoint first
-model.load_state_dict(torch.load('ckpt_pretrained.pt'), strict=False)
-# Then load the LoRA checkpoint
-model.load_state_dict(torch.load('ckpt_lora.pt'), strict=False)
-
-
-
-
-
-

Reference#

- -
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + LoRA — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

LoRA#

+
+
+

0. Abstract#

+

LoRA는 PEFT(Parameter Effecient Fine-Tuning)의 기법 중 하나이다. Pre-trained model의 weight는 고정한 채로, 몇 개의 dense(fc) layer만 학습시켜 downstream task의 연산량을 줄일 수 있다. GPT-3을 기준으로 parameter는 10000배, GPU 메모리는 3배를 줄일 수 있다. 또한 inference 과정에서 추가적인 latency가 없음

+
+
    +
  • PEFT: 모델의 모든 파라미터를 튜닝하는 것이 아닌 일부 파라미터만을 튜닝함으로써 모델의 성능을 적은 자원으로도 높게 유지하는 방법론

  • +
+
+
    +
  • Downstream task: pre-trained model을 사용해, 어떤 문제를 해결하기 위해 fine-tuning 하는것

  • +
  • Upstream task: Pre-train model을 학습시키는것

  • +
  • Latency: 어떤 요청의 시작부터 완료까지 걸리는 시간

  • +
+
+
+
+

1. Introduction#

+

LLM은 기본적으로 pre-trained model을 특정 task에 맞게 fine-tuning을 시킴. 하지만 fine-tuning에서 모든 weight를 다시 학습시키면 GPT-2, GPT-3, RoBERTa 등 큰 모델의 경우 학습에 몇 달이 걸림.

+

이전 연구에서 over-parameterized model들은 low intrinsic dimension에 기반하고 있다는 사실에 기반해, 저자는 학습 과정에서도 모델은 low intrinsic rank을 갖고 있을 것이라 가정함.

+

LoRA는 기존 pre-trained weight는 고정하고, 몇 개의 dense layer만 rank decomposition matrices를 최적화하는 방식으로 학습시키기로 함.

+
+LoRA_00 +
+

Fig. 134 LoRA structure#

+
+
+
+LoRA_01 +
+

Fig. 135 LoRA structure 2#

+
+
+

위 그림처럼 기존 pre-trained weight \(W\)는 고정하고 low rank decomposition된 weight \(A, B\)만 학습시켜 \(W\)에 더해줌. \(A, B\)의 크기는 \(W\)보다 작아 time, computational cost를 최대 3배까지 줄일 수 있음. 또한 task에 따라 LoRA module(\(A, B\))만 바꿔주면 되기 때문에 storage requirement, task-switching overhead를 줄일 수 있음. 이 외에도 추가적인 inference latency가 없다, 다른 기법들과 함께 적용이 가능하다는 장점이 있음.

+
+

1.1. Terminologies and Conventions#

+
    +
  • \(d_{model}\): Transformer의 input/output dimension size

  • +
  • \(W_q, W_k, W_v, W_o\): Self-attention module의 query/key/value/output projection matrices

  • +
  • \(W, W_0\): Pre-trained weight

  • +
  • \(\Delta W\): Adaptation 중 accumulated된 gradient update

  • +
  • \(r\): LoRA module의 rank

  • +
  • 이전 연구의 convention을 사용하고 optimizer는 Adam을 이용

  • +
  • Transformer MLP feedforward dimension \(d_{ffn} = 4 \times d_{model}\)

  • +
+
+
+
+
+

2. Problem Statement#

+

LoRA는 agnostic하지만 본 논문에서는 language model에 집중함.

+
+
    +
  • agnostic: model에 구애받지 않고 해석이 가능함

  • +
+
+
+\[ +\max _{\Phi} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(P_{\Phi}\left(y_t \mid x, y_{<t}\right)\right) +\]
+
    +
  • \(P_{\Phi}\left(y \mid x\right)\): \(\Phi\)로 parameterized된 pre-trained model

  • +
  • \(\mathcal{Z} = \{(x_i, y_i)\}_{i=1,...,N}\): context-target쌍으로 된 학습 데이터셋, \(x_i, y_i\)는 token sequence

  • +
+

Fine-tuning 과정에서 model은 \(\Phi_0\)으로 init.되고 objective를 maximize하기 위해 \(\Phi_0 + \Delta \Phi\) 로 업데이트됨. 각 downstream task를 위해 매번 \(|\Phi_0|\)와 같은 크기의 \(|\Delta \Phi|\)를 학습해 엄청난 cost가 발생.

+
+\[ +\max _{\Theta} \sum_{(x, y) \in \mathcal{Z}} \sum_{t=1}^{|y|} \log \left(p_{\Phi_0+\Delta \Phi(\Theta)}\left(y_t \mid x, y_{<t}\right)\right) +\]
+

반면 위와 같은 LoRA 방식으로 fine-tuning할 경우 \(|\Phi_0|\) 전체가 아니라 그보다 작은 \(|\Theta|\)를 찾아내는 방식으로 바뀌기 때문에 compute-/memory-effecient해짐. \(|\Theta|\)는 최대 \(|\Phi_0|\)의 0.01%까지 작아질 수 있음.

+
+
+
+

3. Aren’t Existing Solutions Good Enough?#

+

기존에도 transfer learning에서 parameter-/compute-effecient를 위한 방법은 몇 가지가 있었음.

+
+LoRA_02 +
+

Fig. 136 Performance Comparison#

+
+
+

하지만 adapter layer를 추가하는 방식은 hardware parellelism이 없다면 작은 bottleneck layer만 추가해도 latency가 상당히 증가해 사용하기 어려웠음.

+

Prefix tuning은 optimize가 어려웠음.

+
+
+
+

4. Our Method#

+
+

4.1. Low-Rank-Parameterized Update Matrices#

+
+\[ +h=W_0 x+\Delta W x=W_0 x+B A x +\]
+
    +
  • \(W_0 \in \mathbb{R}^{d \times k}\)

  • +
  • \(B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}\)

  • +
  • \(r \ll min(d,k)\)

  • +
+

\(W_0\)는 고정하고 \(A, B\)만 학습. 이후 \(W_0\)\(\Delta W = BA\)는 같은 input \(x\)에 곱해진 후 output vector끼리 coordinate-wise하게 sum.

+

\(A\)는 random Gaussian init., \(B\)는 zero-init.이라 \(\Delta W\) 또한 처음에는 zero-init. \(\Delta W x\)\(\alpha/x\)로 scaling됨. \(\alpha\)는 learning rate처럼 tuning해서 r과 같은 값으로 설정. 실제 코드에서는 보통 \(r, \alpha\)는 (8, 16)이나 (16,32)를 사용한다고 함.

+
	...
+        # Actual trainable parameters
+    	# define A, B
+        if r > 0:
+            self.lora_A = nn.Parameter(self.weight.new_zeros((r, num_embeddings)))
+            self.lora_B = nn.Parameter(self.weight.new_zeros((embedding_dim, r)))
+            self.scaling = self.lora_alpha / self.r
+            # Freezing the pre-trained weight matrix
+            self.weight.requires_grad = False
+        self.reset_parameters()
+
+	# initialize A, B
+    def reset_parameters(self):
+        nn.Embedding.reset_parameters(self)
+        if hasattr(self, 'lora_A'):
+            # initialize A the same way as the default for nn.Linear and B to zero
+            nn.init.zeros_(self.lora_A)
+            nn.init.normal_(self.lora_B)
+
+    def train(self, mode: bool = True):
+        nn.Embedding.train(self, mode)
+        if mode:
+            if self.merge_weights and self.merged:
+                # Make sure that the weights are not merged
+                if self.r > 0:
+                    self.weight.data -= (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling
+                self.merged = False
+        else:
+            if self.merge_weights and not self.merged:
+                # Merge the weights and mark it
+                if self.r > 0:
+                    self.weight.data += (self.lora_B @ self.lora_A).transpose(0, 1) * self.scaling
+                self.merged = True
+        
+    def forward(self, x: torch.Tensor):
+        if self.r > 0 and not self.merged:
+        	# pre-trained weight W_0 * x
+            result = nn.Embedding.forward(self, x)
+            if self.r > 0:
+            	# BA * x
+                after_A = F.embedding(
+                    x, self.lora_A.transpose(0, 1), self.padding_idx, self.max_norm,
+                    self.norm_type, self.scale_grad_by_freq, self.sparse
+                )
+                # W_0x + BAx
+                result += (after_A @ self.lora_B.transpose(0, 1)) * self.scaling
+            return result
+        else:
+            return nn.Embedding.forward(self, x)
+
+
+
+
+

4.1.1. No Additional Inference Latency#

+

LoRA를 이용하면 inference시 latency 성능 하락이 없음. 또한 다른 task에 사용할 경우엔 \(BA\)만 제외하고 \(W_0\)로 학습한 다른 \(B'A'\)만 추가하면 되기 때문에 memory overhead가 낮음.

+
+
+
+

4.2. Applying LoRA to Transformer#

+

본 논문에서는 trainable weight를 최소화하기 위해 LoRA를 attention weight만 적용하고 MLP module은 고정함. 이를 통해 GPT-3 175B를 기준으로 VRAM은 1.2TB에서 350GB, checkpoint size는 350GB에서 35MB로 줄임. 또한 학습 속도 또한 25% 정도 빨라짐.

+
+
+
+
+

5.Empirical Experiments#

+
+LoRA_03 +
+

Fig. 137 Performance on BERT#

+
+
+
+LoRA_04 +
+

Fig. 138 Performance on GPT-2#

+
+
+
+LoRA_05 +
+

Fig. 139 Performance on GPT-3#

+
+
+

대부분의 경우에서 성능이 좋음

+
+LoRA_06 +
+

Fig. 140 Validation accuracy table with different hyper-parameters#

+
+
+
+LoRA_07 +
+

Fig. 141 Validation accuracy table with different hyper-parameters#

+
+
+

Transformer에서 한 projection matrix에 큰 r을 적용하는 것보다 모든 matrices에 작은 r을 적용하는 것이 더 성능이 좋았음.

+
+
+
+

+a) IA3#

+
+LoRA_08 +
+

Fig. 142 IA3 structure#

+
+
+

뉴럴네트워크의 Inner Activation을 줄이기도하고 늘리기도하는 어댑터를 중간에 삽입하는 방법론. 기존에 공개된 LoRA보다 적은 파라미터를 사용하면서 높은 성능을 내는 것으로 알려져있으며, GPT-3를 in-context learning 했을때 보다도 성능이 좋다 라고 주장하고 있음. 학습시간도 매우 짧아 A100 GPU 하나로 30분만에 튜닝할 수 있었다고 함.

+
+
+
+

+aa) LoRA 사용법#

+
    +
  1. loralib 설치

  2. +
+
pip install loralib
+# Alternatively
+# pip install git+https://github.com/microsoft/LoRA
+
+
+
    +
  1. 기존 nn.Linear, nn.Embedding, nn.Conv2dlora.~로 대체

  2. +
+
# ===== Before =====
+# layer = nn.Linear(in_features, out_features)
+
+# ===== After ======
+import loralib as lora
+# Add a pair of low-rank adaptation matrices with rank r=16
+layer = lora.Linear(in_features, out_features, r=16)
+
+
+
    +
  1. 학습 전, lora parameter만 학습 가능하게 설정

  2. +
+
import loralib as lora
+model = BigModel()
+# This sets requires_grad to False for all parameters without the string "lora_" in their names
+lora.mark_only_lora_as_trainable(model)
+# Training loop
+for batch in dataloader:
+   ...
+
+
+
    +
  1. checkpoint를 저장할 때엔 state_dict가 LoRA parameter만 저장하게 함.

  2. +
+
# ===== Before =====
+# torch.save(model.state_dict(), checkpoint_path)
+# ===== After =====
+torch.save(lora.lora_state_dict(model), checkpoint_path)
+
+
+
    +
  1. checkpoint를 불러올 때엔 load_state_dict에서 strict=False로 설정.

  2. +
+
# Load the pretrained checkpoint first
+model.load_state_dict(torch.load('ckpt_pretrained.pt'), strict=False)
+# Then load the LoRA checkpoint
+model.load_state_dict(torch.load('ckpt_lora.pt'), strict=False)
+
+
+
+
+
+

Reference#

+ +
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/StyO.html b/docs/review/StyO.html old mode 100644 new mode 100755 index bc39ed53..f20648fc --- a/docs/review/StyO.html +++ b/docs/review/StyO.html @@ -1,827 +1,835 @@ - - - - - - - - - - - - StyO — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

-
    -
  • Title: {StyO: Stylize Your Face in Only One-Shot}

  • -
  • Reference

    - -
  • -
  • Author: Seunghwan Ji

  • -
  • Last updated on Aug. 6, 2023

  • -
-
-
-

StyO#

-
-

학습 자료#

-

StyO: Stylize Your Face in Only One-Shot

-

https://arxiv.org/pdf/1812.04948.pdf

-
-

arXiv:2303.03231v2 [cs.CV] 7 Mar 2023

-
-
-

Abstract#

-
    -
  • Stylize the face in only One-shot.”

  • -
  • 한장의 이미지만으로 다른 이미지로 스타일을 Transfer!

  • -
-
-
-

1. Introduction#

-
    -
  • 현재 다양한 분야에서 이미지에 특정 스타일을 입히고자하는 연구들이 활발히 진행중이다.

  • -
  • 이전까지의 연구들은 대부분 각각의 source 이미지, target 이미지 한장씩을 사용해 GAN based model을 활용하려는 식이 주를 이루었다.

  • -
  • 단 이러한 방식에는 한계가 있는데,

    -
      -
    1. Real Face를 학습한 pre-trained GAN 모델의 의존도가 너무 커서 Style을 입히기 힘들다.

    2. -
    3. latent space안에서 Content 정보와 Style 정보가 Entangle 되어있다.

    4. -
    -
  • -
  • StyO는?

    -
      -
    • GAN 대신 Data의 Distribution을 더 잘 포용하는 Latent Diffusion Model을 Base모델로 채용한다.

    • -
    • 총 2 Stage로 구성되는데

      -
        -
      1. Identifier Disentanglement Learner(IDL)

        -
          -
        • 이미지의 content 정보와 Style 정보를 분리

        • -
        -
      2. -
      3. Fine-grained Content Controller(FCC)

        -
          -
        • IDL로부터 분리된 Content와 Style을 원하는대로 재조합

        • -
        -
      4. -
      -
    • -
    • 추가로 src 이미지의 detail한 정보(head-pose, hair color 등)를 유지하기위해 Generate 과정에서 src 이미지의 attention map을 재사용하는 trick을 제안했다.

    • -
    -
  • -
  • 이러한 StyO는 GAN based 모델에 비해 더 좋은 퀄리티의 이미지를 생성해내고, one-shot face stylization 분야에서 SOTA를 기록했다.

  • -
-
- -
-

3. Method#

-
-

3.2. Framework of StyO#

-
-StyO_00 -
-

Fig. 158 Figure 1#

-
-
-
    -
  • image 간의 style transfer를 위해 identifier disentaglement learnerfine-grained content controller를 제안한다.

  • -
-

IDL

-
    -
  • image의 content 정보와 style 정보를 분리하는 방향으로 학습이 진행

  • -
  • src 이미지는 "a drawing with $S_{src}$ not $S_{tgt}$ style of $C_{src}$ not $C_{tgt}$ portrait" prompt로 학습 (tgt 이미지는 반대)

  • -
-

⇒ 이미지 간의 Style 정보와 Content 정보가 Disentangle 되고, \(S_{src}\)안에 이미지 A의 Style 정보가, \(C_{tgt}\) 안에 src 이미지의 content 정보가 embedding 되도록 학습

-
    -
  • 이 때 \(S_{src}\), \(C_{src}\)에 target 이미지의 conext 정보를 배제함과 동시에\(S_{tgt}\), \(C_{tgt}\)에 포함하기위해 앞에 negator(=부정의 의미를 가진 단어)를 사용

    -
      -
    • e.g. not, without, except …

    • -
    -
  • -
  • src, tgt 이미지에 추가로 auxiliary 이미지 셋을 구성해 “a drawing with $S_{src}$ not $S_{tgt}$ style of portrait” prompt로 학습

    -
      -
    • \(X_{aux}\) : FFHQ dataset에서 임의로 200장의 데이터를 sampling

    • -
    -
  • -
  • 효과

    -
      -
    1. auxiliary 이미지를 학습함으로써 key prompt간 disentanglement를 향상

    2. -
    3. auxiliary 이미지에는 없는 src 이미지만의 정보를 \(C_{src}\) 에 주입

    4. -
    5. src 이미지의 style과 tgt 이미지의 style을 구별하는데 도움을 줌

    6. -
    -
  • -
  • Full Loss

    -
    -StyO_01 -
    -

    Fig. 159 Equation 1#

    -
    -
    -
  • -
  • 이러한 IDL의 학습만으로 src 이미지와 tgt 이미지의 style transfer가 가능하다.

    -
      -
    • “a drawing with $S_{tgt}$ not $S_{src}$ style of $C_{src}$ not $C_{tgt}$ portrait”

      -
      -StyO_02 -
      -

      Fig. 160 Figure 2#

      -
      -
      -
    • -
    -
  • -
  • 하지만 위 이미지처럼 src 이미지의 content 정보(head-pose, facial feature)를 잃어버리는 경향이 있다.

  • -
  • 이러한 문제점을 개선하기위해 FCC를 추가로 도입하였다.

  • -
-

FCC

-
    -
  • IDL로 분리된 content 정보와 style 정보를 원하는 방식으로 조합(Recombination)할 때 A의 Content 정보를 유지하도록 하는 Trick

  • -
-
    -
  1. Cross Attention Control

    -
      -
    • LDM은 기본적으로 Text 정보를 생성 이미지에 주입하기위해 cross attention mechanism을 사용

      -
        -
      • \(Attn(z, r) = M(z, r)V\), z : image latent, r : text embedding

      • -
      -
    • -
    • 이 때 “prompt-to-promt” paper에서 attention map M의 값이 생성 이미지의 Layout에 강한 영향을 미친다는 점을 확인

    • -
    • 따라서 src 이미지의 attention mask를 generate 과정에 주입합으로써 content 정보를 좀 더 잘 유지하도록 유도

    • -
    • 단, attention map의 모든 값을 replace하지않고, content에 관한 Index만 선택적으로 replace

      -
        -
      • content index : ‘\(C_{src}\), not, \(C_{tgt}\), portrait`

        -
        -StyO_03 -
        -

        Fig. 161 Equation 3#

        -
        -
        -
      • -
      -
    • -
    -
  2. -
  3. Augmented Text Prompt

    -
      -
    • training time에서 key prompt를 n번 사용함으로서 생성되는 이미지에 context 정보를 강하게 주입

      -
        -
      • src 이미지는 “a drawing with ($S_{src}$ not $S_{tgt}$) * $n_{s}$ style of ($C_{src}$ not $C_{tgt}$) * $n_{c}$ portrait” (tgt 이미지는 반대)

      • -
      -
    • -
    • 실험상 hyperparameter \(n_{s}\)\(n_{c}\)는 3 이하의 값을 추천

    • -
    -
  4. -
-
-
-
-

4. Experiments#

-

Implementation Details

-
    -
  • base model : Pretrained LDM model checkpoint (trained by LAION-5B)

  • -
  • hyper parameter

    -
      -
    • key prompt : “ak47”, “aug”, “sks”, m4a1”

    • -
    • Learning rate : 1e-6

    • -
    • Optimizer : Adam

    • -
    • train step : 400

    • -
    • \(n_{s}\) : 3, \(n_{c}\) : 1

    • -
    • 나머지는 LDM과 동일

    • -
    -
  • -
-

Comparison with SOTA methods

-
-StyO_04 -
-

Fig. 162 Figure 3#

-
-
-
    -
  • StyO가 src 이미지의 face identity와 local detail 모두 잘 유지함과 동시에, style 정보를 자연스럽게 입힌 결과물을 생성해낸다.

  • -
  • User Study도 다른 모델들에 비해 좋은 결과를 보였다.

    -
    -StyO_05 -
    -

    Fig. 163 Table 1#

    -
    -
    -
  • -
-

Ablation Study

-
    -
  1. Effect of Contrastive Disentangled Prompt Template

    -
      -
    • negative prompt 없이 positive prompt만 넣고 학습할경우 학습 이미지의 overfitting이 심하고, style과 content 정보의 분리에 어려움을 보인다.

      -
      -StyO_06 -
      -

      Fig. 164 Figure 4#

      -
      -
      -
    • -
    • 또, source 이미지의 local detail을 유지하기위해 auxiliary set의 trick도 적용하는것이 Best Quality의 결과물을 생성해냈다.

    • -
    -
  2. -
  3. Effect of Fine-grained Content Controller

    -
      -
    • FCC 없이 Inference할 경우 generated 이미지의 높은 diversity를 보이지만, FCC를 포함할 경우 src 이미지의 fidelity가 높아져 좀더 significant한 이미지가 생성되는것을 보여주었다.

      -
      -StyO_07 -
      -

      Fig. 165 Figure 5#

      -
      -
      -
    • -
    -
  4. -
  5. Hyper-parameters in Augmented Text Prompt

    -
      -
    • \(n_{s}\) 값이 커질수록 이미지가 photorealistic에서 artistic하게 바뀌고, \(n_{c}\)도 마찬가지로 값이 커질수록 src 이미지에 overfitting된 이미지가 나오는 경향을 보여주었다.

    • -
    -
  6. -
-
-
-

5. Conclusion#

-
    -
  • StyO는 IDL과 FCC를 사용해 기존 GAN을 이용한 SOTA 모델들보다 더 자연스럽고 Quality 좋은 style transfered 이미지를 생성해낼 수 있었다.

  • -
  • 단, style 하나의 transfer를 위해 single GPU로 10분이 걸리므로 time-efficiency가 좋지 못하다는 단점이 있다.

  • -
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + StyO — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+
    +
  • Title: {StyO: Stylize Your Face in Only One-Shot}

  • +
  • Reference

    + +
  • +
  • Author: Seunghwan Ji

  • +
  • Last updated on Aug. 6, 2023

  • +
+
+
+

StyO#

+
+

학습 자료#

+

StyO: Stylize Your Face in Only One-Shot

+

https://arxiv.org/pdf/1812.04948.pdf

+
+

arXiv:2303.03231v2 [cs.CV] 7 Mar 2023

+
+
+

Abstract#

+
    +
  • Stylize the face in only One-shot.”

  • +
  • 한장의 이미지만으로 다른 이미지로 스타일을 Transfer!

  • +
+
+
+

1. Introduction#

+
    +
  • 현재 다양한 분야에서 이미지에 특정 스타일을 입히고자하는 연구들이 활발히 진행중이다.

  • +
  • 이전까지의 연구들은 대부분 각각의 source 이미지, target 이미지 한장씩을 사용해 GAN based model을 활용하려는 식이 주를 이루었다.

  • +
  • 단 이러한 방식에는 한계가 있는데,

    +
      +
    1. Real Face를 학습한 pre-trained GAN 모델의 의존도가 너무 커서 Style을 입히기 힘들다.

    2. +
    3. latent space안에서 Content 정보와 Style 정보가 Entangle 되어있다.

    4. +
    +
  • +
  • StyO는?

    +
      +
    • GAN 대신 Data의 Distribution을 더 잘 포용하는 Latent Diffusion Model을 Base모델로 채용한다.

    • +
    • 총 2 Stage로 구성되는데

      +
        +
      1. Identifier Disentanglement Learner(IDL)

        +
          +
        • 이미지의 content 정보와 Style 정보를 분리

        • +
        +
      2. +
      3. Fine-grained Content Controller(FCC)

        +
          +
        • IDL로부터 분리된 Content와 Style을 원하는대로 재조합

        • +
        +
      4. +
      +
    • +
    • 추가로 src 이미지의 detail한 정보(head-pose, hair color 등)를 유지하기위해 Generate 과정에서 src 이미지의 attention map을 재사용하는 trick을 제안했다.

    • +
    +
  • +
  • 이러한 StyO는 GAN based 모델에 비해 더 좋은 퀄리티의 이미지를 생성해내고, one-shot face stylization 분야에서 SOTA를 기록했다.

  • +
+
+ +
+

3. Method#

+
+

3.2. Framework of StyO#

+
+StyO_00 +
+

Fig. 158 Figure 1#

+
+
+
    +
  • image 간의 style transfer를 위해 identifier disentaglement learnerfine-grained content controller를 제안한다.

  • +
+

IDL

+
    +
  • image의 content 정보와 style 정보를 분리하는 방향으로 학습이 진행

  • +
  • src 이미지는 "a drawing with $S_{src}$ not $S_{tgt}$ style of $C_{src}$ not $C_{tgt}$ portrait" prompt로 학습 (tgt 이미지는 반대)

  • +
+

⇒ 이미지 간의 Style 정보와 Content 정보가 Disentangle 되고, \(S_{src}\)안에 이미지 A의 Style 정보가, \(C_{tgt}\) 안에 src 이미지의 content 정보가 embedding 되도록 학습

+
    +
  • 이 때 \(S_{src}\), \(C_{src}\)에 target 이미지의 conext 정보를 배제함과 동시에\(S_{tgt}\), \(C_{tgt}\)에 포함하기위해 앞에 negator(=부정의 의미를 가진 단어)를 사용

    +
      +
    • e.g. not, without, except …

    • +
    +
  • +
  • src, tgt 이미지에 추가로 auxiliary 이미지 셋을 구성해 “a drawing with $S_{src}$ not $S_{tgt}$ style of portrait” prompt로 학습

    +
      +
    • \(X_{aux}\) : FFHQ dataset에서 임의로 200장의 데이터를 sampling

    • +
    +
  • +
  • 효과

    +
      +
    1. auxiliary 이미지를 학습함으로써 key prompt간 disentanglement를 향상

    2. +
    3. auxiliary 이미지에는 없는 src 이미지만의 정보를 \(C_{src}\) 에 주입

    4. +
    5. src 이미지의 style과 tgt 이미지의 style을 구별하는데 도움을 줌

    6. +
    +
  • +
  • Full Loss

    +
    +StyO_01 +
    +

    Fig. 159 Equation 1#

    +
    +
    +
  • +
  • 이러한 IDL의 학습만으로 src 이미지와 tgt 이미지의 style transfer가 가능하다.

    +
      +
    • “a drawing with $S_{tgt}$ not $S_{src}$ style of $C_{src}$ not $C_{tgt}$ portrait”

      +
      +StyO_02 +
      +

      Fig. 160 Figure 2#

      +
      +
      +
    • +
    +
  • +
  • 하지만 위 이미지처럼 src 이미지의 content 정보(head-pose, facial feature)를 잃어버리는 경향이 있다.

  • +
  • 이러한 문제점을 개선하기위해 FCC를 추가로 도입하였다.

  • +
+

FCC

+
    +
  • IDL로 분리된 content 정보와 style 정보를 원하는 방식으로 조합(Recombination)할 때 A의 Content 정보를 유지하도록 하는 Trick

  • +
+
    +
  1. Cross Attention Control

    +
      +
    • LDM은 기본적으로 Text 정보를 생성 이미지에 주입하기위해 cross attention mechanism을 사용

      +
        +
      • \(Attn(z, r) = M(z, r)V\), z : image latent, r : text embedding

      • +
      +
    • +
    • 이 때 “prompt-to-promt” paper에서 attention map M의 값이 생성 이미지의 Layout에 강한 영향을 미친다는 점을 확인

    • +
    • 따라서 src 이미지의 attention mask를 generate 과정에 주입합으로써 content 정보를 좀 더 잘 유지하도록 유도

    • +
    • 단, attention map의 모든 값을 replace하지않고, content에 관한 Index만 선택적으로 replace

      +
        +
      • content index : ‘\(C_{src}\), not, \(C_{tgt}\), portrait`

        +
        +StyO_03 +
        +

        Fig. 161 Equation 3#

        +
        +
        +
      • +
      +
    • +
    +
  2. +
  3. Augmented Text Prompt

    +
      +
    • training time에서 key prompt를 n번 사용함으로서 생성되는 이미지에 context 정보를 강하게 주입

      +
        +
      • src 이미지는 “a drawing with ($S_{src}$ not $S_{tgt}$) * $n_{s}$ style of ($C_{src}$ not $C_{tgt}$) * $n_{c}$ portrait” (tgt 이미지는 반대)

      • +
      +
    • +
    • 실험상 hyperparameter \(n_{s}\)\(n_{c}\)는 3 이하의 값을 추천

    • +
    +
  4. +
+
+
+
+

4. Experiments#

+

Implementation Details

+
    +
  • base model : Pretrained LDM model checkpoint (trained by LAION-5B)

  • +
  • hyper parameter

    +
      +
    • key prompt : “ak47”, “aug”, “sks”, m4a1”

    • +
    • Learning rate : 1e-6

    • +
    • Optimizer : Adam

    • +
    • train step : 400

    • +
    • \(n_{s}\) : 3, \(n_{c}\) : 1

    • +
    • 나머지는 LDM과 동일

    • +
    +
  • +
+

Comparison with SOTA methods

+
+StyO_04 +
+

Fig. 162 Figure 3#

+
+
+
    +
  • StyO가 src 이미지의 face identity와 local detail 모두 잘 유지함과 동시에, style 정보를 자연스럽게 입힌 결과물을 생성해낸다.

  • +
  • User Study도 다른 모델들에 비해 좋은 결과를 보였다.

    +
    +StyO_05 +
    +

    Fig. 163 Table 1#

    +
    +
    +
  • +
+

Ablation Study

+
    +
  1. Effect of Contrastive Disentangled Prompt Template

    +
      +
    • negative prompt 없이 positive prompt만 넣고 학습할경우 학습 이미지의 overfitting이 심하고, style과 content 정보의 분리에 어려움을 보인다.

      +
      +StyO_06 +
      +

      Fig. 164 Figure 4#

      +
      +
      +
    • +
    • 또, source 이미지의 local detail을 유지하기위해 auxiliary set의 trick도 적용하는것이 Best Quality의 결과물을 생성해냈다.

    • +
    +
  2. +
  3. Effect of Fine-grained Content Controller

    +
      +
    • FCC 없이 Inference할 경우 generated 이미지의 높은 diversity를 보이지만, FCC를 포함할 경우 src 이미지의 fidelity가 높아져 좀더 significant한 이미지가 생성되는것을 보여주었다.

      +
      +StyO_07 +
      +

      Fig. 165 Figure 5#

      +
      +
      +
    • +
    +
  4. +
  5. Hyper-parameters in Augmented Text Prompt

    +
      +
    • \(n_{s}\) 값이 커질수록 이미지가 photorealistic에서 artistic하게 바뀌고, \(n_{c}\)도 마찬가지로 값이 커질수록 src 이미지에 overfitting된 이미지가 나오는 경향을 보여주었다.

    • +
    +
  6. +
+
+
+

5. Conclusion#

+
    +
  • StyO는 IDL과 FCC를 사용해 기존 GAN을 이용한 SOTA 모델들보다 더 자연스럽고 Quality 좋은 style transfered 이미지를 생성해낼 수 있었다.

  • +
  • 단, style 하나의 transfer를 위해 single GPU로 10분이 걸리므로 time-efficiency가 좋지 못하다는 단점이 있다.

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/StyleGAN.html b/docs/review/StyleGAN.html old mode 100644 new mode 100755 index ffff6ed4..f027d915 --- a/docs/review/StyleGAN.html +++ b/docs/review/StyleGAN.html @@ -1,711 +1,719 @@ - - - - - - - - - - - - StyleGAN — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

StyleGAN

- -
- -
-
- - - - -
- -
-

Information

- -
-
-

StyleGAN#

-

오늘 알아볼 모델은 StyleGAN입니다. 기존에 다뤘던 GAN과 같이 이미지를 생성하는 모델입니다. generator 구조를 변경함으로써 성능을 올리고 feature의 control이 가능하게 했습니다. loss나 discriminator 구조 개선에 관한 논문은 아닙니다. 먼저 결과를 보도록 하죠.

-
-stylegan_01 -
-

Fig. 26 Images generated by StyleGAN#

-
-
-

이 논문의 contribution은 다음과 같습니다.

-
    -
  1. 새로운 구조를 제안하여 성능을 높이면서 feature의 control이 가능해졌습니다.

  2. -
  3. 새로운 데이터셋을 제안했습니다. (FFHQ)

  4. -
-

이 중에서 첫 번째 contribution을 자세히 보도록 하겠습니다. 논문의 abstract에는 다음과 같은 문장이 있습니다.

-
-

The new architecture leads to an automatically learned, unsupervised separation of high-level attributes (e.g., pose and identity when trained on human faces) and stochastic variation in the generated images (e.g., freckles, hair), and it enables intuitive, scale-specific control of the synthesis.

-
-

논문에서 제안한 새로운 generator 구조가 할 수 있는 일을 설명하는 부분입니다. 여기서 보시면 high level attribute의 separation이 가능하다고 얘기하고 있습니다. 저는 개인적으로 이 부분이 StyleGAN의 가장 중요한 특징이라고 생각합니다.

-

생성 모델로 이미지를 생성하고자 할 때, 사용자는 어떠한 목적을 가지고 자신이 원하는 이미지를 만들고자 할 것입니다. 이미지의 품질이 좋더라도 모델이 사용자의 의도와 상관없는 랜덤한 이미지를 내뱉어준다면 그 모델의 실용성이 좋다고 할 수 없을 것입니다. 근래에 Text-to-Image 모델들이 인기를 얻었던 이유도 누구나 쉽게 텍스트를 통해서 생성되는 이미지를 조절할 수 있다는 점도 한몫했다고 생각합니다. StyleGAN은 그런 controllability를 어느 정도 가능하게 한 모델이라는 측면에서 의미있다고 생각합니다.

-

StyleGAN의 구조는 아래 그림과 같습니다. synthesis network는 해상도를 4x4에서 시작해서 1024x1024까지 높여줍니다. 최종적으로 1024x1024 해상도를 가지는 이미지를 갖게됩니다. 아래 구조를 보면 기존 GAN하고 비교해서 특이한 점이 세 가지 있습니다.

-
    -
  1. z를 input으로 받는 mapping network

  2. -
  3. style과 AdaIN

  4. -
  5. noise와 B (stochastic variation)

  6. -
-

이 각각에 대해서 알아보도록 합시다.

-
-stylegan_02 -
-

Fig. 27 Structure of StyleGAN#

-
-
-
-

Mapping Network#

-
-stylegan_03 -
-

Fig. 28 Mappings with \(w\) and without \(w\)#

-
-
-

기존 GAN을 생각해보면 z를 input으로 받아서 generator를 거쳐서 이미지를 생성하는 구조입니다. 이 z는 보통 Gaussian distribution에서 샘플링으로 얻습니다. GAN은 학습을 통해 Gaussian distribution을 data distribution으로 보내는 방법을 배우게 될 것이고, 이 분포는 (b)처럼 생기게 될 것입니다. 그런데 데이터가 (a)처럼 주어져서 특정한 데이터가 없거나 적을 수도 있을 것입니다. 예를 들어, 데이터에 피부가 희면서 머리가 긴 샘플들이 없다고 해봅시다. 그러면 피부색과 머리 길이라는 두 feature는 서로 얽히게(entangled)되어, 하나를 바꿀 때 다른 하나도 같이 바뀌는 현상이 일어나게 됩니다. 이런 현상을 완화하기 위해 논문에서는 Gaussian에서 뽑은 z를 바로 사용하는 것이 아니라 mapping network를 통해 learnable distribution에서 뽑은 w를 사용합니다.

-
-
-

Style and AdaIN#

-

instance normalization은 샘플 하나의 각 채널마다 정규화를 취해주는 방법입니다.

-
-stylegan_04 -
-

Fig. 29 Normalization methods#

-
-
-

adaptive instance normalization (AdaIN) 은 instance normalization에 scale을 곱해주고 bias를 더해주는 형태입니다. 그런데 이 scale과 bias가 style vector의 linear transformation으로 주어지는 형태입니다. linear layer를 통해서 w는 \(\mathbf{y}=(\mathbf{y}_{s},\mathbf{y}_{b})\)로 보내지게 됩니다. AdaIN의 수식은 아래와 같습니다.

-
-\[ -AdaIN(\mathbf{x}_{i},\mathbf{y})=\mathbf{y}_{s,i}\frac{\mathbf{x}_{i}-\mu(\mathbf{x}_{i})}{\sigma(\mathbf{x}_{i})}+\mathbf{y}_{b,i} -\]
-

AdaIN은 각 블록마다 두 개씩 들어가서 style은 총 열여덟 번 AdaIN을 통해 generator에 들어가게 됩니다. AdaIN은 localization이라는 특징과도 연관이 있습니다. 여기서 말하는 localization이란 열여덟 개의 style 중에서 일부를 바꿈으로써 이미지의 일부 특징들을 바꿀 수 있다는 의미입니다. AdaIN은 각 convolution layer 다음에 적용이 됩니다. 이 때 feature map들은 normalization되고 style에 의해 새로운 statistics를 가지게 됩니다. style은 하나의 convolution에 적용되고, 다음 convolution에서 다시 normalization이 수행되기 때문에 이전 layer에 적용된 style과 다음 layer에 적용된 style이 분리되게 학습될 수 있습니다.

-

관련 코드

-
class StyleMod(nn.Module):
-    def __init__(self, latent_size, channels, use_wscale):
-        super(StyleMod, self).__init__()
-        self.lin = EqualizedLinear(latent_size,
-                                   channels * 2,
-                                   gain=1.0, use_wscale=use_wscale)
-
-    def forward(self, x, latent):
-        style = self.lin(latent)  # style => [batch_size, n_channels*2]
-
-        shape = [-1, 2, x.size(1)] + (x.dim() - 2) * [1]
-        style = style.view(shape)  # [batch_size, 2, n_channels, ...]
-        x = x * (style[:, 0] + 1.) + style[:, 1]
-        return x
-
-class LayerEpilogue(nn.Module):
-    """Things to do at the end of each layer."""
-
-    def __init__(self, channels, dlatent_size, use_wscale,
-                 use_noise, use_pixel_norm, use_instance_norm, use_styles, activation_layer):
-        super().__init__()
-
-        layers = []
-        if use_noise:
-            layers.append(('noise', NoiseLayer(channels)))
-        layers.append(('activation', activation_layer))
-        if use_pixel_norm:
-            layers.append(('pixel_norm', PixelNormLayer()))
-        if use_instance_norm:
-            layers.append(('instance_norm', nn.InstanceNorm2d(channels)))
-
-        self.top_epi = nn.Sequential(OrderedDict(layers))
-
-        if use_styles:
-            self.style_mod = StyleMod(dlatent_size, channels, use_wscale=use_wscale)
-        else:
-            self.style_mod = None
-
-    def forward(self, x, dlatents_in_slice=None):
-        x = self.top_epi(x)
-        if self.style_mod is not None:
-            x = self.style_mod(x, dlatents_in_slice)
-        else:
-            assert dlatents_in_slice is None
-        return x
-
-
-

code from huangzh13/StyleGAN.pytorch

-

아래 그림은 source A의 style 중 일부를 source B의 style로 변경해서 만든 이미지들입니다. style은 총 18곳에서 사용되는데 처음 4곳 (\(4^2 - 8^2\))을 coarse, 그다음 4곳 (\(16^2-32^2\))을 middle, 마지막 10곳 (\(64^2-1024^2\))을 fine style로 정의하였습니다. 그림을 보시면 윗 부분에서는 포즈나 전체적인 머리 스타일같이 coarse style은 source B의 것을 유지하고, 아래로 갈수록 source A의 큰 틀을 유지하면서 세부적인 부분들을 B에서 가져왔음을 볼 수 있습니다.

-
-stylegan_05 -
-

Fig. 30 Mixing two styles#

-
-
-
-
-

Stochastic Variation#

-

한 사람의 이미지 안에는 확률적으로 바뀔 수 있는 부분이 있습니다. (주근깨, 머릿결, 피부) 이를 모델링하기 위해서 noise를 추가적인 input으로 사용하여 각 convolution layer 다음에 더해집니다. 아래 그림에서 (a)의 생성된 한 사람의 이미지 안에서도 디테일들은 (b)와 같이 달라질 수 있습니다. (c)와 같이 standard deviation을 구해봤을 때 얼굴형과 같은 attribute는 변하지않지만 noise에 의해서 머리카락과 같은 부분은 variation이 생김을 볼 수 있습니다.

-
-stylegan_06 -
-

Fig. 31 Examples of stochastic variation#

-
-
-

아래 그림에서 (a)는 모든 layer에 noise를 준 경우, (b)는 noise를 주지 않은 경우, (c)는 fine layers (\(64^2 - 1024^2\))에만 noise를 준 경우, (d)는 coarse layers (\(4^2 - 32^2\))에만 noise를 준 경우입니다. (b)를 보면 noise가 없을 경우 머리카락같은 디테일이 제대로 살아있지 않은 것을 볼 수 있습니다. (c)와 (d)를 보면 fine layers에 들어간 noise가 머리카락의 더 세밀한 부분에 영향을 끼친다는 것을 볼 수 있습니다.

-
-stylegan_07 -
-

Fig. 32 Effect of noise inputs at different layers#

-
-
-
-
-

Mixing Regularization#

-

논문에서는 localization이 더 잘 되게하기 위해 style mixing이라는 방법을 훈련에 사용합니다. 두 개의 style vector \(\mathbf{w}_{1},\mathbf{w}_{2}\)를 사용하여 앞 쪽 layer에는 \(\mathbf{w}_{1}\)을, 뒤 쪽 layer에는 \(\mathbf{w}_{2}\)를 사용하는 방법입니다. 이는 generator가 인접한 style끼리 correlated되어있다고 학습하는 것을 막아서 localization을 더 잘 되게 하는 목적입니다.

-
-
-

실험 결과#

-

마지막으로 저자들이 제안한 방법들이 실제로 효과가 있었는지 확인해봅시다. 아래 표와 같이 실험적으로 보았을 때 저자들이 제안한 방법들을 모두 사용한 경우 FID가 가장 우수하게 나왔습니다.

-
-stylegan_08 -
-

Fig. 33 FID for various generator designs#

-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + StyleGAN — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

StyleGAN

+ +
+ +
+
+ + + + +
+ +
+

Information

+ +
+
+

StyleGAN#

+

오늘 알아볼 모델은 StyleGAN입니다. 기존에 다뤘던 GAN과 같이 이미지를 생성하는 모델입니다. generator 구조를 변경함으로써 성능을 올리고 feature의 control이 가능하게 했습니다. loss나 discriminator 구조 개선에 관한 논문은 아닙니다. 먼저 결과를 보도록 하죠.

+
+stylegan_01 +
+

Fig. 26 Images generated by StyleGAN#

+
+
+

이 논문의 contribution은 다음과 같습니다.

+
    +
  1. 새로운 구조를 제안하여 성능을 높이면서 feature의 control이 가능해졌습니다.

  2. +
  3. 새로운 데이터셋을 제안했습니다. (FFHQ)

  4. +
+

이 중에서 첫 번째 contribution을 자세히 보도록 하겠습니다. 논문의 abstract에는 다음과 같은 문장이 있습니다.

+
+

The new architecture leads to an automatically learned, unsupervised separation of high-level attributes (e.g., pose and identity when trained on human faces) and stochastic variation in the generated images (e.g., freckles, hair), and it enables intuitive, scale-specific control of the synthesis.

+
+

논문에서 제안한 새로운 generator 구조가 할 수 있는 일을 설명하는 부분입니다. 여기서 보시면 high level attribute의 separation이 가능하다고 얘기하고 있습니다. 저는 개인적으로 이 부분이 StyleGAN의 가장 중요한 특징이라고 생각합니다.

+

생성 모델로 이미지를 생성하고자 할 때, 사용자는 어떠한 목적을 가지고 자신이 원하는 이미지를 만들고자 할 것입니다. 이미지의 품질이 좋더라도 모델이 사용자의 의도와 상관없는 랜덤한 이미지를 내뱉어준다면 그 모델의 실용성이 좋다고 할 수 없을 것입니다. 근래에 Text-to-Image 모델들이 인기를 얻었던 이유도 누구나 쉽게 텍스트를 통해서 생성되는 이미지를 조절할 수 있다는 점도 한몫했다고 생각합니다. StyleGAN은 그런 controllability를 어느 정도 가능하게 한 모델이라는 측면에서 의미있다고 생각합니다.

+

StyleGAN의 구조는 아래 그림과 같습니다. synthesis network는 해상도를 4x4에서 시작해서 1024x1024까지 높여줍니다. 최종적으로 1024x1024 해상도를 가지는 이미지를 갖게됩니다. 아래 구조를 보면 기존 GAN하고 비교해서 특이한 점이 세 가지 있습니다.

+
    +
  1. z를 input으로 받는 mapping network

  2. +
  3. style과 AdaIN

  4. +
  5. noise와 B (stochastic variation)

  6. +
+

이 각각에 대해서 알아보도록 합시다.

+
+stylegan_02 +
+

Fig. 27 Structure of StyleGAN#

+
+
+
+

Mapping Network#

+
+stylegan_03 +
+

Fig. 28 Mappings with \(w\) and without \(w\)#

+
+
+

기존 GAN을 생각해보면 z를 input으로 받아서 generator를 거쳐서 이미지를 생성하는 구조입니다. 이 z는 보통 Gaussian distribution에서 샘플링으로 얻습니다. GAN은 학습을 통해 Gaussian distribution을 data distribution으로 보내는 방법을 배우게 될 것이고, 이 분포는 (b)처럼 생기게 될 것입니다. 그런데 데이터가 (a)처럼 주어져서 특정한 데이터가 없거나 적을 수도 있을 것입니다. 예를 들어, 데이터에 피부가 희면서 머리가 긴 샘플들이 없다고 해봅시다. 그러면 피부색과 머리 길이라는 두 feature는 서로 얽히게(entangled)되어, 하나를 바꿀 때 다른 하나도 같이 바뀌는 현상이 일어나게 됩니다. 이런 현상을 완화하기 위해 논문에서는 Gaussian에서 뽑은 z를 바로 사용하는 것이 아니라 mapping network를 통해 learnable distribution에서 뽑은 w를 사용합니다.

+
+
+

Style and AdaIN#

+

instance normalization은 샘플 하나의 각 채널마다 정규화를 취해주는 방법입니다.

+
+stylegan_04 +
+

Fig. 29 Normalization methods#

+
+
+

adaptive instance normalization (AdaIN) 은 instance normalization에 scale을 곱해주고 bias를 더해주는 형태입니다. 그런데 이 scale과 bias가 style vector의 linear transformation으로 주어지는 형태입니다. linear layer를 통해서 w는 \(\mathbf{y}=(\mathbf{y}_{s},\mathbf{y}_{b})\)로 보내지게 됩니다. AdaIN의 수식은 아래와 같습니다.

+
+\[ +AdaIN(\mathbf{x}_{i},\mathbf{y})=\mathbf{y}_{s,i}\frac{\mathbf{x}_{i}-\mu(\mathbf{x}_{i})}{\sigma(\mathbf{x}_{i})}+\mathbf{y}_{b,i} +\]
+

AdaIN은 각 블록마다 두 개씩 들어가서 style은 총 열여덟 번 AdaIN을 통해 generator에 들어가게 됩니다. AdaIN은 localization이라는 특징과도 연관이 있습니다. 여기서 말하는 localization이란 열여덟 개의 style 중에서 일부를 바꿈으로써 이미지의 일부 특징들을 바꿀 수 있다는 의미입니다. AdaIN은 각 convolution layer 다음에 적용이 됩니다. 이 때 feature map들은 normalization되고 style에 의해 새로운 statistics를 가지게 됩니다. style은 하나의 convolution에 적용되고, 다음 convolution에서 다시 normalization이 수행되기 때문에 이전 layer에 적용된 style과 다음 layer에 적용된 style이 분리되게 학습될 수 있습니다.

+

관련 코드

+
class StyleMod(nn.Module):
+    def __init__(self, latent_size, channels, use_wscale):
+        super(StyleMod, self).__init__()
+        self.lin = EqualizedLinear(latent_size,
+                                   channels * 2,
+                                   gain=1.0, use_wscale=use_wscale)
+
+    def forward(self, x, latent):
+        style = self.lin(latent)  # style => [batch_size, n_channels*2]
+
+        shape = [-1, 2, x.size(1)] + (x.dim() - 2) * [1]
+        style = style.view(shape)  # [batch_size, 2, n_channels, ...]
+        x = x * (style[:, 0] + 1.) + style[:, 1]
+        return x
+
+class LayerEpilogue(nn.Module):
+    """Things to do at the end of each layer."""
+
+    def __init__(self, channels, dlatent_size, use_wscale,
+                 use_noise, use_pixel_norm, use_instance_norm, use_styles, activation_layer):
+        super().__init__()
+
+        layers = []
+        if use_noise:
+            layers.append(('noise', NoiseLayer(channels)))
+        layers.append(('activation', activation_layer))
+        if use_pixel_norm:
+            layers.append(('pixel_norm', PixelNormLayer()))
+        if use_instance_norm:
+            layers.append(('instance_norm', nn.InstanceNorm2d(channels)))
+
+        self.top_epi = nn.Sequential(OrderedDict(layers))
+
+        if use_styles:
+            self.style_mod = StyleMod(dlatent_size, channels, use_wscale=use_wscale)
+        else:
+            self.style_mod = None
+
+    def forward(self, x, dlatents_in_slice=None):
+        x = self.top_epi(x)
+        if self.style_mod is not None:
+            x = self.style_mod(x, dlatents_in_slice)
+        else:
+            assert dlatents_in_slice is None
+        return x
+
+
+

code from huangzh13/StyleGAN.pytorch

+

아래 그림은 source A의 style 중 일부를 source B의 style로 변경해서 만든 이미지들입니다. style은 총 18곳에서 사용되는데 처음 4곳 (\(4^2 - 8^2\))을 coarse, 그다음 4곳 (\(16^2-32^2\))을 middle, 마지막 10곳 (\(64^2-1024^2\))을 fine style로 정의하였습니다. 그림을 보시면 윗 부분에서는 포즈나 전체적인 머리 스타일같이 coarse style은 source B의 것을 유지하고, 아래로 갈수록 source A의 큰 틀을 유지하면서 세부적인 부분들을 B에서 가져왔음을 볼 수 있습니다.

+
+stylegan_05 +
+

Fig. 30 Mixing two styles#

+
+
+
+
+

Stochastic Variation#

+

한 사람의 이미지 안에는 확률적으로 바뀔 수 있는 부분이 있습니다. (주근깨, 머릿결, 피부) 이를 모델링하기 위해서 noise를 추가적인 input으로 사용하여 각 convolution layer 다음에 더해집니다. 아래 그림에서 (a)의 생성된 한 사람의 이미지 안에서도 디테일들은 (b)와 같이 달라질 수 있습니다. (c)와 같이 standard deviation을 구해봤을 때 얼굴형과 같은 attribute는 변하지않지만 noise에 의해서 머리카락과 같은 부분은 variation이 생김을 볼 수 있습니다.

+
+stylegan_06 +
+

Fig. 31 Examples of stochastic variation#

+
+
+

아래 그림에서 (a)는 모든 layer에 noise를 준 경우, (b)는 noise를 주지 않은 경우, (c)는 fine layers (\(64^2 - 1024^2\))에만 noise를 준 경우, (d)는 coarse layers (\(4^2 - 32^2\))에만 noise를 준 경우입니다. (b)를 보면 noise가 없을 경우 머리카락같은 디테일이 제대로 살아있지 않은 것을 볼 수 있습니다. (c)와 (d)를 보면 fine layers에 들어간 noise가 머리카락의 더 세밀한 부분에 영향을 끼친다는 것을 볼 수 있습니다.

+
+stylegan_07 +
+

Fig. 32 Effect of noise inputs at different layers#

+
+
+
+
+

Mixing Regularization#

+

논문에서는 localization이 더 잘 되게하기 위해 style mixing이라는 방법을 훈련에 사용합니다. 두 개의 style vector \(\mathbf{w}_{1},\mathbf{w}_{2}\)를 사용하여 앞 쪽 layer에는 \(\mathbf{w}_{1}\)을, 뒤 쪽 layer에는 \(\mathbf{w}_{2}\)를 사용하는 방법입니다. 이는 generator가 인접한 style끼리 correlated되어있다고 학습하는 것을 막아서 localization을 더 잘 되게 하는 목적입니다.

+
+
+

실험 결과#

+

마지막으로 저자들이 제안한 방법들이 실제로 효과가 있었는지 확인해봅시다. 아래 표와 같이 실험적으로 보았을 때 저자들이 제안한 방법들을 모두 사용한 경우 FID가 가장 우수하게 나왔습니다.

+
+stylegan_08 +
+

Fig. 33 FID for various generator designs#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/Textual_Inversion.html b/docs/review/Textual_Inversion.html old mode 100644 new mode 100755 index 19d56b30..44aa761a --- a/docs/review/Textual_Inversion.html +++ b/docs/review/Textual_Inversion.html @@ -1,833 +1,841 @@ - - - - - - - - - - - - Textual Inversion — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

Textual Inversion#

-
-
-

Abstract#

-
이미지 3-5장으로 새로운 개념(또는 콘셉트, concept) 학습해 관련된 이미지를 뽑아내는 모델
-
-
-

text-to-image model은 자연어를 통한 creation에 전례없는 자유도를 주었다. 하지만, 특정한 contept를 생성하고, 그것의 생김새를 바꾸거나, 새로운 역할이 주어지거나 참신한 장면이 그려지는건 아직 불분명하다. 즉, ‘이것을 그려줘’라고 말할 때, ‘이것’에 대한 설명을 prompt로 어떻게 할 것이냐는 물음에는 아직 한계가 있는 것 같다. 이를 해결하기 위해, 저자는 image를 3-5개만으로 사물이나 스타일과 같은 concept, 즉 새로운 ‘단어’를 고정된 text-to-image model의 embedding space에서 표현하는 방법을 제안한다. 이러한 ‘단어’는 자연어 문장에 녹아들어가, 직관적인 방법으로 ‘개인화된’ 이미지 생성을 이끌어 낸다. 특히, 독자적이면서 다양한 콘셉트를 capture하기 위해서는 single word embedding이 충분하다는 것을 알게 되었다.

-
-textual inverison example -
-

Fig. 110 textual inversion example \ (source: https://arxiv.org/abs/2208.01618)#

-
-
-
-
-

Introduction#

-

대규모 학습된 모델에 새로운 개념을 도입하는 일은 어려운 일이다. 각 새로운 개념에 대해 확장된 데이터 셋을 사용해 모델을 retraining하는 것은 엄청나게 비용이 많이 들고, 몇 가지 예제에 해서 fine-tuning은 보통 치명적인 망각을 초래한다. 따라서 저자들은 사전 훈련된 텍스트-이미지 모델의 텍스트 임베딩 공간에서 새로운 단어를 찾아 이러한 문제를 극복할 것을 제안.

-
-architecture -
-

Fig. 111 architecture \ (source: https://arxiv.org/abs/2208.01618)#

-
-
-

위 figure에서, “A photo of S*”은 tokenizer를 지나면서 각각 ‘508’, ‘701’, ‘73’, ‘*’과 같은 형태의 token set으로 변환되고, 이후 각 토큰은 자체 임베딩 벡터로 변환되고 이러한 벡터는 다운스트림 모델을 통해 제공됨.

-

input image의 concept를 나타내는, 새로운 pseudo-word인 S를 이용해 새로운 embedding vector(v)를 나타낸다. 이후 이 vector는 다른 단어와 같이 처리되며 생성 모델에 대한 새로운 text query를 구성하는데 사용될 수 있음. 따라서 이 query는 generator에 들어가서 사용자가 의도한바와 일치하도록 새로운 image를 생성하도록 하는 것이 전반적인 그림이라고 볼 수 있음.

-

여기서 중요한 것은, 이 과정에서 생성모델(여기서는 LDM이 쓰임)은 untouched되어 있다는 것(즉, 따로 수정이 들어가지 않는듯함). 그렇게 함으로써 새로운 task에 대한 fine-tuning을 할 때 일반적으로 손실되는 text에 대한 이해도나 generalization을 유지할 수 있음.

-

이러한 ‘유사단어’를 찾기 위해, 이 작업을 하나로 inversion시켜 프레임화 한다. 그리고 고정된, pre-trained text-to-image model을 사용하고, 3-5개의 concept를 나타내는 small image set이 주어진다. 저자들은 ‘a photo of S*’와 같은 형태의 문장을 설정해 주어진 작은 dataset에서 이미지를 재구성 하는 것으로 이어지는 single-word embedding을 찾는 것을 목표로 함.

-

이 모델의 목표는 새로운 concept인 입력 이미지를 나타내는 S*를 표현하는 방법을 찾는 것이며, 이러한 task를 **’textual inversion’**이라고 한다고 함.

-
This embedding is found through an optimization process, which we refer to as “Textual Inversion”.
-
-
-
- -
-

Method#

-
Our goal is to enable language-guided generation of new, user-specified concepts.
-
-
-
    -
  • 의역) 목표: 유저가 의도한 것에 초첨을 맞춘, 새로운 concept를 embedding으로 잘 가이드해서 괜찮은 성과물을 내는 것.

  • -
-

따라서 pre-trained text-to-image model의 중간 단계의 representation으로 이러한 새로운 ‘concepts’을 인코딩하는데 초점을 맞춤. 일반적인 text-to-image model에서는 image의 representation에 대한 후보군을 text encoder의 word-embedding 단계에서 찾는다. 그러나 이러한 접근 방식은 이미지에 대한 in-depth visual understanding을 필요로 하지 않는다(생성자가 이미지에 대해서 시각적인 이해? 없이 그린다.) 따라서 여기서는 GAN inversion에서 영감을 받은 visual reconstruction objective를 제시.

-
-

cf) GAN Inversion(이해 못함)#

-

출처) - https://hyoseok-personality.tistory.com/entry/GAN-Inversion

-
-GAN inversion -
-

Fig. 112 GAN inversion \ (source: https://hyoseok-personality.tistory.com/entry/GAN-Inversion)#

-
-
-
    -
  • 입력 이미지와 유사한 결과 이미지를 얻을 수 있도록 하는 latent vector를 찾는 과정. GAN이 학습되면 random latent vector로부터 이미지를 생성해낸다. GAN inversion은 이의 역과정으로써 GAN의 latent space로 input image를 inverting시켜 latent vector를 알아가는 과정.

  • -
-
-
-

LDM(Latent Diffusion Model)#

-

논문에서는 생성모델로서 LDM(Latent Diffusion Model)을 사용함. 이전에 말했듯이, LDM은 하나도 건들지 않음.

-
-LDM objective function -
-

Fig. 113 LDM objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
-
-

Text Embeddings#

-
-Text-Embedding -
-

Fig. 114 Text-Embedding \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
    -
  • 입력된 문자열의 각 단어, 하위 단어는 tokenizer를 통과하며, 미리 정의된 dictionary에서 index token으로 변환함. 각 토큰을 통해 찾을 수 있는 고유한 임베딩 벡터에 연결됨.

  • -
  • index에 의한 embedding vector는 일반적으로 text encoder인 C_Θ의 일부로 학습된다. 이러한 space를 inversion target으로 삼았음. 새로운 개념을 나타내기 위해 자리표시자 문자열인 S를 새롭게 지정함. 이 과정에서 PALAVRA를 사용했을 것으로 추정함. 임베딩 process에 개입해서 tokenize된 문자열과 관련된 vector를 새로운 학습된 embedding V로 대체하여 본질적으로 어휘(pseudo-word)에 개념을 주입함. 이렇게 함으로써 다른 단어와 마찬가지로 concept를 포함하는 새로운 문장을 만들 수 있었음.

  • -
-
-
-

Textual Inversion#

-

새로운 embedding을 찾기 위해 작은 규모의 dataset(3-5장)을 사용해 다양한 배경 또는 포즈와 같은 여러 설정에 걸쳐 목표 concept을 묘사함. 이러한 작은 dataset에서 LDM loss를 최소화하는 과정을 통해 V를 최적화함. 생성 조건을 고정하기 위해 CLIP ImageNet 템플릿에서 파생된 중립 컨텍스트 텍스트를 무작위로 샘플링한다. 여기에는 “A photo of S*”, “A rendition of S*” 등의 형식 프롬프트가 포함된다.(아마 원본 이미지와 최대한 비슷하게 만들어서 원본과 비교하기 위한 목적이 아닐까 싶음) 최적화 목표식은 다음과 같음.

-
-textual inversion objective function -
-

Fig. 115 textual inversion objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-

LDM loss함수와 매우 유사함. 여기서 CΘ와 eΘ는 고정. 해당 따라서 학습된 embedding이 개념에 미세한 시각적 detail을 포착할 수 있을것으로 기대함.

-
-
-
-

성능평가#

-
-

DALL:E-2와 비교#

-
-compare with DALLE-2 -
-

Fig. 116 compare with DALLE-2 \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
    -
  • input image에 대한 디테일을 더 잘 포착하는 모습을 볼 수 있다.

  • -
-
-
-

Text guided synthesis#

-
-text guided synthesis -
-

Fig. 117 text guided synthesis - 입력 이미지의 스타일과 유사하면서도 text guide에 맞춰서 잘 진행함. -\ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
    -
  • Textual Inversion 모델은 새로운 주제에 대해 더 정확하게 개념을 보존하고, 새로운 임베딩과 나머지 캡션들에 대해서도 모두 추론이 가능했음.

  • -
-
-style transfer -
-

Fig. 118 style transfer \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
    -
  • 적은 데이터셋으로도 style을 보존하면서 표현한 그림

  • -
-
-
-

pseudo word 두 개 사용#

-
-two pseudo word -
-

Fig. 119 two pseudo word \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
-
-

Bias Reduction#

-
-Bias reduction -
-

Fig. 120 Bias reduction \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-

기존 모델의 결과를 보면, 위 사진에서와 같이 ‘의사’라는 단어를 사용하면, 보통 백인 남성 의사를 잘 그려냈음. 이는 기존 데이터셋에서 남성 의사 사진 데이터가 많았음을 보여준다. 보다 작은 imageset에서 새로운 embedding을 학습함으로써 이러한 bias를 줄일 수 있음을 보여준다(즉, 성별 및 인종적 다양성에 대한 인식을 높일 수 있음).

-
-
-
-

정량평가#

-

latent space embedding의 품질을 분석.

-
    -
  1. reconstruction(y축?): target concept를 얼마나 잘 복제하는지. 특정 이미지가 아닌 개념에 대한 변형을 생성하므로 의미적 CLIP 공간 거리를 고려하여 유사성을 측정.(이미지에 자체가 아닌, 이미지가 가진 ‘개념’에 대해 latent space를 생성하므로) 각 컨셉에 대해 “A photo of S*”라는 prompt를 사용해 64개의 이미지를 생성.

  2. -
  3. editability(x축?): text prompt를 사용해 개념을 수정하는 능력을 평가. 다양한 난이도와 다양한 설정의 prompt를 사용해 일련의 이미지를 생성.

  4. -
-

각 prompt 별로, 50 DDIM step을 사용해 64개의 샘플을 만들고, CLIP-space embedding을 평가, textual prompt의 CLIP-space embedding에서 cosine similarity를 계산. 높은 스코어는 더 높은 editing capability와 prompt의 신뢰도를 보여줌.

-
-

평가 setups#

-

GAN inversion에서 영감을 받은 실험 환경 설정에 따름. 생략

-
-
-

결과#

-
-quantative evaluation1 -
-

Fig. 121 quantative evaluation1 \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-
-

주목할 점#

-
    -
  1. 많은 baseline과 우리 방법의 semantic reconstruction quality는 단순히 training set에서 임의의 이미지를 샘플링하는 것과 비슷함(== 원본 이미지와 생성된 이미지가 큰 차이가 없었다?)

  2. -
  3. single-word method는 비슷한 reconstruction quality를 달성하고, 모든 multi-word baseline에서 상당히 향상된 editablity을 달성. 이러한 점은 text embedding space의 인상적인 유연성을 나타내고, 단일 pseudo word만 사용하면서 높은 정확도로 새로운 개념을 캡처하는데 도움이 될 수 있음을 보여줌.

  4. -
  5. baseline이 distortion-editability tradeoff 곡선의 outline을 그리며 실제 단어 분포에 더 가까운 embedding이 더 쉽게 수정될 수 있음. 그러나 target의 세부 정보를 캡처하지는 못함. 반대로, 단어 분포에서 멀리 벗어나면 editability가 크게 감소하는 대신 향상된 reconstruction이 가능해짐. 특히 single embedding model은 단순히 learning rate를 변경해 이 곡선을 따라 이동할 수 있으므로 사용자에게 이 tradeoff에 대한 어느 정도의 제어를 제공함.

  6. -
  7. concept에 대한 human description을 사용하면 유사성을 포착하지 못하면서도, editability가 감소함.

  8. -
-
-
-
-

사용자평가#

-
-human test -
-

Fig. 122 human test \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

-
-
-

두 개의 설문지:

-
    -
  1. 사용자는 concept의 training set에서 4개의 이미지를 제공받았고, 이미지와의 유사성에 따라 5개의 모델에서 생성된 결과의 순위를 매김.

  2. -
  3. 이미지 context를 설명하는 텍스트를 제공받았고, 텍스트와 생성된 이미지의 유사성에 따라 순위를 매김.

  4. -
-

각 질문별로 600개씩 총 1,200개의 응답을 수집.

-
-
-
-

Limitation#

-
    -
  1. 이미지 생성에 더 많은 자유도를 제공하지만, concept의 의미론적인 본질을 파악하거나, 정확한 shape를 학습하는데 한계.

  2. -
  3. 최적화가 오래 걸린다. 하나의 concept를 학습하는데 약 2시간이 소요됨.

  4. -
-
-
-

마무리#

-

: 새로운 설정과 장면에서 특정 concept의 이미지를 생성하기 위해 text-to-image model를 활용하는 개인화되며, language-guided generation을 소개함. 여기서 사용한 ‘text inversion’은 pretrained text-to-image 모델의 text embedding space 내에서 concept를 새로운 pseudo word로 inverse하여 작동함. 이러한 pseudo-word는 간단한 자연어 설명을 사용해 새로운 장면에 삽입할 수 있으므로 간단하고 직관적인 수정이 가능함.

-

어떤 의미에서 이 방법은 사용자가 편집하기 쉽도록 텍스트 기반 interpace를 사용하지만 자연 언어의 한계에 접근할 때 시각적 단서를 제공하는 등 multi modal 정보를 활용할 수 있도록 함.

-

이러한 접근 방식은 공개적으로 사용가능한 가장 큰 text-to-image model인 LDM을 통해 구현됨. 그러나 접근 방식에 아키텍처 세부 정보에 의존하지 않음. 따라서 textual inversion은 추가적인 대규모 text-to-image model에 쉽게 적용할 수 있다고 생각. 거기에서 text-to-image alignment, shape preseravation, image generation fidelity가 더 향상될 수 있음.

-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Textual Inversion — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

Textual Inversion#

+
+
+

Abstract#

+
이미지 3-5장으로 새로운 개념(또는 콘셉트, concept) 학습해 관련된 이미지를 뽑아내는 모델
+
+
+

text-to-image model은 자연어를 통한 creation에 전례없는 자유도를 주었다. 하지만, 특정한 contept를 생성하고, 그것의 생김새를 바꾸거나, 새로운 역할이 주어지거나 참신한 장면이 그려지는건 아직 불분명하다. 즉, ‘이것을 그려줘’라고 말할 때, ‘이것’에 대한 설명을 prompt로 어떻게 할 것이냐는 물음에는 아직 한계가 있는 것 같다. 이를 해결하기 위해, 저자는 image를 3-5개만으로 사물이나 스타일과 같은 concept, 즉 새로운 ‘단어’를 고정된 text-to-image model의 embedding space에서 표현하는 방법을 제안한다. 이러한 ‘단어’는 자연어 문장에 녹아들어가, 직관적인 방법으로 ‘개인화된’ 이미지 생성을 이끌어 낸다. 특히, 독자적이면서 다양한 콘셉트를 capture하기 위해서는 single word embedding이 충분하다는 것을 알게 되었다.

+
+textual inverison example +
+

Fig. 110 textual inversion example \ (source: https://arxiv.org/abs/2208.01618)#

+
+
+
+
+

Introduction#

+

대규모 학습된 모델에 새로운 개념을 도입하는 일은 어려운 일이다. 각 새로운 개념에 대해 확장된 데이터 셋을 사용해 모델을 retraining하는 것은 엄청나게 비용이 많이 들고, 몇 가지 예제에 해서 fine-tuning은 보통 치명적인 망각을 초래한다. 따라서 저자들은 사전 훈련된 텍스트-이미지 모델의 텍스트 임베딩 공간에서 새로운 단어를 찾아 이러한 문제를 극복할 것을 제안.

+
+architecture +
+

Fig. 111 architecture \ (source: https://arxiv.org/abs/2208.01618)#

+
+
+

위 figure에서, “A photo of S*”은 tokenizer를 지나면서 각각 ‘508’, ‘701’, ‘73’, ‘*’과 같은 형태의 token set으로 변환되고, 이후 각 토큰은 자체 임베딩 벡터로 변환되고 이러한 벡터는 다운스트림 모델을 통해 제공됨.

+

input image의 concept를 나타내는, 새로운 pseudo-word인 S를 이용해 새로운 embedding vector(v)를 나타낸다. 이후 이 vector는 다른 단어와 같이 처리되며 생성 모델에 대한 새로운 text query를 구성하는데 사용될 수 있음. 따라서 이 query는 generator에 들어가서 사용자가 의도한바와 일치하도록 새로운 image를 생성하도록 하는 것이 전반적인 그림이라고 볼 수 있음.

+

여기서 중요한 것은, 이 과정에서 생성모델(여기서는 LDM이 쓰임)은 untouched되어 있다는 것(즉, 따로 수정이 들어가지 않는듯함). 그렇게 함으로써 새로운 task에 대한 fine-tuning을 할 때 일반적으로 손실되는 text에 대한 이해도나 generalization을 유지할 수 있음.

+

이러한 ‘유사단어’를 찾기 위해, 이 작업을 하나로 inversion시켜 프레임화 한다. 그리고 고정된, pre-trained text-to-image model을 사용하고, 3-5개의 concept를 나타내는 small image set이 주어진다. 저자들은 ‘a photo of S*’와 같은 형태의 문장을 설정해 주어진 작은 dataset에서 이미지를 재구성 하는 것으로 이어지는 single-word embedding을 찾는 것을 목표로 함.

+

이 모델의 목표는 새로운 concept인 입력 이미지를 나타내는 S*를 표현하는 방법을 찾는 것이며, 이러한 task를 **’textual inversion’**이라고 한다고 함.

+
This embedding is found through an optimization process, which we refer to as “Textual Inversion”.
+
+
+
+ +
+

Method#

+
Our goal is to enable language-guided generation of new, user-specified concepts.
+
+
+
    +
  • 의역) 목표: 유저가 의도한 것에 초첨을 맞춘, 새로운 concept를 embedding으로 잘 가이드해서 괜찮은 성과물을 내는 것.

  • +
+

따라서 pre-trained text-to-image model의 중간 단계의 representation으로 이러한 새로운 ‘concepts’을 인코딩하는데 초점을 맞춤. 일반적인 text-to-image model에서는 image의 representation에 대한 후보군을 text encoder의 word-embedding 단계에서 찾는다. 그러나 이러한 접근 방식은 이미지에 대한 in-depth visual understanding을 필요로 하지 않는다(생성자가 이미지에 대해서 시각적인 이해? 없이 그린다.) 따라서 여기서는 GAN inversion에서 영감을 받은 visual reconstruction objective를 제시.

+
+

cf) GAN Inversion(이해 못함)#

+

출처) - https://hyoseok-personality.tistory.com/entry/GAN-Inversion

+
+GAN inversion +
+

Fig. 112 GAN inversion \ (source: https://hyoseok-personality.tistory.com/entry/GAN-Inversion)#

+
+
+
    +
  • 입력 이미지와 유사한 결과 이미지를 얻을 수 있도록 하는 latent vector를 찾는 과정. GAN이 학습되면 random latent vector로부터 이미지를 생성해낸다. GAN inversion은 이의 역과정으로써 GAN의 latent space로 input image를 inverting시켜 latent vector를 알아가는 과정.

  • +
+
+
+

LDM(Latent Diffusion Model)#

+

논문에서는 생성모델로서 LDM(Latent Diffusion Model)을 사용함. 이전에 말했듯이, LDM은 하나도 건들지 않음.

+
+LDM objective function +
+

Fig. 113 LDM objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
+
+

Text Embeddings#

+
+Text-Embedding +
+

Fig. 114 Text-Embedding \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
    +
  • 입력된 문자열의 각 단어, 하위 단어는 tokenizer를 통과하며, 미리 정의된 dictionary에서 index token으로 변환함. 각 토큰을 통해 찾을 수 있는 고유한 임베딩 벡터에 연결됨.

  • +
  • index에 의한 embedding vector는 일반적으로 text encoder인 C_Θ의 일부로 학습된다. 이러한 space를 inversion target으로 삼았음. 새로운 개념을 나타내기 위해 자리표시자 문자열인 S를 새롭게 지정함. 이 과정에서 PALAVRA를 사용했을 것으로 추정함. 임베딩 process에 개입해서 tokenize된 문자열과 관련된 vector를 새로운 학습된 embedding V로 대체하여 본질적으로 어휘(pseudo-word)에 개념을 주입함. 이렇게 함으로써 다른 단어와 마찬가지로 concept를 포함하는 새로운 문장을 만들 수 있었음.

  • +
+
+
+

Textual Inversion#

+

새로운 embedding을 찾기 위해 작은 규모의 dataset(3-5장)을 사용해 다양한 배경 또는 포즈와 같은 여러 설정에 걸쳐 목표 concept을 묘사함. 이러한 작은 dataset에서 LDM loss를 최소화하는 과정을 통해 V를 최적화함. 생성 조건을 고정하기 위해 CLIP ImageNet 템플릿에서 파생된 중립 컨텍스트 텍스트를 무작위로 샘플링한다. 여기에는 “A photo of S*”, “A rendition of S*” 등의 형식 프롬프트가 포함된다.(아마 원본 이미지와 최대한 비슷하게 만들어서 원본과 비교하기 위한 목적이 아닐까 싶음) 최적화 목표식은 다음과 같음.

+
+textual inversion objective function +
+

Fig. 115 textual inversion objective function \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+

LDM loss함수와 매우 유사함. 여기서 CΘ와 eΘ는 고정. 해당 따라서 학습된 embedding이 개념에 미세한 시각적 detail을 포착할 수 있을것으로 기대함.

+
+
+
+

성능평가#

+
+

DALL:E-2와 비교#

+
+compare with DALLE-2 +
+

Fig. 116 compare with DALLE-2 \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
    +
  • input image에 대한 디테일을 더 잘 포착하는 모습을 볼 수 있다.

  • +
+
+
+

Text guided synthesis#

+
+text guided synthesis +
+

Fig. 117 text guided synthesis - 입력 이미지의 스타일과 유사하면서도 text guide에 맞춰서 잘 진행함. +\ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
    +
  • Textual Inversion 모델은 새로운 주제에 대해 더 정확하게 개념을 보존하고, 새로운 임베딩과 나머지 캡션들에 대해서도 모두 추론이 가능했음.

  • +
+
+style transfer +
+

Fig. 118 style transfer \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
    +
  • 적은 데이터셋으로도 style을 보존하면서 표현한 그림

  • +
+
+
+

pseudo word 두 개 사용#

+
+two pseudo word +
+

Fig. 119 two pseudo word \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
+
+

Bias Reduction#

+
+Bias reduction +
+

Fig. 120 Bias reduction \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+

기존 모델의 결과를 보면, 위 사진에서와 같이 ‘의사’라는 단어를 사용하면, 보통 백인 남성 의사를 잘 그려냈음. 이는 기존 데이터셋에서 남성 의사 사진 데이터가 많았음을 보여준다. 보다 작은 imageset에서 새로운 embedding을 학습함으로써 이러한 bias를 줄일 수 있음을 보여준다(즉, 성별 및 인종적 다양성에 대한 인식을 높일 수 있음).

+
+
+
+

정량평가#

+

latent space embedding의 품질을 분석.

+
    +
  1. reconstruction(y축?): target concept를 얼마나 잘 복제하는지. 특정 이미지가 아닌 개념에 대한 변형을 생성하므로 의미적 CLIP 공간 거리를 고려하여 유사성을 측정.(이미지에 자체가 아닌, 이미지가 가진 ‘개념’에 대해 latent space를 생성하므로) 각 컨셉에 대해 “A photo of S*”라는 prompt를 사용해 64개의 이미지를 생성.

  2. +
  3. editability(x축?): text prompt를 사용해 개념을 수정하는 능력을 평가. 다양한 난이도와 다양한 설정의 prompt를 사용해 일련의 이미지를 생성.

  4. +
+

각 prompt 별로, 50 DDIM step을 사용해 64개의 샘플을 만들고, CLIP-space embedding을 평가, textual prompt의 CLIP-space embedding에서 cosine similarity를 계산. 높은 스코어는 더 높은 editing capability와 prompt의 신뢰도를 보여줌.

+
+

평가 setups#

+

GAN inversion에서 영감을 받은 실험 환경 설정에 따름. 생략

+
+
+

결과#

+
+quantative evaluation1 +
+

Fig. 121 quantative evaluation1 \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+
+

주목할 점#

+
    +
  1. 많은 baseline과 우리 방법의 semantic reconstruction quality는 단순히 training set에서 임의의 이미지를 샘플링하는 것과 비슷함(== 원본 이미지와 생성된 이미지가 큰 차이가 없었다?)

  2. +
  3. single-word method는 비슷한 reconstruction quality를 달성하고, 모든 multi-word baseline에서 상당히 향상된 editablity을 달성. 이러한 점은 text embedding space의 인상적인 유연성을 나타내고, 단일 pseudo word만 사용하면서 높은 정확도로 새로운 개념을 캡처하는데 도움이 될 수 있음을 보여줌.

  4. +
  5. baseline이 distortion-editability tradeoff 곡선의 outline을 그리며 실제 단어 분포에 더 가까운 embedding이 더 쉽게 수정될 수 있음. 그러나 target의 세부 정보를 캡처하지는 못함. 반대로, 단어 분포에서 멀리 벗어나면 editability가 크게 감소하는 대신 향상된 reconstruction이 가능해짐. 특히 single embedding model은 단순히 learning rate를 변경해 이 곡선을 따라 이동할 수 있으므로 사용자에게 이 tradeoff에 대한 어느 정도의 제어를 제공함.

  6. +
  7. concept에 대한 human description을 사용하면 유사성을 포착하지 못하면서도, editability가 감소함.

  8. +
+
+
+
+

사용자평가#

+
+human test +
+

Fig. 122 human test \ (source: https://arxiv.org/pdf/2208.01618.pdf)#

+
+
+

두 개의 설문지:

+
    +
  1. 사용자는 concept의 training set에서 4개의 이미지를 제공받았고, 이미지와의 유사성에 따라 5개의 모델에서 생성된 결과의 순위를 매김.

  2. +
  3. 이미지 context를 설명하는 텍스트를 제공받았고, 텍스트와 생성된 이미지의 유사성에 따라 순위를 매김.

  4. +
+

각 질문별로 600개씩 총 1,200개의 응답을 수집.

+
+
+
+

Limitation#

+
    +
  1. 이미지 생성에 더 많은 자유도를 제공하지만, concept의 의미론적인 본질을 파악하거나, 정확한 shape를 학습하는데 한계.

  2. +
  3. 최적화가 오래 걸린다. 하나의 concept를 학습하는데 약 2시간이 소요됨.

  4. +
+
+
+

마무리#

+

: 새로운 설정과 장면에서 특정 concept의 이미지를 생성하기 위해 text-to-image model를 활용하는 개인화되며, language-guided generation을 소개함. 여기서 사용한 ‘text inversion’은 pretrained text-to-image 모델의 text embedding space 내에서 concept를 새로운 pseudo word로 inverse하여 작동함. 이러한 pseudo-word는 간단한 자연어 설명을 사용해 새로운 장면에 삽입할 수 있으므로 간단하고 직관적인 수정이 가능함.

+

어떤 의미에서 이 방법은 사용자가 편집하기 쉽도록 텍스트 기반 interpace를 사용하지만 자연 언어의 한계에 접근할 때 시각적 단서를 제공하는 등 multi modal 정보를 활용할 수 있도록 함.

+

이러한 접근 방식은 공개적으로 사용가능한 가장 큰 text-to-image model인 LDM을 통해 구현됨. 그러나 접근 방식에 아키텍처 세부 정보에 의존하지 않음. 따라서 textual inversion은 추가적인 대규모 text-to-image model에 쉽게 적용할 수 있다고 생각. 거기에서 text-to-image alignment, shape preseravation, image generation fidelity가 더 향상될 수 있음.

+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/cycleGAN.html b/docs/review/cycleGAN.html old mode 100644 new mode 100755 index 232f7314..1b2b106b --- a/docs/review/cycleGAN.html +++ b/docs/review/cycleGAN.html @@ -1,951 +1,959 @@ - - - - - - - - - - - - CycleGAN — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

CycleGAN#

-
-

Abstract#

-
    -
  • Image-to-image translation(이하 translation)은 한 이미지 도메인을 다른 이미지 도메인으로 변환시키는 computer vision의 한 task.

  • -
  • translation은 보통 input과 output이 짝이 지어진 상태에서 학습. 하지만 짝이 지어진 학습 데이터를 얻는 것이 어렵습니다. 따라서 cycleGAN 논문에서는 짝지어진 예시 없이 X라는 domain으로부터 얻은 이미지를 target domain Y로 바꾸는 방법을 제안. 이 연구는 Adversarial loss를 활용해, G(x)로부터 생성된 이미지 데이터의 분포와 Y로부터의 이미지 데이터의 분포가 구분이 불가능하도록 “함수 G:X -> Y”를 학습시키는 것을 목표로 합니다. X –> Y로의 mapping에 제약을 가해서 원하는 이미지를 강제하기 위해 F: Y -> X와 같은 역방향 매핑을 함께 진행하고, F(G(x))가 X와 유사해지도록 강제하는 Cycle consistency loss를 도입했습니다.

  • -
  • 결과적으로 collection style transfer, object transfiguration, season transfer, photo enhancement 등의 task에서 이미지 pair가 존재하지 않는 상태에서 우수한 결과를 보여줬다고 합니다.

  • -
-
-
-

Introduction#

-
-

참고) Image-to-Image translation이란?#

-
-https://phillipi.github.io/pix2pix/images/teaser_v3.png -
-

Fig. 9 image-to-image translation#

-
-
-

Image-to-image translation은 input image를 다른 스타일, 속성, 구조 등을 가진 output image로 변환하는 것입니다. 예를 들어 사진을 그림으로 변환한다거나, 낮에 찍은 사진을 밤에 찍은 것 처럼 변환하는 것을 말합니다. 흔히 translation은 input과 output으로 짝이 지어진 data를 바탕으로 학습이 이루어져 있었는데요. 짝이 지어진 사진 데이터를 얻는 것은 어렵고 값이 비싼 일이 됩니다.

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhMGUZ%2Fbtr7HimHXN5%2FHvjTh02iCzP5Sgk8UYkKO0%2Fimg.png -
-

Fig. 10 paired and unpaired data#

-
-
-

이 논문에서는 input image와 output image가 일대일로 짝지어지지 않은 상태에서 하나의 image 모음의 특성을 캡쳐하고, 이러한 특성을 다른 image 모음으로 변환할 수 있는 방법을 제시합니다.
-GAN은 domain X에 이미지 한 세트, domain Y에 이미지 한 세트가 제공되고, model의 output과, Y가 discriminator에 의해 구별할 수 없도록 G:X->Y를 학습합니다. 하지만, 이게 개별 입력 x와 출력 y가 무조건 유의미하게 쌍을 이룬다는 것을 뜻하지는 않습니다. G가 생성할 수 있는 image에는 무한한 경우의 수가 있기 때문. 종종 mode collapse가 일어나기도 합니다.

-
-
-

mode collapse란?#

-
-https://1.bp.blogspot.com/-oDCR5UnEIl4/WZkIId-rYCI/AAAAAAAAAJk/PoLvou4JLNIxn5U-OmPFZ_heyxVQGbMNQCEwYBhgL/s1600/14.png -
-

Fig. 11 mode collapsing 출처: http://dl-ai.blogspot.com/2017/08/gan-problems.html#

-
-
-
    -
  • 어떤 input image든 모두 같은 output image로 매핑하면서 최적화에 실패하는 현상. 이 현상은 generator 입장에서, Discriminator가 이 사진이 진짜 Y인지 가짜인 Y^인지 구별하는 것을 ‘속이기만’ 하면 되기 때문에 우리의 목적과 전혀 상관이 없는 데이터를 generator가 만들더라도 문제가 생기지 않아서 발생함

  • -
  • 참고: http://dl-ai.blogspot.com/2017/08/gan-problems.html

  • -
-

이러한 이슈로 인해 추가 objective function이 필요해 졌습니다. 따라서 translation task는 영어 -> 프랑스어 -> 영어로 번역했을 때 원래 문장에 다시 도달하는 것처럼, X –> Y –> X’로 돌아가는 과정에서 X와 X’가 최대한 같아야 한다는 의미의 cyclic consistency이라는 속성을 이용합니다. 필요한 목적식을 간단하게 정리하면 다음과 같습니다.

-
    -
  • 정방향, 역방향 adversarial Loss(X -> Y & Y -> X)

  • -
  • Cycle consistency loss: X ~= F(G(x))

  • -
-
-
-
- -
-
-

Formulation#

-
-../../_images/fig2.png -
-

Fig. 12 cycleGAN 도식화 자료#

-
-
-
    -
  • 목표: X, Y를 mapping하는 function을 학습하는 것

  • -
  • 용어 정리

  • -
-
    -
  1. data 분포를 x ~ pdata(x), y ~ pdata(y)로 표시

  2. -
  3. G : X -> Y, F: Y -> X

  4. -
  5. Dx, Dy는 discriminator

  6. -
  7. Dx는 X와 F(y)를 구분, Dy는 y와 G(x)를 구분. 목적식은 총 두개

    -
      -
    • adversarial loss: 생성된 이미지의 분포를 대상 domain의 data distribution과 일치시키기 위한 것.

    • -
    • cycle consistency loss: 학습된 mapping G와 F가 서로 모순되는 것을 방지하기 위한 것.

    • -
    -
  8. -
-
-

Adversarial loss#

-

G: X –> Y와 Dy에 대한 목적식은 다음과 같음.

-
-L_GAN Loss function -
-

Fig. 13 L_GAN Loss function (source: https://arxiv.org/abs/1703.10593)#

-
-
-
    -
  • GAN에서 쓰이는 loss function과 동일. 대신에 X -> Y로 갈 때와 Y -> X로 갈 때 총 두개의 수식이 나오며, F:Y->X와 Dx에 대해서도 F, Dx를 넣은, 같은 수식을 사용함.

  • -
-
-
-

Cycle consistency Loss#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzsgD6%2Fbtr8ay8PEBE%2F3mAKd1YSAiCK4ZXeIg84s1%2Fimg.png -
-

Fig. 14 cycle consistency loss result#

-
-
-
    -
  • 앞서 말했듯, mapping distribution에 제한을 두어 최대한 우리가 원하는 이미지를 생성하기 위해 사용하는 수식으로서, 위와 같음.

  • -
  • 예비 실험에서 L1 norm을 adversarial loss로 대체해봤는데, 성능 향상을 관찰할 수 없었음.

  • -
  • cycle consistency loss를 통해 유도된 결과는 아래 그림에서 볼 수 있었음.

  • -
-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmq8pC%2Fbtr724Pl3Q2%2FUSK4TDRaUK860iIdvG0vV0%2Fimg.png -
-

Fig. 15 cycle consistency loss function#

-
-
-
-
-

full objective - 전체 목적식#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUyaOu%2Fbtr724Pl3Rj%2FigjKaeukv5m8Cbdzulp5jK%2Fimg.png -
-

Fig. 16 full objective function#

-
-
-
    -
  • 이 때 consistency loss 앞에 붙은 가중치 (lambda)는 GAN Loss와의 상대적 중요도에 따라 결정됨.

  • -
-
-
-
-
-

Implementation#

-

baseline architecture로서 neural style transfer와 super-resolution에 인상적인 결과를 보여준 논문에서 사용된 구조를 채택함.

-
    -
  • 3개의 convolutions and several residual blocks,

  • -
  • fractionally-strided convolution with stride 1/2,

  • -
  • feature를 RGB로 매핑하는 one convolution layer.

  • -
  • 6 blocks for 128 x 128 image // 9 blocks for 256 x 256 및 고해상도 학습 image.

  • -
  • instance normalization

  • -
-
-

Training details#

-

모델 학습을 안정화시키기 위해 아래와 같은 테크닉을 추가로 적용합니다.

-
    -
  • GAN의 Loss function에서 nll loss를 least-squared loss로 변경

  • -
  • 생성된 이미지 중 가장 최근의 50개를 따로 저장해 discriminator가 이를 한꺼번에 분류(모델 진동을 최소화하기 위함)

  • -
-
-
-

least-square loss 추가 설명#

-

참고)

- -

사용 이유: Generator의 업데이트를 위해서(LSGAN을 참고)

-
    -
  • 이해는 못했고, 이런게 있구나 정도로만 알 수 있었음.

  • -
-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6JIT8%2Fbtr73nVyIqs%2FKfcPK33U3OY0AjKhjFlUh1%2Fimg.png -
-

Fig. 17 출처: https://velog.io/@sjinu/CycleGAN#

-
-
-

(원래 Discriminator는 이보다 더 고차원이지만) 간략히 2차원을 표방하면 결정경계를 위와 같이 나타낼 수 있습니다. 윗 쪽이 가짜 영역, 아래 쪽이 진짜 영역입니다 이 때, 아래에 보면 진짜 데이터 샘플과 거리가 먼 가짜 데이터 샘플이 존재합니다. 즉, NLL Loss를 사용한다면, Generator의 입장에서는 이미 Discriminator를 잘 속이고 있기 때문에 학습할 필요가 없습니다. 즉, Vanishing Gradient가 일어나기 때문에, Discriminator를 잘 속인다는 이유만으로, 안 좋은 샘플을 생성하는 것에 대해 패널티를 줄 수가 없게 됩니다. 이 때, LS GAN을 사용한다면 실제 데이터 분포와 가짜 데이터 샘플이 거리가 먼 것에 대해서도 패널티를 주게 됩니다.

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHsUiX%2Fbtr77PQw99h%2F0Er06IYIGYlBGw2rVufXc0%2Fimg.png -
-

Fig. 18 출처: https://velog.io/@sjinu/CycleGAN#

-
-
-
    -
  • Generator는 Discriminator를 속이는 것을 넘어서, 실제 데이터 분포와 유사한 분포를 가지게끔 해야합니다.

  • -
-
-
-

기타#

-
    -
  • 모든 실험에서 람다를 10으로 설정했다.

  • -
  • batch size == 1, 아담을 사용했다.

  • -
  • 모든 네트워크는 learning rate를 0.0002로 사용했다. 첫 100 에포크 동안에는 같은 ln을 사용했고, 다음 100 에포크마다 0으로 조금식 수렴하게 했다.

  • -
-
-
-
-
-

Result#

-

모델 성능 평가를 위해 아래와 같은 세 개의 지표를 사용.

-
    -
  1. AMT perceptual studies: 참가자들은 실제 사진이미지 vs 가짜 이미지, 또는 지도 이미지 vs 가짜이미지에 노출된 후 진짜라고 생각되는 이미지를 선택하게 함.

  2. -
  3. FCN Score: 1번 study가 테스트에 있어 매우 좋은 기준임에도 불구하고, 사람을 대상으로 한 실험이 아닌, 양적인 기준을 찾았는데, FCN score임. FCN은 생성된 사진에 대한 레이블 맵을 예측합니다. 이 레이블 맵은 아래에서 설명하는 표준 시맨틱 분할 메트릭을 사용하여 input ground truth label과 비교할 수 있다. “도로 상의 자동차”라는 label에서 사진 이미지를 생성하면, 생성된 이미지에 적용된 FCN이 “도로 상의 자동차”를 감지하면 성공한 것입니다.

  4. -
  5. 사진 –> 라벨링 성능을 평가: pixel당 정확도, class 당 정확도, IoU(Intersection-Over-Union)을 포함하는 cityscapes benchmark의 표준 metric

  6. -
-
-

Baseline#

-
    -
  • coGAN, SimGAN, pix2pix

  • -
-
-
-

Comparison against baselines#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZUe4E%2Fbtr8eXUQ6ou%2FikWglP8dEglGUny4dRkMjK%2Fimg.png -
-

Fig. 19 Comparison aginst baselines#

-
-
-

figure 5, figure 6에서 볼 수 있듯이 어떤 baseline에서도 강력한 결과를 얻을 수 없었음. 반면에 cycleGAN은 fully supervise인 pix2pix와 비슷한 품질의 translation을 생성할 수 있음.

-
-
-

Human study#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Zhnx%2Fbtr8eWhk9ID%2FtauuT1N0W2qxRekj3IAnc1%2Fimg.png -
-

Fig. 20 AMT score#

-
-
-

표 1은 AMT perceptual realism task에 대한 성능을 나타냄. 여기서 지도에서 항공 사진, 항공 사진에서 지도 모두에서 약 1/4의 참가자를 속일 수 있었음. 그 외 모든 baseline은 참가자를 거의 속일 수 없었다.

-
-
-

FCN 등#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqzYO1%2Fbtr728xs5iD%2FN5NDNYwUYLnEZfnOVYONM0%2Fimg.png -
-

Fig. 21 FCN scores#

-
-
-

표 2는 도시 풍경에 대한 label –> photo task의 성능을 평가하고 표 3은 반대 매핑을 평가함. 두 경우 모두 cycleGAN이 baseline들의 성능을 능가한다.

-
-
-

Analysis of the loss function#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjQ9QQ%2Fbtr79farEX8%2FkQ6SWARw9QK9jqRqHlZoi1%2Fimg.png -
-

Fig. 22 Analysis of loss function#

-
-
-

GAN, cycle consistency의 중요성을 보여주는 자료.
-table 4, table 5에서 볼 수 있음. GAN을 없애면 cycle을 제거하는 것처럼 결과가 크게 저하됨. 따라서 두 term 모두 결과에 중요하다고 결론을 내릴 수 있음. 또한 한 방향에서만 cycle loss를 통해 각 메소드를 평가함. GAN + forward cycle만 돌렸을 때와, GAN + backward cycle만 돌렸을 때 이따금씩 학습에 불안정성을 보이고, mode collapse를 유발하는 것을 발견함(특히 제거된 매핑의 방향에 대해서 그런 경향을 보임). 그림 7을 보면 그런 경향을 볼 수 잇었음.

-
-
-

Image reconstruction quality#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyy7lt%2Fbtr73PdbuJp%2F5bmDtKSlQJJnd5yKvPgfB1%2Fimg.png -
-

Fig. 23 cycle consistency result#

-
-
-

그림 4에서 재구성된 이미지의 몇가지 무작위 샘플을 보여줌. 지도 –> 항공 사진과 같이 하나의 도메인이 훨씬 더 다양한 정보를 나타내는 경우에도 재구성된 이미지가 훈련 및 테스트 시간 모두 원래 입력 x에 가까운 경우가 많았음.

-
-
-

paired dataset에 대한 추가 결과#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqNrhb%2Fbtr72YaInQa%2Fk8b4K99KrAsD9C0SHINtt1%2Fimg.png -
-

Fig. 24 compare with paired dataset#

-
-
-

그림 8은 CMP Façade Database의 건축 레이블 <–> 사진, UT Zapoos50K dataset의 edge <–> 신발과 같이 pix2pix에 사용된 다른 paired dataset에 대한 몇 가지 예시 결과를 보여줌. cycleGAN의 이미지 품질은 fully supervised pix2pix에 대의 생성된 것과 비슷하지만 cycleGAN은 paired supervision 없이 학습이 된다.(우리가 짱이다!)

-
-
-
-
-

Applications#

-
    -
  • ** 이미지가 너무 많아 이미지는 생략하겠습니다.ㅠ**

  • -
  • paired data가 없는 상태에서 의 application 예시. traning data에서 transslation이 test data에서 한것보다 더 매력적이다. training and test data에 대한 application은 웹사이트에 있다.

  • -
-
-

Collection style transfer#

-

신경 스타일 전달”[13]에 대한 최근 작업과 달리, 우리의 방법은 선택한 단일 예술 작품의 스타일을 전달하는 대신 전체 예술 작품 컬렉션의 스타일을 모방하는 방법을 학습합니다. 그래서 ‘별이 빛나는 밤에’처럼 그리는 것 보다 ‘반 고흐’를 따라하는 느낌을 따라한다.

-
-
-

Object transfiguration#

-

Turmukhambetov et al. [50] 하나의 객체를 동일한 범주의 다른 객체로 변환하는 부분 공간 모델을 제안하는 반면, 우리의 방법은 시각적으로 유사한 두 범주 사이의 객체 변형에 중점을 둡니다.
-Turning a horse video into a zebra video (by CycleGAN)

-
-
-

season transfer#

-
-
-

Photo generation from paintings **#

-

그림을 사진으로 바꿀 때, 입력과 출력 간 색 구성을 보존하기 위해 추가적인 loss를 도입하는 것이 유용하다는 것을 발견할 수 있습니다. 특히, Taigman et al. [49]의 기술을 채택하여 제너레이터가 대상 도메인의 실제 샘플을 입력으로 제공받을 때 identity mapping 근처에 있도록 정규화합니다. 즉, **Lidentity(G,F) = Ey_pdata(y)[∥G(y) − y∥1] + Ex∼pdata (x) [∥F (x) − x∥1 ]**입니다.

-

Lidentity가 없으면, 생성자 G와 F는 굳이 필요하지 않을 때 입력 이미지의 색조를 자유롭게 변경할 수 있습니다. 예를 들어, Monet의 그림과 Flickr 사진 간의 매핑을 학습할 때, 생성자는 종종 낮에 그린 그림을 일몰 시간에 찍은 사진에 매핑합니다. 왜냐하면 적대적 손실과 사이클 일관성 손실 아래에서 이러한 매핑이 동등하게 유효할 수 있기 때문입니다. 이러한 identity mapping 손실의 효과는 그림 9에서 보여집니다. figure 12, figure 9는 학습 데이터셋에 포함되어 있는 그림, 하지만 다른 set은 오직 test set으로부터 그려진 그림. training set이 paired datqa를 포함하고 있지 않아서, 학습 세트 그림에 대한 타당한 translation을 찾는 것은 쉬운 일이 아니다. 실제로, Monet이 새 그림을 그릴 수 없기 때문에, 보지 않은 test set 그림에 대한 generalization은 not pressing problem

-
-
-

Photo enhancement#

-

우리는 우리의 방법이 얕은 깊이의 초점을 가진 사진을 생성하는 데 사용될 수 있음을 보여줍니다. 우리는 Flickr에서 다운로드한 꽃 사진을 기반으로 모델을 훈련합니다. 소스 도메인은 스마트폰으로 찍힌 꽃 사진으로 구성되어 있으며, 보통 작은 조리개로 인해 깊은 DoF(초점 깊이)를 가지고 있습니다. 대상은 조리개가 큰 DSLR로 촬영된 사진을 포함합니다. 우리 모델은 스마트폰으로 촬영된 사진으로부터 더 얕은 깊이의 초점을 가진 사진을 성공적으로 생성합니다.

-
-

: shallow depth of field: 얕은 초점. 초점이 맞은 대상과 배경이 흐릿하게 보이는 효과. 인물 사진 / 작품 사진에 활용. 구목하고자 하는 대상을 강조하기 위해 활용.
-따라서 source domain은 스마트폰의 작은 조리개로 깊은 초점 –> target은 조리개가 커서 얕은 초점.

-
-
-
-

Comparison with Gatys#

-
-
-
-
-

Limitations and Discusssion#

-
-https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJc1k5%2Fbtr76zUPUWj%2F27Mk0oQ5VanEHANWWmaseK%2Fimg.png -
-

Fig. 25 Limitation and Discussion#

-
-
-

이 방법은 많은 경우에 흥미로운 결과를 얻을 수 있지만, 결과는 결과가 균일하게 좋은 것은 아니었습니다.

-
    -
  1. (해석) 개<->고양이 task와 같은 경우는 input image에서 최소한의 변화만 주어, 사람이 보았을 때 실제로 변화가 안되는 경우도 있었고, 형체가 애매해진 경우도 있음. 이런걸 보았을 때, 세부적인 구조(geometry? 라는 표현을 보아), 눈, 코, 입에 대한 정확한 구조를 구현하는데 한계가 있어 보임.

  2. -
  3. 말<–> 얼룩말 예제의 경우, 말은 사람이 타는 모습이 많았는데, 얼룩말의 경우는 사람이 타는 사진이 없다보니, 사람 뿐만 아니라 배경도 얼룩 그림을 그림을 그리거나, 단순히 얼룩말에서 노랗게 칠한 경우가 생김.

  4. -
  5. 때때로 photo –> image task에서 나무와 건물의 label을 바꾸는 경우도 있었음.
    -이러한 모호성을 해결하려면 weak semantic supervision이 필요할 수도 있을 것 같음.

  6. -
-

마무리: 그럼에도 불구하고 많은 경우 완전히 짝지어지지 않은 데이터가 풍부하게 제공되며, 이를 활용해야 합니다. 이 논문은 이러한 “unsupervised” setting에서 가능한 것의 한계를 늘리는데 기여합니다.

-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + CycleGAN — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

CycleGAN#

+
+

Abstract#

+
    +
  • Image-to-image translation(이하 translation)은 한 이미지 도메인을 다른 이미지 도메인으로 변환시키는 computer vision의 한 task.

  • +
  • translation은 보통 input과 output이 짝이 지어진 상태에서 학습. 하지만 짝이 지어진 학습 데이터를 얻는 것이 어렵습니다. 따라서 cycleGAN 논문에서는 짝지어진 예시 없이 X라는 domain으로부터 얻은 이미지를 target domain Y로 바꾸는 방법을 제안. 이 연구는 Adversarial loss를 활용해, G(x)로부터 생성된 이미지 데이터의 분포와 Y로부터의 이미지 데이터의 분포가 구분이 불가능하도록 “함수 G:X -> Y”를 학습시키는 것을 목표로 합니다. X –> Y로의 mapping에 제약을 가해서 원하는 이미지를 강제하기 위해 F: Y -> X와 같은 역방향 매핑을 함께 진행하고, F(G(x))가 X와 유사해지도록 강제하는 Cycle consistency loss를 도입했습니다.

  • +
  • 결과적으로 collection style transfer, object transfiguration, season transfer, photo enhancement 등의 task에서 이미지 pair가 존재하지 않는 상태에서 우수한 결과를 보여줬다고 합니다.

  • +
+
+
+

Introduction#

+
+

참고) Image-to-Image translation이란?#

+
+https://phillipi.github.io/pix2pix/images/teaser_v3.png +
+

Fig. 9 image-to-image translation#

+
+
+

Image-to-image translation은 input image를 다른 스타일, 속성, 구조 등을 가진 output image로 변환하는 것입니다. 예를 들어 사진을 그림으로 변환한다거나, 낮에 찍은 사진을 밤에 찍은 것 처럼 변환하는 것을 말합니다. 흔히 translation은 input과 output으로 짝이 지어진 data를 바탕으로 학습이 이루어져 있었는데요. 짝이 지어진 사진 데이터를 얻는 것은 어렵고 값이 비싼 일이 됩니다.

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhMGUZ%2Fbtr7HimHXN5%2FHvjTh02iCzP5Sgk8UYkKO0%2Fimg.png +
+

Fig. 10 paired and unpaired data#

+
+
+

이 논문에서는 input image와 output image가 일대일로 짝지어지지 않은 상태에서 하나의 image 모음의 특성을 캡쳐하고, 이러한 특성을 다른 image 모음으로 변환할 수 있는 방법을 제시합니다.
+GAN은 domain X에 이미지 한 세트, domain Y에 이미지 한 세트가 제공되고, model의 output과, Y가 discriminator에 의해 구별할 수 없도록 G:X->Y를 학습합니다. 하지만, 이게 개별 입력 x와 출력 y가 무조건 유의미하게 쌍을 이룬다는 것을 뜻하지는 않습니다. G가 생성할 수 있는 image에는 무한한 경우의 수가 있기 때문. 종종 mode collapse가 일어나기도 합니다.

+
+
+

mode collapse란?#

+
+https://1.bp.blogspot.com/-oDCR5UnEIl4/WZkIId-rYCI/AAAAAAAAAJk/PoLvou4JLNIxn5U-OmPFZ_heyxVQGbMNQCEwYBhgL/s1600/14.png +
+

Fig. 11 mode collapsing 출처: http://dl-ai.blogspot.com/2017/08/gan-problems.html#

+
+
+
    +
  • 어떤 input image든 모두 같은 output image로 매핑하면서 최적화에 실패하는 현상. 이 현상은 generator 입장에서, Discriminator가 이 사진이 진짜 Y인지 가짜인 Y^인지 구별하는 것을 ‘속이기만’ 하면 되기 때문에 우리의 목적과 전혀 상관이 없는 데이터를 generator가 만들더라도 문제가 생기지 않아서 발생함

  • +
  • 참고: http://dl-ai.blogspot.com/2017/08/gan-problems.html

  • +
+

이러한 이슈로 인해 추가 objective function이 필요해 졌습니다. 따라서 translation task는 영어 -> 프랑스어 -> 영어로 번역했을 때 원래 문장에 다시 도달하는 것처럼, X –> Y –> X’로 돌아가는 과정에서 X와 X’가 최대한 같아야 한다는 의미의 cyclic consistency이라는 속성을 이용합니다. 필요한 목적식을 간단하게 정리하면 다음과 같습니다.

+
    +
  • 정방향, 역방향 adversarial Loss(X -> Y & Y -> X)

  • +
  • Cycle consistency loss: X ~= F(G(x))

  • +
+
+
+
+ +
+
+

Formulation#

+
+../../_images/fig2.png +
+

Fig. 12 cycleGAN 도식화 자료#

+
+
+
    +
  • 목표: X, Y를 mapping하는 function을 학습하는 것

  • +
  • 용어 정리

  • +
+
    +
  1. data 분포를 x ~ pdata(x), y ~ pdata(y)로 표시

  2. +
  3. G : X -> Y, F: Y -> X

  4. +
  5. Dx, Dy는 discriminator

  6. +
  7. Dx는 X와 F(y)를 구분, Dy는 y와 G(x)를 구분. 목적식은 총 두개

    +
      +
    • adversarial loss: 생성된 이미지의 분포를 대상 domain의 data distribution과 일치시키기 위한 것.

    • +
    • cycle consistency loss: 학습된 mapping G와 F가 서로 모순되는 것을 방지하기 위한 것.

    • +
    +
  8. +
+
+

Adversarial loss#

+

G: X –> Y와 Dy에 대한 목적식은 다음과 같음.

+
+L_GAN Loss function +
+

Fig. 13 L_GAN Loss function (source: https://arxiv.org/abs/1703.10593)#

+
+
+
    +
  • GAN에서 쓰이는 loss function과 동일. 대신에 X -> Y로 갈 때와 Y -> X로 갈 때 총 두개의 수식이 나오며, F:Y->X와 Dx에 대해서도 F, Dx를 넣은, 같은 수식을 사용함.

  • +
+
+
+

Cycle consistency Loss#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzsgD6%2Fbtr8ay8PEBE%2F3mAKd1YSAiCK4ZXeIg84s1%2Fimg.png +
+

Fig. 14 cycle consistency loss result#

+
+
+
    +
  • 앞서 말했듯, mapping distribution에 제한을 두어 최대한 우리가 원하는 이미지를 생성하기 위해 사용하는 수식으로서, 위와 같음.

  • +
  • 예비 실험에서 L1 norm을 adversarial loss로 대체해봤는데, 성능 향상을 관찰할 수 없었음.

  • +
  • cycle consistency loss를 통해 유도된 결과는 아래 그림에서 볼 수 있었음.

  • +
+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmq8pC%2Fbtr724Pl3Q2%2FUSK4TDRaUK860iIdvG0vV0%2Fimg.png +
+

Fig. 15 cycle consistency loss function#

+
+
+
+
+

full objective - 전체 목적식#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUyaOu%2Fbtr724Pl3Rj%2FigjKaeukv5m8Cbdzulp5jK%2Fimg.png +
+

Fig. 16 full objective function#

+
+
+
    +
  • 이 때 consistency loss 앞에 붙은 가중치 (lambda)는 GAN Loss와의 상대적 중요도에 따라 결정됨.

  • +
+
+
+
+
+

Implementation#

+

baseline architecture로서 neural style transfer와 super-resolution에 인상적인 결과를 보여준 논문에서 사용된 구조를 채택함.

+
    +
  • 3개의 convolutions and several residual blocks,

  • +
  • fractionally-strided convolution with stride 1/2,

  • +
  • feature를 RGB로 매핑하는 one convolution layer.

  • +
  • 6 blocks for 128 x 128 image // 9 blocks for 256 x 256 및 고해상도 학습 image.

  • +
  • instance normalization

  • +
+
+

Training details#

+

모델 학습을 안정화시키기 위해 아래와 같은 테크닉을 추가로 적용합니다.

+
    +
  • GAN의 Loss function에서 nll loss를 least-squared loss로 변경

  • +
  • 생성된 이미지 중 가장 최근의 50개를 따로 저장해 discriminator가 이를 한꺼번에 분류(모델 진동을 최소화하기 위함)

  • +
+
+
+

least-square loss 추가 설명#

+

참고)

+ +

사용 이유: Generator의 업데이트를 위해서(LSGAN을 참고)

+
    +
  • 이해는 못했고, 이런게 있구나 정도로만 알 수 있었음.

  • +
+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6JIT8%2Fbtr73nVyIqs%2FKfcPK33U3OY0AjKhjFlUh1%2Fimg.png +
+

Fig. 17 출처: https://velog.io/@sjinu/CycleGAN#

+
+
+

(원래 Discriminator는 이보다 더 고차원이지만) 간략히 2차원을 표방하면 결정경계를 위와 같이 나타낼 수 있습니다. 윗 쪽이 가짜 영역, 아래 쪽이 진짜 영역입니다 이 때, 아래에 보면 진짜 데이터 샘플과 거리가 먼 가짜 데이터 샘플이 존재합니다. 즉, NLL Loss를 사용한다면, Generator의 입장에서는 이미 Discriminator를 잘 속이고 있기 때문에 학습할 필요가 없습니다. 즉, Vanishing Gradient가 일어나기 때문에, Discriminator를 잘 속인다는 이유만으로, 안 좋은 샘플을 생성하는 것에 대해 패널티를 줄 수가 없게 됩니다. 이 때, LS GAN을 사용한다면 실제 데이터 분포와 가짜 데이터 샘플이 거리가 먼 것에 대해서도 패널티를 주게 됩니다.

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHsUiX%2Fbtr77PQw99h%2F0Er06IYIGYlBGw2rVufXc0%2Fimg.png +
+

Fig. 18 출처: https://velog.io/@sjinu/CycleGAN#

+
+
+
    +
  • Generator는 Discriminator를 속이는 것을 넘어서, 실제 데이터 분포와 유사한 분포를 가지게끔 해야합니다.

  • +
+
+
+

기타#

+
    +
  • 모든 실험에서 람다를 10으로 설정했다.

  • +
  • batch size == 1, 아담을 사용했다.

  • +
  • 모든 네트워크는 learning rate를 0.0002로 사용했다. 첫 100 에포크 동안에는 같은 ln을 사용했고, 다음 100 에포크마다 0으로 조금식 수렴하게 했다.

  • +
+
+
+
+
+

Result#

+

모델 성능 평가를 위해 아래와 같은 세 개의 지표를 사용.

+
    +
  1. AMT perceptual studies: 참가자들은 실제 사진이미지 vs 가짜 이미지, 또는 지도 이미지 vs 가짜이미지에 노출된 후 진짜라고 생각되는 이미지를 선택하게 함.

  2. +
  3. FCN Score: 1번 study가 테스트에 있어 매우 좋은 기준임에도 불구하고, 사람을 대상으로 한 실험이 아닌, 양적인 기준을 찾았는데, FCN score임. FCN은 생성된 사진에 대한 레이블 맵을 예측합니다. 이 레이블 맵은 아래에서 설명하는 표준 시맨틱 분할 메트릭을 사용하여 input ground truth label과 비교할 수 있다. “도로 상의 자동차”라는 label에서 사진 이미지를 생성하면, 생성된 이미지에 적용된 FCN이 “도로 상의 자동차”를 감지하면 성공한 것입니다.

  4. +
  5. 사진 –> 라벨링 성능을 평가: pixel당 정확도, class 당 정확도, IoU(Intersection-Over-Union)을 포함하는 cityscapes benchmark의 표준 metric

  6. +
+
+

Baseline#

+
    +
  • coGAN, SimGAN, pix2pix

  • +
+
+
+

Comparison against baselines#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZUe4E%2Fbtr8eXUQ6ou%2FikWglP8dEglGUny4dRkMjK%2Fimg.png +
+

Fig. 19 Comparison aginst baselines#

+
+
+

figure 5, figure 6에서 볼 수 있듯이 어떤 baseline에서도 강력한 결과를 얻을 수 없었음. 반면에 cycleGAN은 fully supervise인 pix2pix와 비슷한 품질의 translation을 생성할 수 있음.

+
+
+

Human study#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1Zhnx%2Fbtr8eWhk9ID%2FtauuT1N0W2qxRekj3IAnc1%2Fimg.png +
+

Fig. 20 AMT score#

+
+
+

표 1은 AMT perceptual realism task에 대한 성능을 나타냄. 여기서 지도에서 항공 사진, 항공 사진에서 지도 모두에서 약 1/4의 참가자를 속일 수 있었음. 그 외 모든 baseline은 참가자를 거의 속일 수 없었다.

+
+
+

FCN 등#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqzYO1%2Fbtr728xs5iD%2FN5NDNYwUYLnEZfnOVYONM0%2Fimg.png +
+

Fig. 21 FCN scores#

+
+
+

표 2는 도시 풍경에 대한 label –> photo task의 성능을 평가하고 표 3은 반대 매핑을 평가함. 두 경우 모두 cycleGAN이 baseline들의 성능을 능가한다.

+
+
+

Analysis of the loss function#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjQ9QQ%2Fbtr79farEX8%2FkQ6SWARw9QK9jqRqHlZoi1%2Fimg.png +
+

Fig. 22 Analysis of loss function#

+
+
+

GAN, cycle consistency의 중요성을 보여주는 자료.
+table 4, table 5에서 볼 수 있음. GAN을 없애면 cycle을 제거하는 것처럼 결과가 크게 저하됨. 따라서 두 term 모두 결과에 중요하다고 결론을 내릴 수 있음. 또한 한 방향에서만 cycle loss를 통해 각 메소드를 평가함. GAN + forward cycle만 돌렸을 때와, GAN + backward cycle만 돌렸을 때 이따금씩 학습에 불안정성을 보이고, mode collapse를 유발하는 것을 발견함(특히 제거된 매핑의 방향에 대해서 그런 경향을 보임). 그림 7을 보면 그런 경향을 볼 수 잇었음.

+
+
+

Image reconstruction quality#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyy7lt%2Fbtr73PdbuJp%2F5bmDtKSlQJJnd5yKvPgfB1%2Fimg.png +
+

Fig. 23 cycle consistency result#

+
+
+

그림 4에서 재구성된 이미지의 몇가지 무작위 샘플을 보여줌. 지도 –> 항공 사진과 같이 하나의 도메인이 훨씬 더 다양한 정보를 나타내는 경우에도 재구성된 이미지가 훈련 및 테스트 시간 모두 원래 입력 x에 가까운 경우가 많았음.

+
+
+

paired dataset에 대한 추가 결과#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqNrhb%2Fbtr72YaInQa%2Fk8b4K99KrAsD9C0SHINtt1%2Fimg.png +
+

Fig. 24 compare with paired dataset#

+
+
+

그림 8은 CMP Façade Database의 건축 레이블 <–> 사진, UT Zapoos50K dataset의 edge <–> 신발과 같이 pix2pix에 사용된 다른 paired dataset에 대한 몇 가지 예시 결과를 보여줌. cycleGAN의 이미지 품질은 fully supervised pix2pix에 대의 생성된 것과 비슷하지만 cycleGAN은 paired supervision 없이 학습이 된다.(우리가 짱이다!)

+
+
+
+
+

Applications#

+
    +
  • ** 이미지가 너무 많아 이미지는 생략하겠습니다.ㅠ**

  • +
  • paired data가 없는 상태에서 의 application 예시. traning data에서 transslation이 test data에서 한것보다 더 매력적이다. training and test data에 대한 application은 웹사이트에 있다.

  • +
+
+

Collection style transfer#

+

신경 스타일 전달”[13]에 대한 최근 작업과 달리, 우리의 방법은 선택한 단일 예술 작품의 스타일을 전달하는 대신 전체 예술 작품 컬렉션의 스타일을 모방하는 방법을 학습합니다. 그래서 ‘별이 빛나는 밤에’처럼 그리는 것 보다 ‘반 고흐’를 따라하는 느낌을 따라한다.

+
+
+

Object transfiguration#

+

Turmukhambetov et al. [50] 하나의 객체를 동일한 범주의 다른 객체로 변환하는 부분 공간 모델을 제안하는 반면, 우리의 방법은 시각적으로 유사한 두 범주 사이의 객체 변형에 중점을 둡니다.
+Turning a horse video into a zebra video (by CycleGAN)

+
+
+

season transfer#

+
+
+

Photo generation from paintings **#

+

그림을 사진으로 바꿀 때, 입력과 출력 간 색 구성을 보존하기 위해 추가적인 loss를 도입하는 것이 유용하다는 것을 발견할 수 있습니다. 특히, Taigman et al. [49]의 기술을 채택하여 제너레이터가 대상 도메인의 실제 샘플을 입력으로 제공받을 때 identity mapping 근처에 있도록 정규화합니다. 즉, **Lidentity(G,F) = Ey_pdata(y)[∥G(y) − y∥1] + Ex∼pdata (x) [∥F (x) − x∥1 ]**입니다.

+

Lidentity가 없으면, 생성자 G와 F는 굳이 필요하지 않을 때 입력 이미지의 색조를 자유롭게 변경할 수 있습니다. 예를 들어, Monet의 그림과 Flickr 사진 간의 매핑을 학습할 때, 생성자는 종종 낮에 그린 그림을 일몰 시간에 찍은 사진에 매핑합니다. 왜냐하면 적대적 손실과 사이클 일관성 손실 아래에서 이러한 매핑이 동등하게 유효할 수 있기 때문입니다. 이러한 identity mapping 손실의 효과는 그림 9에서 보여집니다. figure 12, figure 9는 학습 데이터셋에 포함되어 있는 그림, 하지만 다른 set은 오직 test set으로부터 그려진 그림. training set이 paired datqa를 포함하고 있지 않아서, 학습 세트 그림에 대한 타당한 translation을 찾는 것은 쉬운 일이 아니다. 실제로, Monet이 새 그림을 그릴 수 없기 때문에, 보지 않은 test set 그림에 대한 generalization은 not pressing problem

+
+
+

Photo enhancement#

+

우리는 우리의 방법이 얕은 깊이의 초점을 가진 사진을 생성하는 데 사용될 수 있음을 보여줍니다. 우리는 Flickr에서 다운로드한 꽃 사진을 기반으로 모델을 훈련합니다. 소스 도메인은 스마트폰으로 찍힌 꽃 사진으로 구성되어 있으며, 보통 작은 조리개로 인해 깊은 DoF(초점 깊이)를 가지고 있습니다. 대상은 조리개가 큰 DSLR로 촬영된 사진을 포함합니다. 우리 모델은 스마트폰으로 촬영된 사진으로부터 더 얕은 깊이의 초점을 가진 사진을 성공적으로 생성합니다.

+
+

: shallow depth of field: 얕은 초점. 초점이 맞은 대상과 배경이 흐릿하게 보이는 효과. 인물 사진 / 작품 사진에 활용. 구목하고자 하는 대상을 강조하기 위해 활용.
+따라서 source domain은 스마트폰의 작은 조리개로 깊은 초점 –> target은 조리개가 커서 얕은 초점.

+
+
+
+

Comparison with Gatys#

+
+
+
+
+

Limitations and Discusssion#

+
+https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJc1k5%2Fbtr76zUPUWj%2F27Mk0oQ5VanEHANWWmaseK%2Fimg.png +
+

Fig. 25 Limitation and Discussion#

+
+
+

이 방법은 많은 경우에 흥미로운 결과를 얻을 수 있지만, 결과는 결과가 균일하게 좋은 것은 아니었습니다.

+
    +
  1. (해석) 개<->고양이 task와 같은 경우는 input image에서 최소한의 변화만 주어, 사람이 보았을 때 실제로 변화가 안되는 경우도 있었고, 형체가 애매해진 경우도 있음. 이런걸 보았을 때, 세부적인 구조(geometry? 라는 표현을 보아), 눈, 코, 입에 대한 정확한 구조를 구현하는데 한계가 있어 보임.

  2. +
  3. 말<–> 얼룩말 예제의 경우, 말은 사람이 타는 모습이 많았는데, 얼룩말의 경우는 사람이 타는 사진이 없다보니, 사람 뿐만 아니라 배경도 얼룩 그림을 그림을 그리거나, 단순히 얼룩말에서 노랗게 칠한 경우가 생김.

  4. +
  5. 때때로 photo –> image task에서 나무와 건물의 label을 바꾸는 경우도 있었음.
    +이러한 모호성을 해결하려면 weak semantic supervision이 필요할 수도 있을 것 같음.

  6. +
+

마무리: 그럼에도 불구하고 많은 경우 완전히 짝지어지지 않은 데이터가 풍부하게 제공되며, 이를 활용해야 합니다. 이 논문은 이러한 “unsupervised” setting에서 가능한 것의 한계를 늘리는데 기여합니다.

+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/dalle.html b/docs/review/dalle.html old mode 100644 new mode 100755 index de5f7a09..90abe76a --- a/docs/review/dalle.html +++ b/docs/review/dalle.html @@ -1,846 +1,854 @@ - - - - - - - - - - - - DALL-E — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

DALL-E#

-
-

1. Introduction#

-
    -
  • GPT-3 기반 모델이며 120억개 parameter 수와 2.5억 데이터 (text,image) set으로 학습

  • -
  • Autoregressive 한 모델링을 통하여 image와 text를 이용하여 text-to-image generation task를 수행

  • -
  • 2021년 기준 zero-shot SOTA performance 달성

  • -
  • 아래 그림과 같이 text input에 따라 diverse한 이미지 생성

  • -
-
-fig1 -
-

Fig. 72 Images generated using DALL-E#

-
-
-
-fig2 -
-

Fig. 73 Images generated using DALL-E#

-
-
-
-
-

2. Background#

-
    -
  • GPT-3와 VQ-VAE를 활용하여 나온 논문.

  • -
  • VQ-VAE를 먼저 학습하고, Autoregressive Transformer을 순차적으로 학습하여 zero-shot architecture을 구축.

  • -
-
-

GPT-3#

-
    -
  • Autoregressive Language Model며 few-shot learning을 통해 fine-tuning 없이 높은 성능을 냄 *(fine-tuning 을 할 수는 있지만 본 논문에서는 task-agnostic performance 에 중점을 맞춰 Few shot을 함)

  • -
  • GPT-3 는 transformer에서 decoder 부분만 사용 (GPT-2 와 유사한 구조를 가지고 있음 )

  • -
  • 약 1750억 parameter 개수의 모델

  • -
-
-fig3 -
-

Fig. 74 Transformer 아키텍쳐 \ (source: https://arxiv.org/pdf/2005.14165.pdf)#

-
-
-
-GPT-3 GIF -
-

Fig. 75 GPT 3 Animation \ (source: https://jalammar.github.io/how-gpt3-works-visualizations-animations/)#

-
-
-
-
-

VQ-VAE#

-
    -
  • Encoder에서 나온 output은 discrete 하며 posterior 과 prior 이 categorical distribution을 갖는다고 가정함.

  • -
  • CNN (encoder) 을 거친 각 D차원의 위치에 \(H \times W\) 그리드로 이미지를 나누고 embedding space (Codebook) 에서 \(𝑒_1\)부터 \(𝑒_𝑘\) 중에서 가까운 1개 embedding code로 변환.

  • -
  • Quantization: Encoding output \(z_{e}(x)\) representation 과 유사한 codebook embedding \(e_j\) 를 찾아서 \(k\) 값을 부여함.

  • -
-
-fig5 -
-

Fig. 76 VQ-VAE 아키텍쳐, Loss 함수 \ (source: https://velog.io/@p2yeong/Understanding-VQ-VAE-DALL-E-Explained-Pt.-1)#

-
-
-
-fig6 -
-

Fig. 77 Quantization of VQ-VAE#

-
-
-
-
-
-

3. Methodology#

-
-
-

Limitation of Previous Works#

-
    -
  1. Memory/Bottleneck Issue

  2. -
-
    -
  • 각 Image에서 나오는 pixel을 직접적으로 image token을 사용하면 고화질 이미지일수록 너무 많은 메모리량이 필요해서 “비효율적”

  • -
-
    -
  1. Short-range dependence modeling between pixels

  2. -
-
    -
  • Model들 중 Likelihood function을 objective function으로 사용하면 short-range dependency를 우선적으로 볼 것이며 low-frequency 보다 high-frequency detail에 더욱 집중하게 됨.

  • -
  • Low frequency 는 visually recognizable해서 시각적으로 더 도움이 되는 부분

  • -
-

이 2가지 문제점을 극복하고자 Two-stage training process 제안

-
-
-

DALL-E Overview#

-
-

Stage 1: Training VQ-VAE#

-
    -
  • \textbf{Discrete VAE}를 이용하여 \(256 \times 256\) RGB image \rightarrow \(32 \times 32\) 이미지 토큰으로 압축

  • -
  • 각 이미지 토큰은 8,192개의 code 값 중에 하나 배정

  • -
  • 이미지의 \textbf{quality 손실 없이} \(8 \times 8 \times 3\) 배 만큼 context size를 적게 만들 수 있음.

  • -
-
-
-

Stage 2: Training an Autoregressive Transformer#

-
    -
  • \textbf{최대 256 BPE-Encoded text tokens}들과 1024 image tokens (\(32 \times 32\)) 를 연속적으로 입력함 (concatenate)

  • -
  • Text token과 Image Tokens 들의 joint distribution (결합 분포)를 모델링하여 autoregressive transformer을 학습

  • -
-
-
-
-

DALL-E Pipeline 예시#

-
-fig7 -
-

Fig. 78 DALL-E 시각화 \ (source:https://jiho-ml.com/weekly-nlp-40/)#

-
-
-
-fig8 -
-

Fig. 79 DALL-E 파이프라인 \ (source:https://www.youtube.com/watch?v=CQoM0r2kMvI&t=1729s)#

-
-
-
-
-

Methodology Details#

-
-

DALL-E Equations#

-
-fig9 -
-

Fig. 80 equation 1#

-
-
-
-fig10 -
-

Fig. 81 equation 2: Maximizing ELBO#

-
-
-

x: images, y: captions , z: encoded RGB image tokens

-

𝑞Φ (red) : input image에서 dVAE encoder에서 생성한 32 x 32 image token를 예측

-

𝑝𝜃 (blue): image token에서 dVAE decoder에서 생성한 RGB image를 예측

-

𝑝ψ (purple): transformer 모델로 모델링한 text와 image token들의 결합 분포 (joint distribution)

-
-
-

DALL-E 학습과정 Stage 1: Learning the VIsual Codebook#

-
    -
  • Transformer을 고정하고 dVAE encoder & decoder (𝑞_Φ , 𝑝_𝜃) 을 학습함

    -
      -
    • 즉, ELB (Evidence Lower Bound를 maximize 함)

    • -
    • K = 8,192 codebook (embedding space)로 설정

    • -
    -
  • -
  • \textbf{ELB를 optimize} 하기 위해서는 discrete distribution을 continuous를 바꿔야 함

    -
      -
    • 학습시에는 결국, argmax를 사용해서 codebook vector 인덱스를 선택하여 계산하면 Reparameterization gradient를 연산 X

    • -
    • argmax 대신 \textbf{gumbel softmax}를 사용하여 해결

    • -
    • 평가를 진행할 때에는 \(z = codebook[\underset{i}{argmax}[g_i+log(q(e_i|x))]]\)

    • -
    -
  • -
  • Gumbel Softmax Relaxation를 사용하여 해결! \(q_\phi \rightarrow q_{\phi}^{\tau}\), temperature \(\tau \rightarrow 0\), relaxation을 tight하게 잡아줌.

  • -
-
-
-

DALL-E 학습과정 Stage 2: Learning the Prior#

-
    -
  • Transformer을 고정하고 dVAE encoder & decoder (\(q_{phi}\) , \(p_{\theta}\)) transformer의 prior distribution \(p_{\psi}\)를 학습함.

  • -
  • 이때, \(p_{\psi}\)의 ELB를 maximize 하며 120억개의 parameter를 가진 sparse transformer 구조를 사용함

  • -
  • Image token은 dVAE Encoder logit에서 Argmax sampling을 통해 생성

  • -
  • Text token은 소문자화 후 16,384 개의 vocabulary를 BPE-encoding 통해 한번에 최대 256 token을 활용

  • -
-
-fig11 -
-

Fig. 82 Text-to-text attention: causal attention mask -Image-to-image attention: row/column/convolutional attention mask 적용#

-
-
-
-
-
-

Results#

-
    -
  • 추론 시에는 text에 대하여 N개의 이미지를 생성.

  • -
  • Best of N개는 \textbf{N개 생성 후 best}를 골라서 선택 함.

  • -
  • 우수한 이미지를 고르기 위해 CLIP (Contrastive Language-Image Pretraining, 2021) 논문에서 제시한 text 와 k 번째로 similarity 점수가 높은 이미지를 선택함 (k=1)

  • -
-
-fig12 -
-

Fig. 83 DALL-E 결과물. Best를 고를때 N 수가 증가할수록 주어진 text prompt랑 더 유사한 결과물이 나옴.#

-
-
-
    -
  • 생성한 512개 이미지 중 CLIP 알고리즘을 통해 similarity score이 제일 높은 이미지를 뽑음.

  • -
  • Ours (DALL-E) vs 다른 baseline method 와 비교 시 text에 더욱 알맞은 이미지를 생성한 것을 확인 할 수 있음.

  • -
-
-fig13 -
-

Fig. 84 선택하는 이미지 개수에 따른 성능 향상#

-
-
-
    -
  • DF-GAN 이랑 비교해서 MS-COCO dataset에 대하여 정성적 평가를 진행.

  • -
  • Best-of-Five votes 중에 DF-GAN보다 매번 압도적인 차이로 투표 수를 받았음.

  • -
-
-fig14 -
-

Fig. 85 DF-GAN 이랑 Qualitative Results 비교#

-
-
-
    -
  • FID (Frechet Inception Distance)는 값이 낮을수록 좋으며 / IS (Inception Score)는 높을수록 좋음

  • -
  • MS-COCO 랑 CUB (새 특화 데이터셋) 기준, DALL-E는 MS-COCO에서는 뛰어난 성능을 보여줬음.

  • -
  • CUB에서는 SOTA를 찍지 못하였고 Inception score에서는 낮은 점수를 기록함.

  • -
  • 저자들은 Fine-tuning 으로 CUB에 성능 계선을 할 수 있다고 생각함.

  • -
-
-fig15 -
-

Fig. 86 MS-COCO 와 CUB dataset에서 FID/IS 결과값 비교#

-
-
-
-
-

Conclusion#

-
    -
  • GPT-3의 확장 모델로 120억개의 parameter과 autoregressive Transformer (Decoder only) 기반 모델링을 통해 text-to-image generation task를 뛰어나게 해결함.

  • -
  • Zero-shot learning에서 다른 모델보다 훌륭한 일반화 성능을 보임

  • -
  • 정량적 / 정성적 평가에서 준수한 성능을 보이고 있으며 다양한 이미지 생성이 가능함.

  • -
-

** Limitations: **

-
    -
  • 생성하고 싶은 이미지에 다양한 객체가 포함되면 어려움을 겪음

  • -
  • (b)에 보면 고슴도치가 2마리거나 강아지와 고슴도치 둘다 크리스마스 스웨터를 입고 있음.

  • -
  • CUB dataset 처럼 다소 아쉬운 성능을 보인 데이터셋이 있지만 fine-tuning으로 해결

  • -
-
-fig16 -
-

Fig. 87 Limitation을 보여주는 결과물.#

-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + DALL-E — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

DALL-E#

+
+

1. Introduction#

+
    +
  • GPT-3 기반 모델이며 120억개 parameter 수와 2.5억 데이터 (text,image) set으로 학습

  • +
  • Autoregressive 한 모델링을 통하여 image와 text를 이용하여 text-to-image generation task를 수행

  • +
  • 2021년 기준 zero-shot SOTA performance 달성

  • +
  • 아래 그림과 같이 text input에 따라 diverse한 이미지 생성

  • +
+
+fig1 +
+

Fig. 72 Images generated using DALL-E#

+
+
+
+fig2 +
+

Fig. 73 Images generated using DALL-E#

+
+
+
+
+

2. Background#

+
    +
  • GPT-3와 VQ-VAE를 활용하여 나온 논문.

  • +
  • VQ-VAE를 먼저 학습하고, Autoregressive Transformer을 순차적으로 학습하여 zero-shot architecture을 구축.

  • +
+
+

GPT-3#

+
    +
  • Autoregressive Language Model며 few-shot learning을 통해 fine-tuning 없이 높은 성능을 냄 *(fine-tuning 을 할 수는 있지만 본 논문에서는 task-agnostic performance 에 중점을 맞춰 Few shot을 함)

  • +
  • GPT-3 는 transformer에서 decoder 부분만 사용 (GPT-2 와 유사한 구조를 가지고 있음 )

  • +
  • 약 1750억 parameter 개수의 모델

  • +
+
+fig3 +
+

Fig. 74 Transformer 아키텍쳐 \ (source: https://arxiv.org/pdf/2005.14165.pdf)#

+
+
+
+GPT-3 GIF +
+

Fig. 75 GPT 3 Animation \ (source: https://jalammar.github.io/how-gpt3-works-visualizations-animations/)#

+
+
+
+
+

VQ-VAE#

+
    +
  • Encoder에서 나온 output은 discrete 하며 posterior 과 prior 이 categorical distribution을 갖는다고 가정함.

  • +
  • CNN (encoder) 을 거친 각 D차원의 위치에 \(H \times W\) 그리드로 이미지를 나누고 embedding space (Codebook) 에서 \(𝑒_1\)부터 \(𝑒_𝑘\) 중에서 가까운 1개 embedding code로 변환.

  • +
  • Quantization: Encoding output \(z_{e}(x)\) representation 과 유사한 codebook embedding \(e_j\) 를 찾아서 \(k\) 값을 부여함.

  • +
+
+fig5 +
+

Fig. 76 VQ-VAE 아키텍쳐, Loss 함수 \ (source: https://velog.io/@p2yeong/Understanding-VQ-VAE-DALL-E-Explained-Pt.-1)#

+
+
+
+fig6 +
+

Fig. 77 Quantization of VQ-VAE#

+
+
+
+
+
+

3. Methodology#

+
+
+

Limitation of Previous Works#

+
    +
  1. Memory/Bottleneck Issue

  2. +
+
    +
  • 각 Image에서 나오는 pixel을 직접적으로 image token을 사용하면 고화질 이미지일수록 너무 많은 메모리량이 필요해서 “비효율적”

  • +
+
    +
  1. Short-range dependence modeling between pixels

  2. +
+
    +
  • Model들 중 Likelihood function을 objective function으로 사용하면 short-range dependency를 우선적으로 볼 것이며 low-frequency 보다 high-frequency detail에 더욱 집중하게 됨.

  • +
  • Low frequency 는 visually recognizable해서 시각적으로 더 도움이 되는 부분

  • +
+

이 2가지 문제점을 극복하고자 Two-stage training process 제안

+
+
+

DALL-E Overview#

+
+

Stage 1: Training VQ-VAE#

+
    +
  • \textbf{Discrete VAE}를 이용하여 \(256 \times 256\) RGB image \rightarrow \(32 \times 32\) 이미지 토큰으로 압축

  • +
  • 각 이미지 토큰은 8,192개의 code 값 중에 하나 배정

  • +
  • 이미지의 \textbf{quality 손실 없이} \(8 \times 8 \times 3\) 배 만큼 context size를 적게 만들 수 있음.

  • +
+
+
+

Stage 2: Training an Autoregressive Transformer#

+
    +
  • \textbf{최대 256 BPE-Encoded text tokens}들과 1024 image tokens (\(32 \times 32\)) 를 연속적으로 입력함 (concatenate)

  • +
  • Text token과 Image Tokens 들의 joint distribution (결합 분포)를 모델링하여 autoregressive transformer을 학습

  • +
+
+
+
+

DALL-E Pipeline 예시#

+
+fig7 +
+

Fig. 78 DALL-E 시각화 \ (source:https://jiho-ml.com/weekly-nlp-40/)#

+
+
+
+fig8 +
+

Fig. 79 DALL-E 파이프라인 \ (source:https://www.youtube.com/watch?v=CQoM0r2kMvI&t=1729s)#

+
+
+
+
+

Methodology Details#

+
+

DALL-E Equations#

+
+fig9 +
+

Fig. 80 equation 1#

+
+
+
+fig10 +
+

Fig. 81 equation 2: Maximizing ELBO#

+
+
+

x: images, y: captions , z: encoded RGB image tokens

+

𝑞Φ (red) : input image에서 dVAE encoder에서 생성한 32 x 32 image token를 예측

+

𝑝𝜃 (blue): image token에서 dVAE decoder에서 생성한 RGB image를 예측

+

𝑝ψ (purple): transformer 모델로 모델링한 text와 image token들의 결합 분포 (joint distribution)

+
+
+

DALL-E 학습과정 Stage 1: Learning the VIsual Codebook#

+
    +
  • Transformer을 고정하고 dVAE encoder & decoder (𝑞_Φ , 𝑝_𝜃) 을 학습함

    +
      +
    • 즉, ELB (Evidence Lower Bound를 maximize 함)

    • +
    • K = 8,192 codebook (embedding space)로 설정

    • +
    +
  • +
  • \textbf{ELB를 optimize} 하기 위해서는 discrete distribution을 continuous를 바꿔야 함

    +
      +
    • 학습시에는 결국, argmax를 사용해서 codebook vector 인덱스를 선택하여 계산하면 Reparameterization gradient를 연산 X

    • +
    • argmax 대신 \textbf{gumbel softmax}를 사용하여 해결

    • +
    • 평가를 진행할 때에는 \(z = codebook[\underset{i}{argmax}[g_i+log(q(e_i|x))]]\)

    • +
    +
  • +
  • Gumbel Softmax Relaxation를 사용하여 해결! \(q_\phi \rightarrow q_{\phi}^{\tau}\), temperature \(\tau \rightarrow 0\), relaxation을 tight하게 잡아줌.

  • +
+
+
+

DALL-E 학습과정 Stage 2: Learning the Prior#

+
    +
  • Transformer을 고정하고 dVAE encoder & decoder (\(q_{phi}\) , \(p_{\theta}\)) transformer의 prior distribution \(p_{\psi}\)를 학습함.

  • +
  • 이때, \(p_{\psi}\)의 ELB를 maximize 하며 120억개의 parameter를 가진 sparse transformer 구조를 사용함

  • +
  • Image token은 dVAE Encoder logit에서 Argmax sampling을 통해 생성

  • +
  • Text token은 소문자화 후 16,384 개의 vocabulary를 BPE-encoding 통해 한번에 최대 256 token을 활용

  • +
+
+fig11 +
+

Fig. 82 Text-to-text attention: causal attention mask +Image-to-image attention: row/column/convolutional attention mask 적용#

+
+
+
+
+
+

Results#

+
    +
  • 추론 시에는 text에 대하여 N개의 이미지를 생성.

  • +
  • Best of N개는 \textbf{N개 생성 후 best}를 골라서 선택 함.

  • +
  • 우수한 이미지를 고르기 위해 CLIP (Contrastive Language-Image Pretraining, 2021) 논문에서 제시한 text 와 k 번째로 similarity 점수가 높은 이미지를 선택함 (k=1)

  • +
+
+fig12 +
+

Fig. 83 DALL-E 결과물. Best를 고를때 N 수가 증가할수록 주어진 text prompt랑 더 유사한 결과물이 나옴.#

+
+
+
    +
  • 생성한 512개 이미지 중 CLIP 알고리즘을 통해 similarity score이 제일 높은 이미지를 뽑음.

  • +
  • Ours (DALL-E) vs 다른 baseline method 와 비교 시 text에 더욱 알맞은 이미지를 생성한 것을 확인 할 수 있음.

  • +
+
+fig13 +
+

Fig. 84 선택하는 이미지 개수에 따른 성능 향상#

+
+
+
    +
  • DF-GAN 이랑 비교해서 MS-COCO dataset에 대하여 정성적 평가를 진행.

  • +
  • Best-of-Five votes 중에 DF-GAN보다 매번 압도적인 차이로 투표 수를 받았음.

  • +
+
+fig14 +
+

Fig. 85 DF-GAN 이랑 Qualitative Results 비교#

+
+
+
    +
  • FID (Frechet Inception Distance)는 값이 낮을수록 좋으며 / IS (Inception Score)는 높을수록 좋음

  • +
  • MS-COCO 랑 CUB (새 특화 데이터셋) 기준, DALL-E는 MS-COCO에서는 뛰어난 성능을 보여줬음.

  • +
  • CUB에서는 SOTA를 찍지 못하였고 Inception score에서는 낮은 점수를 기록함.

  • +
  • 저자들은 Fine-tuning 으로 CUB에 성능 계선을 할 수 있다고 생각함.

  • +
+
+fig15 +
+

Fig. 86 MS-COCO 와 CUB dataset에서 FID/IS 결과값 비교#

+
+
+
+
+

Conclusion#

+
    +
  • GPT-3의 확장 모델로 120억개의 parameter과 autoregressive Transformer (Decoder only) 기반 모델링을 통해 text-to-image generation task를 뛰어나게 해결함.

  • +
  • Zero-shot learning에서 다른 모델보다 훌륭한 일반화 성능을 보임

  • +
  • 정량적 / 정성적 평가에서 준수한 성능을 보이고 있으며 다양한 이미지 생성이 가능함.

  • +
+

** Limitations: **

+
    +
  • 생성하고 싶은 이미지에 다양한 객체가 포함되면 어려움을 겪음

  • +
  • (b)에 보면 고슴도치가 2마리거나 강아지와 고슴도치 둘다 크리스마스 스웨터를 입고 있음.

  • +
  • CUB dataset 처럼 다소 아쉬운 성능을 보인 데이터셋이 있지만 fine-tuning으로 해결

  • +
+
+fig16 +
+

Fig. 87 Limitation을 보여주는 결과물.#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/diffusion_beats_GANs.html b/docs/review/diffusion_beats_GANs.html old mode 100644 new mode 100755 index 7cbdc8d2..42cea3b8 --- a/docs/review/diffusion_beats_GANs.html +++ b/docs/review/diffusion_beats_GANs.html @@ -1,854 +1,862 @@ - - - - - - - - - - - - Diffusion Models Beat GANs on Image Synthesis — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

-
    -
  • Title: {Diffusion Models Beat GANs on Image Synthesis}, {NIPS 2021}

  • -
  • Reference

    - -
  • -
  • Author: Donggeun Sean Ko

  • -
  • Last updated on May. 17, 2023

  • -
-
-
-

Diffusion Models Beat GANs on Image Synthesis#

-
-

Abstract#

-
    -
  • Diffusion 모델들은 기존 unconditional 이미지 생성 모델들의 SOTA를 뛰어넘음.

  • -
  • Conditional image synthesis 부분에서도 classifier guidance를 활용해 diffusion model을 활용하여 좋은 성능을 보여준다고 주장함.

  • -
  • Classifier guidance를 활용해 diversity와 fidelity의 trade-off에 대해서도 분석

  • -
-
-
-

1. Introduction#

-
    -
  • Diffusion 모델들은 likelihood-based model들이며 고화질 이미지를 생성해내는데에 성공 했음.

  • -
  • 하지만, FID 수치는 BigGAN-deep에 비해 낮으며, 개선사항이 필요함.

  • -
  • 두가지 contribution을 통해 Diffusion Model들의 성능을 끌어올리며 FID 결과 수치를 낮추겠다고 주장.

    -
      -
    • 모델 아키텍쳐 개선

    • -
    • Classifier Guidance

    • -
    -
  • -
-
-
-

2. Background#

-
    -
  • DDPM, DDIM, Improved DDPM은 이전에 설명되있으므로, 각 background 논문들의 핵심 부분만 설명하겠습니다.

  • -
  • -
-
-

DDPM#

-
    -
  • \(p_\theta(x_{t-1}|x_t)\)\(q(x_{t-1}|x_t)\)의 근사값이라고 가정하며 계산한다. -- \(p_\theta(x_{t-1}|x_t)\)를 학습하여 \(p_\theta(x_{t-1}|x_t) \approx\) \(q(x_{t-1}|x_t)\)를 만든다.

  • -
  • \(\epsilon_\theta(x_t,t)\) 을 모델링하여 noise를 예측한다.

  • -
  • 공분산 \(\Sigma_\theta(X_t,t)\)은 학습 불가능한 매개변수로 설정되며 constant 값을 가진다.

  • -
  • 아래와 같이 \(L_{simple}\) 을 새로운 Loss function으로 제안한다.

  • -
-
-ddpm_pipeline -
-

Fig. 56 DDPM Pipeline#

-
-
-
-ddpm_eq -
-

Fig. 57 DDPM Equation#

-
-
-
-
-

Improved DDPM#

-
-improved_ddpm_pic -
-

Fig. 58 Improved DDPM scheduling comparison with DDPM (Linear vs Cosine)#

-
-
-
    -
  • 더 적은 diffusion step으로 샘플링 함.

  • -
  • Competitive log-likelihood 지표 성능 개선 (전 DDPM에선 log-likelihood 지표가 상대적으로 GAN 모델의 비해 낮았다)

  • -
  • 전 DDPM 논문에서는 linear scheduling을 사용했지만, 본 논문에서는 cosine scheduling을 사용해서 성능 향상을 했다고 주장했다.

  • -
  • 분산 \(\Sigma_\theta(X_t,t)\)을 학습에도 활용

  • -
  • \(L_{hybrid}\)라는 새로운 loss 함수 제시

  • -
-
-improved_ddpm_eq -
-

Fig. 59 Improved DDPM Equation#

-
-
-
-
-

DDIM#

-
-ddim_pipe -
-

Fig. 60 DDIM Pipeline#

-
-
-
    -
  • Markovian Chain Process를 끊고 Non-Markovian 형태로 Deterministic 하게 수식을 바꿈

  • -
  • DDPM 보다 더 적은 iteration으로 image synthesis 가능

  • -
-
-ddim_pic -
-

Fig. 61 DDIM Sampling Equation#

-
-
-
-
-
-

3. Architectural Improvements#

-
    -
  • DDPM에서 사용한 architecture을 그대로 채택했지만, 다양한 ablation 및 parameter을 변경하여 제일 높은 성능이 나오는 architecture을 설명 및 채택함

  • -
  • 모델 크기를 일정하게 가져가면서 Depth vs Width 증가 보기

  • -
  • Attention head 수 증가 시켜보기

  • -
  • 각 Attention head에 resolution 을 8x8, 16x16, 32x32 로 실험 해보기

  • -
  • 일반 ResNet Residual Block이 아닌 BigGAN의 residual block을 채택하여 upsampling / downsampling 사용 해보기

  • -
  • Residual Connection을 1/√2 로 rescaling 해보기

  • -
-
-architect_1 -
-

Fig. 62 Table 1: Ablation of various architecture changes#

-
-
-
-architect_2 -
-

Fig. 63 Table 2: Ablation of various attention configurations. Attention head 가 32일때 FID 값이 제일 낮다 (좋다)#

-
-
-

** 3-1. Best Architecture **

-
    -
  • Channel 수 160

  • -
  • Depth 2

  • -
  • number of Attention Head = 4

  • -
  • Attention Resolution을 32, 16, 8 로 block마다 줄이기

  • -
  • BigGAN residual block 채택

  • -
  • Rescaling X

  • -
  • 위와 같은 parameter를 통해 제일 좋은 FID 결과가 나옴

  • -
-
-architect_3 -
-

Fig. 64 Table 3: 다양한 parameter 튜닝을 통한 제일 좋은 FID 성능 테이블#

-
-
-
-
-

4. Adaptive Group Normalization#

-
    -
  • 본 저자들은 AdaIN이랑 비슷한 방식으로 연산하는 AdaGN 이라는 것을 소개했다. (원래 있는 방법론인지는 모르겠다…)

  • -
  • Group Normalization을 adpative하게 하는 방법으로 Group Normalization 후에 residual block에 time step embedding과 class embedding을 AdaIN 방식으로 곱하고 더함

  • -
-

Equation

-
-\[AdaIN(x,y) = \sigma(y)(\frac{x-\mu(x)}{\sigma(x)})+\mu(y)\]
-
-\[AdaGN(h,y) = y_s + GroupNorm(h) + y_b\]
-

where \(h =\) residual block and \(y = [y_s,y_b]\) time-step embedding and class embedding’s linear projection respectively

-

4-1 AdaGN의 성능

-
-adagn_table -
-

Fig. 65 AdaGN과 Additon+GroupNorm 비교 테이블. DDPM에서 사용한 normalization보다 더 좋은 성능을 보여주고 있음.#

-
-
-
    -
  • 기존 DDPM은 Addition + GroupNorm layer을 사용했는데, AdaGN 을 사용하는 것이 FID가 더 낮게 (즉 더 좋은 성능) 나온 것을 볼 수 있다

  • -
-
-
-

5. Classifier Guidance#

-
    -
  • 본 논문의 주 contribution 중 하나가 classifier guidance를 사용했다는 점이다.

  • -
  • unconditional de-noising process에서 label y를 condition으로 줌으로써 conditional de-noising process로 진행

  • -
-

Equation -$\(p_{\theta, \phi }(x_t|x_{t+1},y) = Zp_\theta(x_t|x_{t+1})p_\phi(y|x_t)\)$

-
    -
  • Z 는 normalizing을 위한 상수 이다

  • -
-

5-1 Classifier Guidance 유도

-

\(log_\phi p(y|x_t)\)\(\Sigma^-1\) 에 비해 곡률이 낮으며, 이 가정을 따라, diffusion step이 무한으로 갈 시, \(||\Sigma^ || \rightarrow0\) 이므로,\(log_\phi p(y|x_t)\)가 테일러 급수를 활용하여 식을 \(x_t = \mu\) 로 재전개 할 수 있다.

-
    -
  • classifier의 gradient를 활용해서 학습을 같이 해준다.

  • -
  • 식 유도는 아래와 같다. 본문의 (3) ~ (10) 번식이므로 본 논문을 참고하면 좋다.

  • -
-
-class_eq1 -
-

Fig. 66 Classifier Guidance 유도 식 1,2#

-
-
-
-classifier_2 -
-

Fig. 67 Classifier Guidance 유도 식 3~7#

-
-
-
-
-

6. Algorithm#

-
-algorithm -
-

Fig. 68 Algorithm 1 & 2 sampling method. Algorithm 1은 일반적인 DDPM 기준, Algorithm 2는 DDIM 기준 guidance 한 sampling 방법#

-
-
-
    -
  • Algorithm 1 은 일반 DDPM에서 샘플링 하는 방법이다. 똑같이 Gaussian distribution에서 샘플링 할 시, classifier의 gradient를 활용하여 \(x_{t-1}\)를 sample한다.

  • -
  • Algorithm 2 는 DDIM에서 샘플링 하는 방법이다. \(\epsilon\) 모델에서 나오는 output과 classifier의 gradient의 joint distribution 값을 빼 score을 구한다.

  • -
  • DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다.

  • -
  • 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다.

  • -
  • DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.

  • -
-
-
-

7. Impact of parameter s in classifier guidance#

-
-class_guidance_vis -
-

Fig. 69 Classifier Guidance scaling의 영향 시각화#

-
-
-
    -
  • classifier guidance 앞에 hyperparameter \bf{s} 의 값에 따라 classifier가 줄 수 있는 scaling이 다르다.

  • -
  • scale을 1.0으로 주면 웰시코기라는 class의 scale 영향을 덜 받아 “웰시코기스러운” 강아지가 생성이 많이 되지는 않는다.

  • -
  • scale을 10.0으로 주면 웰시코기 class라는 scaling의 영향을 많이 받아 웰시코기 분위기의 강아지의 이미지가 더 많이 생성 되는 것을 볼 수 있다.

  • -
  • epsilon이라는 모델이 결국 scale에 따라 gradient의 영향을 얼마나 많이 받는지 sampling할 때 볼 수 있다.

  • -
-
-
-

8. Results#

-
-plot result -
-

Fig. 70 Fidelity vs Diversity Trade-off 결과#

-
-
-
    -
  • gradient scale이 높을수록 recall은 낮지만, precision은 높다. 즉 trade-off 가 생기는데, recall이 낮을수록 diveristy가 낮다는 의미이고, precision이 높을수록 fidelity가 높다는 뜻이다.

  • -
  • scale을 높일수록 다양한 이미지가 생성되는 것이 아닌, classifier가 준 label쪽으로 guide가 생기므로 일정한 class의 사진이 나온다.

  • -
  • FID와 sFID는 diversity와 fidelity의 trade-off로 도출되는 값이므로, 최고의 값은 중간 지점에서 나왔다.

  • -
-

8-1. Result Table

-
    -
  • ADM은 Ablated Diffusion Model의 약자이며, ADM-G는 Ablated Diffusion Model with Guidance의 약자이다.

  • -
  • Guidance를 주었을 시 제일 좋은 FID값이 나왔으며, Precision이 높을수록, Recall이 낮게 나왔다 (and vice versa).

  • -
-
-
-

8-2. Image Synthesis Results#

-
-img_results -
-

Fig. 71 Generated Images (Left: BigGAN, Center: DMs, Right: Train Dataset)#

-
-
-
    -
  • 두번쨰 플라밍고 생성된 사진을 볼때, BigGAN은 이미지간들의 diversity가 없다. 학습된 플라밍고가 다수 플라밍고 시 비슷한 느낌의 이미지만 뽑아낸다.

  • -
  • 반면, Diffusion model with guidance를 사용했을 시, 다채로운 플라밍고 사진을 볼 수 있다. 한마리만 있는 플라밍고 사진도 뽑아 낼 수 있다.

  • -
-
-
-

9. Limitation and Future Work#

-

Limitation 1

-
    -
  • Diffusion 모델들은 GAN보다 샘플링 시간이 아직 느리다.

  • -
-

Future Work 1

-
    -
  • DDIM의 sampling process를 distillation 해서 빠르게 하는 법을 고려

  • -
-

Limitation 2

-
    -
  • Classifier guidance는 classification function의 gradient를 사용함으로써, label이 없는 data에는 확장이 불가능하다.

  • -
-

Future Work 2

-
    -
  • Unlabeled sample을 clustering 하는 방법을 통해 방법론을 expand 하려 한다.

  • -
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Diffusion Models Beat GANs on Image Synthesis — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+
    +
  • Title: {Diffusion Models Beat GANs on Image Synthesis}, {NIPS 2021}

  • +
  • Reference

    + +
  • +
  • Author: Donggeun Sean Ko

  • +
  • Last updated on May. 17, 2023

  • +
+
+
+

Diffusion Models Beat GANs on Image Synthesis#

+
+

Abstract#

+
    +
  • Diffusion 모델들은 기존 unconditional 이미지 생성 모델들의 SOTA를 뛰어넘음.

  • +
  • Conditional image synthesis 부분에서도 classifier guidance를 활용해 diffusion model을 활용하여 좋은 성능을 보여준다고 주장함.

  • +
  • Classifier guidance를 활용해 diversity와 fidelity의 trade-off에 대해서도 분석

  • +
+
+
+

1. Introduction#

+
    +
  • Diffusion 모델들은 likelihood-based model들이며 고화질 이미지를 생성해내는데에 성공 했음.

  • +
  • 하지만, FID 수치는 BigGAN-deep에 비해 낮으며, 개선사항이 필요함.

  • +
  • 두가지 contribution을 통해 Diffusion Model들의 성능을 끌어올리며 FID 결과 수치를 낮추겠다고 주장.

    +
      +
    • 모델 아키텍쳐 개선

    • +
    • Classifier Guidance

    • +
    +
  • +
+
+
+

2. Background#

+
    +
  • DDPM, DDIM, Improved DDPM은 이전에 설명되있으므로, 각 background 논문들의 핵심 부분만 설명하겠습니다.

  • +
  • +
+
+

DDPM#

+
    +
  • \(p_\theta(x_{t-1}|x_t)\)\(q(x_{t-1}|x_t)\)의 근사값이라고 가정하며 계산한다. +- \(p_\theta(x_{t-1}|x_t)\)를 학습하여 \(p_\theta(x_{t-1}|x_t) \approx\) \(q(x_{t-1}|x_t)\)를 만든다.

  • +
  • \(\epsilon_\theta(x_t,t)\) 을 모델링하여 noise를 예측한다.

  • +
  • 공분산 \(\Sigma_\theta(X_t,t)\)은 학습 불가능한 매개변수로 설정되며 constant 값을 가진다.

  • +
  • 아래와 같이 \(L_{simple}\) 을 새로운 Loss function으로 제안한다.

  • +
+
+ddpm_pipeline +
+

Fig. 56 DDPM Pipeline#

+
+
+
+ddpm_eq +
+

Fig. 57 DDPM Equation#

+
+
+
+
+

Improved DDPM#

+
+improved_ddpm_pic +
+

Fig. 58 Improved DDPM scheduling comparison with DDPM (Linear vs Cosine)#

+
+
+
    +
  • 더 적은 diffusion step으로 샘플링 함.

  • +
  • Competitive log-likelihood 지표 성능 개선 (전 DDPM에선 log-likelihood 지표가 상대적으로 GAN 모델의 비해 낮았다)

  • +
  • 전 DDPM 논문에서는 linear scheduling을 사용했지만, 본 논문에서는 cosine scheduling을 사용해서 성능 향상을 했다고 주장했다.

  • +
  • 분산 \(\Sigma_\theta(X_t,t)\)을 학습에도 활용

  • +
  • \(L_{hybrid}\)라는 새로운 loss 함수 제시

  • +
+
+improved_ddpm_eq +
+

Fig. 59 Improved DDPM Equation#

+
+
+
+
+

DDIM#

+
+ddim_pipe +
+

Fig. 60 DDIM Pipeline#

+
+
+
    +
  • Markovian Chain Process를 끊고 Non-Markovian 형태로 Deterministic 하게 수식을 바꿈

  • +
  • DDPM 보다 더 적은 iteration으로 image synthesis 가능

  • +
+
+ddim_pic +
+

Fig. 61 DDIM Sampling Equation#

+
+
+
+
+
+

3. Architectural Improvements#

+
    +
  • DDPM에서 사용한 architecture을 그대로 채택했지만, 다양한 ablation 및 parameter을 변경하여 제일 높은 성능이 나오는 architecture을 설명 및 채택함

  • +
  • 모델 크기를 일정하게 가져가면서 Depth vs Width 증가 보기

  • +
  • Attention head 수 증가 시켜보기

  • +
  • 각 Attention head에 resolution 을 8x8, 16x16, 32x32 로 실험 해보기

  • +
  • 일반 ResNet Residual Block이 아닌 BigGAN의 residual block을 채택하여 upsampling / downsampling 사용 해보기

  • +
  • Residual Connection을 1/√2 로 rescaling 해보기

  • +
+
+architect_1 +
+

Fig. 62 Table 1: Ablation of various architecture changes#

+
+
+
+architect_2 +
+

Fig. 63 Table 2: Ablation of various attention configurations. Attention head 가 32일때 FID 값이 제일 낮다 (좋다)#

+
+
+

** 3-1. Best Architecture **

+
    +
  • Channel 수 160

  • +
  • Depth 2

  • +
  • number of Attention Head = 4

  • +
  • Attention Resolution을 32, 16, 8 로 block마다 줄이기

  • +
  • BigGAN residual block 채택

  • +
  • Rescaling X

  • +
  • 위와 같은 parameter를 통해 제일 좋은 FID 결과가 나옴

  • +
+
+architect_3 +
+

Fig. 64 Table 3: 다양한 parameter 튜닝을 통한 제일 좋은 FID 성능 테이블#

+
+
+
+
+

4. Adaptive Group Normalization#

+
    +
  • 본 저자들은 AdaIN이랑 비슷한 방식으로 연산하는 AdaGN 이라는 것을 소개했다. (원래 있는 방법론인지는 모르겠다…)

  • +
  • Group Normalization을 adpative하게 하는 방법으로 Group Normalization 후에 residual block에 time step embedding과 class embedding을 AdaIN 방식으로 곱하고 더함

  • +
+

Equation

+
+\[AdaIN(x,y) = \sigma(y)(\frac{x-\mu(x)}{\sigma(x)})+\mu(y)\]
+
+\[AdaGN(h,y) = y_s + GroupNorm(h) + y_b\]
+

where \(h =\) residual block and \(y = [y_s,y_b]\) time-step embedding and class embedding’s linear projection respectively

+

4-1 AdaGN의 성능

+
+adagn_table +
+

Fig. 65 AdaGN과 Additon+GroupNorm 비교 테이블. DDPM에서 사용한 normalization보다 더 좋은 성능을 보여주고 있음.#

+
+
+
    +
  • 기존 DDPM은 Addition + GroupNorm layer을 사용했는데, AdaGN 을 사용하는 것이 FID가 더 낮게 (즉 더 좋은 성능) 나온 것을 볼 수 있다

  • +
+
+
+

5. Classifier Guidance#

+
    +
  • 본 논문의 주 contribution 중 하나가 classifier guidance를 사용했다는 점이다.

  • +
  • unconditional de-noising process에서 label y를 condition으로 줌으로써 conditional de-noising process로 진행

  • +
+

Equation +$\(p_{\theta, \phi }(x_t|x_{t+1},y) = Zp_\theta(x_t|x_{t+1})p_\phi(y|x_t)\)$

+
    +
  • Z 는 normalizing을 위한 상수 이다

  • +
+

5-1 Classifier Guidance 유도

+

\(log_\phi p(y|x_t)\)\(\Sigma^-1\) 에 비해 곡률이 낮으며, 이 가정을 따라, diffusion step이 무한으로 갈 시, \(||\Sigma^ || \rightarrow0\) 이므로,\(log_\phi p(y|x_t)\)가 테일러 급수를 활용하여 식을 \(x_t = \mu\) 로 재전개 할 수 있다.

+
    +
  • classifier의 gradient를 활용해서 학습을 같이 해준다.

  • +
  • 식 유도는 아래와 같다. 본문의 (3) ~ (10) 번식이므로 본 논문을 참고하면 좋다.

  • +
+
+class_eq1 +
+

Fig. 66 Classifier Guidance 유도 식 1,2#

+
+
+
+classifier_2 +
+

Fig. 67 Classifier Guidance 유도 식 3~7#

+
+
+
+
+

6. Algorithm#

+
+algorithm +
+

Fig. 68 Algorithm 1 & 2 sampling method. Algorithm 1은 일반적인 DDPM 기준, Algorithm 2는 DDIM 기준 guidance 한 sampling 방법#

+
+
+
    +
  • Algorithm 1 은 일반 DDPM에서 샘플링 하는 방법이다. 똑같이 Gaussian distribution에서 샘플링 할 시, classifier의 gradient를 활용하여 \(x_{t-1}\)를 sample한다.

  • +
  • Algorithm 2 는 DDIM에서 샘플링 하는 방법이다. \(\epsilon\) 모델에서 나오는 output과 classifier의 gradient의 joint distribution 값을 빼 score을 구한다.

  • +
  • DDIM은 Deterministic하기때문에 모든 시점의 값을 모두 계산할 필요 없이 subset의 시점만으로 sampling이 가능하다.

  • +
  • 이 Accelerating method는 약간의 quality 저하가 있지만 Computational efficiency를 충분히 증가시킬 수 있다.

  • +
  • DDIM 방식의 재학습 없이 DDPM의 training에 DDIM의 sampling이 가능하다.

  • +
+
+
+

7. Impact of parameter s in classifier guidance#

+
+class_guidance_vis +
+

Fig. 69 Classifier Guidance scaling의 영향 시각화#

+
+
+
    +
  • classifier guidance 앞에 hyperparameter \bf{s} 의 값에 따라 classifier가 줄 수 있는 scaling이 다르다.

  • +
  • scale을 1.0으로 주면 웰시코기라는 class의 scale 영향을 덜 받아 “웰시코기스러운” 강아지가 생성이 많이 되지는 않는다.

  • +
  • scale을 10.0으로 주면 웰시코기 class라는 scaling의 영향을 많이 받아 웰시코기 분위기의 강아지의 이미지가 더 많이 생성 되는 것을 볼 수 있다.

  • +
  • epsilon이라는 모델이 결국 scale에 따라 gradient의 영향을 얼마나 많이 받는지 sampling할 때 볼 수 있다.

  • +
+
+
+

8. Results#

+
+plot result +
+

Fig. 70 Fidelity vs Diversity Trade-off 결과#

+
+
+
    +
  • gradient scale이 높을수록 recall은 낮지만, precision은 높다. 즉 trade-off 가 생기는데, recall이 낮을수록 diveristy가 낮다는 의미이고, precision이 높을수록 fidelity가 높다는 뜻이다.

  • +
  • scale을 높일수록 다양한 이미지가 생성되는 것이 아닌, classifier가 준 label쪽으로 guide가 생기므로 일정한 class의 사진이 나온다.

  • +
  • FID와 sFID는 diversity와 fidelity의 trade-off로 도출되는 값이므로, 최고의 값은 중간 지점에서 나왔다.

  • +
+

8-1. Result Table

+
    +
  • ADM은 Ablated Diffusion Model의 약자이며, ADM-G는 Ablated Diffusion Model with Guidance의 약자이다.

  • +
  • Guidance를 주었을 시 제일 좋은 FID값이 나왔으며, Precision이 높을수록, Recall이 낮게 나왔다 (and vice versa).

  • +
+
+
+

8-2. Image Synthesis Results#

+
+img_results +
+

Fig. 71 Generated Images (Left: BigGAN, Center: DMs, Right: Train Dataset)#

+
+
+
    +
  • 두번쨰 플라밍고 생성된 사진을 볼때, BigGAN은 이미지간들의 diversity가 없다. 학습된 플라밍고가 다수 플라밍고 시 비슷한 느낌의 이미지만 뽑아낸다.

  • +
  • 반면, Diffusion model with guidance를 사용했을 시, 다채로운 플라밍고 사진을 볼 수 있다. 한마리만 있는 플라밍고 사진도 뽑아 낼 수 있다.

  • +
+
+
+

9. Limitation and Future Work#

+

Limitation 1

+
    +
  • Diffusion 모델들은 GAN보다 샘플링 시간이 아직 느리다.

  • +
+

Future Work 1

+
    +
  • DDIM의 sampling process를 distillation 해서 빠르게 하는 법을 고려

  • +
+

Limitation 2

+
    +
  • Classifier guidance는 classification function의 gradient를 사용함으로써, label이 없는 data에는 확장이 불가능하다.

  • +
+

Future Work 2

+
    +
  • Unlabeled sample을 clustering 하는 방법을 통해 방법론을 expand 하려 한다.

  • +
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/dreambooth.html b/docs/review/dreambooth.html old mode 100644 new mode 100755 index 21684493..59ad3306 --- a/docs/review/dreambooth.html +++ b/docs/review/dreambooth.html @@ -1,813 +1,821 @@ - - - - - - - - - - - - DreamBooth — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

- -
-
-

DreamBooth#

-
-

Introduction#

-

최근에 DALL-E2, Imagen, Stable Diffusion 등 다양한 text-to-image generation 모델들이 등장하였지만, 어떠한 동일한 subject 에 대해서 다른 context 에 적용하는 부분에서 부족한 면들을 보여주고 있습니다. DreamBooth 논문은 이러한 문제점을 개선하기 위해 text-to-image 모델을 fine-tuning 하는 기법으로 소개되었고, 단 3-5장의 이미지를 학습하면 되며 이를 NVIDIA A100 으로 학습하는데 5분 정도밖에 소요되지 않는다고 합니다.

-
-dreambooth_01 -
-

Fig. 88 Subject-Driven Generation#

-
-
-

DreamBooth 가 무엇인지 자세히 알아보기 전에 text-to-image diffusion model 에 대해 다시 한번 개념 정리를 해볼 필요가 있습니다.

-
-
-

Text-to-Image Diffusion Models#

-

사전학습된 text-to-image diffusion model \(\hat{x}_{\theta}\) 는 input 으로 원본 이미지 \(x\), 그리고 text prompt \(P\) 와 text-encoder \(\Gamma\) 로부터 나오는 conditioning vector \(c = \Gamma(P)\) 를 입력받아서 이미지 \(x_{gen} = \hat{x}_{\theta}(\epsilon, c)\) 를 생성하게 됩니다. 학습 시, mean squared loss 를 사용하고 이를 수식적으로 표현하면 다음과 같습니다.

-
-\[ -\mathbb{E}_{x,c,\epsilon,t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_{t}\epsilon, c) - x ||_{2}^{2}] -\]
-

이때, DreamBooth 에서는 text encoder 를 CLIP text embedding 과 사전학습된 T5-XXL 모델 중 T5-XXL 모델을 사용했다고 합니다. 그리고 DreamBooth 로 fine-tuning 할때, diffusion process 에서 사용되는 U-net (때로는 text encoder 도 포함) 은 learnable 한 parameter 로 설정하고 생성된 latent vector 로부터 새로운 이미지를 생성하는 Decoder 의 파라미터 값은 고정시킨다고 합니다.

-

앞써 설명드렸던 내용들을 해당 implementation code 에서 확인할 수 있습니다.

-
    -
  • code

    -
    # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py
    -text_encoder_cls = import_model_class_from_model_name_or_path(args.pretrained_model_name_or_path, args.revision)
    -
    -# Load scheduler and models
    -noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
    -text_encoder = text_encoder_cls.from_pretrained(
    -    args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision
    -)
    -vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision)
    -unet = UNet2DConditionModel.from_pretrained(
    -    args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision
    -)
    -
    -
    -
  • -
  • training code

    -
    # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py
    -for epoch in range(first_epoch, args.num_train_epochs):
    -        unet.train()
    -        if args.train_text_encoder:
    -            text_encoder.train()
    -        for step, batch in enumerate(train_dataloader):
    -            # Skip steps until we reach the resumed step
    -            if args.resume_from_checkpoint and epoch == first_epoch and step < resume_step:
    -                if step % args.gradient_accumulation_steps == 0:
    -                    progress_bar.update(1)
    -                continue
    -
    -            with accelerator.accumulate(unet):
    -                # Convert images to latent space
    -                latents = vae.encode(batch["pixel_values"].to(dtype=weight_dtype)).latent_dist.sample()
    -                latents = latents * vae.config.scaling_factor
    -
    -                # Sample noise that we'll add to the latents
    -                if args.offset_noise:
    -                    noise = torch.randn_like(latents) + 0.1 * torch.randn(
    -                        latents.shape[0], latents.shape[1], 1, 1, device=latents.device
    -                    )
    -                else:
    -                    noise = torch.randn_like(latents)
    -                bsz = latents.shape[0]
    -                # Sample a random timestep for each image
    -                timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (bsz,), device=latents.device)
    -                timesteps = timesteps.long()
    -
    -                # Add noise to the latents according to the noise magnitude at each timestep
    -                # (this is the forward diffusion process)
    -                noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps)
    -
    -                # Get the text embedding for conditioning
    -                encoder_hidden_states = text_encoder(batch["input_ids"])[0]
    -
    -                # Predict the noise residual
    -                model_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample
    -
    -                # Get the target for loss depending on the prediction type
    -                if noise_scheduler.config.prediction_type == "epsilon":
    -                    target = noise
    -                elif noise_scheduler.config.prediction_type == "v_prediction":
    -                    target = noise_scheduler.get_velocity(latents, noise, timesteps)
    -                else:
    -                    raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}")
    -
    -                if args.with_prior_preservation:
    -                    # Chunk the noise and model_pred into two parts and compute the loss on each part separately.
    -                    model_pred, model_pred_prior = torch.chunk(model_pred, 2, dim=0)
    -                    target, target_prior = torch.chunk(target, 2, dim=0)
    -
    -                    # Compute instance loss
    -                    loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
    -
    -                    # Compute prior loss
    -                    prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean")
    -
    -                    # Add the prior loss to the instance loss.
    -                    loss = loss + args.prior_loss_weight * prior_loss
    -                else:
    -                    loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
    -
    -                accelerator.backward(loss)
    -                if accelerator.sync_gradients:
    -                    params_to_clip = (
    -                        itertools.chain(unet.parameters(), text_encoder.parameters())
    -                        if args.train_text_encoder
    -                        else unet.parameters()
    -                    )
    -                    accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm)
    -                optimizer.step()
    -                lr_scheduler.step()
    -                optimizer.zero_grad(set_to_none=args.set_grads_to_none)
    -
    -
    -
  • -
-
-
-

Fine-tuning#

-

DreamBooth 에서 pre-trained 된 text-to-image generation 모델을 fine-tuning 할 때 “a [unique identifier] [class noun]” 그리고 “a [class noun]” 형태의 두 가지 text prompt 를 사용합니다. 이때, unique identifier 에 유지하고자 하는 대상에 대한 정보를 담는 것을 목표로 하기 때문에 사전 정보가 없는 rare token 을 사용하는 것이 중요하다고 합니다. 논문에서는 3개 이하의 Unicode character 혹은 T5-XXL tokenizer 를 랜덤하게 샘플링해서 token 을 생성하고 이를 기반으로 unique identifier 를 정의합니다.

-

또한, 논문에서 Language Drift 그리고 Reduced Output Diversity 두 가지 문제점을 해결하기 위해 Class-specific Prior Preservation Loss 를 소개합니다. 이를 활용하여 모델을 fine-tuning 하는 방법은 다음과 같습니다.

-
-dreambooth_02 -
-

Fig. 89 Fine-tuning#

-
-
-

우선, Gaussian 노이즈 이미지와 “A V [class noun]” 형태의 text prompt 를 사전학습된 text-to-image diffusion 모델에 입력하여 이미지를 생성한 후, 원본 이미지와의 Reconstruction Loss 를 계산합니다. 그리고 비슷한 과정으로 Gaussian 노이즈 이미지와 “A [class noun]” 형태의 text prompt 를 학습하고자 하는 모델, 그리고 freeze 시킨 또 다른 pre-trained diffusion 모델에 각각 입력하여 이미지를 생성한 후 Class-Specific Prior Preservation Loss 를 계산합니다. 이에 대한 training objective 를 수식적으로 표현하면 다음과 같습니다.

-
-\[ -\mathbb{E}_{x,c,\epsilon,\epsilon^{'},t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_t\epsilon, c) - x ||_{2}^{2} + \lambda w_{t^{'}} || \hat{x}_{\theta}(\alpha_{t^{'}} x_{pr} + \sigma_{t^{'}}\epsilon^{'}, c_{pr}) - x_{pr} ||_{2}^{2}] -\]
-

Class-Specific Prior Preservation Loss 를 추가함으로써 class prior 에 대한 정보를 유지하게 되고, 이로써 동일한 class 에 대해 더 다양한 이미지들을 생성할 수 있는 부분을 아래 그림에서 확인할 수 있습니다.

-
-dreambooth_03 -
-

Fig. 90 Encouraging diversity with prior-preservation loss#

-
-
-
-
-

Experiments#

-

DreamBooth 논문에서 세 가지의 모델 평가 metric 을 소개합니다. 첫번째로는 subject fidelity 를 측정하는 CLIP-I, DINO 그리고 prompt fidelity 를 측정하는 CLIP-T metric 을 사용합니다. 이때, DINO metric 이 동일한 class 를 가진 subject 에 대해서 다른 embedding 이 생성되기 때문에 CLIP-I 보다 더 선호된다고 합니다. 더 자세하게는 각 metric 은 다음과 같이 계산됩니다.

-
    -
  • CLIP-I := 생성된 이미지와 실제 이미지의 CLIP embedding 의 평균 pairwise cosine similarity

  • -
  • DINO := 생성된 이미지와 실제 이미지의 ViT-S/16 DINO embedding 의 평균 pairwise cosine similarity

  • -
  • CLIP-T := 입력 prompt 와 생성된 이미지의 CLIP embedding 의 평균 pairwise cosine similarity

  • -
-

Textual Inversion 과 비교했을때, 세 개의 metric 에서 모두 DreamBooth 가 더 좋은 성능을 보여주는 것을 확인할 수 있습니다.

-
-dreambooth_04 -
-

Fig. 91 Comparison of models#

-
-
-
-
-

Ablation Studies#

-

Prior Preservation Loss (PPL) 과 Class-Prior 에 대한 Ablation Studies 결과도 논문에서 공유합니다. PPL 가 적용됨으로써 앞써 소개드렸던 Language Drift 그리고 Reduced Output Diversity 문제점을 PRES 그리고 DIV metric 을 통해 해결되는 것을 보여줍니다. 또한, Class-Prior Ablation 에서 다음과 같은 세 가지 prompt 를 사용하여 fine-tuning 했을 때, 해당 subject 에 맞는 class noun 을 prompt 에 입력했을때가 가장 좋은 성능을 보여준다고 설명합니다.

-
    -
  • “no class noun”

  • -
  • “a randomly sampled incorrect class noun” (e.g., “can” for a backpack)

  • -
  • “correct class noun”

  • -
-
-
-

Applications#

-

논문에서 DreamBooth 를 활용한 여러 application 도 소개합니다.

-
-dreambooth_05 -
-

Fig. 92 Applications of DreamBooth#

-
-
-
    -
  1. Recontextualization

  2. -
-
    -
  • Prompt: “a [V] [class noun] [context description]”

  • -
  • 다음과 같은 prompt 입력 시, 사전에 보지 못했던 새로운 pose 나 articulation 을 잘 표현하는 부분을 확인할 수 있습니다.

  • -
-
-dreambooth_06 -
-

Fig. 93 Recontextualization#

-
-
-
    -
  1. Art Renditions

  2. -
-
    -
  • Prompt: “a painting of a [V] [class noun] in the style of [famous painter]” or “a statue of a [V] [class noun] in the style of [famous sculptor]”

  • -
  • Style Transfer 와 다르게 동일한 구조를 유지한 채 style 만 바꾸는 것이 아니라 다양한 pose 형태도 생성 가능합니다.

  • -
-
    -
  1. Novel View Synthesis

  2. -
-
    -
  • 동일한 subject 에 대해 다양한 각도에서 보는 이미지 생성도 가능합니다.

  • -
-
    -
  1. Property Modification

  2. -
-
    -
  • Prompt: “a cross of a [V] dog and a [target species]”

  • -
  • 사전 학습한 subject 의 고유 feature 들이 다른 target species 에서도 반영이 되는 부분을 확인할 수 있습니다.

  • -
-
-
-

Limitations#

-

하지만 DreamBooth 모델에 다음과 같은 한계점도 존재합니다.

-
-dreambooth_07 -
-

Fig. 94 Limitations of DreamBooth#

-
-
-
    -
  • Incorrect context synthesis := 대표적으로 training set 에 자주 나타나지 않는 subject, prompt, context 에 대해서 낮은 성능을 보여줍니다.

  • -
  • Context-appearance entanglement := 유지하고자 하는 대상의 appearance (e.g, color) 가 prompted context 에 의해 달라지는 현상

  • -
  • Overfitting := 사전학습된 데이터와 유사한 prompt 입력 시, overfitting 현상 발생

  • -
-

마지막으로 subject 대상에 따라 모델 성능(fidelity)이 차이를 보인다고 합니다.

-
-
-

Appendix#

-

마지막으로, 논문 본문에 소개되고 있지는 않지만 Appendix 부문에서도 흥미로운 결과들을 확인할 수 있습니다. Figure 20 은 fine tuning 하는 이미지 개수에 따른 DreamBooth 학습결과를 보여주는데, 단 한 장만으로도 identity 의 전반적인 특징을 잘 담는 것을 확인할 수 있습니다. Figure 18 은 만화 캐릭터의 identity 를 유지한 상태로 다양한 만화 사진들을 모델이 생성하는 사례들을 보여줍니다.

-
-dreambooth_08 -
-

Fig. 95 Appendix-1#

-
-
-
-dreambooth_09 -
-

Fig. 96 Appendix-2#

-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + DreamBooth — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+ +
+
+

DreamBooth#

+
+

Introduction#

+

최근에 DALL-E2, Imagen, Stable Diffusion 등 다양한 text-to-image generation 모델들이 등장하였지만, 어떠한 동일한 subject 에 대해서 다른 context 에 적용하는 부분에서 부족한 면들을 보여주고 있습니다. DreamBooth 논문은 이러한 문제점을 개선하기 위해 text-to-image 모델을 fine-tuning 하는 기법으로 소개되었고, 단 3-5장의 이미지를 학습하면 되며 이를 NVIDIA A100 으로 학습하는데 5분 정도밖에 소요되지 않는다고 합니다.

+
+dreambooth_01 +
+

Fig. 88 Subject-Driven Generation#

+
+
+

DreamBooth 가 무엇인지 자세히 알아보기 전에 text-to-image diffusion model 에 대해 다시 한번 개념 정리를 해볼 필요가 있습니다.

+
+
+

Text-to-Image Diffusion Models#

+

사전학습된 text-to-image diffusion model \(\hat{x}_{\theta}\) 는 input 으로 원본 이미지 \(x\), 그리고 text prompt \(P\) 와 text-encoder \(\Gamma\) 로부터 나오는 conditioning vector \(c = \Gamma(P)\) 를 입력받아서 이미지 \(x_{gen} = \hat{x}_{\theta}(\epsilon, c)\) 를 생성하게 됩니다. 학습 시, mean squared loss 를 사용하고 이를 수식적으로 표현하면 다음과 같습니다.

+
+\[ +\mathbb{E}_{x,c,\epsilon,t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_{t}\epsilon, c) - x ||_{2}^{2}] +\]
+

이때, DreamBooth 에서는 text encoder 를 CLIP text embedding 과 사전학습된 T5-XXL 모델 중 T5-XXL 모델을 사용했다고 합니다. 그리고 DreamBooth 로 fine-tuning 할때, diffusion process 에서 사용되는 U-net (때로는 text encoder 도 포함) 은 learnable 한 parameter 로 설정하고 생성된 latent vector 로부터 새로운 이미지를 생성하는 Decoder 의 파라미터 값은 고정시킨다고 합니다.

+

앞써 설명드렸던 내용들을 해당 implementation code 에서 확인할 수 있습니다.

+
    +
  • code

    +
    # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py
    +text_encoder_cls = import_model_class_from_model_name_or_path(args.pretrained_model_name_or_path, args.revision)
    +
    +# Load scheduler and models
    +noise_scheduler = DDPMScheduler.from_pretrained(args.pretrained_model_name_or_path, subfolder="scheduler")
    +text_encoder = text_encoder_cls.from_pretrained(
    +    args.pretrained_model_name_or_path, subfolder="text_encoder", revision=args.revision
    +)
    +vae = AutoencoderKL.from_pretrained(args.pretrained_model_name_or_path, subfolder="vae", revision=args.revision)
    +unet = UNet2DConditionModel.from_pretrained(
    +    args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision
    +)
    +
    +
    +
  • +
  • training code

    +
    # https://github.com/huggingface/diffusers/blob/main/examples/dreambooth/train_dreambooth.py
    +for epoch in range(first_epoch, args.num_train_epochs):
    +        unet.train()
    +        if args.train_text_encoder:
    +            text_encoder.train()
    +        for step, batch in enumerate(train_dataloader):
    +            # Skip steps until we reach the resumed step
    +            if args.resume_from_checkpoint and epoch == first_epoch and step < resume_step:
    +                if step % args.gradient_accumulation_steps == 0:
    +                    progress_bar.update(1)
    +                continue
    +
    +            with accelerator.accumulate(unet):
    +                # Convert images to latent space
    +                latents = vae.encode(batch["pixel_values"].to(dtype=weight_dtype)).latent_dist.sample()
    +                latents = latents * vae.config.scaling_factor
    +
    +                # Sample noise that we'll add to the latents
    +                if args.offset_noise:
    +                    noise = torch.randn_like(latents) + 0.1 * torch.randn(
    +                        latents.shape[0], latents.shape[1], 1, 1, device=latents.device
    +                    )
    +                else:
    +                    noise = torch.randn_like(latents)
    +                bsz = latents.shape[0]
    +                # Sample a random timestep for each image
    +                timesteps = torch.randint(0, noise_scheduler.config.num_train_timesteps, (bsz,), device=latents.device)
    +                timesteps = timesteps.long()
    +
    +                # Add noise to the latents according to the noise magnitude at each timestep
    +                # (this is the forward diffusion process)
    +                noisy_latents = noise_scheduler.add_noise(latents, noise, timesteps)
    +
    +                # Get the text embedding for conditioning
    +                encoder_hidden_states = text_encoder(batch["input_ids"])[0]
    +
    +                # Predict the noise residual
    +                model_pred = unet(noisy_latents, timesteps, encoder_hidden_states).sample
    +
    +                # Get the target for loss depending on the prediction type
    +                if noise_scheduler.config.prediction_type == "epsilon":
    +                    target = noise
    +                elif noise_scheduler.config.prediction_type == "v_prediction":
    +                    target = noise_scheduler.get_velocity(latents, noise, timesteps)
    +                else:
    +                    raise ValueError(f"Unknown prediction type {noise_scheduler.config.prediction_type}")
    +
    +                if args.with_prior_preservation:
    +                    # Chunk the noise and model_pred into two parts and compute the loss on each part separately.
    +                    model_pred, model_pred_prior = torch.chunk(model_pred, 2, dim=0)
    +                    target, target_prior = torch.chunk(target, 2, dim=0)
    +
    +                    # Compute instance loss
    +                    loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
    +
    +                    # Compute prior loss
    +                    prior_loss = F.mse_loss(model_pred_prior.float(), target_prior.float(), reduction="mean")
    +
    +                    # Add the prior loss to the instance loss.
    +                    loss = loss + args.prior_loss_weight * prior_loss
    +                else:
    +                    loss = F.mse_loss(model_pred.float(), target.float(), reduction="mean")
    +
    +                accelerator.backward(loss)
    +                if accelerator.sync_gradients:
    +                    params_to_clip = (
    +                        itertools.chain(unet.parameters(), text_encoder.parameters())
    +                        if args.train_text_encoder
    +                        else unet.parameters()
    +                    )
    +                    accelerator.clip_grad_norm_(params_to_clip, args.max_grad_norm)
    +                optimizer.step()
    +                lr_scheduler.step()
    +                optimizer.zero_grad(set_to_none=args.set_grads_to_none)
    +
    +
    +
  • +
+
+
+

Fine-tuning#

+

DreamBooth 에서 pre-trained 된 text-to-image generation 모델을 fine-tuning 할 때 “a [unique identifier] [class noun]” 그리고 “a [class noun]” 형태의 두 가지 text prompt 를 사용합니다. 이때, unique identifier 에 유지하고자 하는 대상에 대한 정보를 담는 것을 목표로 하기 때문에 사전 정보가 없는 rare token 을 사용하는 것이 중요하다고 합니다. 논문에서는 3개 이하의 Unicode character 혹은 T5-XXL tokenizer 를 랜덤하게 샘플링해서 token 을 생성하고 이를 기반으로 unique identifier 를 정의합니다.

+

또한, 논문에서 Language Drift 그리고 Reduced Output Diversity 두 가지 문제점을 해결하기 위해 Class-specific Prior Preservation Loss 를 소개합니다. 이를 활용하여 모델을 fine-tuning 하는 방법은 다음과 같습니다.

+
+dreambooth_02 +
+

Fig. 89 Fine-tuning#

+
+
+

우선, Gaussian 노이즈 이미지와 “A V [class noun]” 형태의 text prompt 를 사전학습된 text-to-image diffusion 모델에 입력하여 이미지를 생성한 후, 원본 이미지와의 Reconstruction Loss 를 계산합니다. 그리고 비슷한 과정으로 Gaussian 노이즈 이미지와 “A [class noun]” 형태의 text prompt 를 학습하고자 하는 모델, 그리고 freeze 시킨 또 다른 pre-trained diffusion 모델에 각각 입력하여 이미지를 생성한 후 Class-Specific Prior Preservation Loss 를 계산합니다. 이에 대한 training objective 를 수식적으로 표현하면 다음과 같습니다.

+
+\[ +\mathbb{E}_{x,c,\epsilon,\epsilon^{'},t}[w_t || \hat{x}_{\theta}(\alpha_tx + \sigma_t\epsilon, c) - x ||_{2}^{2} + \lambda w_{t^{'}} || \hat{x}_{\theta}(\alpha_{t^{'}} x_{pr} + \sigma_{t^{'}}\epsilon^{'}, c_{pr}) - x_{pr} ||_{2}^{2}] +\]
+

Class-Specific Prior Preservation Loss 를 추가함으로써 class prior 에 대한 정보를 유지하게 되고, 이로써 동일한 class 에 대해 더 다양한 이미지들을 생성할 수 있는 부분을 아래 그림에서 확인할 수 있습니다.

+
+dreambooth_03 +
+

Fig. 90 Encouraging diversity with prior-preservation loss#

+
+
+
+
+

Experiments#

+

DreamBooth 논문에서 세 가지의 모델 평가 metric 을 소개합니다. 첫번째로는 subject fidelity 를 측정하는 CLIP-I, DINO 그리고 prompt fidelity 를 측정하는 CLIP-T metric 을 사용합니다. 이때, DINO metric 이 동일한 class 를 가진 subject 에 대해서 다른 embedding 이 생성되기 때문에 CLIP-I 보다 더 선호된다고 합니다. 더 자세하게는 각 metric 은 다음과 같이 계산됩니다.

+
    +
  • CLIP-I := 생성된 이미지와 실제 이미지의 CLIP embedding 의 평균 pairwise cosine similarity

  • +
  • DINO := 생성된 이미지와 실제 이미지의 ViT-S/16 DINO embedding 의 평균 pairwise cosine similarity

  • +
  • CLIP-T := 입력 prompt 와 생성된 이미지의 CLIP embedding 의 평균 pairwise cosine similarity

  • +
+

Textual Inversion 과 비교했을때, 세 개의 metric 에서 모두 DreamBooth 가 더 좋은 성능을 보여주는 것을 확인할 수 있습니다.

+
+dreambooth_04 +
+

Fig. 91 Comparison of models#

+
+
+
+
+

Ablation Studies#

+

Prior Preservation Loss (PPL) 과 Class-Prior 에 대한 Ablation Studies 결과도 논문에서 공유합니다. PPL 가 적용됨으로써 앞써 소개드렸던 Language Drift 그리고 Reduced Output Diversity 문제점을 PRES 그리고 DIV metric 을 통해 해결되는 것을 보여줍니다. 또한, Class-Prior Ablation 에서 다음과 같은 세 가지 prompt 를 사용하여 fine-tuning 했을 때, 해당 subject 에 맞는 class noun 을 prompt 에 입력했을때가 가장 좋은 성능을 보여준다고 설명합니다.

+
    +
  • “no class noun”

  • +
  • “a randomly sampled incorrect class noun” (e.g., “can” for a backpack)

  • +
  • “correct class noun”

  • +
+
+
+

Applications#

+

논문에서 DreamBooth 를 활용한 여러 application 도 소개합니다.

+
+dreambooth_05 +
+

Fig. 92 Applications of DreamBooth#

+
+
+
    +
  1. Recontextualization

  2. +
+
    +
  • Prompt: “a [V] [class noun] [context description]”

  • +
  • 다음과 같은 prompt 입력 시, 사전에 보지 못했던 새로운 pose 나 articulation 을 잘 표현하는 부분을 확인할 수 있습니다.

  • +
+
+dreambooth_06 +
+

Fig. 93 Recontextualization#

+
+
+
    +
  1. Art Renditions

  2. +
+
    +
  • Prompt: “a painting of a [V] [class noun] in the style of [famous painter]” or “a statue of a [V] [class noun] in the style of [famous sculptor]”

  • +
  • Style Transfer 와 다르게 동일한 구조를 유지한 채 style 만 바꾸는 것이 아니라 다양한 pose 형태도 생성 가능합니다.

  • +
+
    +
  1. Novel View Synthesis

  2. +
+
    +
  • 동일한 subject 에 대해 다양한 각도에서 보는 이미지 생성도 가능합니다.

  • +
+
    +
  1. Property Modification

  2. +
+
    +
  • Prompt: “a cross of a [V] dog and a [target species]”

  • +
  • 사전 학습한 subject 의 고유 feature 들이 다른 target species 에서도 반영이 되는 부분을 확인할 수 있습니다.

  • +
+
+
+

Limitations#

+

하지만 DreamBooth 모델에 다음과 같은 한계점도 존재합니다.

+
+dreambooth_07 +
+

Fig. 94 Limitations of DreamBooth#

+
+
+
    +
  • Incorrect context synthesis := 대표적으로 training set 에 자주 나타나지 않는 subject, prompt, context 에 대해서 낮은 성능을 보여줍니다.

  • +
  • Context-appearance entanglement := 유지하고자 하는 대상의 appearance (e.g, color) 가 prompted context 에 의해 달라지는 현상

  • +
  • Overfitting := 사전학습된 데이터와 유사한 prompt 입력 시, overfitting 현상 발생

  • +
+

마지막으로 subject 대상에 따라 모델 성능(fidelity)이 차이를 보인다고 합니다.

+
+
+

Appendix#

+

마지막으로, 논문 본문에 소개되고 있지는 않지만 Appendix 부문에서도 흥미로운 결과들을 확인할 수 있습니다. Figure 20 은 fine tuning 하는 이미지 개수에 따른 DreamBooth 학습결과를 보여주는데, 단 한 장만으로도 identity 의 전반적인 특징을 잘 담는 것을 확인할 수 있습니다. Figure 18 은 만화 캐릭터의 identity 를 유지한 상태로 다양한 만화 사진들을 모델이 생성하는 사례들을 보여줍니다.

+
+dreambooth_08 +
+

Fig. 95 Appendix-1#

+
+
+
+dreambooth_09 +
+

Fig. 96 Appendix-2#

+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/gan.html b/docs/review/gan.html old mode 100644 new mode 100755 index 54a22da8..93f9d151 --- a/docs/review/gan.html +++ b/docs/review/gan.html @@ -1,765 +1,773 @@ - - - - - - - - - - - - GAN — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

GAN

- -
- -
-
- - - - -
- -
-

Information

- -
-
-

GAN#

-
-

Introduction#

-

Ian Goodfellow 가 2014년에 발표한 GAN 은 최근에 Diffusion Model 이 소개되기 전까지 몇 년 동안 이미지 생성분야에서 대표적인 모델로 자리잡았었습니다. GAN 은 VAE 와 달리 marginal likelihood \(p_{\theta}(x)\) 를 직접 구하지 않고, Adversarial Process 를 통해 implicit 하게 샘플링을 해서 분포를 구하게 됩니다.

-
-gan_01 -
-

Fig. 5 Taxonomy of Generative Models#

-
-
-

아래 그림과 같이 GAN 은 크게 잠재변수 \(z\) 로부터 가짜 데이터를 생성하는 Generator 와 그로부터 생성된 데이터와 실제 training 데이터를 구분하는 Discriminator 로 구성이 되어 있습니다. 다시 말해서 Discriminator 는 실제 데이터가 들어오면 1, 그리고 가짜로 생성된 데이터가 들어오면 0 을 출력하는 binary classification task 를 진행합니다.

-
-gan_03 -
-

Fig. 6 Generative Adversarial Network(GAN) Architecture#

-
-
-

Generator 와 Discriminator 구현 코드도 같이 살펴보겠습니다.

-
    -
  • Generator 구현 code

    -
    class Generator(nn.Module):
    -    def __init__(self):
    -        super(Generator, self).__init__()
    -
    -        def block(in_feat, out_feat, normalize=True):
    -            layers = [nn.Linear(in_feat, out_feat)]
    -            if normalize:
    -                layers.append(nn.BatchNorm1d(out_feat, 0.8))
    -            layers.append(nn.LeakyReLU(0.2, inplace=True))
    -            return layers
    -
    -        self.model = nn.Sequential(
    -            *block(opt.latent_dim, 128, normalize=False),
    -            *block(128, 256),
    -            *block(256, 512),
    -            *block(512, 1024),
    -            nn.Linear(1024, int(np.prod(img_shape))),
    -            nn.Tanh()
    -        )
    -
    -    def forward(self, z):
    -        img = self.model(z)
    -        img = img.view(img.size(0), *img_shape)
    -        return img
    -
    -
    -
  • -
  • Discriminator 구현 code

    -
    class Discriminator(nn.Module):
    -    def __init__(self):
    -        super(Discriminator, self).__init__()
    -
    -        self.model = nn.Sequential(
    -            nn.Linear(int(np.prod(img_shape)), 512),
    -            nn.LeakyReLU(0.2, inplace=True),
    -            nn.Linear(512, 256),
    -            nn.LeakyReLU(0.2, inplace=True),
    -            nn.Linear(256, 1),
    -            nn.Sigmoid(),
    -        )
    -
    -    def forward(self, img):
    -        img_flat = img.view(img.size(0), -1)
    -        validity = self.model(img_flat)
    -
    -        return validity
    -
    -
    -
  • -
-
-
-

Training Procedure#

-

GAN 을 학습할 시, D를 먼저 최적화하는 k 단계G를 최적화하는 한 단계를 번갈아 수행합니다. 그리고 이때 쓰이는 손실함수(loss function)은 다음과 같습니다.

-
-\[ -\min_G \max_D V(D,G) = \mathbb{E}_{x \sim p_{data}(x)}[log\ D(x)] + \mathbb{E}_{z \sim p_z(z)}[log(1-D(G(z))] -\]
-

논문에서 제시한 학습 알고리즘과 실제 implementation code 를 비교해보겠습니다.

-
-gan_02 -
-

Fig. 7 Generative Adversarial Network(GAN) Training Procedure#

-
-
-
    -
  • GAN 학습 code

    -
    # ----------
    -#  Training
    -# ----------
    -
    -for epoch in range(opt.n_epochs):
    -    for i, (imgs, _) in enumerate(dataloader):
    -
    -        # Adversarial ground truths
    -        valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False)
    -        fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False)
    -
    -        # Configure input
    -        real_imgs = Variable(imgs.type(Tensor))
    -
    -        # -----------------
    -        #  Train Generator
    -        # -----------------
    -
    -        optimizer_G.zero_grad()
    -
    -        # Sample noise as generator input
    -        z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim))))
    -
    -        # Generate a batch of images
    -        gen_imgs = generator(z)
    -
    -        # Loss measures generator's ability to fool the discriminator
    -        g_loss = adversarial_loss(discriminator(gen_imgs), valid)
    -
    -        g_loss.backward()
    -        optimizer_G.step()
    -
    -        # ---------------------
    -        #  Train Discriminator
    -        # ---------------------
    -
    -        optimizer_D.zero_grad()
    -
    -        # Measure discriminator's ability to classify real from generated samples
    -        real_loss = adversarial_loss(discriminator(real_imgs), valid)
    -        fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake)
    -        d_loss = (real_loss + fake_loss) / 2
    -
    -        d_loss.backward()
    -        optimizer_D.step()
    -
    -        print(
    -            "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]"
    -            % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item())
    -        )
    -
    -        batches_done = epoch * len(dataloader) + i
    -        if batches_done % opt.sample_interval == 0:
    -            save_image(gen_imgs.data[:25], "images/%d.png" % batches_done, nrow=5, normalize=True)
    -
    -
    -
  • -
-

이렇게 Discriminator 와 Generator 는 각각 \(V(D,G)\) 가 최대화하고 최소화하는 방향으로 stochastic gradient descent 를 진행하게 됩니다. 하지만 아래 그림처럼 실제로 Generator를 학습할 때, 초반에 \(D(G(z)) \approx 0\) 일 경우 학습하지 못하는 상황이 발생합니다. 이 때, \(log(1-D(G(z))\) 를 최소화하지 않고 \(log(D(G(z))\) 를 최대화하는 방향으로 Generator 를 학습하는 기법도 있습니다.

-
-gan_04 -
-

Fig. 8 Alternative to Vanishing Gradient when Training the Generator#

-
-
-

이렇게 학습함으로써 최적화된 solution 에서는 Generator 가 training 데이터 분포를 완벽히 복원하고 Discriminator 는 binary classification 확률을 언제나 1/2 로 내뱉게 됩니다.

-
-

Theoretical Results#

-

Proposition 1. 고정된 Generator 에 대해서, 최적화된 Discriminator 는 다음과 같습니다.

-
-\[ -D_{G}^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)} -\]
-

이를 증명하자면, Discriminator 에 대한 손실함수를 다음과 같이 쓸 수 있고 \(D = D_{G}^*(x)\) 가 이를 최대화하는 solution 입니다.

-
-\[ -V(D,G) = \int_x p_{data}(x)\ log(D(x))\ dx+ \int_z p_{z}(z)\ log(1-D(g(z))\ dz -\]
-
-\[ -= \int_x p_{data}(x)\ log(D(x)) + p_{g}(x)\ log(1-D(x))\ dx -\]
-

Proposition 2. 최적화된 Discriminator 에 대해 \(\max_D V(D,G)\) 를 최소화하는 Generator 는 \(p_g = p_{data}\) 일때 성립하고 이때 \(D = D_{G}^*(x) = 1/2\) 입니다.

-

이를 증명하자면, 최적화된 Discriminator 에 대한 손실함수는 다음과 같고

-
-\[ -V(D^{\ast},G) = \mathbb{E}_{x \sim p_{data}(x)} [ log D^{\ast}(x) ] + \mathbb{E}_{x \sim p_g(x)} [ log(1-D^{\ast}(x) ] -\]
-
-\[ -= \int_x p_{data}(x)\ log(\frac{p_{data}(x)}{p_{data}(x) + p_g(x)}) + \int_x p_{g}(x)\ log(\frac{p_{g}(x)}{p_{data}(x) + p_g(x)})\ dx -\]
-
-\[ -= -log(4)\ + KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) -\]
-

\(KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) = 2\ \cdot\ JSD(p_{data}\ ||\ p_{g})\) 의 최솟값은 0 이고 이는 \(p_g = p_{data}\) 일때 성립합니다.

-
-
-
-

Experiments#

-

논문에서 MNIST, the Toronto Face Database(TFD), 그리고 CIFAR-10 dataset 로 모델 실험 및 성능 평가했습니다. 평가시에는 \(p_g\) 로부터 Parzen density estimation 을 거쳐 계산한 log likelihood estimate 로 모델 성능 평가를 진행했습니다.

-
-
-

Summary#

-

VAE는 새로운 데이터를 잘 생성하지만 생성된 이미지가 흐릿하다는 단점을 지니고 있습니다. 반면에 GAN 은 high quality image 를 잘 생성하지만 unstable 한 convergence 를 가지고 있습니다. 그래서 실제로 VAE 는 Encoder 를 활용한 차원축소로 많이 활용되고 이미지 데이터를 생성하는데는 GAN 이 많이 활용되었다고 합니다.

-
-
- - - - -
- - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + GAN — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

GAN

+ +
+ +
+
+ + + + +
+ +
+

Information

+ +
+
+

GAN#

+
+

Introduction#

+

Ian Goodfellow 가 2014년에 발표한 GAN 은 최근에 Diffusion Model 이 소개되기 전까지 몇 년 동안 이미지 생성분야에서 대표적인 모델로 자리잡았었습니다. GAN 은 VAE 와 달리 marginal likelihood \(p_{\theta}(x)\) 를 직접 구하지 않고, Adversarial Process 를 통해 implicit 하게 샘플링을 해서 분포를 구하게 됩니다.

+
+gan_01 +
+

Fig. 5 Taxonomy of Generative Models#

+
+
+

아래 그림과 같이 GAN 은 크게 잠재변수 \(z\) 로부터 가짜 데이터를 생성하는 Generator 와 그로부터 생성된 데이터와 실제 training 데이터를 구분하는 Discriminator 로 구성이 되어 있습니다. 다시 말해서 Discriminator 는 실제 데이터가 들어오면 1, 그리고 가짜로 생성된 데이터가 들어오면 0 을 출력하는 binary classification task 를 진행합니다.

+
+gan_03 +
+

Fig. 6 Generative Adversarial Network(GAN) Architecture#

+
+
+

Generator 와 Discriminator 구현 코드도 같이 살펴보겠습니다.

+
    +
  • Generator 구현 code

    +
    class Generator(nn.Module):
    +    def __init__(self):
    +        super(Generator, self).__init__()
    +
    +        def block(in_feat, out_feat, normalize=True):
    +            layers = [nn.Linear(in_feat, out_feat)]
    +            if normalize:
    +                layers.append(nn.BatchNorm1d(out_feat, 0.8))
    +            layers.append(nn.LeakyReLU(0.2, inplace=True))
    +            return layers
    +
    +        self.model = nn.Sequential(
    +            *block(opt.latent_dim, 128, normalize=False),
    +            *block(128, 256),
    +            *block(256, 512),
    +            *block(512, 1024),
    +            nn.Linear(1024, int(np.prod(img_shape))),
    +            nn.Tanh()
    +        )
    +
    +    def forward(self, z):
    +        img = self.model(z)
    +        img = img.view(img.size(0), *img_shape)
    +        return img
    +
    +
    +
  • +
  • Discriminator 구현 code

    +
    class Discriminator(nn.Module):
    +    def __init__(self):
    +        super(Discriminator, self).__init__()
    +
    +        self.model = nn.Sequential(
    +            nn.Linear(int(np.prod(img_shape)), 512),
    +            nn.LeakyReLU(0.2, inplace=True),
    +            nn.Linear(512, 256),
    +            nn.LeakyReLU(0.2, inplace=True),
    +            nn.Linear(256, 1),
    +            nn.Sigmoid(),
    +        )
    +
    +    def forward(self, img):
    +        img_flat = img.view(img.size(0), -1)
    +        validity = self.model(img_flat)
    +
    +        return validity
    +
    +
    +
  • +
+
+
+

Training Procedure#

+

GAN 을 학습할 시, D를 먼저 최적화하는 k 단계G를 최적화하는 한 단계를 번갈아 수행합니다. 그리고 이때 쓰이는 손실함수(loss function)은 다음과 같습니다.

+
+\[ +\min_G \max_D V(D,G) = \mathbb{E}_{x \sim p_{data}(x)}[log\ D(x)] + \mathbb{E}_{z \sim p_z(z)}[log(1-D(G(z))] +\]
+

논문에서 제시한 학습 알고리즘과 실제 implementation code 를 비교해보겠습니다.

+
+gan_02 +
+

Fig. 7 Generative Adversarial Network(GAN) Training Procedure#

+
+
+
    +
  • GAN 학습 code

    +
    # ----------
    +#  Training
    +# ----------
    +
    +for epoch in range(opt.n_epochs):
    +    for i, (imgs, _) in enumerate(dataloader):
    +
    +        # Adversarial ground truths
    +        valid = Variable(Tensor(imgs.size(0), 1).fill_(1.0), requires_grad=False)
    +        fake = Variable(Tensor(imgs.size(0), 1).fill_(0.0), requires_grad=False)
    +
    +        # Configure input
    +        real_imgs = Variable(imgs.type(Tensor))
    +
    +        # -----------------
    +        #  Train Generator
    +        # -----------------
    +
    +        optimizer_G.zero_grad()
    +
    +        # Sample noise as generator input
    +        z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim))))
    +
    +        # Generate a batch of images
    +        gen_imgs = generator(z)
    +
    +        # Loss measures generator's ability to fool the discriminator
    +        g_loss = adversarial_loss(discriminator(gen_imgs), valid)
    +
    +        g_loss.backward()
    +        optimizer_G.step()
    +
    +        # ---------------------
    +        #  Train Discriminator
    +        # ---------------------
    +
    +        optimizer_D.zero_grad()
    +
    +        # Measure discriminator's ability to classify real from generated samples
    +        real_loss = adversarial_loss(discriminator(real_imgs), valid)
    +        fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake)
    +        d_loss = (real_loss + fake_loss) / 2
    +
    +        d_loss.backward()
    +        optimizer_D.step()
    +
    +        print(
    +            "[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]"
    +            % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item())
    +        )
    +
    +        batches_done = epoch * len(dataloader) + i
    +        if batches_done % opt.sample_interval == 0:
    +            save_image(gen_imgs.data[:25], "images/%d.png" % batches_done, nrow=5, normalize=True)
    +
    +
    +
  • +
+

이렇게 Discriminator 와 Generator 는 각각 \(V(D,G)\) 가 최대화하고 최소화하는 방향으로 stochastic gradient descent 를 진행하게 됩니다. 하지만 아래 그림처럼 실제로 Generator를 학습할 때, 초반에 \(D(G(z)) \approx 0\) 일 경우 학습하지 못하는 상황이 발생합니다. 이 때, \(log(1-D(G(z))\) 를 최소화하지 않고 \(log(D(G(z))\) 를 최대화하는 방향으로 Generator 를 학습하는 기법도 있습니다.

+
+gan_04 +
+

Fig. 8 Alternative to Vanishing Gradient when Training the Generator#

+
+
+

이렇게 학습함으로써 최적화된 solution 에서는 Generator 가 training 데이터 분포를 완벽히 복원하고 Discriminator 는 binary classification 확률을 언제나 1/2 로 내뱉게 됩니다.

+
+

Theoretical Results#

+

Proposition 1. 고정된 Generator 에 대해서, 최적화된 Discriminator 는 다음과 같습니다.

+
+\[ +D_{G}^*(x) = \frac{p_{data}(x)}{p_{data}(x) + p_g(x)} +\]
+

이를 증명하자면, Discriminator 에 대한 손실함수를 다음과 같이 쓸 수 있고 \(D = D_{G}^*(x)\) 가 이를 최대화하는 solution 입니다.

+
+\[ +V(D,G) = \int_x p_{data}(x)\ log(D(x))\ dx+ \int_z p_{z}(z)\ log(1-D(g(z))\ dz +\]
+
+\[ += \int_x p_{data}(x)\ log(D(x)) + p_{g}(x)\ log(1-D(x))\ dx +\]
+

Proposition 2. 최적화된 Discriminator 에 대해 \(\max_D V(D,G)\) 를 최소화하는 Generator 는 \(p_g = p_{data}\) 일때 성립하고 이때 \(D = D_{G}^*(x) = 1/2\) 입니다.

+

이를 증명하자면, 최적화된 Discriminator 에 대한 손실함수는 다음과 같고

+
+\[ +V(D^{\ast},G) = \mathbb{E}_{x \sim p_{data}(x)} [ log D^{\ast}(x) ] + \mathbb{E}_{x \sim p_g(x)} [ log(1-D^{\ast}(x) ] +\]
+
+\[ += \int_x p_{data}(x)\ log(\frac{p_{data}(x)}{p_{data}(x) + p_g(x)}) + \int_x p_{g}(x)\ log(\frac{p_{g}(x)}{p_{data}(x) + p_g(x)})\ dx +\]
+
+\[ += -log(4)\ + KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) +\]
+

\(KL(p_{data}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) + KL(p_{g}(x)\ ||\ \frac{p_{data}+p_{g}}{2}) = 2\ \cdot\ JSD(p_{data}\ ||\ p_{g})\) 의 최솟값은 0 이고 이는 \(p_g = p_{data}\) 일때 성립합니다.

+
+
+
+

Experiments#

+

논문에서 MNIST, the Toronto Face Database(TFD), 그리고 CIFAR-10 dataset 로 모델 실험 및 성능 평가했습니다. 평가시에는 \(p_g\) 로부터 Parzen density estimation 을 거쳐 계산한 log likelihood estimate 로 모델 성능 평가를 진행했습니다.

+
+
+

Summary#

+

VAE는 새로운 데이터를 잘 생성하지만 생성된 이미지가 흐릿하다는 단점을 지니고 있습니다. 반면에 GAN 은 high quality image 를 잘 생성하지만 unstable 한 convergence 를 가지고 있습니다. 그래서 실제로 VAE 는 Encoder 를 활용한 차원축소로 많이 활용되고 이미지 데이터를 생성하는데는 GAN 이 많이 활용되었다고 합니다.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/imagen.html b/docs/review/imagen.html old mode 100644 new mode 100755 index fc3b1949..419fa52a --- a/docs/review/imagen.html +++ b/docs/review/imagen.html @@ -1,799 +1,806 @@ - - - - - - - - - - - - Imagen — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Information

-
    -
  • Title: Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding (NeurIPS 2022)

  • -
  • Reference

    - -
  • -
  • Author: Donggeun Sean Ko

  • -
  • Last updated on Sep. 13, 2023

  • -
-
-
-

Imagen#

-
-
-

Introduction#

-
    -
  • Multi-modal learning, 특히 text-to-image generation 에서 contrastive learning이 최근에 많은 주목을 받고 있음.

  • -
  • Contrastive learning 과 더불어 large language model (LLM) 들과 diffusion model 들을 사용하여 독창적인 image 생성도 가능함

  • -
  • 텍스트 전용 말뭉치 (text corpus)로 학습된 LLM들의 text embedding들은 text-to-image 합성에 매우 효과적이라고 함.

  • -
  • Classifier-free guidance 사용하여, 더 높은 충실도 (fidelity)의 이미지를 생성하는 새로운 샘플링 기술을 사용함.

  • -
-
-imagen_1 -
-

Fig. 166 Concept of Contrastive Learning#

-
-
-
-
-

Contributions#

-
    -
  1. Pretrained Frozen text encoder (T5-XXL) 이 text-to-image generation task 에 매우 좋은 성능을 보여줌.

  2. -
  3. Pretrained Text Encoder 사이즈를 fine-tuning하는 것이 diffusion model size fine tuning 하는 것보다 더 중요하다는 것을 실험적으로 증명함

  4. -
  5. Dynamic Thresholding 이라는 새로운 diffusion sampling technique (thresholding diffusion sampler) 을 제시하여 high guidance weight을 leverage 할 수 있게 만들어 더욱 “현실적인” 이미지 생성을 할 수 있음

  6. -
  7. Efficient U-Net이라는 기존 Palette 나 DDIM에서 사용하는 U-Net 구조보다 computational, memory efficient 한 U-Net 구조를 제시함

  8. -
  9. COCO FID 점수 7.27 SOTA 점수를 달성함

  10. -
  11. DrawBench라는 새로운 text-to-image generation evaluation용 benchmark dataset을 제시함

  12. -
-
-
-

Methodology#

-
-

Pretrained T5-XXL + Cascaded Diffusion Model#

-
    -
  • Pretrained Text Encoder 중 T5-XXL (구글 모델) 사용

  • -
  • 학습 시 pretrained text encoder을 Freeze 해놓음

  • -
  • Text-to-Image Diffusion Model (Improved DDPM 아키텍쳐) 사용해 64x64 image 생성

  • -
  • 2가지 SR model (Efficient U-Net)을 사용해서 64 → 256 → 1024 로 upsampling

  • -
-
-imagen_2 -
-

Fig. 167 Imagen overall pipeline#

-
-
-
-
-

Classifier-Free Guidance#

-
    -
  • Classifier-free guidance 이란 auxiliary classifier의 효과 없이 classifier guidance 효과를 얻는 방법

  • -
  • 아래의 그림처럼 guidance가 없을 시 image generation이 일정하지 않음. 즉, label/class 의 영향을 못받아서, 생성이 일정하지 않음.

  • -
  • guidance를 줄 시, 생성된 이미지의 class나 object이 일정하고 무엇을 생성하는것인지 좀 더 자세하게 알 수 있음.

  • -
-
-imagen_3 -
-

Fig. 168 Comparison between when guidance is not used (left) vs when guidance is used with parameter, w=3 (right)#

-
-
-
-
-

Large guidance weight sampler#

-
    -
  • Guide의 가중치 w 를 높이면 train-test 불일치가 생긴다.

  • -
  • 이로 인해, 높은 가중치의 이미지는 훈련 데이터 범위 안에 없어 [-1,1], classifier-free guidance가 평균과 분산을 이동시켜 이미지가 아예 “빗나가” 이상한 이미지를 생성하게 된다

  • -
-
-
-

Static Thresholding#

-
    -
  • x-prediction 을 [-1,1]로 clipping 한다. 여전히 saturation 이 되고 fidelity가 덜한 이미지가 생성 됌

  • -
  • 문제를 해결하고자 dynamic thresholding 을 제시함

  • -
-
-imagen_5 -
-

Fig. 169 Graphical visualization of static thresholding#

-
-
-
-
-

Dynamic Thresholding#

-
    -
  • 특정 백분위수 절대 픽셀 값을 s 라고 지정하고 s > 1 이면, 임계값을 [-s,s]로 지정한 다음 s로 나눈다.

  • -
  • 예시: 90% 지점의 픽셀 값이 3 이면 [-3,3]으로 clipping 한 후 3으로 나눠서 [-1,1] 로 normalize 함.

  • -
  • Thresholding 의 차이는 아래 결과 비교 이미지로 확인 할 수 있다.

  • -
-
-imagen_6 -
-

Fig. 170 Graphical visualization of dynamic thresholding#

-
-
-
-imagen_7 -
-

Fig. 171 Comparison among no thresholding, static thresholding and dynamic thresholding, respectively#

-
-
-
-
-

Super Resolution Models#

-
    -
  • Efficient U-Net이라는 새로운 모델을 만들어, 기존 U-Net에서 여러가지 modification을 하였다고 주장 (그렇지만 EffU-Net은 의료쪽으로 이름이 이미 있는걸로 아는데…)

  • -
  • Removed self-attention layer

  • -
  • Keep the text cross-attention layer

  • -
  • Skip connection scaling을 1/(√2)로 하여 convergence 를 더 빠르게 함

  • -
  • Lower resolution block에서 residual blocks를 더 추가함

  • -
-
-imagen_8 -
-

Fig. 172 Architecture of Super Resolution Diffusion Model used in Imagen#

-
-
-
-
-

DrawBench#

-
    -
  • Imagen 저자들이 제시한 새로운 벤치마크 데이터셋. 본 데이터셋은 text prompt 와 category label 로 이루어졌다

  • -
  • 깃허브에서 다운 받을 수 있으며, 예시는 아래 그림과 갗다 -11 categories, 200 text prompts -Human evaluation 으로 진행 (25명의 평가자) -Model A에서 생성한 이미지 set vs Model B에서 생성한 이미지 set

  • -
-

평가자는 2가지 질문을 주며 2가지 기준점으로 평가함 -Q1. Which set of images is of higher quality? -Q2. Which set of images better represents the text caption: {text caption}?

-

기준점

-
    -
  • Image Fidelity

  • -
  • Image-text alignment

  • -
-

평가자는 3가지 답변 중 하나를 선택해야함

-
    -
  1. I prefer set A

  2. -
  3. I am Indifferent

  4. -
  5. I prefer set B

  6. -
-
-imagen_9 -
-

Fig. 173 Screenshot of DrawBench dataset#

-
-
-
-
-
-

Results#

-
    -
  • Figure 2 에서는 DrawBench에서 나온 결과를 체리피킹 없이 보여준다.

  • -
  • 아마 저자들은 체리피킹 없이도 좋은 결과를 보여주고, 다양한 카테고리에서도 훌륭한 이미지를 생성 할 수 있다는 주장인 것 같다.

  • -
-
-imagen_10 -
-

Fig. 174 Result of Imagen in DrawBench dataset#

-
-
-
    -
  • Zero-shot 으로 한 FID값이 MS-COCO로 학습한 모델들 FID 보다 높음.

  • -
  • Table 2 에서는 Imagen이 no people (사람이 없는 사진) 에는 photorealism 점수가 올라감 -→ Imagen 은 photorealistic people을 생성하기에 한계가 있음.

  • -
-
-imagen_11 -
-

Fig. 175 Result Table of Imagen#

-
-
-
-

Qualitative Result Table of Imagen from Human Evaluators#

-
    -
  • Human raters (사람 평가자) 들은 T5-XXL로 text encoding 한 text-to-image generation 모델을 CLIP-based 보다 더 선호함

  • -
  • 기본적으로 Imagen 은 다른 text-to-image generation 모델에서 (SOTA 모델인 DALL-E 2) 보다도 human raters 에서 DrawBench 데이터셋에서 좋은 평가를 받음

  • -
-
-imagen_12 -
-

Fig. 176 Qualitative Result Table of Imagen from Human evaulators#

-
-
-
-
-
-

Ablation Study#

-
    -
  • Scaling text encoder size 가 U-Net size scaling 보다 더 중요함

  • -
  • (a)의 text encoder 사이즈의 변화가 FID 및 CLIP score 점수에 더욱 많은 영향을 끼침

  • -
  • Dynamic thresholding 이 performance boost에 더욱 영향을 끼침

  • -
  • Dynamic thresholding을 이용하면 성능을 더욱 끌어 올릴 수 있음

  • -
-
-imagen_13 -
-

Fig. 177 Qualitative Result Table of Imagen from Human evaulators#

-
-
-
-
-

Conclusion#

-
    -
  • Frozen large pretrained language model shows better performance over text-image paired multimodal encoders such as CLIP in text-to-image generation task

  • -
  • Efficient U-Net significantly improves performance time

  • -
  • Dynamic thresholding allows usage of much higher guidance weights with better fidelity of generated images

  • -
-
- - - - -
- - - - - - -
- - - - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Imagen — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + + + + + + +
+ +
+

Information

+
    +
  • Title: Photorealistic Text-to-Image Diffusion Models with Deep Language Understanding (NeurIPS 2022)

  • +
  • Reference

    + +
  • +
  • Author: Donggeun Sean Ko

  • +
  • Last updated on Sep. 13, 2023

  • +
+
+
+

Imagen#

+
+
+

Introduction#

+
    +
  • Multi-modal learning, 특히 text-to-image generation 에서 contrastive learning이 최근에 많은 주목을 받고 있음.

  • +
  • Contrastive learning 과 더불어 large language model (LLM) 들과 diffusion model 들을 사용하여 독창적인 image 생성도 가능함

  • +
  • 텍스트 전용 말뭉치 (text corpus)로 학습된 LLM들의 text embedding들은 text-to-image 합성에 매우 효과적이라고 함.

  • +
  • Classifier-free guidance 사용하여, 더 높은 충실도 (fidelity)의 이미지를 생성하는 새로운 샘플링 기술을 사용함.

  • +
+
+imagen_1 +
+

Fig. 166 Concept of Contrastive Learning#

+
+
+
+
+

Contributions#

+
    +
  1. Pretrained Frozen text encoder (T5-XXL) 이 text-to-image generation task 에 매우 좋은 성능을 보여줌.

  2. +
  3. Pretrained Text Encoder 사이즈를 fine-tuning하는 것이 diffusion model size fine tuning 하는 것보다 더 중요하다는 것을 실험적으로 증명함

  4. +
  5. Dynamic Thresholding 이라는 새로운 diffusion sampling technique (thresholding diffusion sampler) 을 제시하여 high guidance weight을 leverage 할 수 있게 만들어 더욱 “현실적인” 이미지 생성을 할 수 있음

  6. +
  7. Efficient U-Net이라는 기존 Palette 나 DDIM에서 사용하는 U-Net 구조보다 computational, memory efficient 한 U-Net 구조를 제시함

  8. +
  9. COCO FID 점수 7.27 SOTA 점수를 달성함

  10. +
  11. DrawBench라는 새로운 text-to-image generation evaluation용 benchmark dataset을 제시함

  12. +
+
+
+

Methodology#

+
+

Pretrained T5-XXL + Cascaded Diffusion Model#

+
    +
  • Pretrained Text Encoder 중 T5-XXL (구글 모델) 사용

  • +
  • 학습 시 pretrained text encoder을 Freeze 해놓음

  • +
  • Text-to-Image Diffusion Model (Improved DDPM 아키텍쳐) 사용해 64x64 image 생성

  • +
  • 2가지 SR model (Efficient U-Net)을 사용해서 64 → 256 → 1024 로 upsampling

  • +
+
+imagen_2 +
+

Fig. 167 Imagen overall pipeline#

+
+
+
+
+

Classifier-Free Guidance#

+
    +
  • Classifier-free guidance 이란 auxiliary classifier의 효과 없이 classifier guidance 효과를 얻는 방법

  • +
  • 아래의 그림처럼 guidance가 없을 시 image generation이 일정하지 않음. 즉, label/class 의 영향을 못받아서, 생성이 일정하지 않음.

  • +
  • guidance를 줄 시, 생성된 이미지의 class나 object이 일정하고 무엇을 생성하는것인지 좀 더 자세하게 알 수 있음.

  • +
+
+imagen_3 +
+

Fig. 168 Comparison between when guidance is not used (left) vs when guidance is used with parameter, w=3 (right)#

+
+
+
+
+

Large guidance weight sampler#

+
    +
  • Guide의 가중치 w 를 높이면 train-test 불일치가 생긴다.

  • +
  • 이로 인해, 높은 가중치의 이미지는 훈련 데이터 범위 안에 없어 [-1,1], classifier-free guidance가 평균과 분산을 이동시켜 이미지가 아예 “빗나가” 이상한 이미지를 생성하게 된다

  • +
+
+
+

Static Thresholding#

+
    +
  • x-prediction 을 [-1,1]로 clipping 한다. 여전히 saturation 이 되고 fidelity가 덜한 이미지가 생성 됌

  • +
  • 문제를 해결하고자 dynamic thresholding 을 제시함

  • +
+
+imagen_5 +
+

Fig. 169 Graphical visualization of static thresholding#

+
+
+
+
+

Dynamic Thresholding#

+
    +
  • 특정 백분위수 절대 픽셀 값을 s 라고 지정하고 s > 1 이면, 임계값을 [-s,s]로 지정한 다음 s로 나눈다.

  • +
  • 예시: 90% 지점의 픽셀 값이 3 이면 [-3,3]으로 clipping 한 후 3으로 나눠서 [-1,1] 로 normalize 함.

  • +
  • Thresholding 의 차이는 아래 결과 비교 이미지로 확인 할 수 있다.

  • +
+
+imagen_6 +
+

Fig. 170 Graphical visualization of dynamic thresholding#

+
+
+
+imagen_7 +
+

Fig. 171 Comparison among no thresholding, static thresholding and dynamic thresholding, respectively#

+
+
+
+
+

Super Resolution Models#

+
    +
  • Efficient U-Net이라는 새로운 모델을 만들어, 기존 U-Net에서 여러가지 modification을 하였다고 주장 (그렇지만 EffU-Net은 의료쪽으로 이름이 이미 있는걸로 아는데…)

  • +
  • Removed self-attention layer

  • +
  • Keep the text cross-attention layer

  • +
  • Skip connection scaling을 1/(√2)로 하여 convergence 를 더 빠르게 함

  • +
  • Lower resolution block에서 residual blocks를 더 추가함

  • +
+
+imagen_8 +
+

Fig. 172 Architecture of Super Resolution Diffusion Model used in Imagen#

+
+
+
+
+

DrawBench#

+
    +
  • Imagen 저자들이 제시한 새로운 벤치마크 데이터셋. 본 데이터셋은 text prompt 와 category label 로 이루어졌다

  • +
  • 깃허브에서 다운 받을 수 있으며, 예시는 아래 그림과 갗다 +11 categories, 200 text prompts +Human evaluation 으로 진행 (25명의 평가자) +Model A에서 생성한 이미지 set vs Model B에서 생성한 이미지 set

  • +
+

평가자는 2가지 질문을 주며 2가지 기준점으로 평가함 +Q1. Which set of images is of higher quality? +Q2. Which set of images better represents the text caption: {text caption}?

+

기준점

+
    +
  • Image Fidelity

  • +
  • Image-text alignment

  • +
+

평가자는 3가지 답변 중 하나를 선택해야함

+
    +
  1. I prefer set A

  2. +
  3. I am Indifferent

  4. +
  5. I prefer set B

  6. +
+
+imagen_9 +
+

Fig. 173 Screenshot of DrawBench dataset#

+
+
+
+
+
+

Results#

+
    +
  • Figure 2 에서는 DrawBench에서 나온 결과를 체리피킹 없이 보여준다.

  • +
  • 아마 저자들은 체리피킹 없이도 좋은 결과를 보여주고, 다양한 카테고리에서도 훌륭한 이미지를 생성 할 수 있다는 주장인 것 같다.

  • +
+
+imagen_10 +
+

Fig. 174 Result of Imagen in DrawBench dataset#

+
+
+
    +
  • Zero-shot 으로 한 FID값이 MS-COCO로 학습한 모델들 FID 보다 높음.

  • +
  • Table 2 에서는 Imagen이 no people (사람이 없는 사진) 에는 photorealism 점수가 올라감 +→ Imagen 은 photorealistic people을 생성하기에 한계가 있음.

  • +
+
+imagen_11 +
+

Fig. 175 Result Table of Imagen#

+
+
+
+

Qualitative Result Table of Imagen from Human Evaluators#

+
    +
  • Human raters (사람 평가자) 들은 T5-XXL로 text encoding 한 text-to-image generation 모델을 CLIP-based 보다 더 선호함

  • +
  • 기본적으로 Imagen 은 다른 text-to-image generation 모델에서 (SOTA 모델인 DALL-E 2) 보다도 human raters 에서 DrawBench 데이터셋에서 좋은 평가를 받음

  • +
+
+imagen_12 +
+

Fig. 176 Qualitative Result Table of Imagen from Human evaulators#

+
+
+
+
+
+

Ablation Study#

+
    +
  • Scaling text encoder size 가 U-Net size scaling 보다 더 중요함

  • +
  • (a)의 text encoder 사이즈의 변화가 FID 및 CLIP score 점수에 더욱 많은 영향을 끼침

  • +
  • Dynamic thresholding 이 performance boost에 더욱 영향을 끼침

  • +
  • Dynamic thresholding을 이용하면 성능을 더욱 끌어 올릴 수 있음

  • +
+
+imagen_13 +
+

Fig. 177 Qualitative Result Table of Imagen from Human evaulators#

+
+
+
+
+

Conclusion#

+
    +
  • Frozen large pretrained language model shows better performance over text-image paired multimodal encoders such as CLIP in text-to-image generation task

  • +
  • Efficient U-Net significantly improves performance time

  • +
  • Dynamic thresholding allows usage of much higher guidance weights with better fidelity of generated images

  • +
+
+ + + + +
+ + + + + + + + +
+ + + + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/imagen_editor.html b/docs/review/imagen_editor.html old mode 100644 new mode 100755 index d68a3404..10fd092e --- a/docs/review/imagen_editor.html +++ b/docs/review/imagen_editor.html @@ -1,584 +1,591 @@ - - - - - - - - - - - - Imagen Editor — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Imagen Editor

- -
-
- -
-
-
- - - - -
- -
-

Information

-
    -
  • Title: Imagen Editor and EditBench: Advancing and Evaluating Text-Guided Image Inpainting (CVPR 2023)

  • -
  • Reference

    - -
  • -
  • Author: Sangwoo Jo

  • -
  • Last updated on Sep. 06, 2023

  • -
-
-
-

Imagen Editor#

-

이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다.

-

Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다.

-
-imagen_editor_01 -
-

Fig. 178 Effect of Object Masking#

-
-
-

Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다.

-
-imagen_editor_02 -
-

Fig. 179 Imagen Editor Architecture#

-
-
-

Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다.

-

논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다.

-

EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, attribute-object-scene 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다.

-
    -
  • Attributes (material, color, shape, size, count)

  • -
  • Objects (common, rare, text rendering)

  • -
  • Scenes (indoor, outdoor, realistic, paintings)

  • -
-

예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 Mask-Simple, Mask-Rich, 그리고 Full 로 정의합니다.

-
-imagen_editor_03 -
-

Fig. 180 EditBench example#

-
-
-

데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다.

-
-imagen_editor_04 -
-

Fig. 181 Human Evaluations on EditBench#

-
-
-

또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다.

-
-imagen_editor_05 -
-

Fig. 182 Imagen Editor failure cases by attribute#

-
-
-

마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다.

-
-imagen_editor_06 -
-

Fig. 183 Example model outputs for Mask-Simple vs MaskRich prompts#

-
-
-
- - - - -
- - - - - - -
- - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + Imagen Editor — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

Imagen Editor

+ +
+
+ +
+
+
+ + + + +
+ +
+

Information

+
    +
  • Title: Imagen Editor and EditBench: Advancing and Evaluating Text-Guided Image Inpainting (CVPR 2023)

  • +
  • Reference

    + +
  • +
  • Author: Sangwoo Jo

  • +
  • Last updated on Sep. 06, 2023

  • +
+
+
+

Imagen Editor#

+

이번 시간에는 Google Research 에서 소개하는 Imagen 모델 기반의 text-guided image inpainting 모델 Imagen Editor 와 text-guided impainting 의 평가기법 EditBench 에 대해 알아볼 예정입니다.

+

Text-guided image inpainting 에서 기존에는 mask 영역을 random 하게 지정하여 학습을 진행했습니다. 이는 입력된 text prompt 와 무관한 영역을 masking 하게 됨으로써 모델이 prompt 를 참조하지 않고 오로지 image content 만으로 학습하게 되는 현상이 발생합니다. Imagen Editor 는 이를 해결하기 위해 Object Masking 기법을 소개합니다. Prompt 에 해당하는 객체 전체를 masking 함으로써 모델이 text prompt 를 더 참조할 수 있도록 유도하는 것이 목표입니다. SSD MobileNet v2 모델을 Object Detector 로 사용함으로써 모델 성능이 크게 개선되는 부분을 확인할 수 있었다고 합니다.

+
+imagen_editor_01 +
+

Fig. 178 Effect of Object Masking#

+
+
+

Imagen Editor 에서 또 다른 특징은 Imagen 모델 기반의 cascaded diffusion model architecture 를 지니고 있다는 점입니다. 이때, SR3, Palette, GLIDE 와 유사하게 이미지와 mask 가 Encoder 를 거친 후, diffusion latent 와 concatenate 하면서 conditioning input 으로 들어가게 되며, 모두 1024x1024 해상도를 가진다고 합니다. 따라서, base diffusion 64x64 모델 그리고 64x64 → 256x256 super resolution 모델에 입력 시, downsampling 작업 후 모델 input 으로 입력합니다. 또한, conditioning 이미지와 mask 없을 시 Imagen 모델을 사용하는 것과 동일한 효과를 내기 위해, 새로 추가되는 input channel weights 는 0으로 초기화해서 학습을 진행했다고 소개합니다.

+
+imagen_editor_02 +
+

Fig. 179 Imagen Editor Architecture#

+
+
+

Imagen 에서 소개되었던 Classifier-Free Guidance 를 동일하게 사용하고, 이때 guidance weight 를 1부터 30 까지 범위 내에서 변화시키는 oscillating guidance 기법을 적용함으로써 생성된 이미지 퀄리티 및 text-image alignment 가 상승되는 효과를 볼 수 있었다고 합니다.

+

논문에서는 Imagen Editor 와 같은 text-guided image inpainting 모델들을 평가할 수 있는 새로운 benchmark EditBench 를 제시합니다. 240개의 (image, mask) 쌍으로 데이터셋이 구축되어있고, 각 쌍마다 3가지의 prompt 로 생성된 이미지로 사람이 모델 성능을 측정하게 됩니다. Automatic Evaluation Metric 으로는 CLIPScore, 그리고 CLIP-R-Prec 를 사용했습니다.

+

EditBench 이미지 데이터셋의 절반은 open source 로 공개된 computer vision 데이터셋으로부터 수집되었고, 나머지 절반은 text-to-image 모델로 생성해서 구축했습니다. 이때, attribute-object-scene 의 요소들을 모두 갖추도록 이미지들을 수집 및 생성했습니다.

+
    +
  • Attributes (material, color, shape, size, count)

  • +
  • Objects (common, rare, text rendering)

  • +
  • Scenes (indoor, outdoor, realistic, paintings)

  • +
+

예를 들어서, ‘a=metal|o=cat|s=outdoor’ 요소들을 포함하는 문구를 ‘a metal cat standing in the middle of a farm field’ 처럼 생성하는 것입니다. 앞써 언급한 3가지 prompt 는 해당사진처럼 Mask-Simple, Mask-Rich, 그리고 Full 로 정의합니다.

+
+imagen_editor_03 +
+

Fig. 180 EditBench example#

+
+
+

데이터셋 구축시, mask 크기도 다양하게 설정하여 mask 크기에 따른 모델 성능도 확인할 수 있었습니다. 성능을 측정해본 결과, Object masking 으로 학습한 모델이 random masking 으로 학습한 모델보다 small/medium masks 에서 성능적으로 월등히 좋다는 것을 확인할 수 있습니다.

+
+imagen_editor_04 +
+

Fig. 181 Human Evaluations on EditBench#

+
+
+

또한, object-rendering 에 비해 text-rendering 성능이 저하되는 부분을 확인할 수 있고, material/color/size 속성보다 count/size 속성에 더 취약한 부분도 확인할 수 있었습니다.

+
+imagen_editor_05 +
+

Fig. 182 Imagen Editor failure cases by attribute#

+
+
+

마지막으로, 동일한 prompt 에 대해 Stable Diffusion, DALL-E2, Imagen Editor 모델로 inpainting 한 결과를 비교한 예시 사진입니다.

+
+imagen_editor_06 +
+

Fig. 183 Example model outputs for Mask-Simple vs MaskRich prompts#

+
+
+
+ + + + +
+ + + + + + + + +
+ + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/docs/review/vae.html b/docs/review/vae.html old mode 100644 new mode 100755 index 234fd8c6..3b8acd37 --- a/docs/review/vae.html +++ b/docs/review/vae.html @@ -1,679 +1,687 @@ - - - - - - - - - - - - VAE — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

VAE

- -
- -
-
- - - - -
- -
-

Information

- -
-
-

VAE#

-
-

Introduction#

-

논문의 Introduction 에 다음과 같은 문구가 적혀있는데요.

-
-

“Variational Bayesian (VB) approach involves the optimization of an approximation to the intractable posterior”

-
-

이처럼 Variational Autoencoder 는 논문에서 제시하는 Auto-Encoding Variational Bayes(AEVB) 알고리즘 중 하나로, intractable 한 posterior 분포를 다루기 쉬운 뉴럴 네트워크로 근사함으로써 Variational Inference 를 하게 됩니다.

-

이가 의미하는 바가 무엇인지 한번 살펴보도록 하겠습니다.

-
-
-

Intractability#

-

Variational Autoencoder(VAE) 는 크게 Encoder 와 Decoder 부분으로 이루어져 있습니다. 더 자세하게는, Encoder는 입력 데이터 \(x\) 를 받아서 잠재변수(Latent Variable) \(z\) 를 만들어내고, Decoder 는 잠재변수 \(z\) 를 활용해서 다시 \(x\) 를 복원하게 됩니다.

-
-vae_01 -
-

Fig. 1 Variational Autoencoder(VAE) Architecture#

-
-
-

Variational Autoencoder (VAE) 는 AutoEncoder 와 달리 확률 분포를 이용해 어떤 새로운 데이터를 생성하는 Decoder 부분에 초점을 둡니다. 이때 논문에서 다음과 같은 assumption 들을 내립니다. 첫번째로 \(p_{\theta}(z)\)\(p_{\theta}(x|z)\) 는 parametric 한 distribution 을 가지고 있고, 이는 \(\theta\)\(z\) 에 대해 differentiable 하다는 가정을 내립니다. 이 때, 대표적으로 \(p_{\theta}(z)\) 는 Gaussian distribution 을 따르고 \(p_{\theta}(x|z)\) 는 생성하고자 하는 데이터 성질에 따라 Bernoulli 혹은 Gaussian distribution 을 따르도록 정의합니다. 그리고 \(p_{\theta}(x|z)\) 의 파라미터 \(p\) 혹은 \((\mu, \sigma)\) 는 아래 그림과 같이 뉴럴 네트워크로 구성된 Decoder 로부터 계산이 됩니다.

-
-vae_07 -
-

Fig. 2 Overview of Bernoulli(left) and Gaussian(right) Decoder#

-
-
-

이를 기반으로 우리는 ML/MAP estimation 을 통해 marginal likelihood \(p_{\theta}(x)\) 를 최대화시키는 파라미터 \(\theta\) 를 구하는 것이 목적입니다. 하지만, \(p_{\theta}(x) = \int p_{\theta}(z)p_{\theta}(x|z) \ dz\) 는 intractable 하기 때문에 \(p_{\theta}(z|x)\) 를 계산하기 위한 Encoder 가 등장하게 됩니다.

-
-\[ -p_{\theta}(x) = p_{\theta}(x|z)p_{\theta}(z)/p_{\theta}(z|x) -\]
-

여기서 \(p_{\theta}(z|x)\) 역시 intractable 하기 때문에 이를 잘 근사화하는 뉴럴 네트워크 \(q_{\phi}(z|x)\) 를 정의하게 되고, 이러한 과정을 변분추론(Variational Inference) 라고 합니다. 아래는 Encoder 와 Decoder 를 함께 도식화한 그림입니다. 정리하자면, MLP Encoder 를 통해 계산된 \(\mu\)\(\sigma\) 로 잠재변수 \(z\) 를 생성하게 되고, 이를 기반으로 Decoder 는 원본 이미지와 유사한 데이터를 생성하게 됩니다.

-
-vae_08 -
-

Fig. 3 Overview of Gaussian Encoder and Decoder#

-
-
-

해당 implementation code 도 확인해보겠습니다.

-
    -
  • Encoder 구현 code

    -
    
    -class Encoder(nn.Module):
    -    def __init__(self):
    -        super(Encoder,self).__init__()
    -        self.fc1_1 = nn.Linear(784, hidden_size)
    -        self.fc1_2 = nn.Linear(784, hidden_size)
    -        self.relu = nn.ReLU()
    -                        
    -    def encode(self,x):
    -        x = x.view(batch_size,-1)
    -        mu = self.relu(self.fc1_1(x))
    -        log_var = self.relu(self.fc1_2(x))
    -                
    -        return mu,log_var
    -    
    -    def reparametrize(self, mu, logvar):
    -        std = logvar.mul(0.5).exp_()
    -        
    -        eps = torch.FloatTensor(std.size()).normal_()
    -        eps = Variable(eps).cuda()
    -        
    -        return eps.mul(std).add_(mu)
    -    
    -    def forward(self,x):
    -        mu, logvar = self.encode(x)
    -        reparam = self.reparametrize(mu,logvar)
    -        
    -        return mu,logvar,reparam
    -
    -
    -
  • -
  • Decoder 구현 code

    -
    class Decoder(nn.Module):
    -    def __init__(self):
    -        super(Decoder,self).__init__()
    -        self.fc1 = nn.Linear(hidden_size, 784)
    -        self.sigmoid = nn.Sigmoid()
    -    
    -    def forward(self,x):
    -        out = self.fc1(x)
    -        out = self.sigmoid(out)
    -        out = out.view(batch_size,28,28,1)
    -        
    -        return out
    -
    -
    -
  • -
-

이로써 우리는 marginal likelihood \(p_{\theta}(x)\) 를 최대화시키는 파라미터 \((\theta, \phi)\) 를 찾으면 되고, 수식적으로 표현하면 손실함수(loss function) 를 다음과 같이 Reconstruction Error 와 Regularization term 로 분할할 수 있습니다.

-
-\[ -L(\theta, \phi;x_i) = \arg \min_{\theta, \phi} \sum_{i} -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] + KL(q_{\phi}(z|x_i)||p(z)) -\]
-

Reconstruction Error 는 Decoder 에서 생성하는 데이터가 최대한 원본 데이터와 유사하도록 하는 term 이고, Regularization 은 Encoder 에서 만드는 잠재변수의 분포가 저희가 부여한 prior distribution 이랑 가깝도록 설정하는 term 입니다. 이때, Reconstruction Error 는 Monte Carlo 기법으로 근사값을 구할 수 있고, 하나의 sample 을 계산하는 것도 연산량이 많으므로 논문에서는 sample size \(L\) 을 1 로 설정합니다.

-
-\[ -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] = \int log(p_{\theta}(x_i|z))q_{\phi}(z|x_i)dz \approx \frac{1}{L}\sum_{z^{i,l}} log(p_{\theta}(x_i|z^{i,l})) -\]
-
-
-

Reparameterization Trick#

-

마지막으로 소개하는 기법은 reparameterization trick 입니다. 잠재변수 \(z\) 를 Encoder 에서 나온 \(\mu\)\(\sigma\) 로 직접 샘플링하지 않고, backpropagation 이 가능하도록 Gaussian noise 를 우선적으로 샘플링하고 해당 \(\mu\)\(\sigma\) 를 각각 더하고 곱하게 됩니다. 이는 \(q_{\phi}(z|x)\) 이 Gaussian distribution 을 따른다고 설정했을 때이고, \(q_{\phi}(z|x)\) 에 대해 다른 분포를 가정할 때 그리고 그에 따른 다른 reparameterization trick 을 시도할 수 있다고 논문에 명시되어 있습니다.

-
-vae_05 -
-

Fig. 4 Overview of Reparameterization Trick#

-
-
-
-
-

Summary#

-

AutoEncoder 는 latent space 에 하나의 값으로 지정해줬다면, VAE 는 평균 그리고 분산 파라미터들과 Gaussian 분포를 가진 샘플을 통해 잠재변수를 생성합니다. 그리고 VAE 를 실제로 사용해보면 생성된 데이터 image quality 가 낮다는 단점을 가지고 있다고 합니다.

-
-
- - - - -
- - - - - - -
- - - -
- - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + VAE — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

VAE

+ +
+ +
+
+ + + + +
+ +
+

Information

+ +
+
+

VAE#

+
+

Introduction#

+

논문의 Introduction 에 다음과 같은 문구가 적혀있는데요.

+
+

“Variational Bayesian (VB) approach involves the optimization of an approximation to the intractable posterior”

+
+

이처럼 Variational Autoencoder 는 논문에서 제시하는 Auto-Encoding Variational Bayes(AEVB) 알고리즘 중 하나로, intractable 한 posterior 분포를 다루기 쉬운 뉴럴 네트워크로 근사함으로써 Variational Inference 를 하게 됩니다.

+

이가 의미하는 바가 무엇인지 한번 살펴보도록 하겠습니다.

+
+
+

Intractability#

+

Variational Autoencoder(VAE) 는 크게 Encoder 와 Decoder 부분으로 이루어져 있습니다. 더 자세하게는, Encoder는 입력 데이터 \(x\) 를 받아서 잠재변수(Latent Variable) \(z\) 를 만들어내고, Decoder 는 잠재변수 \(z\) 를 활용해서 다시 \(x\) 를 복원하게 됩니다.

+
+vae_01 +
+

Fig. 1 Variational Autoencoder(VAE) Architecture#

+
+
+

Variational Autoencoder (VAE) 는 AutoEncoder 와 달리 확률 분포를 이용해 어떤 새로운 데이터를 생성하는 Decoder 부분에 초점을 둡니다. 이때 논문에서 다음과 같은 assumption 들을 내립니다. 첫번째로 \(p_{\theta}(z)\)\(p_{\theta}(x|z)\) 는 parametric 한 distribution 을 가지고 있고, 이는 \(\theta\)\(z\) 에 대해 differentiable 하다는 가정을 내립니다. 이 때, 대표적으로 \(p_{\theta}(z)\) 는 Gaussian distribution 을 따르고 \(p_{\theta}(x|z)\) 는 생성하고자 하는 데이터 성질에 따라 Bernoulli 혹은 Gaussian distribution 을 따르도록 정의합니다. 그리고 \(p_{\theta}(x|z)\) 의 파라미터 \(p\) 혹은 \((\mu, \sigma)\) 는 아래 그림과 같이 뉴럴 네트워크로 구성된 Decoder 로부터 계산이 됩니다.

+
+vae_07 +
+

Fig. 2 Overview of Bernoulli(left) and Gaussian(right) Decoder#

+
+
+

이를 기반으로 우리는 ML/MAP estimation 을 통해 marginal likelihood \(p_{\theta}(x)\) 를 최대화시키는 파라미터 \(\theta\) 를 구하는 것이 목적입니다. 하지만, \(p_{\theta}(x) = \int p_{\theta}(z)p_{\theta}(x|z) \ dz\) 는 intractable 하기 때문에 \(p_{\theta}(z|x)\) 를 계산하기 위한 Encoder 가 등장하게 됩니다.

+
+\[ +p_{\theta}(x) = p_{\theta}(x|z)p_{\theta}(z)/p_{\theta}(z|x) +\]
+

여기서 \(p_{\theta}(z|x)\) 역시 intractable 하기 때문에 이를 잘 근사화하는 뉴럴 네트워크 \(q_{\phi}(z|x)\) 를 정의하게 되고, 이러한 과정을 변분추론(Variational Inference) 라고 합니다. 아래는 Encoder 와 Decoder 를 함께 도식화한 그림입니다. 정리하자면, MLP Encoder 를 통해 계산된 \(\mu\)\(\sigma\) 로 잠재변수 \(z\) 를 생성하게 되고, 이를 기반으로 Decoder 는 원본 이미지와 유사한 데이터를 생성하게 됩니다.

+
+vae_08 +
+

Fig. 3 Overview of Gaussian Encoder and Decoder#

+
+
+

해당 implementation code 도 확인해보겠습니다.

+
    +
  • Encoder 구현 code

    +
    
    +class Encoder(nn.Module):
    +    def __init__(self):
    +        super(Encoder,self).__init__()
    +        self.fc1_1 = nn.Linear(784, hidden_size)
    +        self.fc1_2 = nn.Linear(784, hidden_size)
    +        self.relu = nn.ReLU()
    +                        
    +    def encode(self,x):
    +        x = x.view(batch_size,-1)
    +        mu = self.relu(self.fc1_1(x))
    +        log_var = self.relu(self.fc1_2(x))
    +                
    +        return mu,log_var
    +    
    +    def reparametrize(self, mu, logvar):
    +        std = logvar.mul(0.5).exp_()
    +        
    +        eps = torch.FloatTensor(std.size()).normal_()
    +        eps = Variable(eps).cuda()
    +        
    +        return eps.mul(std).add_(mu)
    +    
    +    def forward(self,x):
    +        mu, logvar = self.encode(x)
    +        reparam = self.reparametrize(mu,logvar)
    +        
    +        return mu,logvar,reparam
    +
    +
    +
  • +
  • Decoder 구현 code

    +
    class Decoder(nn.Module):
    +    def __init__(self):
    +        super(Decoder,self).__init__()
    +        self.fc1 = nn.Linear(hidden_size, 784)
    +        self.sigmoid = nn.Sigmoid()
    +    
    +    def forward(self,x):
    +        out = self.fc1(x)
    +        out = self.sigmoid(out)
    +        out = out.view(batch_size,28,28,1)
    +        
    +        return out
    +
    +
    +
  • +
+

이로써 우리는 marginal likelihood \(p_{\theta}(x)\) 를 최대화시키는 파라미터 \((\theta, \phi)\) 를 찾으면 되고, 수식적으로 표현하면 손실함수(loss function) 를 다음과 같이 Reconstruction Error 와 Regularization term 로 분할할 수 있습니다.

+
+\[ +L(\theta, \phi;x_i) = \arg \min_{\theta, \phi} \sum_{i} -\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] + KL(q_{\phi}(z|x_i)||p(z)) +\]
+

Reconstruction Error 는 Decoder 에서 생성하는 데이터가 최대한 원본 데이터와 유사하도록 하는 term 이고, Regularization 은 Encoder 에서 만드는 잠재변수의 분포가 저희가 부여한 prior distribution 이랑 가깝도록 설정하는 term 입니다. 이때, Reconstruction Error 는 Monte Carlo 기법으로 근사값을 구할 수 있고, 하나의 sample 을 계산하는 것도 연산량이 많으므로 논문에서는 sample size \(L\) 을 1 로 설정합니다.

+
+\[ +\mathbb{E}_{q_{\phi}(z|x_i)}[log(p(x_i|g_{\theta}(z))] = \int log(p_{\theta}(x_i|z))q_{\phi}(z|x_i)dz \approx \frac{1}{L}\sum_{z^{i,l}} log(p_{\theta}(x_i|z^{i,l})) +\]
+
+
+

Reparameterization Trick#

+

마지막으로 소개하는 기법은 reparameterization trick 입니다. 잠재변수 \(z\) 를 Encoder 에서 나온 \(\mu\)\(\sigma\) 로 직접 샘플링하지 않고, backpropagation 이 가능하도록 Gaussian noise 를 우선적으로 샘플링하고 해당 \(\mu\)\(\sigma\) 를 각각 더하고 곱하게 됩니다. 이는 \(q_{\phi}(z|x)\) 이 Gaussian distribution 을 따른다고 설정했을 때이고, \(q_{\phi}(z|x)\) 에 대해 다른 분포를 가정할 때 그리고 그에 따른 다른 reparameterization trick 을 시도할 수 있다고 논문에 명시되어 있습니다.

+
+vae_05 +
+

Fig. 4 Overview of Reparameterization Trick#

+
+
+
+
+

Summary#

+

AutoEncoder 는 latent space 에 하나의 값으로 지정해줬다면, VAE 는 평균 그리고 분산 파라미터들과 Gaussian 분포를 가진 샘플을 통해 잠재변수를 생성합니다. 그리고 VAE 를 실제로 사용해보면 생성된 데이터 image quality 가 낮다는 단점을 가지고 있다고 합니다.

+
+
+ + + + +
+ + + + + + + + +
+ + + +
+ + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/genindex.html b/genindex.html old mode 100644 new mode 100755 index 02402c38..8c19f9c9 --- a/genindex.html +++ b/genindex.html @@ -1,435 +1,442 @@ - - - - - - - - - - - Index — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

- -
-
- -
-
-
- - - - -
- - -

Index

- -
- -
- - -
- - - - -
- -
- -
-
-
- -
- -
- -
- - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + Index — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

+ +
+
+ +
+
+
+ + + + +
+ + +

Index

+ +
+ +
+ + +
+ + + + + + +
+ +
+
+
+ +
+ + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/index.html b/index.html old mode 100644 new mode 100755 index de49afb2..4ade9deb --- a/index.html +++ b/index.html @@ -1,2 +1,2 @@ - - + + diff --git a/intro.html b/intro.html old mode 100644 new mode 100755 index fa53cd6d..1c7f25dd --- a/intro.html +++ b/intro.html @@ -1,519 +1,526 @@ - - - - - - - - - - - - [PseudoLab] Text-to-Image Generation (feat. Diffusion) — Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

[PseudoLab] Text-to-Image Generation (feat. Diffusion)

- -
-
- -
-
-
- - - - -
- -
-

[PseudoLab] Text-to-Image Generation (feat. Diffusion)#

-

This is the repository of Pseudo Lab’s Text-to-Image Generation (feat. Diffusion) team.

-

:bulb: Our aim is to review papers and code related to image generation and text-to-image generation models, approach them theoretically, and conduct various experiments by fine-tuning diffusion based models.

-

About Us - Pseudo Lab

-

About Us - Text-to-Image Generation (feat. Diffusion) Team

-

참여 방법: 매주 수요일 오후 9시, 가짜연구소 Discord Room-DH 로 입장!

-
-
-
-
-
- - - - -
- - - - - - -
- - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + + + [PseudoLab] Text-to-Image Generation (feat. Diffusion) — Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + + +
+

[PseudoLab] Text-to-Image Generation (feat. Diffusion)

+ +
+
+ +
+
+
+ + + + +
+ +
+

[PseudoLab] Text-to-Image Generation (feat. Diffusion)#

+

This is the repository of Pseudo Lab’s Text-to-Image Generation (feat. Diffusion) team.

+

:bulb: Our aim is to review papers and code related to image generation and text-to-image generation models, approach them theoretically, and conduct various experiments by fine-tuning diffusion based models.

+

About Us - Pseudo Lab

+

About Us - Text-to-Image Generation (feat. Diffusion) Team

+

참여 방법: 매주 수요일 오후 9시, 가짜연구소 Discord Room-DH 로 입장!

+
+
+
+
+
+ + + + +
+ + + + + + + + +
+ + + + +
+
+ + +
+ + +
+
+
+ + + + + +
+
+ \ No newline at end of file diff --git a/objects.inv b/objects.inv old mode 100644 new mode 100755 index 122aa932..d55282c0 Binary files a/objects.inv and b/objects.inv differ diff --git a/search.html b/search.html old mode 100644 new mode 100755 index 1ae45998..50df4ce8 --- a/search.html +++ b/search.html @@ -1,447 +1,454 @@ - - - - - - - - - - Search - Text-to-Image Generation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- - - -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - -
- -
- -
-
- - -
-

Search

- - - -
-
- - - - -
- -
- -
-
-
- -
- -
- -
- - - - -
-
- - -
- - -
-
-
- - - - - -
-
- + + + + + + + + + + Search - Text-to-Image Generation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+ +
+ +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+

Search

+ + + +
+
+ + + + + + +
+ +
+
+
+ +
+ + + + +
+
+ + +
+ + +
+
+
+ + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js old mode 100644 new mode 100755 index 0ab5442e..adbf122a --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({"docnames": ["docs/experiments/js_exp", "docs/experiments/swjo_exp", "docs/review/ControlNet", "docs/review/CustomDiffusion", "docs/review/DDIM", "docs/review/DDPM", "docs/review/I-DDPM", "docs/review/Latent_Diffusion_Model", "docs/review/LoRA", "docs/review/StyO", "docs/review/StyleGAN", "docs/review/Textual_Inversion", "docs/review/cycleGAN", "docs/review/dalle", "docs/review/diffusion_beats_GANs", "docs/review/dreambooth", "docs/review/gan", "docs/review/imagen", "docs/review/imagen_editor", "docs/review/vae", "intro"], "filenames": ["docs/experiments/js_exp.md", "docs/experiments/swjo_exp.md", "docs/review/ControlNet.md", "docs/review/CustomDiffusion.md", "docs/review/DDIM.md", "docs/review/DDPM.md", "docs/review/I-DDPM.md", "docs/review/Latent_Diffusion_Model.md", "docs/review/LoRA.md", "docs/review/StyO.md", "docs/review/StyleGAN.md", "docs/review/Textual_Inversion.md", "docs/review/cycleGAN.md", "docs/review/dalle.md", "docs/review/diffusion_beats_GANs.md", "docs/review/dreambooth.md", "docs/review/gan.md", "docs/review/imagen.md", "docs/review/imagen_editor.md", "docs/review/vae.md", "intro.md"], "titles": ["Synthetic Data with Stable Diffusion for Foliar Disease Classification", "Training DreamBooth on Naver Webtoon Face Dataset", "ControlNet", "Custom Diffusion", "DDIM", "DDPM", "I-DDPM", "Latent Diffusion Model", "LoRA", "StyO", "StyleGAN", "Textual Inversion", "CycleGAN", "DALL-E", "Diffusion Models Beat GANs on Image Synthesis", "DreamBooth", "GAN", "Imagen", "Imagen Editor", "VAE", "[PseudoLab] Text-to-Image Generation (feat. Diffusion)"], "terms": {"titl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "author": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "jisu": [0, 2, 10], "kim": [0, 2, 10], "last": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "updat": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "jul": [0, 1], "05": 0, "2023": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "\uc0ac\uacfc": 0, "\ub098\ubb34\uc758": 0, "\uc78e\uc5d0": 0, "\uc0dd\uae30\ub294": 0, "\uc9c8\ubcd1\uc744": 0, "\uc774\ubbf8\uc9c0\ub85c": [0, 1, 3, 9, 17, 18], "\ud310\ubcc4\ud558\ub294": 0, "kaggl": 0, "competit": [0, 14], "\ub9c1\ud06c": [0, 2], "\uc5d0\uc11c": [0, 2, 5, 6, 8, 13, 15, 17, 18, 19], "\uc544\uc774\ub514\uc5b4\ub97c": 0, "\uc5bb\uc5b4\uc11c": 0, "\uc9c4\ud589\ud55c": 0, "\ud504\ub85c\uc81d\ud2b8\uc785\ub2c8\ub2e4": 0, "\ud574\ub2f9": [0, 3, 5, 7, 11, 15, 19], "competition\uc740": 0, "\uc0ac\uacfc\ub098\ubb34": 0, "\uac78\ub9b0": 0, "\uc9c8\ubcd1\uc5d0": 0, "\ub530\ub77c": [0, 6, 8, 11, 12, 13, 14, 15, 19], "\uc78e": 0, "\uc774\ubbf8\uc9c0\ub97c": [0, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 17], "4\uac1c\uc758": [0, 11], "class\ub85c": 0, "\ubd84\ub958\ud558\ub294": 0, "task\uc785\ub2c8\ub2e4": 0, "class": [0, 2, 3, 4, 5, 6, 10, 12, 14, 15, 16, 17, 19], "leav": 0, "competition\uc744": 0, "\uc124\uba85\ud55c": 0, "articl": 0, "\uc804\uccb4\uc801\uc778": [0, 10], "accuracy\ub294": 0, "97": 0, "\uc774\uc9c0\ub9cc": 0, "multipl": 0, "class\uc758": [0, 14], "\uacbd\uc6b0": [0, 1, 2, 3, 6, 7, 8, 9, 10, 12, 16], "accuracy\uac00": 0, "51": 0, "\uc5d0": [0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19], "\ubd88\uacfc\ud588\ub2e4\uace0": 0, "\uc5b8\uae09\ud569\ub2c8\ub2e4": 0, "\uc774\ubbf8\uc9c0": [0, 2, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], "\uac1c\uc218\uac00": 0, "\ub2e4\ub978": [0, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 17, 18, 19], "class\uc5d0": 0, "\ube44\ud574": [0, 2, 3, 4, 6, 9, 14, 18], "\uc801\uc740": [0, 2, 3, 4, 5, 6, 8, 11, 14], "\uc810\uc5d0": 0, "\uc8fc\ubaa9\ud588\uace0": 0, "diffusion\uc744": 0, "\uc0ac\uc6a9\ud558\uc5ec": [0, 5, 10, 12, 13, 15, 17], "\ud074\ub798\uc2a4\uc758": 0, "\ub370\uc774\ud130": [0, 11, 12, 13, 16, 17, 19], "\uac1c\uc218\ub97c": [0, 5], "\ub298\ub824\uc11c": 0, "classifi": [0, 16, 18], "\ud559\uc2b5\uc5d0": [0, 8, 12], "\uc0ac\uc6a9\ud558\uba74": [0, 11, 13], "\ub354": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19], "\uc88b\uc740": [0, 1, 3, 9, 12, 14, 15, 17], "\uc131\ub2a5\uc758": 0, "classifier\ub97c": 0, "\uc5bb\uc744": [0, 11, 12], "\uc218": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "\uc788\uc744": [0, 1, 2, 5, 8, 10, 12], "\uac83\uc73c\ub85c": [0, 8, 11], "\uae30\ub300\ud588\uc2b5\ub2c8\ub2e4": 0, "\ubb38\uc81c": 0, "\uc0c1\ud669\uc744": 0, "\uc7ac\ud604\ud558\uae30": 0, "\uc704\ud574": [0, 2, 3, 5, 8, 9, 10, 11, 12, 13, 15, 18], "\uae30\uc874": [0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 14, 17], "\ub370\uc774\ud130\ub85c": [0, 1, 2], "imag": [0, 1, 4, 7, 9, 10, 11, 13, 16, 17, 18, 19], "\ud559\uc2b5\ud558\uc5ec": [0, 13, 14], "baseline\uc73c\ub85c": 0, "\uc7a1\uc558\uc2b5\ub2c8\ub2e4": 0, "\ubaa8\ub378\uc740": [0, 6, 7, 8, 10, 11, 12], "pretrained\ub41c": 0, "resnet18\uc5d0": 0, "linear": [0, 5, 6, 8, 10, 14, 16, 19], "layer\ub97c": [0, 8, 10], "\ubd99\uc5ec\uc11c": 0, "\uc0ac\uc6a9\ud588\uc2b5\ub2c8\ub2e4": [0, 18], "\uc804\uccb4": [0, 2, 3, 6], "7": [0, 1, 4, 5, 6, 9, 17], "class\ubcc4": 0, "healthi": 0, "99": 0, "73": [0, 11], "rust": 0, "scab": 0, "98": 0, "class\ub294": 0, "\uac1c\uc218": 0, "91\uac1c\ub85c": 0, "\ud074\ub798\uc2a4\ub4e4\uc5d0": 0, "\ube44\ud574\uc11c": 0, "\uc801\uc2b5\ub2c8\ub2e4": 0, "imbalance\uac00": 0, "\uc131\ub2a5\uc744": [0, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18], "\ub0ae\ucd94\ub294": 0, "\uc6d0\uc778\uc77c": 0, "\uac83\uc774\ub77c": [0, 8], "\uac00\uc815\ud558\uace0": 0, "diffusion\uc73c\ub85c": 0, "data\ub97c": [0, 3, 12], "\ucd94\uac00\ub85c": [0, 6, 9, 12], "\uc0dd\uc131\ud574\ubcf4\uae30\ub85c": 0, "\ud588\uc2b5\ub2c8\ub2e4": [0, 1, 10], "\uc608\uc2dc": [0, 12, 17, 18], "pretran": 0, "diffusion\uc758": 0, "\ub300\ud55c": [0, 1, 2, 3, 5, 6, 9, 11, 15, 16], "\uc815\ubcf4\uac00": [0, 9, 15], "\uc5c6\uc5b4\uc11c": 0, "\uc0dd\uc131\ud560": [0, 1, 2, 12, 15], "\uc544\ub798\uc640": [0, 2, 7, 10, 12, 14], "\uac19\uc774": [0, 2, 3, 5, 7, 10, 11, 12, 13, 14, 15, 16, 19], "\uad00\ub828\uc5c6\ub294": 0, "\uc774\ubbf8\uc9c0\uac00": [0, 2, 5, 9, 11, 12, 14, 16, 17], "\uc0dd\uc131\ub429\ub2c8\ub2e4": 0, "prompt": [0, 2, 3, 9, 11, 15, 17, 18], "photo": [0, 1, 3, 11], "\ub530\ub77c\uc11c": [0, 2, 5, 6, 9, 11, 12, 18], "model": [0, 2, 4, 8, 13, 16, 18, 20], "\uc815\ubcf4\ub97c": [0, 2, 5, 9, 11, 12, 15], "\ub123\uc5b4\uc8fc\uae30": 0, "dreambooth": [0, 3], "\ub97c": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "tuning\ud588\uc2b5\ub2c8\ub2e4": 0, "training\uc5d0": [0, 4, 14], "\uc0ac\uc6a9\ud55c": [0, 10, 11, 14], "prompt\ub294": 0, "disea": 0, "leaf": 0, "\uc774\uba70": [0, 11], "\uc0dd\uc131\ud55c": [0, 2, 13, 15, 17], "\uc774\ubbf8\uc9c0\uc758": [0, 1, 2, 3, 5, 9, 10, 11, 12, 13, 15, 17], "\uc608\uc2dc\ub294": [0, 17], "\uac19\uc2b5\ub2c8\ub2e4": [0, 1, 2, 10, 12, 15, 16], "\uc0dd\uc131": [0, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17], "engineering\uc744": 0, "\uc218\ud589\ud558\ub358": 0, "\uc911": [0, 3, 4, 6, 8, 9, 10, 12, 13, 14, 15, 17, 19], "\uc758\ub3c4\ud558\uc9c0\uc54a\uc740": 0, "\uacb0\uacfc\ub97c": [0, 2, 4, 6, 9, 10, 11, 12, 17, 18], "\ubc1c\uacac\ud588\uc2b5\ub2c8\ub2e4": [0, 1], "\uc544\ub798\ub294": [0, 2, 19], "\uc774\uc5d0": [0, 2, 9, 15], "\uc608\uc2dc\ub85c": 0, "\uc804\uc758": 0, "model\uc758": [0, 2, 3, 5, 6, 8, 11, 12, 14], "\uacb0\uacfc\uc640": 0, "\ube44\uad50\uc785\ub2c8\ub2e4": 0, "\uc0c1\ud6691": 0, "\uc804": [0, 5, 8, 14], "\ud6c4": [0, 1, 5, 8, 12, 13, 15, 17, 18], "\uc0c1\ud6691\uc744": 0, "\ubcf4\uba74": [0, 3, 6, 10, 11, 12, 13], "\ub2f4\uc740": 0, "uniqu": [0, 1, 15], "identifi": [0, 1, 9, 15], "\uac00": [0, 1, 2, 5, 6, 8, 12, 14, 15, 16, 17, 18, 19], "\uc5c6\uc74c\uc5d0\ub3c4": 0, "diseases\uc758": 0, "\uc78e\ub4e4\ub9cc": 0, "\uc774\ub294": [0, 2, 4, 10, 11, 16, 18, 19], "\uac19\uc740": [0, 1, 2, 5, 6, 7, 8, 10, 11, 12, 14, 15, 18, 19], "\uc18d\ud558\ub294": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc744": [0, 1, 2, 15, 18], "\uc0dd\uc131\ud574\ub0b4\uc9c0": [0, 3], "\ubabb\ud558\uace0": [0, 5], "\uc788\ub2e4\ub294": [0, 8, 10, 11, 17, 18], "\uac83\uc785\ub2c8\ub2e4": [0, 2, 10, 12, 18], "\uc774": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19], "\ud604\uc0c1\uc744": [0, 3, 10], "languag": [0, 3, 8, 11, 13, 15, 17], "drift\ub77c\uace0": 0, "\ud558\uba70": [0, 13], "\ubaa8\ub378\uc774": [0, 1, 2, 3, 4, 5, 9, 10, 14, 15, 18], "leaf\uac00": 0, "\uc544\ub2cc": [0, 1, 2, 4, 8, 11, 12, 14], "\uc77c\ubc18\uc801\uc778": [0, 3, 11, 14], "\uad00\ud55c": [0, 6, 9, 10], "\uc78a\uc5b4\ubc84\ub838\uae30": 0, "\ub54c\ubb38\uc785\ub2c8\ub2e4": [0, 12], "\uc0c1\ud6692": 0, "\uc0c1\ud6692\ub97c": 0, "photo\ub77c\ub294": 0, "prompt\ub9cc": [0, 9], "\uc0ac\uc6a9\ud558\uc600\ub294\ub370\ub3c4": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc5d0": 0, "\ud2b9\uc9d5\ub4e4\uc774": 0, "\ub098\ud0c0\ub0a9\ub2c8\ub2e4": 0, "dreambooth\uc5d0\uc11c\ub294": 0, "drift\ub97c": 0, "prior": [0, 15, 19], "preserv": [0, 15], "loss\ub97c": [0, 5, 11, 12], "\uc0ac\uc6a9\ud574\uc11c": [0, 2, 13, 14, 17], "\ud574\uacb0\ud558\uc600\uc73c\ubbc0\ub85c": 0, "\ubc29\ubc95\uc744": [0, 6, 10, 11, 12, 14], "\ud574\uacb0\ud558\uae30": [0, 8, 11, 15, 18], "train": [0, 4, 6, 8, 9, 10, 11, 14, 15, 17], "prompt\uc5d0\uc11c": 0, "\uc81c\uc678\ud558\uace0": [0, 8], "\ucd5c\ub300\ud55c": [0, 11, 12, 19], "\ub2e8\uc21c\ud55c": [0, 3], "model\uc744": [0, 2, 3, 4, 6, 8, 9, 11, 14], "\ub2e4\uc2dc": [0, 5, 8, 10, 12, 15, 16, 19], "\uacb0\uacfc": [0, 1, 3, 6, 7, 14, 17, 18], "\uc7ac\ud6c8\ub828": 0, "\uc774\ud6c4\uc5d0\ub3c4": 0, "model\ub85c": 0, "\uc0dd\uc131\ud558\uc600\uc744": 0, "\ub54c\uc640": [0, 12], "\ube44\uc2b7\ud55c": [0, 3, 6, 11, 12, 14, 15], "\uc758": [0, 1, 2, 4, 5, 6, 8, 10, 12, 13, 14, 15, 16, 17, 18, 19], "\uacbd\uc6b0\uc5d0\ub294": 0, "\uc5ec\uc804\ud788": [0, 3, 17], "\uc601\ud5a5\uc744": [0, 5, 9, 10, 14, 17], "\ubc1b\uc740": [0, 11], "\uac83\uac19\uc740": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc774": [0, 2], "photo\uc758": 0, "\uc5ec\ub7ec": [0, 7, 11, 15], "\ub300\uc0c1\ub4e4\uacfc": 0, "\uc0ac\uc6a9\ub418\ub294": [0, 11, 15], "\ud2b9\uc131\uc744": [0, 12], "\uac00\uc9c0\uace0\uc788\uc5b4\uc11c": 0, "\uadf8\ub7f0": [0, 10, 12], "\uac83\uc774\ub77c\ub294": 0, "\uc0dd\uac01\uc774": 0, "\ub4e4\uc5c8\uace0": 0, "\uc774\ub97c": [0, 2, 5, 7, 8, 10, 11, 12, 15, 16, 18, 19], "\uccb4\ud06c\ud574\ubcf4\uae30": 0, "\ud2b9\uc815\ud55c": [0, 10, 11], "photo\uc640": 0, "\uc6a9\ub3c4\ub85c": 0, "prompt\ub4e4\ub85c": 0, "\uc0dd\uc131\ubcf4\uc558\uc2b5\ub2c8\ub2e4": 0, "\ub300\uc0c1": [0, 12], "\uc138\uac00\uc9c0\ub85c\ub294": 0, "cat": [0, 5, 18], "sea": 0, "pirate\uc744": 0, "\uc0ac\uc6a9\ud588\uace0": [0, 12], "\ube44\uc2b7\ud558\uac8c": [0, 11], "\ud14d\uc2a4\ud2b8": [0, 11, 17], "\uc138\uac00\uc9c0\ub294": 0, "illustr": 0, "anim": [0, 13], "wallpaper\ub97c": 0, "\uc774\ubbf8\uc9c0\ub294": [0, 3, 9, 12, 17], "\uae00": 0, "\ub9c8\uc9c0\ub9c9": [0, 5, 10], "\ubd80\ubd84\uc758": 0, "appendix\uc5d0": 0, "\uc788\uc2b5\ub2c8\ub2e4": [0, 1, 2, 10, 12, 15, 16, 18, 19], "\ub300\uc0c1\uc744": [0, 12], "\uc9c0\uce6d\ud558\ub294": 0, "\ud14d\uc2a4\ud2b8\uc758": 0, "\ub300\uc0c1\uc758": [0, 15], "\ud2b9\uc9d5\uc774": 0, "\uc798": [0, 1, 2, 3, 6, 9, 10, 11, 12, 15, 16, 19], "\ub4dc\ub7ec\ub098\ub294": 0, "\uc0dd\uc131\ub418\uc5c8\uc9c0\ub9cc": 0, "\ub300\uc0c1\uacfc": [0, 12], "\ud568\uaed8": [0, 8, 12, 19], "\uc4f0\uc774\ub294": [0, 12, 16], "\uc78e\uc0ac\uadc0\uc758": 0, "\ud2b9\uc9d5\uc744": [0, 2, 15], "\uac00\uc9c0\ub294": [0, 1, 10], "\uc77c\ubd80": [0, 8, 10], "\uc0dd\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4": 0, "tuning\ud55c": 0, "400\uc7a5": 0, "\uc0dd\uc131\ud558\uc5ec": 0, "\ud6c8\ub828\ud588\uc2b5\ub2c8\ub2e4": 0, "result_bas": 0, "\ucd94\uac00": [0, 3, 5], "\ud65c\uc6a9\ud55c": [0, 15, 16], "9": [0, 6, 12], "84": 0, "result_now": 0, "kaggle\uc5d0\uc11c": 0, "\uc81c\uacf5\ud558\ub294": [0, 11], "test": [0, 11, 12, 17], "set\uc5d0": 0, "\uc801\uc6a9\ud588\uc744": 0, "\ub54c\ub294": 0, "baseline\uc774": [0, 11], "94": 0, "\uacbd\uc6b0\uac00": [0, 2, 4, 12], "93": 0, "\uc5ec\uc11c": 0, "baseline\ubcf4\ub2e4": 0, "\uc5bb\uc9c0\ub294": 0, "\ubabb": 0, "\ud6c8\ub828": [0, 2, 12, 17], "\uc911\uac04\uc911\uac04\uc5d0": 0, "\uc77c\uc815": 0, "step\ub9c8\ub2e4": 0, "\uc0dd\uc131\ud558\uac8c\ud574\uc11c": 0, "\ud6c8\ub828\uc5d0": [0, 10], "\ubaa8\ub2c8\ud130\ub9c1\uc774": 0, "\uc788\uc73c\uba74": 0, "\uc88b\uaca0\ub2e4\ub294": 0, "\uc0dd\uac01\uc744": 0, "\ud6c8\ub828\uc2dc": 0, "hyperparamet": [0, 4, 9, 14], "tuning\uc744": [0, 2, 8, 11], "\uc880": [0, 2, 9, 17], "\ucca0\uc800\ud558\uac8c": 0, "\ud574\uc57c\uaca0\ub2e4\ub294": 0, "\uc2e4\uc81c\ub85c": [0, 6, 10, 12, 16, 19], "\uc870\uac74\uc744": [0, 11], "\ub9cc\uc871\ud558\ub294\uc9c0": 0, "\uac80\uc218\ud560": 0, "\ubc29\uc548\uc774": 0, "\ud544\uc694\ud569\ub2c8\ub2e4": 0, "\ub0b4\uc5d0\uc11c\ub3c4": 0, "\uce74\ud14c\uace0\ub9ac\ub97c": 0, "\ub098\ub20c": 0, "\uc788\ub2e4\uba74": [0, 5], "\ub098\ub220\uc11c": [0, 17], "\uac01\uac01\uc5d0": [0, 10], "tuning\ud560": [0, 3, 8], "\uc218\ub3c4": [0, 10, 12], "\ud65c\uc6a9\ud574\ubcfc": 0, "submiss": 0, "score\uc5d0\uc11c": 0, "baseline\uc744": 0, "\uc774\uae30\uc9c0": 0, "\ud588\uc9c0\ub9cc": 0, "text": [0, 1, 2, 5, 7, 9, 10, 13, 17, 18], "\uc774\uc6a9\ud55c": [0, 9], "data\uc758": [0, 6, 9], "\uac00\ub2a5\uc131\uc744": [0, 4], "\ubcfc": [0, 1, 10, 11, 12, 13, 14, 18], "\uc788\uc5c8\ub2e4\uace0": [0, 8, 18], "\uc0dd\uac01\ud569\ub2c8\ub2e4": [0, 10], "\uc55e\uc5d0\uc11c": 0, "\uc5b8\uae09\ud55c": [0, 2, 18], "prompt\uc5d0": [0, 3], "\uc608\uc2dc\uc785\ub2c8\ub2e4": [0, 1], "nsfw\ub85c": 0, "\ud310\ub2e8\ub418\uc5b4": 0, "\uac80\uc740\uc0c9\uc73c\ub85c": 0, "\ub098\uc654\uc2b5\ub2c8\ub2e4": [0, 10], "pirat": 0, "wallpap": 0, "sangwoo": [1, 15, 16, 18, 19], "jo": [1, 15, 16, 18, 19], "09": 1, "\uc774\ubc88": [1, 18], "\ud3ec\uc2a4\ud305\uc5d0\uc11c\ub294": 1, "\uc9c1\uc811": [1, 6, 16, 19], "\ud559\uc2b5\ud574\ubcf4\uace0": 1, "\uc2e4\ud5d8\ud55c": 1, "\uacb0\uacfc\ub4e4\uc744": [1, 15], "\uacf5\uc720\ud560\ub824\uace0": 1, "\ud569\ub2c8\ub2e4": [1, 2, 12, 15, 16, 18, 19], "\uc6b0\uc120\uc801\uc73c\ub85c": [1, 13, 19], "\ud559\uc2b5\ub370\uc774\ud130\ub294": 1, "bryandle": 1, "data": [1, 8, 10, 12, 16], "\uacf5\uac1c\ub41c": [1, 8, 18], "yolov5": 1, "\ubaa8\ub378": [1, 3, 4, 6, 8, 11, 12, 13, 14, 15, 16, 17, 18], "\ubc0f": [1, 8, 11, 12, 14, 16, 17, 18], "waifu2x": 1, "\ud6c4\ucc98\ub9ac": 1, "\uae30\ubc95\uc744": [1, 3, 6, 18], "\ud65c\uc6a9\ud558\uc5ec": [1, 13, 14, 15], "\ud504\ub9ac\ub4dc\ub85c\uc6b0\uc5d0": 1, "\ub4f1\uc7a5\ud558\ub294": 1, "\uc778\ubb3c": [1, 12], "\uc0ac\uc9c4\ub4e4\uc744": [1, 15], "\uc218\uc9d1\ud588\uc2b5\ub2c8\ub2e4": 1, "\ub17c\ubb38\uc5d0\uc11c\ub294": [1, 2, 5, 7, 8, 10, 11, 12, 13, 14, 15, 18, 19], "3": [1, 7, 11, 15, 16, 17, 19], "5": [1, 5, 12, 16, 19], "\uc7a5\uc73c\ub85c": 1, "fine": [1, 2, 8, 9, 10, 11, 13, 17, 20], "tune": [1, 8, 13, 17, 20], "\uac00\ub2a5\ud558\ub2e4\uace0": [1, 10], "\uc81c\uc2dc\ub418\uc5b4\uc788\uc9c0\ub9cc": 1, "\uc0ac\uc9c4": [1, 3, 11, 12, 17], "\ub9ce\uc740": [1, 2, 11, 12, 13, 17], "\ud559\uc2b5\ud558\uba74": [1, 5, 15], "\uc131\ub2a5\uc774": [1, 5, 6, 8, 14, 18], "\uc88b\uc544\uc838\uc11c": 1, "15": 1, "20": [1, 15], "\uc7a5\uc758": 1, "\ud559\uc2b5\ud558\uc600\uc2b5\ub2c8\ub2e4": 1, "\ud559\uc2b5\ud55c": [1, 3, 6, 8, 9, 15, 17, 18], "\uc774\ubbf8\uc9c0\ub4e4": 1, "\uc2e4\ud5d8\ud558\uba74\uc11c": 1, "\ub300\ud45c\uc801\uc73c\ub85c": [1, 15, 19], "\uadf8\ub9ac\uace0": [1, 11, 15, 16, 18, 19], "\ub9c8\uc9c0\ub9c9\uc73c\ub85c": [1, 10, 15, 18, 19], "\ubc18\uc601\ud558\ub294": 1, "\uc815\ub3c4\ub97c": [1, 4, 6], "\uc870\uc808\ud558\ub294": [1, 2, 4], "prior_loss_weight": [1, 15], "\ubc14\uafd4\uac00\uba74\uc11c": 1, "\ud559\uc2b5\ud574\ubcf4\uc558\uc2b5\ub2c8\ub2e4": 1, "\uc0ac\uc804\ud559\uc2b5\ub41c": [1, 15], "\ubaa8\ub378\ub85c": [1, 3, 10, 13, 16, 18], "\ucc98\uc74c\uc5d0\ub294": [1, 8], "hakurei": 1, "waifu": 1, "diffus": [1, 2, 4, 8, 16, 18], "\ubaa8\ub378\uc744": [1, 3, 4, 5, 6, 11, 12, 15, 17, 18], "\uc2dc\ub3c4\ud574\ubd24\uc9c0\ub9cc": 1, "\uacb0\uacfc\uac00": [1, 5, 12, 14], "\ub9cc\uc871\uc2a4\ub7fd\uc9c0": 1, "\ubabb\ud574": 1, "runwayml": 1, "stabl": [1, 2, 6, 8, 15, 18], "v1": 1, "\uc791\uc5c5\uc744": [1, 11], "\uc9c4\ud589\ud588\uc2b5\ub2c8\ub2e4": [1, 16, 18], "\uc81c\uc678\ud55c": 1, "\ub3d9\uc77c\ud55c": [1, 6, 12, 15, 18], "configur": [1, 14, 16], "\uc73c\ub85c": [1, 8, 11, 13, 15, 17, 18], "\uacb0\uacfc\uc785\ub2c8\ub2e4": [1, 7], "model_nam": 1, "instance_prompt": 1, "A": [1, 2, 3, 8, 10, 11, 15, 17], "sk": [1, 9, 11], "girl": 1, "class_prompt": 1, "python3": 1, "train_dreambooth": [1, 15], "py": [1, 15], "pretrained_model_name_or_path": [1, 15], "pretrained_vae_name_or_path": 1, "stabilityai": 1, "sd": 1, "vae": [1, 3, 6, 15, 16], "ft": 1, "mse": [1, 5], "output_dir": 1, "revis": [1, 15], "fp16": 1, "with_prior_preserv": [1, 15], "1": [1, 2, 7, 10, 11, 12, 15, 16, 17, 19], "0": [1, 2, 3, 4, 5, 7, 10, 12, 13, 15, 16, 19], "seed": 1, "1337": 1, "resolut": [1, 6, 7, 14, 18], "512": [1, 16], "train_batch_s": 1, "train_text_encod": [1, 15], "mixed_precis": 1, "use_8bit_adam": 1, "gradient_accumulation_step": [1, 15], "gradient_checkpoint": 1, "learning_r": 1, "1e": [1, 9], "6": [1, 3, 9, 12], "lr_schedul": [1, 15], "constant": [1, 6, 14], "lr_warmup_step": 1, "num_class_imag": 1, "200": [1, 17], "sample_batch_s": 1, "4": [1, 7, 10, 12, 16], "max_train_step": 1, "800": 1, "save_interv": 1, "100": [1, 6, 12], "save_sample_prompt": 1, "concepts_list": 1, "json": 1, "w": [1, 2, 3, 5, 7, 8, 10, 13, 17], "o": [1, 9, 18], "\uc544\ub798": [1, 2, 6, 10, 12, 13, 15, 16, 17, 19], "\uadf8\ub9bc\ucc98\ub7fc": [1, 8, 16, 17], "infer": [1, 5, 19], "\uc785\ub825\ud588\uc744": 1, "\ub54c": [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 14, 15, 16, 19], "\uc81c\uc678\ud568\uc73c\ub85c\uc368": 1, "input": [1, 2, 3, 8, 10, 11, 12, 13, 15, 16, 18], "\uac00\uae4c\uc6b4": [1, 11, 12, 13], "\uc6f9\ud230": 1, "\uc788\uc5c8\uc2b5\ub2c8\ub2e4": [1, 2, 18], "\ub610\ud55c": [1, 2, 3, 5, 7, 8, 12, 15, 18], "\ud551\ud06c\uc0c9": 1, "\uba38\ub9ac\ub97c": 1, "\ud55c": [1, 5, 6, 8, 10, 12, 13, 14, 15, 16, 17, 18, 19], "\uc774\ubbfc\uc9c0": 1, "\uce90\ub9ad\ud130\ub97c": 1, "\uc5b4\ub290": [1, 10, 11], "\uc815\ub3c4": [1, 4, 6, 8, 10], "\uc0dd\uc131\ud558\ub294": [1, 2, 5, 7, 10, 12, 15, 16, 17, 18, 19], "\ubd80\ubd84\ub3c4": [1, 18], "\ud655\uc778\ud560": [1, 6, 15, 18], "pink": 1, "hair": [1, 9, 10], "With": 1, "without": [1, 8, 9, 10], "\ub3c4": [1, 5, 9, 15, 19], "\uce90\ub9ad\ud130\uc758": [1, 15], "\ubd80\uc790\uc5f0\uc2a4\ub7ec\uc6b4": 1, "\ubd80\ubd84\uc774\ub098": 1, "\uc800\ud574\uc0c1\ub3c4": 1, "\uacbd\uc6b0\ub4e4\uc774": 1, "\uc885\uc885": [1, 12], "\ubc1c\uc0dd\ud588\ub294\ub370": 1, "\ud1b5\ud574": [1, 3, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 19], "\ud004\ub9ac\ud2f0\uc758": [1, 6, 9], "ugli": 1, "disfigur": 1, "deform": 1, "low": [1, 6, 13], "\ub17c\ubb38\uc5d0\uc11c": [1, 2, 7, 10, 12, 13, 15, 16, 19], "\uc81c\uc2dc\ud55c": [1, 3, 13, 16, 17], "\uc678\uc5d0": 1, "style": [1, 9, 11, 15], "\ub77c\ub294": [1, 2, 11, 12, 14, 17], "\ub85c": [1, 2, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "\ud559\uc2b5\uc744": [1, 3, 7, 10, 12, 14, 18], "\uc2dc\ub3c4\ud574\ubcf4\uae30\ub3c4": 1, "\ud2b9\uc815": [1, 3, 4, 5, 8, 9, 11, 17], "\uc5ec\uc790": 1, "\uce90\ub9ad\ud130\uc5d0": 1, "\uc815\ubcf4\ubfd0\ub9cc": 1, "\uc544\ub2c8\ub77c": [1, 3, 5, 8, 10, 12, 15], "\ud504\ub9ac\ub4dc\ub85c\uc6b0": 1, "\uadf8\ub9bc\uccb4": 1, "\uc790\uccb4\ub97c": [1, 6], "\ub2f4\uc544\ub0b4\uae30": 1, "\uc704\ud55c": [1, 6, 7, 8, 11, 12, 14, 19], "\ubaa9\uc801\uc774\uc600\uc2b5\ub2c8\ub2e4": 1, "differ": [1, 8, 10], "\uc2dc": [1, 13, 14, 15, 16, 17, 18], "\ud504\ub9ac\ub4dc\ub85c\uc6b0\uc758": 1, "\uadf8\ub9bc\uccb4\uac00": 1, "\ubc18\uc601\ub41c": 1, "\ub0a8\uc790\uac00": 1, "\uc0dd\uc131\ub418\ub3c4\ub85d": 1, "boi": 1, "\uc785\ub825\ud588\uc744\ub54c\uc758": 1, "\ud639\uc740": [1, 3, 7, 15, 19], "\uc791\uac00\ub2d8\uc758": 1, "\uc7a5\uba74\ub4e4\ub85c": 1, "\uc804\uccb4\uc801\uc73c\ub85c": 1, "\ud559\uc2b5\ud558\uac8c": [1, 18], "\ub41c\ub2e4\uba74": 1, "\ub2e4\uc591\ud55c": [1, 3, 6, 7, 9, 11, 12, 13, 14, 15, 17], "\uac83": [1, 5, 11, 12, 17], "num_inference_step": 1, "24": 1, "step": [1, 3, 4, 5, 6, 9, 14, 15, 16], "\uc744": [1, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 19], "\ub298\ub824\uac00\uba74\uc11c": 1, "\ucd94\ub860\ub41c": 1, "\ud004\ub9ac\ud2f0\uac00": 1, "\uc0c1\uc2b9\ud558\ub294": 1, "\uc2e4\ud5d8\ub3c4": 1, "\uc9c4\ud589\ud588\ub294\ub370": 1, "\uc791\uc744\uc218\ub85d": 1, "\uc640": [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 16, 17, 18, 19], "\ubb34\uad00\ud55c": [1, 18], "random": [1, 3, 4, 5, 8, 11, 15, 16, 18], "\uc0dd\uc131\ud558\uac8c": [1, 15, 17, 19], "\ub429\ub2c8\ub2e4": [1, 2, 10, 12, 15, 16, 18, 19], "\ucd5c\uc885\uc801\uc73c\ub85c": [1, 10], "num_infer": 1, "\uac12\uc740": [1, 6, 14, 15], "\uac01\uac01": [1, 2, 3, 11, 15, 16, 19], "\uacfc": [1, 4, 5, 6, 9, 11, 13, 15, 17], "\uc124\uc815\ud558\uc600\uc2b5\ub2c8\ub2e4": 1, "increas": 1, "number": [1, 14], "guidance_scal": 1, "\uc81c\uc678\ud574\ubcf8": 1, "\uc0dd\uc131\ub41c": [1, 10, 11, 12, 14, 15, 16, 17, 18, 19], "\ub0a8\uc790\uc758": 1, "\uba38\ub9ac\uce74\ub77d\uc774": 1, "\uae38\uc5b4\uc9c0\uace0": 1, "\uc5ec\uc131\uc2a4\ub7ec\uc6b4": 1, "\uc0dd\uae40\uc0c8\ub97c": [1, 11], "\ub180\ub77c\uc6b4": 1, "\uc0ac\uc2e4\ub3c4": 1, "\uadf8": [1, 5, 7, 10, 11, 12], "\uc678": [1, 12], "\ub530\ub978": [1, 2, 6, 13, 15, 18, 19], "\uc7ac\ubbf8\uc788\ub294": 1, "\uc2e4\ud5d8\uacb0\uacfc\ub4e4\uc744": 1, "\uacf5\uc720\ud569\ub2c8\ub2e4": [1, 15], "\uc544\uc9c1": [1, 11, 14], "\uc190\uc758": 1, "\ubaa8\uc591\uc744": 1, "\uc0dd\uc131\ud558\uc9c0": 1, "\ubabb\ud558\ub294": [1, 16], "\uc7ac\ucc28": 1, "climb": 1, "up": [1, 5], "mountain": 1, "paint": [1, 15, 18], "2": [1, 7, 10, 11, 12, 15, 16, 17], "hand": 1, "draw": [1, 9], "\ud558\ub2e8\uc758": 1, "\uc88c\uce21\uacfc": 1, "\uc6b0\uce21": 1, "\uc0ac\uc9c4\uc740": 1, "\uc774\ub77c\ub294": [1, 14, 17], "\ub098\ube44\ub97c": 1, "\uc0dd\uc131\ud558\ub77c\ub294": 1, "\ucd94\ub860\ud574\ubcf8": 1, "\uc218\uc2dd\ud558\ub294": 1, "\uba85\uc0ac\uac00": 1, "\uc774\ub3c4\ub85d": 1, "\uc218\uc815\ud568\uc73c\ub85c\uc368": [1, 6], "butterfli": 1, "\uc0ac\uc9c4\uc744": [1, 12, 14], "\uc0dd\uc131\ud560\ub54c": 1, "\uc870\uae08\uc774\ub098\ub9c8": 1, "\uc6f9\ud230\uc758": 1, "\uadf8\ub9bc\uccb4\ub97c": 1, "\ubc18\uc601\ud560": 1, "\uc788\uc5c8\ub358": 1, "ad": 2, "arxiv": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "refer": [2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "paper": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "http": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "org": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "ab": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19], "2302": 2, "05543": 2, "code": [2, 3, 5, 7, 8, 10, 11, 12, 13, 14, 15, 16, 19, 20], "lllyasviel": 2, "mai": [2, 7, 11, 14, 15], "28": [2, 19], "\uae30\uc874\uc758": 2, "\ubaa8\ub378\ub4e4\uc740": [2, 3, 14], "prompt\ub85c": [2, 9, 11], "\uc870\uc808\ud560": [2, 10], "\ud558\uc9c0\ub9cc": [2, 3, 4, 6, 8, 9, 11, 12, 14, 15, 16, 19], "\uc774\ub7f0": [2, 10], "control\ub9cc\uc73c\ub85c": 2, "\uc870\uc808\ud558\ub294\ub370": 2, "\ud55c\uacc4\uac00": [2, 9, 11, 12, 17], "condition\uc744": [2, 3], "\ucd94\uac00\uc801\uc73c\ub85c": 2, "\uc918\uc11c": 2, "\uc0dd\uc131\ub418\ub294": [2, 9, 10, 14], "controlnet\uc774\ub77c\ub294": 2, "\uc2e0\uacbd\ub9dd": 2, "\uad6c\uc870\ub97c": [2, 7, 10, 12, 13, 15, 17], "\uc81c\uc548\ud569\ub2c8\ub2e4": 2, "\uadf8\ub9bc\uc740": [2, 7, 10], "high": [2, 6, 7, 10, 13, 16, 17], "qualiti": [2, 4, 9, 13, 14, 16, 17, 19], "detail": [2, 9], "profession": 2, "prompt\uc640": [2, 3], "\uc67c\ucabd": 2, "\uc544\ub798\uc758": [2, 7, 17], "canni": 2, "edge\ub97c": 2, "input\uc73c\ub85c": [2, 7, 10], "\ubc1b\uc544\uc11c": [2, 10, 19], "\uc624\ub978\ucabd\uc758": 2, "\uc2dd\uc73c\ub85c": 2, "\ucd94\uac00\uc801\uc778": [2, 3, 5, 7, 8, 10, 11, 12], "\uadf8\ub9bc\uc5d0\uc11c\ub294": 2, "edg": [2, 12], "\ubc1b\uc544": [2, 5, 14], "\uac83\uc774": [2, 5, 8, 10, 11, 12, 14, 15, 17, 18, 19], "controlnet\uc774": 2, "\ud558\ub294": [2, 5, 6, 9, 10, 11, 12, 14, 15, 17, 19], "\uc5ed\ud560\uc785\ub2c8\ub2e4": 2, "gener": [2, 6, 9, 10, 11, 13, 14, 15, 16, 17], "conrolnet": 2, "\uadf8\ub7ec\uba74": [2, 10], "\uc5b4\ub5a4": [2, 5, 8, 11, 12, 19], "\uac00\ub2a5\ud558\uac8c": [2, 8, 10], "\ud588\uc744\uae4c\uc694": 2, "\uc774\uc81c\ubd80\ud130": 2, "\ub300\ud574": [2, 3, 5, 6, 11, 12, 15, 16, 18, 19], "\uc54c\uc544\ubcf4\ub3c4\ub85d": [2, 10], "\ud558\uaca0\uc2b5\ub2c8\ub2e4": [2, 10, 19], "controlnet\uc758": 2, "\uad6c\uc870\ub294": [2, 10], "\ub2e4\uc74c\uacfc": [2, 7, 10, 11, 12, 15, 16, 19], "\ub450": [2, 5, 6, 10, 12, 15], "\uac00\uc9c0": [2, 10, 11, 12, 15], "\uac00\uc9d1\ub2c8\ub2e4": [2, 7], "pretrain": [2, 3, 8, 9, 11, 13], "lock": 2, "copy\uc640": 2, "trainabl": [2, 4, 6, 8], "copy\ub97c": 2, "\uc0ac\uc6a9": [2, 3, 5, 6, 9, 12, 13, 14, 17], "\uc65c": [2, 6], "\uc774\ub807\uac8c": [2, 11, 16], "\uc124\uacc4\ud588\ub294\uc9c0": 2, "\uc54c\uc544\ubd05\uc2dc\ub2e4": 2, "\uc6b0\uc120": [2, 15], "\uc0ac\uc6a9\ud558\ub294": [2, 5, 10, 12, 14, 15, 17, 18], "\uc774\uc720\ub294": [2, 5], "\uae30\uc874\uc5d0": [2, 3, 7, 8, 10], "\ubc29\ub300\ud55c": 2, "\uc591\uc758": 2, "\ud559\uc2b5\uc2dc\ud0a8": 2, "\uc720\uc9c0\ud558\uae30": 2, "\uc704\ud574\uc11c\uc785\ub2c8\ub2e4": 2, "\ud559\uc2b5": [2, 4, 5, 7, 8, 12, 13, 14, 15, 16, 17], "\ub370\uc774\ud130\uac00": [2, 5, 10, 11, 12, 16, 19], "\uc591\uc774": 2, "\uacbd\uc6b0\uc5d0": [2, 12], "\uc624\ubc84\ud53c\ud305\uc744": 2, "\ud53c\ud560": 2, "\uc788\ub294": [2, 6, 10, 11, 12, 14, 15, 18], "\ud6a8\uacfc\ub3c4": 2, "convolution\uc774\ub780": 2, "weight\ub791": 2, "bias\uac00": [2, 10], "0\uc73c\ub85c": [2, 12, 14, 18], "\ucd08\uae30\ud654\ud55c": 2, "1x1": 2, "convolution\uc744": 2, "\ub9d0\ud569\ub2c8\ub2e4": [2, 12], "\uc0ac\uc6a9\ud560": [2, 8], "\ud6c8\ub828\uc774": 2, "\uc2dc\uc791\ub418\uae30": 2, "\uc804\uc5d0\ub294": 2, "input\uc5d0": [2, 13], "model\uacfc": [2, 6, 7], "output\uc774": [2, 12], "\ub611\uac19\uc544\uc9d1\ub2c8\ub2e4": 2, "\ubaa8\ub378\uc774\ub791": 2, "\ub611\uac19\uc740": 2, "output\uc744": 2, "\uac00\uc9c0\uac8c\ub418\ubbc0\ub85c": 2, "\ubaa8\ub378\uc758": [2, 3, 6, 8, 9, 10, 11, 14], "\uc720\uc9c0\ud560": [2, 11], "\uc788\uc73c\uba70": [2, 12, 13, 17], "\uac83\uacfc": [2, 11, 12, 18], "\ube44\uc2b7\ud558\ubbc0\ub85c": 2, "scratch\ubd80\ud130": 2, "\ud559\uc2b5\ud558\ub294": [2, 5, 6, 10, 12, 16], "\uac83\uc5d0": [2, 11, 12], "\ube60\ub974\uac8c": [2, 14, 17], "\ud6c8\ub828\uc2dc\ud0ac": 2, "\uc788\uac8c\ub429\ub2c8\ub2e4": 2, "convolution\uc740": 2, "\uc5b4\ub5bb\uac8c": [2, 5, 11], "\ud558\ub294\uc9c0": 2, "\uc790\uc138\ud788": [2, 10, 15], "\uba3c\uc800": [2, 10, 13, 16], "\uc704\uc758": [2, 4, 6], "\uadf8\ub9bc\uc5d0\uc11c": [2, 10, 12, 15], "\ud574\ub2f9\ud558\ub294": [2, 18], "\ubd80\ubd84\uc744": [2, 15, 18], "\uc218\uc2dd\uc73c\ub85c": 2, "\ud45c\ud604\ud558\uaca0\uc2b5\ub2c8\ub2e4": 2, "mathbf": [2, 10], "y": [2, 4, 5, 8, 10, 12, 13, 14], "mathcal": [2, 5, 7, 8], "f": [2, 4, 5, 7, 8, 12, 15, 16], "x": [2, 4, 7, 8, 10, 12, 13, 14, 15, 16, 17, 19], "theta": [2, 5, 7, 8, 13, 14, 15, 16, 19], "\ub294": [2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19], "featur": [2, 3, 5, 9, 10, 15], "map": [2, 5, 9, 12, 19], "neural": [2, 4, 6, 12], "network": [2, 4, 5, 12, 16], "paramet": [2, 4, 5, 8, 9, 13, 15, 17], "\uc758\ubbf8\ud569\ub2c8\ub2e4": 2, "\uc704": [2, 5, 6, 8, 9, 11, 12], "\uadf8\ub9bc\uc758": 2, "b": [2, 5, 8, 10, 13, 17], "\ud45c\ud604\ud558\uae30\uc704\ud574": 2, "\ub9cc\ub4e4\uc5b4\uc11c": [2, 11], "parameter\ub97c": [2, 3, 5, 13, 14], "theta_": 2, "c": [2, 3, 5, 7, 9, 10, 15], "\ub77c\uace0\ud558\uace0": 2, "\uace0\uc815\uc2dc\ucf1c\ub450\uaca0\uc2b5\ub2c8\ub2e4": 2, "z": [2, 5, 7, 8, 9, 13, 14, 16, 19], "\ud45c\ud604\ud558\uace0": 2, "convolution\uc758": 2, "z1": 2, "z2": 2, "\ub450\uaca0\uc2b5\ub2c8\ub2e4": 2, "output": [2, 5, 8, 12, 13, 15, 18], "_": [2, 7, 8, 10, 15, 16, 19], "\ud45c\ud604\ud560": 2, "\uadf8\ub7f0\ub370": [2, 10], "weight\uc640": 2, "bias\uc758": 2, "\ucd08\uae43\uac12\uc774": 2, "0\uc774\ubbc0\ub85c": 2, "\uc9c4\ud589\ub418\uc9c0": 2, "\uc54a\uc558\uc744": 2, "\uc785\ub2c8\ub2e4": [2, 12, 16, 19], "\uc2dc\uc791": 2, "controlnet\uacfc": 2, "\ub0b4\ubbc0\ub85c": 2, "\ubcf4\uc874\ud560": 2, "\uc804\ubd80": 2, "\ucd08\uae30\ud654\ub418\uc5b4\uc788\uc73c\uba74": 2, "gradient\uac00": [2, 12], "0\uc774\ub77c\uc11c": 2, "\uc548": [2, 12], "\ub418\ub294\uac70": 2, "\uc544\ub2d0\uae4c\uc694": 2, "\ud655\uc778\ud558\uae30": 2, "\uac04\ub2e8\ud55c": [2, 11], "\uacbd\uc6b0\ub97c": 2, "\uc0dd\uac01\ud574\ubcf4\uc8e0": 2, "wx": 2, "gradient\ub294": 2, "frac": [2, 5, 7, 10, 14, 16, 19], "partial": [2, 3, 5], "0\uc774\uace0": 2, "neq0": 2, "\uc774\ub77c\uace0": [2, 11], "\ud558\uba74": [2, 12], "\uccab": [2, 10, 12], "\ubc88\uc9f8": [2, 10], "gradient": [2, 4, 5, 6, 8, 14, 16], "step\uc5d0\uc11c": [2, 5, 6], "weight\ub294": [2, 8], "0\uc774": [2, 4, 5], "\uac12\uc73c\ub85c": [2, 6, 8, 19], "\uac00\uac8c\ub418\uace0": 2, "\ub418\ubbc0\ub85c": 2, "\uc5ec\uae30\uc11c": [2, 5, 7, 10, 11, 12, 19], "\ud575\uc2ec\uc801\uc778": 2, "\uac00\uc815\uc774": 2, "\uc778\ub370": 2, "\ubd80\ubd84\uc740": [2, 7, 10], "\ud6c8\ub828\ub41c": [2, 11], "\uc0ac\uc6a9\ud558\uace0": [2, 3, 8, 9, 11, 15, 18], "\uc788\uae30": [2, 12], "\ub54c\ubb38\uc5d0": [2, 5, 8, 10, 12, 15, 19], "\uc704\ubc30\ub420": 2, "\uac00\ub2a5\uc131\uc774": [2, 6], "\ub0ae\uc744": 2, "\uc9c0\uae08\uae4c\uc9c0": [2, 5], "\uc598\uae30\ud55c": 2, "diffusion\uc5d0": 2, "\uc801\uc6a9\ud55c": [2, 6], "\uadf8\ub9bc\uacfc": [2, 10, 12, 13, 16, 17, 19], "overal": [2, 17], "structur": [2, 7, 8, 10], "loss\ub294": [2, 5], "diffusion\uc5d0\uc11c": 2, "\ucd94\uac00\ub41c": [2, 5], "\ud615\ud0dc\uc785\ub2c8\ub2e4": [2, 10], "loss": [2, 4, 6, 7, 9, 13, 14, 15, 16, 19], "training\uc744": 2, "\ud560": [2, 5, 9, 10, 11, 13, 14, 15, 17], "50": [2, 5, 11, 12], "\ud655\ub960\ub85c": 2, "t": [2, 3, 4, 6, 7, 13, 14, 15], "empti": 2, "string\uc73c\ub85c": 2, "\ubc14\uafd4\uc8fc\uc5c8\ub2e4\uace0": 2, "prompt\uac00": [2, 3], "\uc8fc\uc5b4\uc9c0\uc9c0\uc54a\uc744": 2, "\ub85c\ubd80\ud130": [2, 12, 15, 16, 19], "semantics\ub97c": 2, "\ubc30\uc6b0\ub294": 2, "\uacbd\ud5a5\uc774": [2, 3, 9], "\uc0dd\uc131\uc744": [2, 11, 17], "\ub2a5\ub825\uc744": [2, 11], "\ud5a5\uc0c1\uc2dc\ucf1c\uc904": 2, "\uc788\ub2e4\uace0": [2, 5, 11, 13, 19], "\uacb0\uacfc\ub294": [2, 6, 12], "training\uc774": 2, "\ubc29\ubc95\ubcf4\ub2e4": 2, "\ud6a8\uc728\uc801\uc774\ub77c\ub294": 2, "\uac83\uc744": [2, 5, 6, 10, 11, 12, 13, 14, 15, 17, 18], "\ubcf4\uc5ec\uc90d\ub2c8\ub2e4": [2, 12, 15], "effici": [2, 4, 8, 17], "\uacb0\uacfc\ub4e4\uc740": 2, "task\uc5d0": [2, 7, 8, 11, 12], "\uacb0\uacfc\ub4e4\uc785\ub2c8\ub2e4": 2, "\ub17c\ubb38\uc5d0": [2, 5, 19], "\uc788\uc73c\ub2c8": 2, "\ucc38\uace0\ud558\uc2dc\uae30": 2, "\ubc14\ub78d\ub2c8\ub2e4": 2, "pose": [2, 9, 10, 15], "limitation\uc774\ub77c\uace0": 2, "\uc774\ubbf8\uc9c0\uc785\ub2c8\ub2e4": 2, "\ud14d\uc2a4\ud2b8\ub85c": 2, "\uc8fc\uc5c8\uc74c\uc5d0\ub3c4": 2, "\uc6d0\ud558\ub294": [2, 3, 9, 10, 12], "\uc0dd\uc131\ub418\uc9c0": 2, "\uc54a\ub294": [2, 12, 15], "\ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4": 2, "limit": 2, "\ucf54\ub4dc\ub294": 2, "\uacf5\uc2dd": 2, "\uad6c\ud604": [2, 16, 19], "\uac00\uc838\uc654\uc2b5\ub2c8\ub2e4": 2, "\ucd08\uae30\ud654\ud558\ub294": 2, "\ucf54\ub4dc\ub85c": 2, "\ub9cc\ub4e4": [2, 11, 13], "\uc0ac\uc6a9\ub429\ub2c8\ub2e4": 2, "def": [2, 4, 5, 8, 10, 16, 19], "zero_modul": 2, "modul": [2, 5, 8, 10, 16, 19], "out": [2, 5, 19], "return": [2, 3, 4, 5, 8, 10, 16, 19], "p": [2, 6, 14, 15, 19], "detach": [2, 16], "zero_": 2, "\uae30\ubcf8\uc801\uc73c\ub85c": [2, 8, 9, 17], "nn": [2, 5, 8, 10, 16, 19], "sequential\uacfc": 2, "\uac19\uc740\ub370": 2, "time": [2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 17], "step\uac19\uc740": 2, "input\uc744": 2, "\ubc1b\uc544\uc904": 2, "\uc788\uac8c": [2, 17], "\ub9cc\ub4e0": [2, 10, 12], "timestepembedsequenti": 2, "sequenti": [2, 5, 10, 16], "timestepblock": 2, "pass": 2, "timestep": [2, 3, 15], "embed": [2, 3, 5, 8, 9, 13, 14, 15], "children": 2, "support": 2, "an": [2, 10, 11, 19], "extra": 2, "forward": [2, 6, 8, 10, 12, 15, 16, 19], "self": [2, 4, 5, 8, 10, 16, 17, 19], "emb": [2, 5], "context": [2, 5, 8, 9, 13, 15], "none": [2, 5, 10], "layer": [2, 4, 5, 8, 10, 12, 16, 17], "isinst": 2, "elif": [2, 5, 15], "spatialtransform": 2, "els": [2, 4, 5, 8, 10, 15], "github\uc758": 2, "cldm": 2, "py\uc5d0": 2, "class\uc785\ub2c8\ub2e4": 2, "init": [2, 8], "\uae38\uc5b4\uc11c": 2, "\uc0dd\ub7b5\ud588\uc2b5\ub2c8\ub2e4": 2, "__init__": [2, 4, 5, 10, 16, 19], "make_zero_conv": 2, "channel": [2, 5, 10, 14, 18], "conv_nd": 2, "dim": [2, 5, 10, 15], "pad": [2, 5], "hint": [2, 3], "kwarg": 2, "t_emb": 2, "timestep_embed": 2, "model_channel": 2, "repeat_onli": 2, "fals": [2, 4, 5, 8, 16], "time_emb": 2, "guided_hint": 2, "input_hint_block": 2, "h": [2, 5, 7, 8, 13, 14], "type": [2, 15, 16], "dtype": [2, 5, 15], "zero_conv": 2, "zip": [2, 4, 5], "input_block": 2, "append": [2, 5, 10, 16], "middle_block": 2, "middle_block_out": 2, "multi": [3, 11, 17], "customizi": 3, "To": [3, 4], "vcpr": 3, "2212": [3, 18], "04488": 3, "offici": [3, 4, 13, 14], "seunghwan": [3, 4, 6, 9], "ji": [3, 4, 6, 9], "aug": [3, 6, 9], "pdf": [3, 6, 9, 11, 13, 18], "cvpr": [3, 6, 7, 10, 15, 18], "adob": 3, "larg": 3, "scale": [3, 8, 10, 14, 17], "\ub6f0\uc5b4\ub09c": [3, 4, 6, 13], "\ubcf4\uc774\ub294": [3, 4, 6, 12], "\ucd94\uc138": 3, "user\uc758": 3, "private\ud55c": 3, "concept\uc744": [3, 11], "\uc0dd\uc131\ud558\uace0\uc790\ud558\ub294": 3, "\uc695\uad6c\ub294": 3, "\ud480\uc9c0": 3, "\ubabb\ud568": 3, "diffusion\uc740": 3, "partial\ud55c": 3, "\ubd80\ubd84\ub9cc\uc744": 3, "\ud559\uc2b5\uc2dc\ud0b4\uc73c\ub85c\uc368": 3, "\uae30\uc874\ubcf4\ub2e4": 3, "\ube60\ub978": 3, "finetun": 3, "\ubc29\uc2dd\uc744": 3, "\uc81c\uc548": [3, 4, 6, 11, 12, 13], "\ubfd0": 3, "concept\uc5d0": [3, 11], "\ud559\uc2b5\uc774": [3, 5, 9, 12], "\uac00\ub2a5": [3, 5, 14], "\ud558\ub098\uc758": [3, 5, 8, 9, 10, 11, 12, 19], "compress\ud558\ub294": 3, "\ucd5c\uadfc": [3, 6, 9, 12], "\ubaa8\ub378\ub4e4\uc774": [3, 10, 15], "\ud65c\ubc1c\ud558\uac8c": 3, "\uc5f0\uad6c": [3, 6], "\ub418\uc5b4\uc9d0": 3, "\uc785\ub825\ub9cc\uc73c\ub85c": 3, "\uc0dd\uc131\ud574\ub0b4\ub294": [3, 6], "\uc218\uc900\uae4c\uc9c0": [3, 6], "\uc774\ub984": 3, "\uc774\ub7ec\ud55c": [3, 9, 11, 12, 15, 19], "general\ud55c": 3, "\uc0dd\uc131\ud558\uc9c0\ub9cc": [3, 16], "user\uac00": 3, "specif": [3, 10, 15], "concept\uc758": [3, 11], "e": [3, 4, 5, 6, 7, 9, 10, 15, 16, 17, 19], "g": [3, 4, 6, 9, 10, 12, 15, 16], "\ud589\ubcf5\ud55c": 3, "\uc6b0\ub9ac": [3, 11, 12], "\uac00\uc871": 3, "\uc6b0\ub9ac\uc9d1": 3, "\uac15\uc544\uc9c0": 3, "\ubf40\uc090\uac00": 3, "\ud30c\ub9ac\ub85c": 3, "\uc5ec\ud589\uc744": 3, "\ub5a0\ub098\ub294": 3, "\ub4f1": [3, 4, 8, 9, 11, 15], "\uacfc\uc815\uc911\uc5d0": 3, "\ub370\uc774\ud130\ub97c": [3, 5, 6, 9, 12, 16, 19], "\ubcf4\uc9c0": [3, 12, 15], "\ubabb\ud588\uae30\ub54c\ubb38\uc5d0": 3, "model\uc5d0\uac8c\ub294": 3, "\ub2f9\uc5f0\ud55c": 3, "\uba87\uc7a5\uc758": 3, "\ud3ec\ud568\ud558\ub294": [3, 11, 12, 18], "\uc774\ubbf8\uc9c0\ub9cc\uc73c\ub85c": [3, 9], "finetuning\ud558\ub294": 3, "\ubc29\uc2dd": 3, "In": 3, "person": [3, 11], "\ubaa9\ud45c": [3, 11, 12], "\ud559\uc2b5\ud558\uace0\uc790\ud558\ub294": 3, "\uc0dd\uc131\ud574\ub0b4\uc57c\ud568": 3, "\ud559\uc2b5\ub418\uc5c8\ub358": 3, "finetuning\ud55c": 3, "\ud6c4\uc5d0\ub3c4": 3, "customization\uc774": 3, "\uc5b4\ub824\uc6b4": [3, 11], "\uc774\uc720": [3, 6, 12], "\uc9c4\ud589\ud558\ub2e4\ubcf4\uba74": 3, "\ud559\uc2b5\ud588\ub358": 3, "\uc78a\uc5b4\ubc84\ub9ac\uac70\ub098": 3, "\uc65c\uace1\ud574\ubc84\ub9bc": 3, "draft": 3, "\uc0c8\ub85c\uc6b4": [3, 10, 11, 14, 15, 16, 17, 18, 19], "overfit": [3, 15], "\ub418\uc5b4\uc11c": 3, "\uacb0\uacfc\ubb3c\uc758": 3, "variation\uc774": [3, 10], "\ub0ae\uc544\uc9d0": 3, "\uc880\ub354": [3, 4, 6, 9], "\ub098\uc544\uac00": 3, "\uc5b4\ub824\uc6c0": 3, "text\ub85c": 3, "\uacfc\uc815": [3, 5, 6, 11], "\uc131\ub2a5": [3, 8, 12, 13, 14, 15, 16], "\uc720\uc9c0\ub97c": 3, "real": [3, 9, 16], "image\uc640": [3, 12, 13], "caption\uc744": 3, "regular": [3, 5, 19], "data\ub85c": 3, "tuning\ub3d9\uc548": 3, "augment": [3, 9], "\uc18c\uac1c": 3, "gan": [3, 4, 9, 12, 13], "\ubc29\uc2dd\uc758": [3, 4, 14], "model\ub4e4\uc774": [3, 4], "\ubcf4\uc5ec\uc8fc\uace0\uc788\uc74c": 3, "\uac8c\ub2e4\uac00": 3, "control\ub3c4": 3, "\uac00\ub2a5\ud568": [3, 8, 11, 13, 17], "general\ud558\uc9c0": 3, "\uc54a\uc740": [3, 6, 10, 12], "\uc0dd\uc131\uc740": 3, "\ubd88\uac00\ub2a5\ud568": 3, "new": [3, 4, 10, 11], "global\ud55c": 3, "distribution\uc744": [3, 9, 10, 13], "\uc774\ubbf8": [3, 12, 17], "\ubaa8\ub378\uc5d0": [3, 5, 6, 9, 11, 15, 18], "\ud3ec\ud568\ud55c": 3, "\uc18c\ub7c9\uc758": [3, 5], "\uae30\ubc95": [3, 8], "learning\uc740": 3, "\uc0dd\uac01\ubcf4\ub2e4": 3, "\ud6a8\uacfc\uc801\uc774\uace0": 3, "\uc720\uc6a9\ud568": 3, "\ub300\ubd80\ubd84": [3, 6, 9], "\uc2dc\uc5d0\ub294": [3, 5, 6, 13], "\uc804\uccb4\ub97c": [3, 18], "\ud559\uc2b5\ud558\uac70\ub098": 3, "\ucd94\uac00\ud574": [3, 5], "\uc7ac\ud559\uc2b5": [3, 4, 14], "\uc704\uc5d0\uc11c": 3, "customization\uc758": 3, "\ubb38\uc81c\ub97c": [3, 8, 11, 17], "\uc77c\uc73c\ud0a4\uae30": 3, "\uc26c\uc6c0": 3, "etc": 3, "\uc544\uc8fc": 3, "\uc77c\ubd80\ub9cc\uc744": 3, "\ub300\uc0c1\uc73c\ub85c": [3, 12], "\ucee8\uc149\uc73c\ub85c": 3, "finetuning\uc744": 3, "\ud1b5\ud55c": [3, 11, 14], "\uc5f0\uad6c\ub4e4\uc774": [3, 6, 9], "\uc788\uc74c": [3, 5, 6, 8, 11, 12, 13, 14, 17], "textual": [3, 15], "invers": [3, 15], "vs": [3, 4, 12, 13, 14, 17, 18], "\ubaa8\ub378\ub4e4\uc744": [3, 18], "compress\ud560": 3, "finetuning\ud568\uc73c\ub85c\uc368": 3, "resourse\ub97c": 3, "\uc808\uc57d\ud560": 3, "backbone\uc73c\ub85c": 3, "latent": [3, 9, 10, 15, 18, 19], "\ucc44\ud0dd": [3, 14], "l": [3, 7, 19], "dm\uc758": 3, "equat": [3, 4, 6, 9, 14], "x_": [3, 4, 5, 9, 14, 15], "\uc2dc\uc810\uc5d0": 3, "noise\uac00": [3, 5, 10], "\uc11e\uc778": 3, "condit": [3, 5, 6, 14, 15, 18], "text\ub098": 3, "image\ub97c": [3, 5, 7, 11, 12, 13], "\ubc14\ub85c": [3, 5, 10], "\uc0ac\uc6a9\ud558\uc9c0\uc54a\uace0": 3, "space\ub85c": [3, 11], "embedding\ub41c": 3, "\uac12\uc744": [3, 4, 6, 9, 13, 14, 17], "us": [3, 4, 11, 12, 13, 17, 20], "clip": [3, 11, 13, 15, 17, 18], "\u03b5": [3, 4], "nois": [3, 4, 5, 6, 10, 14, 15, 16, 19], "\u03b5_": 3, "\u03b8": 3, "\ub080": 3, "\u03b5\ub97c": 3, "\uc608\uce21\ud574\ub0b4\ub294": [3, 5], "\uc989": [3, 5, 11, 12, 13, 14, 17], "ldm": [3, 7, 9], "tuning\ud560\ub54c\ub294": 3, "\ubaa8\ub4e0": [3, 4, 8, 9, 10, 11, 12, 14], "layer\uc5d0\ub300\ud574": 3, "update\ud558\ub294\uac8c": 3, "\uae30\ubcf8": 3, "\ubc29\uc2dd\uc740": [3, 8, 11], "resource\uac00": 3, "\ube44\ud6a8\uc728\uc801\uc73c\ub85c": 3, "\ub9ce\uc774\ub4e4\uace0": 3, "\uc774\ubbf8\uc9c0\uc5d0": [3, 4, 6, 9, 11, 12, 13], "overfitting\ub418\uae30": 3, "weight": [3, 4, 8, 18], "\ubcc0\ud654\ub7c9\uc744": 3, "\uccb4\ud06c": 3, "delta": [3, 8], "while": 3, "\ubd80\ubd84\uc5d0\ube44\ud574": 3, "cross": [3, 9, 15, 17], "attent": [3, 5, 7, 8, 9, 13, 14, 17], "\uc5f0\uc0b0\uc758": [3, 7], "wegith": 3, "\ubcc0\ud654\ub7c9\uc774": 3, "\uac00\uc7a5": [3, 10, 11, 12, 15], "\ud07c": 3, "fig": [3, 4, 6], "latent\uc5d0": 3, "\uc8fc\uc785\ud558\ub294": 3, "mechan": 3, "queri": [3, 7, 8, 11], "kei": [3, 7, 8, 9], "valu": [3, 4, 8], "parameter\uc5d0": 3, "\ub2e8": [3, 9, 15], "\ucc28\uc9c0": 3, "\uc758\ubbf8\ud558\ub294": [3, 19], "v": [3, 5, 7, 8, 9, 11, 13, 15, 16], "\ud3ec\ud568\ub418\ub294": 3, "k": [3, 5, 7, 8, 13, 16], "\ub9cc": [3, 5, 8, 15], "\ub098\uba38\uc9c0\ub294": [3, 9, 12], "freez": [3, 8, 15, 17], "\uc740": [3, 5, 10, 11, 12, 14, 15, 16, 17, 19], "\uc2e4\uc81c\ub85c\ub294": [3, 4], "\uc4f0\uc9c0\uc54a\ub294": 3, "\ub2e8\uc5b4\ub85c": 3, "\ud615\uc2dd\uc73c\ub85c": 3, "captioning\ud55c": 3, "\ud6c4\uc5d0": [3, 14], "\ub610": [3, 6, 9, 15, 18], "finetuning\uc911\uc5d0": 3, "\uc78a\uc5b4\ubc84\ub9ac\ub294": 3, "\ud604\uc0c1\uc774": [3, 10, 18], "\uc788\uc744\uc218\uc788\uc74c": 3, "moon": 3, "\uc0dd\uc131\ud558\uba74": [3, 12], "finetuning\ud588\ub358": 3, "moongat": 3, "\uc0dd\uc131\ud574\ubc84\ub9bc": 3, "\ubc29\uc9c0\ud558\uae30\uc704\ud574": 3, "world\uc758": 3, "image\uc5d0\uc11c": [3, 12, 13], "target": [3, 5, 9, 11, 12, 15], "\uc720\uc0ac\ud55c": [3, 7, 11, 12, 13, 15, 19], "200\uc7a5\uc758": [3, 9], "regul": 3, "\uc720\uc0ac\ud558\ub2e4": 3, "clip\uc5d0\uc11c": 3, "\ucd94\ucd9c\ud55c": 3, "space\uc0c1\uc758": 3, "vector\uac00": 3, "similar\ud558\ub2e4": 3, "joint": [3, 13, 14], "trane": [3, 12], "\uac01\uac01\uc758": [3, 9], "\uac16\ub294": 3, "rare\ud55c": 3, "key\ub97c": 3, "\ubd80\uc5ec\ud574": 3, "\ub3d9\uc2dc\uc5d0": [3, 9], "i": [3, 5, 7, 8, 10, 13, 15, 16, 17, 19], "constrain": 3, "optim": [3, 4, 9, 11, 13, 15, 19], "merg": [3, 8], "concept\uc73c\ub85c": 3, "\ud559\uc2b5\ub41c": [3, 11, 12, 14, 17], "weight\ub97c": [3, 8], "w_0": [3, 8], "appendix": 3, "a\uc5d0\ub294": 3, "\ub77c\uace0": [3, 8, 11, 17, 19], "\ub098\uc640\uc788\ub294\ub370": 3, "\uc624\ud0c8\uc790\uc77c": 3, "\uac00\ub2a5\uc131": 3, "c_": [3, 9, 15], "reg": 3, "caption\uc758": 3, "\ubaa8\ub450": [3, 4, 6, 9, 10, 11, 12, 14, 15, 18], "\ubf51\uc544": [3, 14], "concat": 3, "\uacf1\ud55c": 3, "\uac12\uacfc\uc758": 3, "norm\uc744": [3, 12], "\uacc4\uc0b0\ud588\uc744\ub54c": 3, "\uac12\uc774": [3, 4, 6, 9, 12, 13, 14, 17], "\uc791\uc740": [3, 5, 8, 11, 12], "n\uac1c\uc758": [3, 13], "attention\uc774": 3, "\ub3d9\uc791\ud558\ub294": [3, 7], "\ucc3e\uc544": [3, 11], "\ud558\ub098\ub9cc": 3, "\uc0ac\uc6a9\ud558\uc790": 3, "250": 3, "two": [3, 10, 11, 13, 15], "500": 3, "batch": [3, 8, 12, 15, 16], "8": [3, 5, 6, 7, 8, 10, 13, 16], "rate": [3, 4, 9], "10": [3, 5, 6, 14, 16], "resiz": 3, "veri": 3, "small": [3, 11, 18], "far": 3, "awai": 3, "zoom": 3, "techniqu": [3, 5, 17], "qualit": [3, 13], "evalu": [3, 4, 18], "quant": [3, 11], "align": [3, 5, 11, 17, 18], "kid": 3, "\uc5bc\ub9c8\ub098": [3, 5, 11, 14], "\ub300\uc751\ub418\ub294": 3, "\uc0dd\uc131\ud574\ub0c8\ub294\uac00": 3, "image\uc758": [3, 6, 7, 9, 11], "\ud45c\ud604\ud574\ub0c8\ub294\uac00": 3, "tabl": [3, 6, 8, 9, 12, 14], "\uc815\uc131\uc801": [3, 13], "\uc815\ub7c9\uc801": [3, 13], "\ud3c9\uac00": [3, 12, 15], "human": [3, 10, 11, 18], "prefer": [3, 17], "studi": [3, 9], "baselin": [3, 13], "customdiffus": 3, "all": [3, 8], "\uc120\ud638": 3, "inversion\uc740": [3, 11], "alignment\ub294": 3, "\uc120\ud638\ub3c4\uc640": 3, "\ube44\uc2b7\ud558\uc9c0\ub9cc": [3, 12], "alignment\uc218\uce58\ub97c": 3, "diffusion\uc774": 3, "\ub9e4\uc6b0": [3, 4, 5, 8, 11, 12, 17], "\ub192\uc544": 3, "overfitting\ub41c": [3, 9], "ablat": [3, 9, 14], "\u314cgen": 3, "\ub300\uc2e0": [3, 5, 6, 9, 11, 12, 13], "generate\ub41c": 3, "\uc5c6\uc774": [3, 4, 5, 9, 11, 12, 13, 14, 17], "\uc218\uce58\ub294": [3, 6, 14], "regulat": 3, "world": 3, "customizing\uc774": 3, "\uac00\ub2a5\ud558\uace0": 3, "resourse\uac00": 3, "Of": 3, "category\uc758": 3, "object\uc5d0": 3, "\ub300\ud574\uc11c\ub294": [3, 6], "\ub3d9\uc791\ud558\uc9c0": [3, 6], "\uc54a\uc74c": [3, 5, 11, 17], "denois": [4, 8], "implicit": [4, 16], "iclr": [4, 5, 8, 19], "2021": [4, 5, 6, 8, 13, 14], "2010": 4, "02502": 4, "april": 4, "23": [4, 12], "ddpm\uc758": [4, 6, 9, 14], "\ub2e8\uc810\uc778": 4, "markov": [4, 5], "process\ub97c": [4, 5, 14], "process\ub85c": [4, 5, 6, 14], "\uc815\uc758\ud568\uc73c\ub85c\uc11c": 4, "deterministic\ud55c": 4, "sampling\uc774": [4, 14], "\uac00\ub2a5\ud55c": [4, 5, 7, 9, 12], "determinist": [4, 14], "stochast": [4, 16], "\ubd84\uc57c\uc5d0\uc11c": [4, 6, 9], "adversari": [4, 10, 16], "\ubcf4\uc5ec\uc8fc\uace0\uc788\ub2e4": 4, "gan\uc740": [4, 10, 12], "\uacfc\uc815\uc5d0\uc11c": [4, 5, 8, 9, 11, 12], "\ubd88\uc548\uc815\uc131\uc744": [4, 12], "\ub9ce\ub2e4": 4, "generator\uc640": 4, "discriminator\uc758": 4, "imbalanced\uc5d0": 4, "\uc758\ud55c": [4, 11], "mode": [4, 8], "collaps": [4, 12], "\uadf8\ub7ec\ub358": 4, "ddpm\uacfc": 4, "ncsn\uac19\uc740": 4, "training\uad6c\uc870\uac00": 4, "\ub4f1\uc7a5\ud558\uc600\uace0": 4, "\uc131\uacf5\uc758": 4, "\ubcf4\uc5ec\uc8fc\uc5c8\ub2e4": [4, 9], "ddpm\uc740": [4, 14], "process\uc5d0\uc11c": [4, 6, 14], "\uac70\uce58\ub294\ub370": 4, "\uc774\ub54c\ubb38\uc5d0": 4, "gan\uc5d0": 4, "\ub290\ub9b0": 4, "performance\ub97c": 4, "\ubcf4\uc5ec\uc900\ub2e4": [4, 9, 11, 17], "32": [4, 5, 8, 10, 13, 14], "50k": 4, "less": 4, "than": 4, "min": [4, 8], "about": [4, 20], "20h": 4, "256": [4, 12, 13, 16, 17], "1000h": 4, "ddim\uc740": [4, 14], "chain\uc5d0": 4, "\uae30\ubc18\ud55c": 4, "\ub300\uccb4\ud558\uc600\uace0": 4, "\uacb0\uad6d": [4, 6, 13, 14], "\ube60\ub974\uace0": 4, "\ube44\uad50\uc801": 4, "\uc6b0\uc218\ud55c": [4, 12, 13], "quality\uc758": [4, 6, 9], "\uc0dd\uc131\ud574\ub0b4\uace0": [4, 9], "accel": 4, "ddpm\uacfc\ub294": 4, "\ub2e4\ub974\uac8c": [4, 15], "consistency\ud55c": 4, "\ubcf4\uc5ec\uc90c\uc73c\ub85c\uc368": 4, "latent\uac04\uc758": 4, "interpolation\uc774": 4, "\uac00\ub2a5\ud558\ub2e4": [4, 5, 9, 14], "consist": 4, "If": 4, "equival": 4, "architectur": [4, 10, 11, 16, 17, 18, 19], "process\ub294": 4, "\ub3d9\uc791\ud55c\ub2e4": 4, "\ubbf8\ub798": 4, "\uc2dc\uc810\uc744": 4, "\uc608\uce21\ud558\uae30\uc704\ud574": 4, "\ud604\uc7ac": [4, 9], "\uc2dc\uc810\uc758": [4, 14], "\uc774\uc6a9\ud55c\ub2e4": 4, "\uc2dc\uc810\uc740": 4, "\uacfc\uac70": 4, "\uac12\uc5d0\ub294": 4, "\ub3c5\ub9bd\uc801\uc778": 4, "\uac16\ub294\ub2e4": 4, "t\ub294": 4, "ddpm\uc5d0\uc11c": [4, 6, 14], "\uc88c\uc9c0\uc6b0\uc9c0\ud558\ub294": 4, "\uc911\uc694\ud55c": [4, 6, 10, 11, 12], "hyper": [4, 6, 8, 9], "parameter\uc774\ub2e4": 4, "\ub300\ucda9": 4, "1000": [4, 5], "\ubc88\uc758": 4, "\uacfc\uc815\uc744": [4, 5, 11, 19], "sequential\ud558\uac8c": 4, "\uac70\uccd0\uc57c\ud558\uace0": 4, "method": [4, 10, 13, 14], "\ubcf4\ub2e4": [4, 5, 6, 8, 11, 12, 13, 14, 15, 17], "\ud604\uc800\ud788": [4, 6], "\uc18d\ub3c4\ub97c": 4, "\uc694\uc18c\uac00": 4, "\ub41c\ub2e4": [4, 12, 17], "s": [4, 9, 10, 11, 15, 16, 17, 18, 20], "distribut": [4, 5, 13, 14, 19], "\uc815\uc758": [4, 6], "\uad6c\ud558\uae30\uc704\ud574": 4, "\uac12\uacfc": 4, "\ucc38\uc870": 4, "\uac12\ub9cc\uc744": 4, "\u03c3\ub294": 4, "process\uc758": 4, "stochastic\ud55c": 4, "chap": 4, "And": 4, "unifi": 4, "object": [4, 11, 13, 15, 18], "revers": [4, 6], "\uc608\uce21": [4, 5, 13], "\uc2dd\uc744": [4, 14], "\uc774\uc6a9\ud574": [4, 11, 19], "\uc0d8\ud50c\ub9c1": [4, 14, 17], "\uad00\uacc4": 4, "noise\ub97c": [4, 5, 6, 10], "\uc774\ubbf8\uc9c0\uc640": [4, 9, 11, 15, 18, 19], "\uacc4\uc0b0": [4, 5, 11], "fix": [4, 5], "t\uc2dc\uc810\uc758": 4, "\uc608\uce21\ud55c": 4, "\u03c3": 4, "\u03c3\uac00": 4, "\uac00\uc9c8": 4, "\uc218\uc2dd\uacfc": 4, "\ub3d9\uc77c\ud558\ub2e4": 4, "explan": 4, "acceler": [4, 14, 15], "deterministic\ud558\uae30\ub54c\ubb38\uc5d0": [4, 14], "\uacc4\uc0b0\ud560": [4, 14], "\ud544\uc694": [4, 14], "subset\uc758": [4, 14], "\uc2dc\uc810\ub9cc\uc73c\ub85c": [4, 14], "method\ub294": [4, 11, 14], "\uc57d\uac04\uc758": [4, 14], "\uc800\ud558\uac00": [4, 14], "\uc788\uc9c0\ub9cc": [4, 12, 13, 14], "comput": [4, 8, 12, 14, 15, 17, 18], "efficiency\ub97c": [4, 14], "\ucda9\ubd84\ud788": [4, 14], "\uc99d\uac00\uc2dc\ud0ac": [4, 14], "\uc788\ub2e4": [4, 6, 8, 9, 11, 12, 14, 17], "ddim\uc758": [4, 14], "relev": 4, "od": 4, "encoding\uc774": 4, "\uc720\ub3c4\ud560": 4, "table1": 4, "euqat": 4, "\u03b7": 4, "simple\ud558\uac8c": 4, "control\ud558\uae30\uc704\ud55c": 4, "\ube44\uad50": [4, 6, 13, 14, 17], "\ud69f\uc218": 4, "\ucee4\uc9c8\uc218\ub85d": [4, 6, 9], "\ub0ae\uc740": [4, 5, 6, 13, 15], "fid\ub97c": 4, "3\uc758": [4, 13], "\u03b7\uac00": 4, "step\uc5d0": [4, 6], "figur": [4, 6, 9, 11, 12, 15, 17], "step\uacfc": 4, "time\uc774": 4, "linear\ud55c": 4, "\uad00\uacc4\ub97c": [4, 6], "step\uc5d0\uc11c\ub3c4": 4, "\uc5b4\ub290\uc815\ub3c4\uc758": 4, "object\ub97c": 4, "kera": 4, "io": [4, 5, 6, 11, 12, 13], "exampl": [4, 10, 11, 15, 18], "diffusionmodel": 4, "image_s": 4, "width": [4, 14], "block_depth": 4, "super": [4, 5, 10, 12, 16, 18, 19], "normal": [4, 5, 10, 12, 16, 17], "get_network": 4, "unet": [4, 5, 15], "\uad6c\uc870": [4, 10, 12], "denorm": 4, "convert": [4, 15], "pixel": [4, 13], "back": 4, "rang": [4, 13, 15, 16], "mean": [4, 5, 15], "varianc": [4, 5], "tf": 4, "clip_by_valu": 4, "diffusion_schedul": 4, "diffusion_tim": 4, "angl": 4, "start_angl": 4, "aco": 4, "max_signal_r": 4, "end_angl": 4, "min_signal_r": 4, "diffusion_angl": 4, "signal": 4, "signal_r": 4, "co": [4, 5], "noise_r": 4, "sin": [4, 5], "note": 4, "squar": [4, 15], "sum": [4, 8], "alwai": 4, "noisy_imag": 4, "exponenti": 4, "move": 4, "averag": 4, "ar": [4, 5, 8], "ema_network": 4, "predict": [4, 5, 15, 17], "compon": 4, "calcul": 4, "pred_nois": [4, 5], "pred_imag": 4, "train_step": 4, "have": 4, "standard": [4, 10], "deviat": 4, "like": 4, "true": [4, 5, 8, 16], "shape": [4, 5, 10, 11, 15, 16, 18], "batch_siz": [4, 10, 19], "uniform": 4, "minval": 4, "maxval": 4, "mix": 4, "accordingli": 4, "gradienttap": 4, "tape": 4, "separ": [4, 10, 15], "noisi": 4, "noise_loss": 4, "image_loss": 4, "onli": [4, 9, 13], "metric": [4, 5, 12, 15, 18], "trainable_weight": 4, "apply_gradi": 4, "noise_loss_track": 4, "update_st": 4, "image_loss_track": 4, "m": [4, 5, 7, 9], "name": [4, 8], "result": [4, 6, 8], "reverse_diffus": 4, "initial_nois": 4, "diffusion_step": 4, "num_imag": 4, "step_siz": 4, "import": [4, 6, 8], "line": 4, "first": [4, 8], "pure": 4, "its": 4, "assum": 4, "nonzero": 4, "next_noisy_imag": 4, "current": [4, 5], "ones": 4, "eval": 4, "remix": 4, "next": 4, "next_diffusion_tim": 4, "next_noise_r": 4, "next_signal_r": 4, "thi": [4, 5, 8, 11, 15, 20], "generated_imag": 4, "probabilist": [5, 8], "2006": [5, 8], "11239": [5, 8], "pytorch": [5, 8, 10, 13, 16, 19], "implement": [5, 8, 9, 15, 16, 19], "review": [5, 8, 11, 20], "pr": [5, 8, 15], "409": [5, 8], "beomsoo": [5, 8], "park": [5, 8], "apr": [5, 8, 10, 12, 16, 19], "19": [5, 8], "sourc": [5, 9, 10, 11, 12, 13, 18], "velog": [5, 12, 13], "yetsyl0705": 5, "what": 5, "variat": [5, 19], "inference\ub85c": 5, "\ud559\uc2b5\uc2dc\ucf1c": [5, 8], "parameter": 5, "chain": [5, 14, 15], "model\uc740": [5, 7, 8, 11], "markov\uac00": 5, "distribution\uc758": 5, "\ud615\ud0dc\ub97c": 5, "\ub54c\uae4c\uc9c0": 5, "\ub354\ud574\uac00\ub294": 5, "\uc5ed\uc73c\ub85c": 5, "\uac70\uce58\uba70": 5, "\uad6c\uc131\ub428": 5, "\uc815\uc758\ud558\uae30": 5, "\uc27d\uace0": 5, "\ud559\uc2b5\uc2dc\ud0a4\ub294": [5, 12], "\uac83\ub3c4": [5, 19], "\ud3b8\ub9ac\ud568": 5, "\ub192\uc740": [5, 6, 8, 9, 11, 13, 14, 17], "\ud488\uc9c8\uc758": [5, 12], "\uc0dd\uc131\uc774": [5, 9, 13, 14, 17], "\ubcc0\ubd84\ucd94\ub860": [5, 19], "\uc0ac\ud6c4\ud655\ub960": 5, "posterior": [5, 13, 19], "\ubd84\ud3ec": [5, 13], "\ub2e4\ub8e8\uae30": [5, 19], "\uc26c\uc6b4": [5, 12, 19], "\ud655\ub960\ubd84\ud3ec": 5, "\uadfc\uc0ac": 5, "approxim": [5, 19], "\ud45c\ud604\uc2dd\uc5d0": 5, "\ud45c\ud604\ud558\ub294": [5, 11, 15], "\ubcf4\ud1b5": [5, 8, 10, 11, 12], "parameter\uc758": 5, "\ud45c\ud604": 5, "\uc2dd\uc758": 5, "\ucc28\uc218\ubcf4\ub2e4": 5, "\uc218\ub85c": 5, "\uc120\ud0dd": [5, 13], "ex": [5, 12], "3\ucc28": 5, "\ud45c\ud604\uc2dd": 5, "2\uac1c": 5, "\ud558\ubbc0\ub85c": 5, "\ucc28\uc218\ub85c\uc758": 5, "\ud568\uc218": [5, 12, 13, 14], "3d": 5, "2d": 5, "\uc0c1\ud0dc\uc5d0\uc11c": [5, 12], "\uc0c1\ud0dc\ub85c": [5, 15], "\ub118\uc5b4\uac08": 5, "\ub2e8\uacc4\uc758": [5, 11], "\uc0c1\ud0dc\uc5d0\ub9cc": 5, "\ubc1b\ub294": [5, 10], "\ud655\ub960": [5, 19], "graphic": [5, 17], "left": [5, 7, 8, 14, 17, 19], "mid": [5, 8], "_0": 5, "right": [5, 7, 8, 14, 17, 19], "prod_": 5, "quad": 5, "n": [5, 7, 8, 13], "sqrt": [5, 7], "beta_t": 5, "chain\uc73c\ub85c": 5, "data\uc5d0": [5, 12], "\ucd94\uac00\ud560": 5, "schedul": [5, 6, 14, 15], "beta_1": 5, "\ub354\ud574\uc900\ub2e4": 5, "\uc774\uba74": [5, 17], "mean\uc778": 5, "\uc774\uc804": [5, 8, 10], "\uac16\uc9c0": 5, "\ub178\uc774\uc988\uac00": 5, "\uc99d\uac00\ud568": 5, "\ub2e8\uc21c\ud788": [5, 11, 12], "noise\ub9cc\uc744": 5, "\ub354\ud574\uc8fc\ub294\uac8c": 5, "scaling\ud558\ub294": 5, "variance\uac00": 5, "\ubc1c\uc0b0\ud558\ub294": 5, "\ub9c9\uae30": 5, "\uc704\ud568": [5, 12], "x_1": 5, "x_0": 5, "\ub9cc\ub4dc\ub294": [5, 19], "x_t": [5, 7, 14], "\uc644\uc804": 5, "destroy\ub41c": 5, "\uc0c1\ud0dc": 5, "p_": [5, 8, 13, 14, 16, 19], "boldsymbol": 5, "mu": [5, 10, 14, 19], "sigma": [5, 10, 14, 19], "\uac00\uc6b0\uc2dc\uc548": 5, "\ub178\uc774\uc988\ub97c": 5, "1994\ub144": 5, "process\uac00": 5, "\uac00\uc6b0\uc2dc\uc548\uc774\uba74": 5, "process\ub3c4": 5, "\uac00\uc6b0\uc2dc\uc548\uc73c\ub85c": 5, "\uc4f0\uba74": 5, "\ub41c\ub2e4\ub77c\ub294": 5, "\uc99d\uba85\uc774": 5, "\ud568": [5, 8, 11, 12, 13, 14, 17], "\uc6b0\ub9ac\uac00": [5, 12], "\ud574\uc57c": 5, "\uac83\uc740": [5, 11, 12], "\ubcf4\uace0": 5, "\ud3c9\uade0": [5, 15, 19], "mu_": 5, "\ubd84\uc0b0": [5, 14, 19], "sigma_": [5, 14, 15], "hierarach": 5, "vae\uc5d0\uc11c\uc758": 5, "\uacfc\uc815\uacfc": 5, "\ube44\uc2b7\ud568": [5, 11], "\ubaa9\uc801\uc740": 5, "\uc81c\uac70\ud560": 5, "\uac83\uc778\uac00": 5, "\uc774\ub2e4": [5, 8, 14], "\ub4e4\uc5b4\uc654\uc744": 5, "\uc608\uce21\ud560": 5, "\uc608\uce21\uc774": 5, "\uac00\ub2a5\ud574\uc9d0": [5, 11], "mathbb": [5, 7, 8, 15, 16, 19], "log": [5, 8, 13, 14, 16, 19], "leq": 5, "_q": [5, 7], "sum_": [5, 8, 19], "geq": 5, "\ubcf8": [5, 8, 13, 14, 17], "neg": [5, 9], "likelihood\ub97c": 5, "\ucd5c\uc18c\ud654": 5, "\ubc29\ud5a5\uc73c\ub85c": [5, 9, 16], "\uc9c4\ud589": [5, 9, 13, 14, 17], "\uc218\uc2dd\uc744": [5, 12, 14], "elbo": [5, 13], "evid": [5, 13], "lower": [5, 13, 17], "bound": 5, "\uc6b0\ud56d\uacfc": 5, "\uc815\ub9ac\ud558\uace0": 5, "\ud480\uc5b4\ub0b4\uba74": 5, "elbo\uc758": 5, "\uc5ed\ud560\uc740": 5, "\uad00\ucc30\ud55c": 5, "\ud798\ub4e0": 5, "\ubd84\ud3ec\ub97c": [5, 12, 16, 19], "\uc774\ub8e8\uace0": 5, "\uc870\uae08": 5, "\ubd84\ud3ec\uc778": 5, "\ud45c\ud604\ud558\ub824": 5, "\ucc28\uc774": 5, "kl": [5, 7, 16, 19], "diverg": 5, "\ud558\uae30": [5, 13, 15, 19], "\uc0ac\uc6a9\ub41c\ub2e4": 5, "underbrac": 5, "d_": [5, 8, 16], "mathrm": 5, "_1": 5, "\ub098\uc628\ub2e4": [5, 14], "term\uc73c\ub85c": 5, "\ud559\uc2b5\uc2dc\ud0b4": 5, "reconstruct": [5, 11, 15, 19], "\ub9e4": 5, "\ub2e8\uacc4\uc5d0\uc11c": [5, 11], "\uc9c0\uc6b0\ub294": 5, "\uc9c0\uc6c0": 5, "\ucd5c\uc885": 5, "ddpm\uc5d0\uc11c\ub294": [5, 6], "induct": 5, "bias\ub97c": [5, 10, 11], "\ub298\ub824": 5, "stable\ud558\uace0": 5, "\uc131\ub2a5\ub3c4": [5, 18], "\uac1c\uc120\ud560": [5, 6], "\uc788\uc5c8\uc74c": [5, 8, 11, 12], "bia": 5, "\ub9cc\ub098\ubcf4\uc9c0": 5, "\ubabb\ud588\ub358": [5, 15], "\uc0c1\ud669\uc5d0\uc11c": 5, "\uc815\ud655\ud55c": [5, 11, 12], "\uc608\uce21\uc744": 5, "\uac00\uc815": 5, "\ud480\ub824\ub294": 5, "\ubb38\uc81c\uc5d0": 5, "\uc801\uc6a9\ud558\ub294": [5, 8, 15], "\uace0\uc815": [5, 6, 11], "\ud588\ub354\ub2c8": 5, "\uc798\ub428": 5, "02\ub85c": 5, "linear\ud558\uac8c": 5, "image\uc5d0": [5, 11], "\uac00\uae4c\uc6b8\uc218\ub85d": 5, "\uc801\uac8c": [5, 13], "\uc8fc\ub294": 5, "\ubc29\uc2dd\uc73c\ub85c": [5, 8, 9, 14], "\uc124\uc815": [5, 8, 13], "\uc5d0\ub294": [5, 17], "parameter\uac00": 5, "\uc5c6\uc5b4": [5, 12, 17], "\ub418\uae30": [5, 8, 12], "\uc0ad\uc81c": 5, "tild": [5, 6], "beta": 5, "progress": 5, "posterior\ub97c": 5, "\uc608\uce21\ud558\ub294": 5, "\ub354\ud574": 5, "\ub9cc\ub4e4\uc5c8\uc744\ub54c": 5, "\ubcf5\uc6d0": 5, "simplic": 5, "sjina0722": 5, "\ub17c\ubb38": [5, 8, 12, 13, 15], "\ub9ac\ubdf0": [5, 8], "\uc0c1\uc218\ub85c": 5, "\uac00\uc815\ud588\uace0": 5, "\ubc1b\uae30": [5, 9], "\ud559\uc2b5\uc2dc\ud0a4\uc9c0": 5, "\uc54a\uc544\ub3c4": 5, "\ub41c\ub2e4\uace0": 5, "\uc0dd\uac01\ud574": 5, "term\uc744": 5, "\uc81c\uac70": 5, "residu": [5, 12, 14, 15, 17], "estim": [5, 16, 19], "\uad6c\ud558\uc9c0": [5, 16], "\uc54a\uace0": [5, 8, 16, 18, 19], "epsilon_": [5, 7, 14], "\uad6c\ud574": 5, "\uc815\ud655\ub3c4\ub97c": 5, "\ub192\uc784": 5, "begin": 5, "d": [5, 7, 8, 10, 16], "int_": 5, "delta_": 5, "sigma_1": 5, "arrai": 5, "ll": [5, 8, 15], "infti": 5, "255": 5, "end": [5, 10], "case": [5, 18], "\uc0ac\uc774\ub85c": 5, "linearli": 5, "\ub2e8\uacc4\uc5d0\ub294": 5, "\ucd94\uac00\ud558\uc9c0": 5, "\uc0ac\uc774\uc758": [5, 12], "divergence\ub97c": 5, "\ub098\ud0c0\ub0c4": [5, 12], "dimension": 5, "\uc88c\ud45c": 5, "final": 5, "\uc704\uc640": [5, 8, 12, 14], "\ub098\ud0c0\ub09c\ub2e4": 5, "ground": [5, 12, 16], "truth": [5, 12, 16], "output\uac04": 5, "\uc904\uc774\ub294": 5, "\uacfc\uc815\uc774": 5, "denoising\uacfc": 5, "\ube44\uc2b7\ud574": 5, "ddpm\uc774\ub77c\ub294": 5, "\uc774\ub984\uc774": [5, 17], "\ubd99\uc74c": 5, "objective\uc744": 5, "\uc5d0\uc11c\ubfd0\ub9cc": 5, "\ud070": [5, 6, 8, 10, 11, 12], "t\uc5d0": 5, "\ub300\ud574\uc11c\ub3c4": [5, 11, 12, 14], "\uac00\ub2a5\ud558\uae30": 5, "\ud6a8\uacfc\uc801": 5, "psuedo": 5, "algorithm": 5, "\ub354\ud574\ub098\uac00\ub294": 5, "epsilon": [5, 7, 14, 15], "\uc5bc\ub9c8\ub9cc\ud07c": 5, "\ub354\ud574\uc84c\ub294\uc9c0\ub97c": 5, "\ud559\uc2b5\ud55c\ub2e4": 5, "step\uc758": 5, "gaussian": [5, 8, 10, 14, 15, 19], "\ucd94\uac00\ub418\uc5c8\ub294\uc9c0\ub97c": 5, "\uc608\uce21\ud558\ub3c4\ub85d": [5, 6], "\ud559\uc2b5\ub41c\ub2e4": [5, 11], "\ucf54\ub4dc\uc5d0\uc11c\ub294": [5, 8], "\ub79c\ub364": 5, "\ub178\uc774\uc988\uc640": 5, "\uc2dc\uac04": [5, 8, 12], "\ub2e8\uacc4": [5, 16], "t\ub85c": 5, "\uc5bb\uace0": 5, "p_loss": 5, "x_start": 5, "default": [5, 8], "lambda": [5, 12, 15], "torch": [5, 8, 15, 19], "randn_lik": [5, 15], "q_sampl": 5, "do": [5, 10, 11], "from": [5, 10, 16], "set": [5, 8, 12, 15, 17], "slow": 5, "down": 5, "25": [5, 8, 16], "seem": 5, "fid": [5, 6, 7, 10, 13, 14, 17], "significantli": [5, 17], "x_self_cond": 5, "self_condit": 5, "no_grad": 5, "model_predict": 5, "pred_x_start": 5, "detach_": 5, "take": 5, "model_out": 5, "pred_x0": 5, "pred_v": 5, "predict_v": 5, "rais": [5, 15], "valueerror": [5, 15], "unknown": [5, 15], "loss_fn": 5, "reduct": [5, 15], "reduc": [5, 15], "extract": 5, "loss_weight": 5, "network\ub97c": [5, 10], "\ud559\uc2b5\ud558\uace0": [5, 13], "\ub098\uba74": 5, "noise\uc5d0\uc11c": 5, "\uc2dc\uc791\ud574\uc11c": [5, 10], "\uc21c\ucc28\uc801\uc73c\ub85c": [5, 13], "markovian": [5, 14], "\ucd94\uac00\ud558\uace0": 5, "p_sampl": 5, "int": [5, 16, 19], "devic": [5, 15], "batched_tim": 5, "full": [5, 6, 9, 18], "long": [5, 15], "model_mean": 5, "model_log_vari": 5, "p_mean_vari": 5, "clip_denois": 5, "pred_img": 5, "exp": 5, "backbon": 5, "u": [5, 7, 15, 17], "net": [5, 7, 15, 17], "\uac01": [5, 8, 10, 11, 12, 13, 14, 15, 18], "upsampl": [5, 14, 17], "\ub2e8\uacc4\ub294": 5, "resnet": [5, 14], "convnext": 5, "\ube14\ub85d": 5, "groupnorm": [5, 14], "upsampling\uc73c\ub85c": 5, "block_klass": 5, "resnetblock": 5, "group": 5, "resnet_block_group": 5, "modulelist": 5, "dim_in": 5, "time_emb_dim": 5, "time_dim": 5, "prenorm": 5, "linearattent": 5, "downsampl": [5, 14, 18], "dim_out": 5, "is_last": 5, "conv2d": [5, 8], "init_dim": 5, "out_dim": 5, "dim_mult": 5, "learned_vari": 5, "learned_sinusoidal_cond": 5, "random_fourier_featur": 5, "learned_sinusoidal_dim": 5, "16": [5, 7, 8, 10, 13, 14, 15], "determin": 5, "dimens": [5, 8], "input_channel": 5, "init_conv": 5, "in_out": 5, "list": 5, "random_or_learned_sinusoidal_cond": 5, "sinu_pos_emb": 5, "randomorlearnedsinusoidalposemb": 5, "fourier_dim": 5, "sinusoidalposemb": 5, "time_mlp": 5, "gelu": 5, "num_resolut": 5, "len": [5, 16], "ind": 5, "enumer": [5, 15, 16], "mid_dim": 5, "mid_block1": 5, "mid_attn": 5, "mid_block2": 5, "default_out_dim": 5, "final_res_block": 5, "final_conv": 5, "zeros_lik": 5, "r": [5, 6, 7, 8, 9, 18], "clone": 5, "block1": 5, "block2": 5, "attn": [5, 9], "pop": 5, "resolution\uc5d0": [5, 12], "conv\uc5d0\uc11c": 5, "\ucc28\uc6d0\uc744": 5, "3\ubc30\ub85c": 5, "\ub298\ub9ac\uace0": 5, "v\ub85c": 5, "\ubd84\ud574": 5, "head": [5, 9, 14], "dim_head": 5, "hidden_dim": 5, "to_qkv": 5, "to_out": 5, "qkv": 5, "chunk": [5, 15], "rearrang": 5, "sim": [5, 7, 16], "einsum": 5, "j": 5, "softmax": [5, 7, 13], "layernorm": 5, "block\uc5d0": [5, 14], "transform": [5, 6], "sinusoid": 5, "posit": [5, 9], "embedding\uc774": [5, 11], "\ucd94\uac00\ub3fc\uc11c": 5, "\uad6c\ubd84\ub428": 5, "half_dim": 5, "math": 5, "10000": 5, "arang": 5, "score": [5, 12, 13, 17], "is\ub85c": 5, "uncondit": [5, 14], "model\uc778\ub370\ub3c4": 5, "model\ubcf4\ub2e4": 5, "\uc6b0\uc6d4": 5, "codelength\uc5d0\uc11c": 5, "\ucc28\uc774\uac00": [5, 6, 11], "\uc5c6\uae30": [5, 12], "overfitting\uc758": 5, "\uac00\ub2a5\uc131\ub3c4": 5, "\uc801\uc74c": 5, "incept": [5, 13], "v3\uc73c\ub85c": 5, "\uacc4\uc0b0\ud55c": [5, 16], "\ud55c\ubc88": [5, 15, 19], "dataset\uc5d0": [5, 13], "\ud559\uc2b5\ub418\uba74": [5, 11], "label": [5, 12, 14, 17], "\ub4f1\uc758": [5, 11, 12], "\uacc4\uc0b0\ud558\ub294": [5, 19], "\uc131\uc801\uc774": 5, "\uc88b\uace0": 5, "variance\ub97c": [5, 6], "\uc0ac\uc6a9\ud588\uc744": [5, 11, 14], "\ub54c\uc5d0\ub3c4": 5, "\uac10\uc18c\ud558\uc9c0": 5, "2102": [6, 13], "09672": 6, "alex": 6, "nichol": 6, "ddpm\uc744": 6, "\uc57d\uac04": 6, "quality\ub97c": [6, 11], "\uc720\uc9c0\ud558\uace0": [6, 10], "likelihood\uc218\uce58\ub3c4": 6, "\ud5a5\uc0c1\ub41c": [6, 11], "sampling\uc2dc": 6, "base": [6, 9, 10, 11, 14, 17, 18, 20], "step\uc73c\ub85c": [6, 14], "\ub0bc": [6, 14], "scale\uacfc": [6, 10], "quailty\uc640": 6, "\uc218\uce58\uac04\uc758": 6, "ho": 6, "et": [6, 12], "al": [6, 12], "\uc654\ub2e4": 6, "quality\uc5d0": 6, "\ubc18\ud574": 6, "\ubaa8\ub378\uc5d0\ube44\ud574": 6, "\ub5a8\uc5b4\uc84c\ub2e4": 6, "ddpm\uc774": 6, "diversity\uac00": [6, 14], "dataset": [6, 11, 12, 13, 14, 16, 17], "cifar": [6, 16], "lsun": 6, "\uc5d0\uc11c\ub294": [6, 15, 16, 17], "\ub3d9\uc791\ud588\uc9c0\ub9cc": 6, "divers": [6, 14, 15], "dataset\uc5d0\uc11c\uc758": 6, "\ub3d9\uc791\uc740": 6, "\uc99d\uba85\ub418\uc9c0": 6, "\ubabb\ud588\ub2e4": 6, "\uc218\uce58": 6, "\uac1c\uc120": [6, 14], "imagenet\uac19\uc740": 6, "dataset\uc5d0\uc11c\ub3c4": 6, "\ub3d9\uc791": 6, "process\uc5d0\uc11c\uc758": 6, "term": [6, 12, 19], "\uc81c\uc548\ud558\uc600\ub2e4": 6, "\ud6e8\uc52c": [6, 12], "\ub0b4\ub294": [6, 8, 11], "\ud655\uc778": [6, 9, 13, 17], "\uc5f0\uad6c\ub4e4\uc5d0\uc11c": 6, "loglikelihood": 6, "\uc218\uce58\uc640": 6, "sample\uc758": 6, "quality\uac04\uc758": 6, "\uc5f0\uad00\uc131\uc744": 6, "\ub9ce\uc558\ub2e4": 6, "distribution\uc5d0": [6, 12], "model\uc774": 6, "\uc218\uce58\ud654\ud55c": 6, "\ub290\ub08c": 6, "\uc218\uce58\uac00": 6, "\uc88b\uc544\uc9c0\uba74": 6, "quality\ub3c4": 6, "\uc99d\uac00\ud558\ub294": 6, "\uacbd\ud5a5\uc744": [6, 9, 12], "\ubcf4\uc600\ub2e4": [6, 9], "ddpm\uc5d0\uc11c\ub3c4": 6, "\uc218\uce58\ub97c": [6, 14], "\uac1c\uc120\ud55c\ub2e4\uba74": 6, "\uc99d\uac00\ud560": 6, "\uc788\uc9c0": [6, 12], "\uc54a\uc744\uae4c": 6, "angeloyeo": 6, "github": [6, 8, 11, 12, 13, 15], "2020": 6, "07": 6, "17": [6, 14], "mle": 6, "html": [6, 12], "process": [6, 11, 13, 15, 16], "\uc785\ud78c": [6, 9], "\ud615\ud0dc": 6, "denoising\uc5d0": 6, "parameter\ub85c": 6, "b_": 6, "noising\ud560": 6, "denoising\uc744": 6, "\uc544\ub798\uc640\uac19\uc774": 6, "\uc0ac\uc6a9\ud574\ub3c4": 6, "\ubcf4\uc5ec\uc11c": [6, 12], "\ubb38\uc7a5": 6, "\uc758\ubb38\uc810": 6, "\uc0ac\uc2e4": 6, "\uc815": 6, "\ubc18\ub300\uc758": 6, "\uc5ed\ud560\uc744": 6, "parameter\uc778\ub370": 6, "\ubcf4\uc600\uace0": 6, "fix\ub97c": 6, "\ud558\ub294\uac8c": 6, "\ub9de\uc744\uae4c": 6, "step\uac04": 6, "\ucc28\uc774\ub97c": [6, 15], "\ube44\uad50\ud574\ubcf4\uba74": 6, "step\uc774": [6, 14], "\ub450\uac1c\uc758": [6, 12], "\uac70\uc758": [6, 12], "\ub3d9\uc77c\ud574\uc9c4\ub2e4": 6, "2\ub97c": 6, "\uc131\ub2a5\uc740": 6, "\ucd08\ubc18\uc5d0": [6, 16], "\uacb0\uc815\ub418\ub294\ub370": 6, "\ucd08\ubc18\uc5d0\ub294": 6, "\uac12\uc758": 6, "\uacb0\uc815\ub418\ub294": 6, "\ubd80\ubd84": [6, 12, 13], "\uae09\uaca9\ud558\uac8c": 6, "\ub5a8\uc5b4\uc9c0\ub294": 6, "\ub450\uace0": 6, "non": [6, 14], "\ub450\ub294\uac83\uc740": 6, "\uc124\uacc4\uc758": 6, "miss": 6, "\ud559\uc2b5\ud558\uae30\uc5d0\ub294": 6, "\ubc94\uc704\uac00": 6, "\ub108\ubb34": [6, 9, 12, 13], "\uc791\uc544\uc11c": 6, "interpol": 6, "predict\ud558\ub3c4\ub85d": 6, "\uc124\uacc4": 6, "hybrid": [6, 14], "l_": [6, 14], "hyprid": 6, "simpl": [6, 14, 18], "\u03bbl_": 6, "vlb": 6, "\uc774\ubbf8\uc9c0\uc5d0\ub300\ud574": 6, "\ub3d9\uc791\ud558\uc9c0\ub9cc": 6, "32x32": [6, 14], "64x64": [6, 17, 18], "\uc54a\ub294\uac83\uc744": 6, "scheduling\uc5d0\uc11c": 6, "mode\uc758": 6, "limitation\uc774": 6, "\uc788\uc74c\uc744": [6, 11, 12], "\uc9c0\uc801": 6, "direct\ub85c": 6, "\ucd5c\uc801\ud654\ud558\ub3c4\ub85d": 6, "\uc124\uacc4\ud558\uba74": 6, "best": [6, 9, 13, 14], "\uc774\ubbf8\uc9c0\uc640\uac19\uc774": 6, "\uc790\uccb4\uac00": [6, 11], "unstable\ud574\uc11c": 6, "\ucd5c\uc801\ud654\uc5d0\ub294": 6, "\uc5b4\ub824\uc6c0\uc774": 6, "\uc904\uc774\uae30\uc704\ud574": 6, "\ub3c4\uc785": 6, "2\uc5d0\uc11c": 6, "\ub9d0\uae30\ub294": 6, "loss\uc758": 6, "\ubcc0\ud654\uc5d0": 6, "\uc601\ud5a5\uc774": 6, "\uc5c6\uc73c\ubbc0\ub85c": 6, "\ud655\ub960\uc801\uc73c\ub85c": [6, 10], "\ucd08\ubc18\uc758": 6, "sampling\ud574\uc11c": 6, "\ud559\uc2b5\ud558\ub3c4\ub85d": 6, "\uc801\uc6a9\ud574\ubcf8": 6, "\ubcf4\uc784": [6, 12, 13], "sampling\uc744": [6, 13], "\uc801\uc6a9\ud558\uba74": 6, "\uc801\uc6a9": [6, 13], "\uc804\ubcf4\ub2e4": 6, "\uc88b\uc9c0": [6, 9], "\ubcf4\uc778\ub2e4": [6, 9], "\ub2e4\uc18c": [6, 13], "\ucde8\uc57d\ud588\ub358": 6, "imagenet": [6, 11], "64x64\uc640": 6, "cidar": 6, "\uae30\uc900": [6, 13, 14], "convolut": [6, 10, 12, 13], "\ubaa8\ub378\uc774\ub098": 6, "\ubaa8\ub378\uc911\uc5d0\uc11c\ub294": 6, "\ub6f0\uc5b4\ub098\uc9c0\ub9cc": 6, "fulli": [6, 12], "\ube44\ud574\uc11c\ub294": 6, "\ubd80\uc871\ud55c": [6, 15], "\uba74\uc774": 6, "speed\ub97c": 6, "\ub192\uc774\uae30": 6, "\uba87\uba87": 6, "step\ub9cc": 6, "\uac00\ub3c4": 6, "fid\uac12\uc744": 6, "metric\uc73c\ub85c": 6, "biggan": [6, 14], "big": 6, "deep": [6, 17], "\ubaa8\ub378\ubcf4\ub2e4": [6, 13, 18], "\ud0c0\uac9f\uc5d0": 6, "\uc218\uce58\ub098": 6, "recal": 6, "metric\uc5d0\uc11c": 6, "capacity\ub97c": 6, "\uac00\uc9c4": [6, 9, 11, 12, 13, 15, 19], "fid\uc640": [6, 14], "nll": [6, 12], "\ud06c\uae30\uc640": 6, "\ud559\uc2b5\ub7c9": 6, "\uc5b4\ub290\uc815\ub3c4": 6, "\ube44\ub840\ud568": 6, "synthesi": [7, 10, 15], "2022": [7, 12, 17], "2112": 7, "10752": 7, "compvi": 7, "namkyeong": 7, "cho": 7, "31": [7, 11, 15], "\uc624\ub298": [7, 10], "\uc54c\uc544\ubcfc": [7, 10, 18], "model\uc785\ub2c8\ub2e4": 7, "\ub2e4\ub918\ub358": [7, 10], "\uc720\uc0ac\ud558\uac8c": [7, 18], "\ubaa8\ub378\uc785\ub2c8\ub2e4": [7, 10], "\ucef4\ud4e8\ud130": 7, "\uc790\uc6d0\uc758": 7, "\uc18c\ubaa8\ub97c": 7, "\uc904\uc774\uba74\uc11c": 7, "\uc5bb\ub294\uac83\uc774": 7, "\ubaa9\ud45c\uc785\ub2c8\ub2e4": [7, 18], "\uc804\ubc18\uc801\uc73c\ub85c": 7, "\uc8fc\uc5b4\uc84c\uc744\ub54c": 7, "encod": [7, 13, 15, 16, 17, 18, 19], "\ud1b5\ud574\uc11c": [7, 10], "\uc778\ucf54\ub529": 7, "\ud558\uace0": 7, "hat": [7, 15], "\ub514\ucf54\ub529\uc744": 7, "\ud55c\ub2e4": [7, 11, 14, 17], "\ub418\ub3c4\ub85d": [7, 9], "\ub300\ud574\uc11c": [7, 10, 11, 12, 15, 16], "\ud14c\uc2a4\ud2b8\ub97c": 7, "\uc9c4\ud589\ud558\uc600\ub2e4": 7, "space\uc5d0\uc11c": [7, 11], "\ubd84\uc0b0\uc774": 7, "\ucee4\uc9c0\uc9c0": 7, "\uc54a\ub3c4\ub85d": 7, "divergence\uc640": 7, "vector": [7, 10, 11, 13, 15], "quantiz": [7, 13], "vq": 7, "\ud65c\uc6a9\ud558\uc600\ub2e4": 7, "\uc774\ubbf8\uc9c0\uc678": 7, "\ud14d\uc2a4\ud2b8\ub098": 7, "semat": 7, "map\uacfc": 7, "\uc815\ubcf4\ub294": 7, "tau_": 7, "\uc804\ub2ec\uc744": 7, "\ud558\uc600\uace0": 7, "q": [7, 13, 14], "phi_i": 7, "z_i": 7, "_k": 7, "_v": 7, "\uc815\uc758\ub418\uace0": 7, "\uc911\uac04\uc758": 7, "represent": [7, 13], "project": [7, 8, 14], "matrix\uc774\ub2e4": 7, "attention\uc758": 7, "value\uc5d0": 7, "\ud574\ub2f9\ud558\uba70": 7, "qk": 7, "cdot": [7, 16], "\uc5f0\uc0b0\uc774": 7, "\uc9c4\ud589\ub41c\ub2e4": 7, "\ud568\uc218\ub294": 7, "\uac19\uc774\ud45c\ud604\ub41c\ub2e4": 7, "z_t": 7, "\uc8fc\ubaa9\ud560\ub9cc\ud55c": 7, "model\uc5d0\uc11c": 7, "dm": [7, 14], "function\uc73c\ub85c": [7, 13, 14], "\uc9c4\ud589\uc2dc\ud0a4\ub294\ub370": 7, "\ubc14\uafb8\uba74\uc11c": 7, "\uc591\uc744": 7, "\uc904\uc600\ub2e4\ub294": 7, "\uc810\uc774\ub2e4": [7, 14], "\uc2e4\ud5d8\uc744": 7, "\uc9c4\ud589\ud558\uc600\ub294\ub370": 7, "\uadf8\uc911": 7, "\uc77c\ubd80\ub9cc": 7, "\uc18c\uac1c\ud558\ub3c4\ub85d": 7, "\ud558\uaca0\ub2e4": 7, "dataset\uc5d0\uc11c": [7, 9, 11, 13], "\ubf51\uc740": [7, 10], "\uc0d8\ud50c\uacfc": [7, 12], "sample\ub4e4\uc785\ub2c8\ub2e4": 7, "sampl": [7, 9, 14, 15, 16, 17, 19], "laion": [7, 9], "\ub098\uc628": [7, 13, 14, 17, 19], "\uc778": 7, "\uc801\uc808\ud55c": 7, "\uc810\uc218\uc640": 7, "\ud6a8\uc728\uc131\uc744": 7, "\ubcf4\uc5ec\uc8fc\uc5c8\uc2b5\ub2c8\ub2e4": 7, "layout\uc774": 7, "\uc8fc\uc5b4\uc84c\uc744": 7, "\uae30\ubc18\uc73c\ub85c": [7, 9, 12, 15, 19], "layout": 7, "\uc0d8\ud50c": [7, 10], "lora\ub294": 8, "peft": 8, "effeci": 8, "\ud558\ub098": [8, 13], "pre": [8, 9, 11, 15], "\uace0\uc815\ud55c": 8, "\ucc44\ub85c": 8, "\uba87": [8, 11, 12, 16], "\uac1c\uc758": [8, 10, 11, 12, 13, 15], "dens": 8, "fc": 8, "layer\ub9cc": 8, "downstream": 8, "task\uc758": [8, 12], "\uc5f0\uc0b0\ub7c9\uc744": 8, "\uc904\uc77c": [8, 11], "gpt": 8, "3\uc744": 8, "\uae30\uc900\uc73c\ub85c": 8, "parameter\ub294": 8, "10000\ubc30": 8, "gpu": 8, "\uba54\ubaa8\ub9ac\ub294": 8, "3\ubc30\ub97c": 8, "latency\uac00": 8, "\uc5c6\uc74c": 8, "\ud30c\ub77c\ubbf8\ud130\ub97c": 8, "\ud29c\ub2dd\ud558\ub294": 8, "\ud30c\ub77c\ubbf8\ud130\ub9cc\uc744": 8, "\ud29c\ub2dd\ud568\uc73c\ub85c\uc368": 8, "\uc790\uc6d0\uc73c\ub85c\ub3c4": 8, "\ub192\uac8c": 8, "\uc720\uc9c0\ud558\ub294": 8, "\ubc29\ubc95\ub860": 8, "task": [8, 12, 13, 16, 17], "\uc0ac\uc6a9\ud574": [8, 9, 11, 17], "\ud558\ub294\uac83": 8, "upstream": 8, "\ud559\uc2b5\uc2dc\ud0a4\ub294\uac83": 8, "\uc694\uccad\uc758": 8, "\uc2dc\uc791\ubd80\ud130": 8, "\uc644\ub8cc\uae4c\uc9c0": 8, "\uac78\ub9ac\ub294": 8, "llm\uc740": 8, "\ub9de\uac8c": 8, "\uc2dc\ud0b4": 8, "tuning\uc5d0\uc11c": 8, "\ud559\uc2b5\uc2dc\ud0a4\uba74": 8, "roberta": 8, "\ub2ec\uc774": 8, "\uac78\ub9bc": 8, "\uc5f0\uad6c\uc5d0\uc11c": 8, "over": [8, 12, 17], "model\ub4e4\uc740": 8, "intrins": 8, "dimension\uc5d0": 8, "\uae30\ubc18\ud558\uace0": 8, "\uc0ac\uc2e4\uc5d0": 8, "\uae30\ubc18\ud574": 8, "\uc800\uc790\ub294": [8, 11], "\uacfc\uc815\uc5d0\uc11c\ub3c4": 8, "\uac16\uace0": 8, "\uac00\uc815\ud568": [8, 13], "\uace0\uc815\ud558\uace0": [8, 13], "decomposit": 8, "matrices\ub97c": 8, "\ucd5c\uc801\ud654\ud558\ub294": [8, 16], "\uc2dc\ud0a4\uae30\ub85c": 8, "decomposition\ub41c": 8, "\ub354\ud574\uc90c": 8, "\ud06c\uae30\ub294": 8, "\uc791\uc544": 8, "cost\ub97c": 8, "\ucd5c\ub300": [8, 13], "3\ubc30\uae4c\uc9c0": 8, "\ubc14\uafd4\uc8fc\uba74": 8, "storag": 8, "requir": 8, "switch": 8, "overhead\ub97c": 8, "\uc678\uc5d0\ub3c4": 8, "\uc5c6\ub2e4": [8, 14], "\uae30\ubc95\ub4e4\uacfc": 8, "\uc801\uc6a9\uc774": [8, 10], "\uac00\ub2a5\ud558\ub2e4\ub294": 8, "\uc7a5\uc810\uc774": 8, "transformer\uc758": [8, 13], "size": [8, 10, 12, 16, 17, 18, 19], "w_q": 8, "w_k": 8, "w_v": 8, "w_o": 8, "module\uc758": 8, "adapt": [8, 10], "accumulated\ub41c": 8, "\uc5f0\uad6c\uc758": 8, "convention\uc744": 8, "optimizer\ub294": 8, "adam\uc744": 8, "\uc774\uc6a9": 8, "mlp": [8, 19], "feedforward": 8, "ffn": 8, "agnostic\ud558\uc9c0\ub9cc": 8, "model\uc5d0": [8, 11], "\uc9d1\uc911\ud568": 8, "agnost": [8, 13], "\uad6c\uc560\ubc1b\uc9c0": 8, "\ud574\uc11d\uc774": 8, "max": 8, "phi": [8, 13, 14, 19], "y_t": 8, "y_": [8, 14], "parameterized\ub41c": 8, "x_i": [8, 19], "y_i": 8, "target\uc30d\uc73c\ub85c": 8, "\ub41c": [8, 15], "\ub370\uc774\ud130\uc14b": [8, 13, 17, 18], "token": [8, 11, 13, 15], "sequenc": 8, "phi_0": 8, "\ub418\uace0": [8, 9, 15, 17, 19], "objective\ub97c": [8, 11], "maximize\ud558\uae30": 8, "\uc5c5\ub370\uc774\ud2b8\ub428": 8, "task\ub97c": [8, 11, 13], "\ub9e4\ubc88": [8, 13], "\ud06c\uae30\uc758": 8, "\ud559\uc2b5\ud574": [8, 11], "\uc5c4\uccad\ub09c": 8, "cost\uac00": 8, "\ubc1c\uc0dd": [8, 15], "\ubc18\uba74": [8, 12, 14], "\uc804\uccb4\uac00": 8, "\uadf8\ubcf4\ub2e4": 8, "\ucc3e\uc544\ub0b4\ub294": 8, "\ubc14\ub00c\uae30": 8, "memori": [8, 13, 17], "effecient\ud574\uc9d0": 8, "01": 8, "\uae4c\uc9c0": [8, 18], "\uc791\uc544\uc9c8": 8, "\uae30\uc874\uc5d0\ub3c4": 8, "transfer": [8, 9, 11, 15], "learning\uc5d0\uc11c": [8, 13], "effecient\ub97c": 8, "\ubc29\ubc95\uc740": [8, 11, 12, 15], "\uac00\uc9c0\uac00": 8, "perform": [8, 13, 17], "comparison": [8, 9, 14, 15, 17], "\ucd94\uac00\ud558\ub294": 8, "hardwar": 8, "parellelism\uc774": 8, "\uc5c6\ub2e4\uba74": 8, "bottleneck": [8, 13], "\ucd94\uac00\ud574\ub3c4": 8, "\uc0c1\ub2f9\ud788": [8, 11], "\uc99d\uac00\ud574": 8, "\uc0ac\uc6a9\ud558\uae30": 8, "\uc5b4\ub824\uc6e0\uc74c": 8, "prefix": 8, "tuning\uc740": [8, 11], "optimize\uac00": 8, "\uc774\ud6c4": [8, 11], "ba": 8, "\uacf1\ud574\uc9c4": 8, "vector\ub07c\ub9ac": 8, "coordin": 8, "wise\ud558\uac8c": 8, "zero": [8, 13, 17], "\uc774\ub77c": 8, "alpha": 8, "scaling\ub428": 8, "learn": [8, 9, 10, 11, 12, 17], "rate\ucc98\ub7fc": 8, "tuning\ud574\uc11c": 8, "r\uacfc": 8, "\uc2e4\uc81c": [8, 11, 12, 15, 16], "\uc774\ub098": 8, "\uc0ac\uc6a9\ud55c\ub2e4\uace0": 8, "actual": 8, "defin": 8, "lora_a": 8, "new_zero": 8, "num_embed": 8, "lora_b": 8, "embedding_dim": 8, "lora_alpha": 8, "matrix": 8, "requires_grad": [8, 16], "reset_paramet": 8, "initi": 8, "hasattr": 8, "same": 8, "wai": 8, "zeros_": 8, "normal_": [8, 19], "bool": 8, "merge_weight": 8, "make": 8, "sure": 8, "transpos": 8, "mark": 8, "tensor": [8, 16], "after_a": 8, "padding_idx": 8, "max_norm": 8, "norm_typ": 8, "scale_grad_by_freq": 8, "spars": [8, 13], "w_0x": 8, "bax": 8, "lora\ub97c": 8, "\uc774\uc6a9\ud558\uba74": [8, 17], "inference\uc2dc": 8, "\ud558\ub77d\uc774": 8, "\uacbd\uc6b0\uc5d4": 8, "\ucd94\uac00\ud558\uba74": 8, "overhead\uac00": 8, "\ub0ae\uc74c": 8, "\ucd5c\uc18c\ud654\ud558\uae30": [8, 12], "weight\ub9cc": 8, "\uc801\uc6a9\ud558\uace0": 8, "module\uc740": 8, "\uace0\uc815\ud568": 8, "175b\ub97c": 8, "vram\uc740": 8, "2tb\uc5d0\uc11c": 8, "350gb": 8, "checkpoint": [8, 9], "size\ub294": 8, "350gb\uc5d0\uc11c": 8, "35mb\ub85c": 8, "\uc904\uc784": 8, "\uc18d\ub3c4": 8, "\ube68\ub77c\uc9d0": 8, "bert": 8, "\ub300\ubd80\ubd84\uc758": 8, "\uacbd\uc6b0\uc5d0\uc11c": 8, "\uc88b\uc74c": [8, 13], "valid": [8, 16], "accuraci": 8, "transformer\uc5d0\uc11c": [8, 13], "matrix\uc5d0": 8, "r\uc744": 8, "\uac83\ubcf4\ub2e4": [8, 17], "matrices\uc5d0": 8, "\uc88b\uc558\uc74c": 8, "\ub274\ub7f4\ub124\ud2b8\uc6cc\ud06c\uc758": 8, "inner": 8, "activation\uc744": 8, "\uc904\uc774\uae30\ub3c4\ud558\uace0": 8, "\ub298\ub9ac\uae30\ub3c4\ud558\ub294": 8, "\uc5b4\ub311\ud130\ub97c": 8, "\uc911\uac04\uc5d0": 8, "\uc0bd\uc785\ud558\ub294": 8, "lora\ubcf4\ub2e4": 8, "\uc0ac\uc6a9\ud558\uba74\uc11c": [8, 11], "\uc54c\ub824\uc838\uc788\uc73c\uba70": 8, "3\ub97c": 8, "\ud588\uc744\ub54c": 8, "\ubcf4\ub2e4\ub3c4": [8, 17], "\uc88b\ub2e4": [8, 14], "\uc8fc\uc7a5\ud558\uace0": 8, "\ud559\uc2b5\uc2dc\uac04\ub3c4": 8, "\uc9e7\uc544": 8, "a100": [8, 15], "\ud558\ub098\ub85c": [8, 11, 19], "30\ubd84\ub9cc\uc5d0": 8, "\ud29c\ub2dd\ud560": 8, "loralib": 8, "\uc124\uce58": 8, "pip": 8, "instal": 8, "altern": [8, 16], "git": 8, "com": [8, 11, 12, 13, 15], "microsoft": 8, "\ub300\uccb4": 8, "befor": 8, "in_featur": 8, "out_featur": 8, "after": 8, "add": [8, 15], "pair": [8, 17], "parameter\ub9cc": 8, "bigmodel": 8, "string": 8, "lora_": 8, "mark_only_lora_as_train": 8, "loop": 8, "dataload": [8, 16], "checkpoint\ub97c": [8, 9], "\uc800\uc7a5\ud560": 8, "\ub54c\uc5d4": 8, "state_dict": 8, "\uc800\uc7a5\ud558\uac8c": 8, "save": 8, "checkpoint_path": 8, "lora_state_dict": 8, "\ubd88\ub7ec\uc62c": 8, "load_state_dict": 8, "strict": 8, "load": [8, 15], "ckpt_pretrain": 8, "pt": [8, 13], "Then": 8, "ckpt_lora": 8, "llm": [8, 17], "\ud29c\ub2dd": 8, "gpu\ub85c": [8, 9], "\uac00\ub2a5\ud560\uae4c": 8, "\uc18c\uac1c\ud569\ub2c8\ub2e4": [8, 15, 18], "www": [8, 13], "youtub": [8, 13], "watch": [8, 13], "da": 8, "nhctrrve": 8, "your": 9, "One": [9, 11], "shot": [9, 13, 17], "2303": 9, "03231": 9, "1812": [9, 10], "04948": [9, 10], "03231v2": 9, "cs": [9, 11], "cv": [9, 11], "mar": 9, "sty": 9, "lize": 9, "ne": 9, "\ud55c\uc7a5\uc758": 9, "\uc2a4\ud0c0\uc77c\uc744": [9, 12], "\uc785\ud788\uace0\uc790\ud558\ub294": 9, "\ud65c\ubc1c\ud788": 9, "\uc9c4\ud589\uc911\uc774\ub2e4": 9, "\uc774\uc804\uae4c\uc9c0\uc758": 9, "\uc5f0\uad6c\ub4e4\uc740": 9, "\ud55c\uc7a5\uc529\uc744": 9, "\ud65c\uc6a9\ud558\ub824\ub294": 9, "\uc2dd\uc774": 9, "\uc8fc\ub97c": 9, "\uc774\ub8e8\uc5c8\ub2e4": 9, "\ubc29\uc2dd\uc5d0\ub294": 9, "\uc788\ub294\ub370": 9, "face\ub97c": 9, "\uc758\uc874\ub3c4\uac00": 9, "\ucee4\uc11c": [9, 12], "style\uc744": [9, 11], "\uc785\ud788\uae30": 9, "\ud798\ub4e4\ub2e4": 9, "space\uc548\uc5d0\uc11c": 9, "content": [9, 18], "\uc815\ubcf4\uc640": 9, "entangl": [9, 10, 15], "\ub418\uc5b4\uc788\ub2e4": 9, "styo\ub294": 9, "\ud3ec\uc6a9\ud558\ub294": 9, "base\ubaa8\ub378\ub85c": 9, "\ucc44\uc6a9\ud55c\ub2e4": 9, "\ucd1d": [9, 10, 11, 12], "stage\ub85c": 9, "\uad6c\uc131\ub418\ub294\ub370": 9, "disentangl": 9, "learner": 9, "idl": 9, "\ubd84\ub9ac": 9, "grain": 9, "control": [9, 10], "fcc": 9, "idl\ub85c\ubd80\ud130": 9, "\ubd84\ub9ac\ub41c": 9, "content\uc640": 9, "\uc6d0\ud558\ub294\ub300\ub85c": 9, "\uc7ac\uc870\ud569": 9, "src": 9, "detail\ud55c": 9, "\uc815\ubcf4": 9, "color": [9, 15, 18], "\uc720\uc9c0\ud558\uae30\uc704\ud574": 9, "map\uc744": 9, "\uc7ac\uc0ac\uc6a9\ud558\ub294": 9, "trick\uc744": 9, "\uc81c\uc548\ud588\ub2e4": 9, "one": [9, 12], "sota\ub97c": [9, 13, 14], "\uae30\ub85d\ud588\ub2e4": 9, "gan\uc774": [9, 11], "\ubd84\uc57c\ub97c": 9, "\uc7a5\uc545\ud558\ub358": 9, "\ub4f1\uc7a5\uc73c\ub85c": 9, "\uc8fc\ubaa9\uc744": [9, 17], "\uc2dc\uc791\ud588\ub2e4": 9, "prompt\ub97c": [9, 11], "manipul": 9, "\uac00\ub2a5\ud574\uc84c\uc9c0\ub9cc": 9, "\ubd80\ubd84\uae4c\uc9c0": 9, "control\ud558\uae30\uc5d0\ub294": 9, "\uc788\uc5c8\ub2e4": 9, "fine\ud55c": 9, "\uc815\ubcf4\uae4c\uc9c0": 9, "model\uc774\ub2e4": 9, "\ubcf4\uc774\uba74\uc11c": 9, "stylegan\uc744": 9, "\ubca0\uc774\uc2a4\ub85c": 9, "dataset\uc744": [9, 17], "\uc758\uc874\uc131\uc774": 9, "\ucee4": 9, "artist": 9, "\uc785\ud788\ub294\ub370": 9, "\ud55c\uacc4\ub97c": [9, 12], "\uac1c\uc120\ud55c": 9, "\uac04\uc758": [9, 12], "transfer\ub97c": 9, "disentagl": 9, "\uc81c\uc548\ud55c\ub2e4": [9, 11, 14], "\ubd84\ub9ac\ud558\ub294": 9, "s_": 9, "tgt": 9, "portrait": 9, "\ubc18\ub300": [9, 12], "\uc548\uc5d0": [9, 17], "a\uc758": [9, 10], "conext": 9, "\ubc30\uc81c\ud568\uacfc": 9, "\ud3ec\ud568\ud558\uae30\uc704\ud574": 9, "\uc55e\uc5d0": [9, 12, 14], "negat": 9, "\ubd80\uc815\uc758": 9, "\uc758\ubbf8\ub97c": 9, "\ub2e8\uc5b4": [9, 11], "except": 9, "auxiliari": [9, 17], "\uc14b\uc744": [9, 11], "\uad6c\uc131\ud574": 9, "aux": 9, "ffhq": [9, 10], "\uc784\uc758\ub85c": 9, "\ud6a8\uacfc": [9, 12, 17], "\ud559\uc2b5\ud568\uc73c\ub85c\uc368": [9, 11, 16], "prompt\uac04": 9, "disentanglement\ub97c": 9, "\ud5a5\uc0c1": [9, 13], "\uc774\ubbf8\uc9c0\uc5d0\ub294": 9, "\uc5c6\ub294": [9, 12, 14, 15, 17], "\uc774\ubbf8\uc9c0\ub9cc\uc758": 9, "\uc8fc\uc785": 9, "style\uacfc": [9, 10], "\uad6c\ubcc4\ud558\ub294\ub370": 9, "\ub3c4\uc6c0\uc744": 9, "\uc90c": 9, "idl\uc758": 9, "\ud559\uc2b5\ub9cc\uc73c\ub85c": 9, "transfer\uac00": 9, "\uc774\ubbf8\uc9c0\ucc98\ub7fc": 9, "facial": 9, "\uc783\uc5b4\ubc84\ub9ac\ub294": 9, "\ubb38\uc81c\uc810\uc744": [9, 13, 15], "\uac1c\uc120\ud558\uae30\uc704\ud574": 9, "\ub3c4\uc785\ud558\uc600\ub2e4": 9, "idl\ub85c": 9, "\uc870\ud569": 9, "recombin": 9, "\uc720\uc9c0\ud558\ub3c4\ub85d": 9, "trick": 9, "ldm\uc740": [9, 11], "\uc8fc\uc785\ud558\uae30\uc704\ud574": 9, "mechanism\uc744": 9, "promt": 9, "paper\uc5d0\uc11c": 9, "m\uc758": 9, "layout\uc5d0": 9, "\uac15\ud55c": 9, "\ubbf8\uce5c\ub2e4": 9, "\uc810\uc744": 9, "mask\ub97c": 9, "\uacfc\uc815\uc5d0": 9, "\uc8fc\uc785\ud569\uc73c\ub85c\uc368": 9, "\uc720\ub3c4": [9, 14], "map\uc758": 9, "replace\ud558\uc9c0\uc54a\uace0": 9, "content\uc5d0": 9, "index\ub9cc": 9, "\uc120\ud0dd\uc801\uc73c\ub85c": 9, "replac": 9, "index": [9, 11], "time\uc5d0\uc11c": 9, "n\ubc88": 9, "\uc0ac\uc6a9\ud568\uc73c\ub85c\uc11c": 9, "\uac15\ud558\uac8c": 9, "n_": 9, "\uc2e4\ud5d8\uc0c1": 9, "\uc774\ud558\uc758": [9, 15], "\ucd94\ucc9c": 9, "5b": 9, "ak47": 9, "m4a1": 9, "adam": 9, "400": 9, "ldm\uacfc": 9, "\ub3d9\uc77c": [9, 12], "sota": [9, 13, 17], "styo\uac00": 9, "identity\uc640": 9, "local": 9, "\uc720\uc9c0\ud568\uacfc": 9, "\uc790\uc5f0\uc2a4\ub7fd\uac8c": 9, "\uacb0\uacfc\ubb3c\uc744": 9, "\uc0dd\uc131\ud574\ub0b8\ub2e4": [9, 11], "user": [9, 11], "study\ub3c4": 9, "\ubaa8\ub378\ub4e4\uc5d0": 9, "effect": [9, 10, 18], "contrast": [9, 13, 17], "templat": 9, "\ub123\uace0": 9, "\ud559\uc2b5\ud560\uacbd\uc6b0": 9, "overfitting\uc774": 9, "\uc2ec\ud558\uace0": 9, "\uc815\ubcf4\uc758": 9, "\ubd84\ub9ac\uc5d0": 9, "\uc5b4\ub824\uc6c0\uc744": [9, 13], "detail\uc744": [9, 11], "set\uc758": 9, "trick\ub3c4": 9, "\uc801\uc6a9\ud558\ub294\uac83\uc774": 9, "\uc0dd\uc131\ud574\ub0c8\ub2e4": 9, "inference\ud560": 9, "diversity\ub97c": 9, "\ubcf4\uc774\uc9c0\ub9cc": 9, "fcc\ub97c": 9, "\ud3ec\ud568\ud560": 9, "fidelity\uac00": [9, 11, 14, 17], "\ub192\uc544\uc838": 9, "significant\ud55c": 9, "\uc0dd\uc131\ub418\ub294\uac83\uc744": 9, "photorealistic\uc5d0\uc11c": 9, "artistic\ud558\uac8c": 9, "\ubc14\ub00c\uace0": 9, "\ub9c8\ucc2c\uac00\uc9c0\ub85c": [9, 11], "\ub098\uc624\ub294": [9, 13, 14, 15], "idl\uacfc": 9, "gan\uc744": [9, 10, 12], "\ubaa8\ub378\ub4e4\ubcf4\ub2e4": 9, "\uc790\uc5f0\uc2a4\ub7fd\uace0": 9, "\uc0dd\uc131\ud574\ub0bc": 9, "singl": [9, 11], "10\ubd84\uc774": 9, "\uac78\ub9ac\ubbc0\ub85c": 9, "efficiency\uac00": 9, "\ubabb\ud558\ub2e4\ub294": 9, "\ub2e8\uc810\uc774": 9, "2019": 10, "huangzh13": 10, "12": [10, 12, 16, 19], "stylegan\uc785\ub2c8\ub2e4": 10, "gan\uacfc": 10, "\ubcc0\uacbd\ud568\uc73c\ub85c\uc368": 10, "\uc62c\ub9ac\uace0": 10, "feature\uc758": 10, "control\uc774": 10, "loss\ub098": 10, "discrimin": [10, 12, 16], "\uac1c\uc120\uc5d0": 10, "\ub17c\ubb38\uc740": [10, 12, 15], "\uc544\ub2d9\ub2c8\ub2e4": 10, "\ubcf4\ub3c4\ub85d": 10, "\ud558\uc8e0": 10, "\ub17c\ubb38\uc758": [10, 14, 19], "contribution\uc740": 10, "\uc81c\uc548\ud558\uc5ec": 10, "\ub192\uc774\uba74\uc11c": 10, "\uac00\ub2a5\ud574\uc84c\uc2b5\ub2c8\ub2e4": 10, "\ub370\uc774\ud130\uc14b\uc744": 10, "\uc81c\uc548\ud588\uc2b5\ub2c8\ub2e4": 10, "\uc911\uc5d0\uc11c": [10, 13], "contribution\uc744": [10, 14], "abstract\uc5d0\ub294": 10, "\ubb38\uc7a5\uc774": 10, "The": 10, "lead": 10, "automat": [10, 18], "unsupervis": [10, 12], "level": 10, "attribut": [10, 18], "ident": [10, 12, 15], "when": [10, 16, 17], "face": [10, 16], "freckl": 10, "enabl": [10, 11], "intuit": 10, "\uc81c\uc548\ud55c": 10, "\uad6c\uc870\uac00": 10, "\uc77c\uc744": 10, "\uc124\uba85\ud558\ub294": [10, 11, 12], "\ubd80\ubd84\uc785\ub2c8\ub2e4": 10, "\ubcf4\uc2dc\uba74": 10, "attribute\uc758": 10, "separation\uc774": 10, "\uc598\uae30\ud558\uace0": 10, "\uc800\ub294": 10, "\uac1c\uc778\uc801\uc73c\ub85c": 10, "\ubd80\ubd84\uc774": 10, "stylegan\uc758": 10, "\ud2b9\uc9d5\uc774\ub77c\uace0": 10, "\uc0dd\uc131\ud558\uace0\uc790": [10, 19], "\uc0ac\uc6a9\uc790\ub294": [10, 11], "\uc5b4\ub5a0\ud55c": [10, 15], "\ubaa9\uc801\uc744": 10, "\uac00\uc9c0\uace0": [10, 12, 13, 16, 19], "\uc790\uc2e0\uc774": 10, "\ub9cc\ub4e4\uace0\uc790": 10, "\ud488\uc9c8\uc774": 10, "\uc88b\ub354\ub77c\ub3c4": 10, "\uc0ac\uc6a9\uc790\uc758": 10, "\uc758\ub3c4\uc640": 10, "\uc0c1\uad00\uc5c6\ub294": 10, "\ub79c\ub364\ud55c": 10, "\ub0b4\ubc49\uc5b4\uc900\ub2e4\uba74": 10, "\uc2e4\uc6a9\uc131\uc774": 10, "\uc88b\ub2e4\uace0": 10, "\uc5c6\uc744": [10, 17, 18], "\uadfc\ub798\uc5d0": 10, "\uc778\uae30\ub97c": 10, "\uc5bb\uc5c8\ub358": 10, "\uc774\uc720\ub3c4": 10, "\ub204\uad6c\ub098": 10, "\uc27d\uac8c": [10, 11], "\ud14d\uc2a4\ud2b8\ub97c": [10, 11], "\uc810\ub3c4": 10, "\ud55c\ubaab\ud588\ub2e4\uace0": 10, "stylegan\uc740": 10, "controllability\ub97c": 10, "\ubaa8\ub378\uc774\ub77c\ub294": 10, "\uce21\uba74\uc5d0\uc11c": 10, "\uc758\ubbf8\uc788\ub2e4\uace0": 10, "network\ub294": 10, "\ud574\uc0c1\ub3c4\ub97c": [10, 18], "4x4\uc5d0\uc11c": 10, "1024x1024\uae4c\uc9c0": 10, "\ub192\uc5ec\uc90d\ub2c8\ub2e4": 10, "1024x1024": [10, 18], "\uac16\uac8c\ub429\ub2c8\ub2e4": 10, "gan\ud558\uace0": 10, "\ube44\uad50\ud574\uc11c": [10, 13], "\ud2b9\uc774\ud55c": 10, "\uc810\uc774": 10, "\uc138": [10, 12, 15], "z\ub97c": 10, "noise\uc640": 10, "\ud569\uc2dc\ub2e4": 10, "\uc0dd\uac01\ud574\ubcf4\uba74": 10, "generator\ub97c": [10, 16], "\uac70\uccd0\uc11c": 10, "\uad6c\uc870\uc785\ub2c8\ub2e4": 10, "z\ub294": 10, "distribution\uc5d0\uc11c": [10, 14], "\uc0d8\ud50c\ub9c1\uc73c\ub85c": 10, "\uc5bb\uc2b5\ub2c8\ub2e4": 10, "distribution\uc73c\ub85c": 10, "\ubcf4\ub0b4\ub294": 10, "\ubc30\uc6b0\uac8c": 10, "\ub420": [10, 11], "\uac83\uc774\uace0": 10, "\ubd84\ud3ec\ub294": 10, "\ucc98\ub7fc": [10, 12, 13, 18], "\uc0dd\uae30\uac8c": 10, "\uc8fc\uc5b4\uc838\uc11c": 10, "\uc5c6\uac70\ub098": 10, "\uc801\uc744": 10, "\uc608\ub97c": [10, 12, 18], "\ub4e4\uc5b4": [10, 12], "\ub370\uc774\ud130\uc5d0": 10, "\ud53c\ubd80\uac00": 10, "\ud76c\uba74\uc11c": 10, "\uba38\ub9ac\uac00": 10, "\uae34": 10, "\uc0d8\ud50c\ub4e4\uc774": 10, "\uc5c6\ub2e4\uace0": 10, "\ud574\ubd05\uc2dc\ub2e4": 10, "\ud53c\ubd80\uc0c9\uacfc": 10, "\uba38\ub9ac": 10, "\uae38\uc774\ub77c\ub294": 10, "feature\ub294": 10, "\uc11c\ub85c": [10, 12], "\uc5bd\ud788\uac8c": 10, "\ub418\uc5b4": [10, 16], "\ud558\ub098\ub97c": [10, 17], "\ubc14\uafc0": [10, 12], "\ud558\ub098\ub3c4": [10, 11], "\ubc14\ub00c\ub294": 10, "\uc77c\uc5b4\ub098\uac8c": 10, "\uc644\ud654\ud558\uae30": 10, "gaussian\uc5d0\uc11c": 10, "learnabl": [10, 15], "w\ub97c": 10, "\uc0ac\uc6a9\ud569\ub2c8\ub2e4": [10, 15], "instanc": [10, 12, 15], "normalization\uc740": 10, "\ucc44\ub110\ub9c8\ub2e4": 10, "\uc815\uaddc\ud654\ub97c": 10, "\ucde8\ud574\uc8fc\ub294": 10, "\ubc29\ubc95\uc785\ub2c8\ub2e4": 10, "normalization\uc5d0": 10, "scale\uc744": [10, 14], "\uacf1\ud574\uc8fc\uace0": 10, "\ub354\ud574\uc8fc\ub294": 10, "vector\uc758": 10, "transformation\uc73c\ub85c": 10, "\uc8fc\uc5b4\uc9c0\ub294": 10, "w\ub294": 10, "\ubcf4\ub0b4\uc9c0\uac8c": 10, "adain\uc758": 10, "\uc218\uc2dd\uc740": 10, "adain\uc740": 10, "\ube14\ub85d\ub9c8\ub2e4": 10, "\uac1c\uc529": 10, "\ub4e4\uc5b4\uac00\uc11c": [10, 11], "style\uc740": 10, "\uc5f4\uc5ec\ub35f": 10, "\ubc88": 10, "adain\uc744": 10, "generator\uc5d0": [10, 11], "\ub4e4\uc5b4\uac00\uac8c": [10, 18], "localization\uc774\ub77c\ub294": 10, "\ud2b9\uc9d5\uacfc\ub3c4": 10, "\uc5f0\uad00\uc774": 10, "\ub9d0\ud558\ub294": 10, "localization\uc774\ub780": 10, "\uc77c\ubd80\ub97c": 10, "\ubc14\uafc8\uc73c\ub85c\uc368": 10, "\ud2b9\uc9d5\ub4e4\uc744": 10, "\uc758\ubbf8\uc785\ub2c8\ub2e4": 10, "\ub2e4\uc74c\uc5d0": 10, "map\ub4e4\uc740": 10, "normalization\ub418\uace0": 10, "style\uc5d0": 10, "\uc758\ud574": [10, 12, 15], "statistics\ub97c": 10, "\uac00\uc9c0\uac8c": 10, "convolution\uc5d0": 10, "\uc801\uc6a9\ub418\uace0": 10, "\ub2e4\uc74c": [10, 11, 12, 17], "convolution\uc5d0\uc11c": 10, "normalization\uc774": 10, "\uc218\ud589\ub418\uae30": 10, "layer\uc5d0": 10, "\uc801\uc6a9\ub41c": [10, 12], "style\uc774": 10, "\ubd84\ub9ac\ub418\uac8c": 10, "\ud559\uc2b5\ub420": 10, "\uad00\ub828": 10, "\ucf54\ub4dc": 10, "stylemod": 10, "latent_s": 10, "use_wscal": 10, "lin": 10, "equalizedlinear": 10, "gain": 10, "n_channel": 10, "view": [10, 15, 16, 19], "layerepilogu": 10, "thing": 10, "each": [10, 15], "dlatent_s": 10, "use_nois": 10, "use_pixel_norm": 10, "use_instance_norm": 10, "use_styl": 10, "activation_lay": 10, "noiselay": 10, "activ": 10, "pixel_norm": 10, "pixelnormlay": 10, "instance_norm": 10, "instancenorm2d": 10, "top_epi": 10, "ordereddict": 10, "style_mod": 10, "dlatents_in_slic": 10, "assert": 10, "b\uc758": 10, "style\ub85c": 10, "\ubcc0\uacbd\ud574\uc11c": 10, "\uc774\ubbf8\uc9c0\ub4e4\uc785\ub2c8\ub2e4": 10, "18\uacf3\uc5d0\uc11c": 10, "\uc0ac\uc6a9\ub418\ub294\ub370": 10, "\ucc98\uc74c": 10, "4\uacf3": 10, "coars": 10, "\uadf8\ub2e4\uc74c": 10, "middl": [10, 18], "10\uacf3": 10, "64": [10, 17], "1024": [10, 13, 16, 17], "\uc815\uc758\ud558\uc600\uc2b5\ub2c8\ub2e4": 10, "\uadf8\ub9bc\uc744": [10, 12], "\uc717": [10, 12], "\ubd80\ubd84\uc5d0\uc11c\ub294": 10, "\ud3ec\uc988\ub098": 10, "\uc2a4\ud0c0\uc77c\uac19\uc774": 10, "\uc544\ub798\ub85c": 10, "\uac08\uc218\ub85d": 10, "\ud2c0\uc744": 10, "\uc720\uc9c0\ud558\uba74\uc11c": 10, "\uc138\ubd80\uc801\uc778": [10, 12], "\ubd80\ubd84\ub4e4\uc744": 10, "b\uc5d0\uc11c": [10, 17], "\uac00\uc838\uc654\uc74c\uc744": 10, "\uc0ac\ub78c\uc758": 10, "\uc548\uc5d0\ub294": 10, "\ubc14\ub014": 10, "\uc8fc\uadfc\uae68": 10, "\uba38\ub9bf\uacb0": 10, "\ud53c\ubd80": 10, "\ubaa8\ub378\ub9c1\ud558\uae30": 10, "\uc704\ud574\uc11c": [10, 12], "\ub354\ud574\uc9d1\ub2c8\ub2e4": 10, "\uc548\uc5d0\uc11c\ub3c4": 10, "\ub514\ud14c\uc77c\ub4e4\uc740": 10, "\ub2ec\ub77c\uc9c8": 10, "deviation\uc744": 10, "\uad6c\ud574\ubd24\uc744": 10, "\uc5bc\uad74\ud615\uacfc": 10, "attribute\ub294": 10, "\ubcc0\ud558\uc9c0\uc54a\uc9c0\ub9cc": 10, "noise\uc5d0": 10, "\uc758\ud574\uc11c": 10, "\uba38\ub9ac\uce74\ub77d\uacfc": 10, "\uc0dd\uae40\uc744": 10, "\uc900": [10, 14], "\uc8fc\uc9c0": 10, "\uc5d0\ub9cc": 10, "\uacbd\uc6b0\uc785\ub2c8\ub2e4": 10, "\uba38\ub9ac\uce74\ub77d\uac19\uc740": 10, "\ub514\ud14c\uc77c\uc774": 10, "\uc81c\ub300\ub85c": 10, "\uc0b4\uc544\uc788\uc9c0": 10, "layers\uc5d0": 10, "\ub4e4\uc5b4\uac04": 10, "\uba38\ub9ac\uce74\ub77d\uc758": 10, "\uc138\ubc00\ud55c": 10, "\ubd80\ubd84\uc5d0": [10, 19], "\ub07c\uce5c\ub2e4\ub294": 10, "localization\uc774": 10, "\ub418\uac8c\ud558\uae30": 10, "mixing\uc774\ub77c\ub294": 10, "\uc55e": 10, "\ucabd": 10, "layer\uc5d0\ub294": 10, "\ub4a4": 10, "generator\uac00": [10, 12], "\uc778\uc811\ud55c": 10, "style\ub07c\ub9ac": 10, "correlated\ub418\uc5b4\uc788\ub2e4\uace0": 10, "\ub9c9\uc544\uc11c": 10, "localization\uc744": 10, "\ub418\uac8c": 10, "\ubaa9\uc801\uc785\ub2c8\ub2e4": [10, 19], "\uc800\uc790\ub4e4\uc774": [10, 17], "\ubc29\ubc95\ub4e4\uc774": 10, "\ud6a8\uacfc\uac00": 10, "\uc788\uc5c8\ub294\uc9c0": 10, "\ud655\uc778\ud574\ubd05\uc2dc\ub2e4": 10, "\ud45c\uc640": 10, "\uc2e4\ud5d8\uc801\uc73c\ub85c": [10, 17], "\ubcf4\uc558\uc744": [10, 12], "\ubc29\ubc95\ub4e4\uc744": 10, "fid\uac00": [10, 14], "\uc6b0\uc218\ud558\uac8c": 10, "variou": [10, 14, 20], "design": [10, 16, 19], "worth": 11, "2208": [11, 15], "01618": 11, "devocean": 11, "blog": 11, "techboarddetail": 11, "page": 11, "id": 11, "164320": 11, "boardtyp": 11, "writer": 11, "searchdata": 11, "sam56903": 11, "subindex": 11, "idlist": 11, "pnwriterid": 11, "kwang": 11, "su": 11, "mun": [11, 12], "5\uc7a5\uc73c\ub85c": 11, "\uac1c\ub150": [11, 15], "\ub610\ub294": [11, 12], "\ucf58\uc149\ud2b8": 11, "concept": [11, 17], "\uad00\ub828\ub41c": [11, 12], "\ubf51\uc544\ub0b4\ub294": 11, "\uc790\uc5f0\uc5b4\ub97c": 11, "creation\uc5d0": 11, "\uc804\ub840\uc5c6\ub294": 11, "\uc790\uc720\ub3c4\ub97c": 11, "\uc8fc\uc5c8\ub2e4": 11, "contept\ub97c": 11, "\uc0dd\uc131\ud558\uace0": [11, 13, 15], "\uadf8\uac83\uc758": 11, "\ubc14\uafb8\uac70\ub098": 11, "\uc5ed\ud560\uc774": 11, "\uc8fc\uc5b4\uc9c0\uac70\ub098": 11, "\ucc38\uc2e0\ud55c": 11, "\uc7a5\uba74\uc774": 11, "\uadf8\ub824\uc9c0\ub294\uac74": 11, "\ubd88\ubd84\uba85\ud558\ub2e4": 11, "\uc774\uac83\uc744": 11, "\uadf8\ub824\uc918": 11, "\ub9d0\ud560": 11, "\uc774\uac83": 11, "\uc124\uba85\uc744": 11, "\uac83\uc774\ub0d0\ub294": 11, "\ubb3c\uc74c\uc5d0\ub294": 11, "\uac19\ub2e4": [11, 14, 17], "5\uac1c\ub9cc\uc73c\ub85c": 11, "\uc0ac\ubb3c\uc774\ub098": 11, "\uc2a4\ud0c0\uc77c\uacfc": 11, "\uace0\uc815\ub41c": [11, 16], "\uc790\uc5f0\uc5b4": 11, "\ubb38\uc7a5\uc5d0": [11, 12], "\ub179\uc544\ub4e4\uc5b4\uac00": 11, "\uc9c1\uad00\uc801\uc778": 11, "\ubc29\ubc95\uc73c\ub85c": [11, 14], "\uac1c\uc778\ud654\ub41c": 11, "\uc774\ub04c\uc5b4": 11, "\ub0b8\ub2e4": 11, "\ud2b9\ud788": [11, 12, 17], "\ub3c5\uc790\uc801\uc774\uba74\uc11c": 11, "\ucf58\uc149\ud2b8\ub97c": 11, "capture\ud558\uae30": 11, "\uc704\ud574\uc11c\ub294": [11, 13], "\ucda9\ubd84\ud558\ub2e4\ub294": 11, "\uc54c\uac8c": 11, "\ub418\uc5c8\ub2e4": 11, "\ub300\uaddc\ubaa8": 11, "\uac1c\ub150\uc744": 11, "\ub3c4\uc785\ud558\ub294": [11, 12], "\uc77c\uc740": 11, "\uc77c\uc774\ub2e4": 11, "\uac1c\ub150\uc5d0": 11, "\ud655\uc7a5\ub41c": 11, "retraining\ud558\ub294": 11, "\uc5c4\uccad\ub098\uac8c": 11, "\ube44\uc6a9\uc774": 11, "\ub9ce\uc774": [11, 14, 16], "\ub4e4\uace0": 11, "\uc608\uc81c\uc5d0": 11, "\ud574\uc11c": [11, 14, 16], "\uce58\uba85\uc801\uc778": 11, "\ub9dd\uac01\uc744": 11, "\ucd08\ub798\ud55c\ub2e4": 11, "\uc800\uc790\ub4e4\uc740": [11, 13, 14, 17], "\uc0ac\uc804": [11, 15], "\uc784\ubca0\ub529": 11, "\uacf5\uac04\uc5d0\uc11c": 11, "\ub2e8\uc5b4\ub97c": 11, "\uadf9\ubcf5\ud560": 11, "figure\uc5d0\uc11c": 11, "tokenizer\ub97c": 11, "\uc9c0\ub098\uba74\uc11c": 11, "508": 11, "701": 11, "\ud615\ud0dc\uc758": [11, 15], "set\uc73c\ub85c": [11, 13], "\ubcc0\ud658\ub418\uace0": 11, "\ud1a0\ud070\uc740": [11, 13], "\uc790\uccb4": 11, "\ubca1\ud130\ub85c": 11, "\ubca1\ud130\ub294": 11, "\ub2e4\uc6b4\uc2a4\ud2b8\ub9bc": 11, "\uc81c\uacf5\ub428": 11, "concept\ub97c": 11, "\ub098\ud0c0\ub0b4\ub294": [11, 12], "word\uc778": 11, "\ub098\ud0c0\ub0b8\ub2e4": 11, "vector\ub294": 11, "\ub2e8\uc5b4\uc640": 11, "\ucc98\ub9ac\ub418\uba70": 11, "query\ub97c": 11, "\uad6c\uc131\ud558\ub294\ub370": 11, "\uc0ac\uc6a9\ub420": [11, 12], "query\ub294": 11, "\uc0ac\uc6a9\uc790\uac00": 11, "\uc758\ub3c4\ud55c\ubc14\uc640": 11, "\uc77c\uce58\ud558\ub3c4\ub85d": 11, "\uc0dd\uc131\ud558\ub3c4\ub85d": 11, "\uc804\ubc18\uc801\uc778": [11, 15], "\uadf8\ub9bc\uc774\ub77c\uace0": 11, "\uc0dd\uc131\ubaa8\ub378": 11, "\uc5ec\uae30\uc11c\ub294": 11, "ldm\uc774": 11, "\uc4f0\uc784": 11, "untouched\ub418\uc5b4": 11, "\ub530\ub85c": [11, 12], "\uc218\uc815\uc774": 11, "\ub4e4\uc5b4\uac00\uc9c0": 11, "\uc54a\ub294\ub4ef\ud568": 11, "\uadf8\ub807\uac8c": 11, "\ud568\uc73c\ub85c\uc368": [11, 18], "\uc77c\ubc18\uc801\uc73c\ub85c": 11, "\uc190\uc2e4\ub418\ub294": 11, "text\uc5d0": [11, 13], "\uc774\ud574\ub3c4\ub098": 11, "generalization\uc744": 11, "\uc720\uc0ac\ub2e8\uc5b4": 11, "\ucc3e\uae30": 11, "inversion\uc2dc\ucf1c": 11, "\ud504\ub808\uc784\ud654": 11, "5\uac1c\uc758": 11, "set\uc774": [11, 12], "\uc8fc\uc5b4\uc9c4\ub2e4": 11, "\ubb38\uc7a5\uc744": 11, "\uc124\uc815\ud574": 11, "\uc8fc\uc5b4\uc9c4": [11, 13], "\uc7ac\uad6c\uc131": 11, "\uc774\uc5b4\uc9c0\ub294": 11, "embedding\uc744": [11, 14], "\ucc3e\ub294": [11, 12], "\ubaa9\ud45c\ub85c": [11, 12, 15], "\ubaa9\ud45c\ub294": 11, "concept\uc778": 11, "\uc785\ub825": [11, 12, 15, 18, 19], "\ud55c\ub2e4\uace0": 11, "found": 11, "through": 11, "which": [11, 17], "we": [11, 15], "palavra": 11, "\ubc14\uafb8\ub294\ub370": 11, "\uae30\uc220\ub85c": 11, "\ucd94\uc815": 11, "\uc774\uc6a9\ud574\uc11c": 11, "object\uc758": 11, "\ubcf5\uad6c": 11, "segmentation\uc744": 11, "\uc218\ud589": [11, 13, 16], "palavra\ub294": 11, "\uac1c\uccb4\ub97c": 11, "\ucc38\uc870\ud558\ub294": 11, "clip\uc758": 11, "word\ub97c": 11, "\uc2dd\ubcc4\ud568": 11, "\uac80\uc0c9\uc744": 11, "\uc124\uba85\ud558\uac70\ub098": 11, "\uc7a5\uba74\uc5d0\uc11c": 11, "\ubd84\ud560\ud558\uae30": 11, "\uc0ac\uc6a9\ub428": 11, "5\uc5d0\uc11c": [11, 12], "\ubcf4\ub4ef\uc774": 11, "\uadf8\ub4e4\uc758": 11, "\uc811\uadfc": 11, "\uadf8\ub7f4\ub4ef\ud55c": 11, "\ud569\uc131\uc5d0": [11, 17], "\ud544\uc694\ud55c": [11, 12], "\uc138\ubd80": 11, "\ucea1\ucc98\ud558\uc9c0": 11, "our": [11, 13, 20], "goal": 11, "specifi": 11, "\uc758\uc5ed": 11, "\uc720\uc800\uac00": 11, "\uc758\ub3c4\ud55c": 11, "\ucd08\ucca8\uc744": 11, "\ub9de\ucd98": 11, "embedding\uc73c\ub85c": 11, "\uac00\uc774\ub4dc\ud574\uc11c": 11, "\uad1c\ucc2e\uc740": 11, "\uc131\uacfc\ubb3c\uc744": 11, "\uc911\uac04": [11, 14], "representation\uc73c\ub85c": 11, "\uc778\ucf54\ub529\ud558\ub294\ub370": 11, "\ucd08\uc810\uc744": [11, 12, 19], "\ub9de\ucda4": 11, "model\uc5d0\uc11c\ub294": 11, "representation\uc5d0": 11, "\ud6c4\ubcf4\uad70\uc744": 11, "encoder\uc758": 11, "\ucc3e\ub294\ub2e4": 11, "\uadf8\ub7ec\ub098": 11, "depth": [11, 12, 14], "visual": [11, 17], "understanding\uc744": 11, "\ud544\uc694\ub85c": 11, "\ud558\uc9c0": 11, "\uc54a\ub294\ub2e4": [11, 14], "\uc0dd\uc131\uc790\uac00": 11, "\uc2dc\uac01\uc801\uc778": 11, "\uadf8\ub9b0\ub2e4": 11, "inversion\uc5d0\uc11c": 11, "\uc601\uac10\uc744": 11, "\uc81c\uc2dc": [11, 14], "\ucd9c\ucc98": [11, 12], "hyoseok": 11, "tistori": 11, "entri": 11, "\uc788\ub3c4\ub85d": [11, 12, 18], "vector\ub97c": 11, "vector\ub85c\ubd80\ud130": 11, "\uc774\uc758": 11, "\uc5ed\uacfc\uc815\uc73c\ub85c\uc368": 11, "gan\uc758": [11, 12], "inverting\uc2dc\ucf1c": 11, "\uc54c\uc544\uac00\ub294": 11, "\uc0dd\uc131\ubaa8\ub378\ub85c\uc11c": 11, "\uc0ac\uc6a9\ud568": [11, 12, 13, 17], "\uc774\uc804\uc5d0": [11, 14], "\ub9d0\ud588\ub4ef\uc774": 11, "\uac74\ub4e4\uc9c0": 11, "function": [11, 16, 19], "\uc785\ub825\ub41c": [11, 18], "\ubb38\uc790\uc5f4\uc758": 11, "\ud558\uc704": 11, "\ub2e8\uc5b4\ub294": 11, "\ud1b5\uacfc\ud558\uba70": 11, "\ubbf8\ub9ac": 11, "\uc815\uc758\ub41c": 11, "dictionary\uc5d0\uc11c": 11, "token\uc73c\ub85c": 11, "\ubcc0\ud658\ud568": 11, "\ud1a0\ud070\uc744": 11, "\ucc3e\uc744": 11, "\uace0\uc720\ud55c": 11, "\ubca1\ud130\uc5d0": 11, "\uc5f0\uacb0\ub428": 11, "index\uc5d0": 11, "encoder\uc778": 11, "c_\u03b8\uc758": 11, "\uc77c\ubd80\ub85c": 11, "space\ub97c": 11, "target\uc73c\ub85c": 11, "\uc0bc\uc558\uc74c": 11, "\ub098\ud0c0\ub0b4\uae30": 11, "\uc790\ub9ac\ud45c\uc2dc\uc790": 11, "\ubb38\uc790\uc5f4\uc778": 11, "\uc0c8\ub86d\uac8c": 11, "\uc9c0\uc815\ud568": 11, "palavra\ub97c": 11, "\ucd94\uc815\ud568": 11, "process\uc5d0": 11, "\uac1c\uc785\ud574\uc11c": 11, "tokenize\ub41c": 11, "\ubb38\uc790\uc5f4\uacfc": 11, "\ub300\uccb4\ud558\uc5ec": 11, "\ubcf8\uc9c8\uc801\uc73c\ub85c": 11, "\uc5b4\ud718": 11, "\uc8fc\uc785\ud568": 11, "\uaddc\ubaa8\uc758": 11, "5\uc7a5": 11, "\ubc30\uacbd": 11, "\ud3ec\uc988\uc640": 11, "\uc124\uc815\uc5d0": 11, "\uac78\uccd0": 11, "\ubb18\uc0ac\ud568": 11, "\ucd5c\uc18c\ud654\ud558\ub294": [11, 16], "v\ub97c": 11, "\ucd5c\uc801\ud654\ud568": 11, "\uace0\uc815\ud558\uae30": 11, "\ud15c\ud50c\ub9bf\uc5d0\uc11c": 11, "\ud30c\uc0dd\ub41c": 11, "\uc911\ub9bd": 11, "\ucee8\ud14d\uc2a4\ud2b8": 11, "\ubb34\uc791\uc704\ub85c": 11, "\uc0d8\ud50c\ub9c1\ud55c\ub2e4": 11, "\uc5ec\uae30\uc5d0\ub294": 11, "rendit": [11, 15], "\ud615\uc2dd": 11, "\ud504\ub86c\ud504\ud2b8\uac00": 11, "\ud3ec\ud568\ub41c\ub2e4": 11, "\uc544\ub9c8": [11, 17], "\uc6d0\ubcf8": [11, 15, 19], "\uc6d0\ubcf8\uacfc": 11, "\ube44\uad50\ud558\uae30": 11, "\ubaa9\uc801\uc774": 11, "\uc544\ub2d0\uae4c": 11, "\uc2f6\uc74c": 11, "\ucd5c\uc801\ud654": 11, "\ubaa9\ud45c\uc2dd\uc740": 11, "\uac19\uc74c": [11, 12], "loss\ud568\uc218\uc640": 11, "\uc720\uc0ac\ud568": 11, "c\u03b8\uc640": 11, "e\u03b8\ub294": 11, "\ubbf8\uc138\ud55c": 11, "\uc2dc\uac01\uc801": 11, "\ud3ec\ucc29\ud560": 11, "\uc788\uc744\uac83\uc73c\ub85c": 11, "\uae30\ub300\ud568": 11, "compar": [11, 12], "\ub514\ud14c\uc77c\uc744": 11, "\ud3ec\ucc29\ud558\ub294": 11, "\ubaa8\uc2b5\uc744": 11, "\uc720\uc0ac\ud558\uba74\uc11c\ub3c4": 11, "guide\uc5d0": 11, "\ub9de\ucdb0\uc11c": 11, "\uc9c4\ud589\ud568": 11, "\uc8fc\uc81c\uc5d0": 11, "\uc815\ud655\ud558\uac8c": 11, "\ubcf4\uc874\ud558\uace0": 11, "\uc784\ubca0\ub529\uacfc": 11, "\ub098\uba38\uc9c0": [11, 18], "\ucea1\uc158\ub4e4\uc5d0": 11, "\ucd94\ub860\uc774": 11, "\uac00\ub2a5\ud588\uc74c": 11, "\ub370\uc774\ud130\uc14b\uc73c\ub85c\ub3c4": 11, "\ubcf4\uc874\ud558\uba74\uc11c": 11, "\ud45c\ud604\ud55c": 11, "\uadf8\ub9bc": [11, 12], "\uc0ac\uc9c4\uc5d0\uc11c\uc640": 11, "\uc758\uc0ac": 11, "\ubc31\uc778": 11, "\ub0a8\uc131": 11, "\uc758\uc0ac\ub97c": 11, "\uadf8\ub824\ub0c8\uc74c": 11, "\ub370\uc774\ud130\uc14b\uc5d0\uc11c": [11, 17], "\ub9ce\uc558\uc74c\uc744": 11, "imageset\uc5d0\uc11c": 11, "\uc131\ubcc4": 11, "\uc778\uc885\uc801": 11, "\ub2e4\uc591\uc131\uc5d0": 11, "\uc778\uc2dd\uc744": 11, "\ub192\uc77c": 11, "space": [11, 13, 15, 19], "embedding\uc758": 11, "\ud488\uc9c8\uc744": 11, "\ubd84\uc11d": [11, 14], "y\ucd95": 11, "\ubcf5\uc81c\ud558\ub294\uc9c0": 11, "\ubcc0\ud615\uc744": 11, "\uc0dd\uc131\ud558\ubbc0\ub85c": 11, "\uc758\ubbf8\uc801": 11, "\uacf5\uac04": [11, 12], "\uac70\ub9ac\ub97c": 11, "\uace0\ub824\ud558\uc5ec": 11, "\uc720\uc0ac\uc131\uc744": 11, "\uce21\uc815": 11, "\ucee8\uc149\uc5d0": 11, "64\uac1c\uc758": 11, "edit": 11, "x\ucd95": 11, "\uc218\uc815\ud558\ub294": 11, "\ub09c\uc774\ub3c4\uc640": 11, "\uc124\uc815\uc758": 11, "\uc77c\ub828\uc758": 11, "\ubcc4\ub85c": 11, "ddim": 11, "step\uc744": 11, "\uc0d8\ud50c\uc744": [11, 12, 19], "\ub9cc\ub4e4\uace0": 11, "prompt\uc758": 11, "embedding\uc5d0\uc11c": 11, "cosin": [11, 14, 15], "similarity\ub97c": 11, "\uc2a4\ucf54\uc5b4\ub294": 11, "capability\uc640": 11, "\uc2e0\ub8b0\ub3c4\ub97c": 11, "\ubcf4\uc5ec\uc90c": [11, 12, 17], "\uc2e4\ud5d8": [11, 14, 16], "\ud658\uacbd": 11, "\ub530\ub984": 11, "\uc0dd\ub7b5": 11, "evaluation1": 11, "baseline\uacfc": 11, "\ubc29\ubc95\uc758": 11, "semant": [11, 12], "quality\ub294": 11, "set\uc5d0\uc11c": 11, "\uc784\uc758\uc758": 11, "\uc0d8\ud50c\ub9c1\ud558\ub294": 11, "\uc5c6\uc5c8\ub2e4": [11, 12], "\ub2ec\uc131\ud558\uace0": 11, "baseline\uc5d0\uc11c": 11, "editablity\uc744": 11, "\ub2ec\uc131": [11, 13], "\uc810\uc740": 11, "space\uc758": 11, "\uc778\uc0c1\uc801\uc778": [11, 12], "\uc720\uc5f0\uc131\uc744": 11, "\ub098\ud0c0\ub0b4\uace0": 11, "\ub2e8\uc77c": [11, 12], "word\ub9cc": 11, "\uc815\ud655\ub3c4\ub85c": 11, "\ucea1\ucc98\ud558\ub294\ub370": 11, "\ub3c4\uc6c0\uc774": [11, 13], "distort": 11, "tradeoff": 11, "\uace1\uc120\uc758": 11, "outline\uc744": 11, "\uadf8\ub9ac\uba70": 11, "\ubd84\ud3ec\uc5d0": 11, "\uc218\uc815\ub420": 11, "target\uc758": 11, "\ucea1\ucc98\ud558\uc9c0\ub294": 11, "\ubc18\ub300\ub85c": 11, "\ubd84\ud3ec\uc5d0\uc11c": 11, "\uba40\ub9ac": 11, "\ubc97\uc5b4\ub098\uba74": 11, "editability\uac00": 11, "\ud06c\uac8c": [11, 12, 16, 18, 19], "\uac10\uc18c\ud558\ub294": 11, "reconstruction\uc774": 11, "rate\ub97c": [11, 12], "\ubcc0\uacbd\ud574": 11, "\uace1\uc120\uc744": 11, "\uc774\ub3d9\ud560": 11, "\uc788\uc73c\ubbc0\ub85c": 11, "\uc0ac\uc6a9\uc790\uc5d0\uac8c": 11, "tradeoff\uc5d0": 11, "\uc815\ub3c4\uc758": 11, "\uc81c\uc5b4\ub97c": 11, "\uc81c\uacf5\ud568": 11, "description\uc744": 11, "\ud3ec\ucc29\ud558\uc9c0": 11, "\ubabb\ud558\uba74\uc11c\ub3c4": 11, "\uac10\uc18c\ud568": 11, "\uc124\ubb38\uc9c0": 11, "\uc81c\uacf5\ubc1b\uc558\uace0": 11, "\uc774\ubbf8\uc9c0\uc640\uc758": [11, 15], "\uc720\uc0ac\uc131\uc5d0": 11, "\ubaa8\ub378\uc5d0\uc11c": [11, 14, 17], "\uacb0\uacfc\uc758": 11, "\uc21c\uc704\ub97c": 11, "\ub9e4\uae40": 11, "context\ub97c": 11, "\ud14d\uc2a4\ud2b8\uc640": 11, "\uc9c8\ubb38\ubcc4\ub85c": 11, "600\uac1c\uc529": 11, "200\uac1c\uc758": 11, "\uc751\ub2f5\uc744": 11, "\uc218\uc9d1": [11, 18], "\uc0dd\uc131\uc5d0": 11, "\uc81c\uacf5\ud558\uc9c0\ub9cc": 11, "\uc758\ubbf8\ub860\uc801\uc778": 11, "\ubcf8\uc9c8\uc744": 11, "\ud30c\uc545\ud558\uac70\ub098": 11, "shape\ub97c": 11, "\ud559\uc2b5\ud558\ub294\ub370": [11, 15], "\ud55c\uacc4": 11, "\ucd5c\uc801\ud654\uac00": 11, "\uc624\ub798": 11, "\uac78\ub9b0\ub2e4": 11, "\uc57d": [11, 12, 13], "2\uc2dc\uac04\uc774": 11, "\uc18c\uc694\ub428": 11, "\uc124\uc815\uacfc": 11, "\uc0dd\uc131\ud558\uae30": [11, 12], "model\ub97c": 11, "\ud65c\uc6a9\ud558\ub294": 11, "\uac1c\uc778\ud654\ub418\uba70": 11, "generation\uc744": 11, "\uc18c\uac1c\ud568": 11, "\ub0b4\uc5d0\uc11c": [11, 18], "word\ub85c": 11, "inverse\ud558\uc5ec": 11, "\uc791\ub3d9\ud568": 11, "word\ub294": 11, "\uc7a5\uba74\uc5d0": 11, "\uc0bd\uc785\ud560": 11, "\uac04\ub2e8\ud558\uace0": 11, "\uc758\ubbf8\uc5d0\uc11c": 11, "\ud3b8\uc9d1\ud558\uae30": 11, "\uc27d\ub3c4\ub85d": 11, "\uae30\ubc18": [11, 13], "interpace\ub97c": 11, "\uc0ac\uc6a9\ud558\uc9c0\ub9cc": 11, "\uc790\uc5f0": 11, "\uc5b8\uc5b4\uc758": 11, "\ud55c\uacc4\uc5d0": 11, "\uc811\uadfc\ud560": 11, "\ub2e8\uc11c\ub97c": 11, "modal": [11, 17], "\ud65c\uc6a9\ud560": 11, "\uacf5\uac1c\uc801\uc73c\ub85c": 11, "\uc0ac\uc6a9\uac00\ub2a5\ud55c": 11, "model\uc778": 11, "ldm\uc744": 11, "\uad6c\ud604\ub428": 11, "\ubc29\uc2dd\uc5d0": 11, "\uc544\ud0a4\ud14d\ucc98": 11, "\uc815\ubcf4\uc5d0": 11, "\uc758\uc874\ud558\uc9c0": 11, "\uc801\uc6a9\ud560": 11, "\uc0dd\uac01": 11, "\uac70\uae30\uc5d0\uc11c": 11, "preserav": 11, "\ud5a5\uc0c1\ub420": 11, "unpair": 12, "translat": 12, "iccv": 12, "2017": 12, "1703": 12, "10593": 12, "tensorflow": 12, "tutori": 12, "\ub17c\ubb38\ub9ac\ubdf0": 12, "cyclegan\uc744": 12, "\uc0ac\ub78c\uc774": [12, 17, 18], "\ud55c\uad6d\uc778\uc774\ub77c\uace0": 12, "\ub72f\uc5b4\ubcf4\uae30": 12, "kwangsu": 12, "\uc774\ud558": 12, "\ub3c4\uba54\uc778\uc744": 12, "\ub3c4\uba54\uc778\uc73c\ub85c": 12, "\ubcc0\ud658\uc2dc\ud0a4\ub294": 12, "vision\uc758": 12, "translation\uc740": 12, "input\uacfc": 12, "\uc9dd\uc774": 12, "\uc9c0\uc5b4\uc9c4": 12, "\uc5bb\ub294": [12, 17], "\uc5b4\ub835\uc2b5\ub2c8\ub2e4": 12, "\uc9dd\uc9c0\uc5b4\uc9c4": 12, "x\ub77c\ub294": 12, "domain\uc73c\ub85c\ubd80\ud130": 12, "\uc5bb\uc740": 12, "domain": 12, "y\ub85c": 12, "\ubc14\uafb8\ub294": [12, 15], "\uc5f0\uad6c\ub294": 12, "\ud65c\uc6a9\ud574": [12, 14], "\ub370\uc774\ud130\uc758": 12, "\ubd84\ud3ec\uc640": 12, "y\ub85c\ubd80\ud130\uc758": 12, "\ubd84\ud3ec\uac00": [12, 19], "\uad6c\ubd84\uc774": 12, "\ubd88\uac00\ub2a5\ud558\ub3c4\ub85d": 12, "y\ub85c\uc758": 12, "mapping\uc5d0": 12, "\uc81c\uc57d\uc744": 12, "\uac00\ud574\uc11c": 12, "\uac15\uc81c\ud558\uae30": 12, "x\uc640": 12, "\uc5ed\ubc29\ud5a5": 12, "\ub9e4\ud551\uc744": 12, "\uc9c4\ud589\ud558\uace0": 12, "\uc720\uc0ac\ud574\uc9c0\ub3c4\ub85d": 12, "\uac15\uc81c\ud558\ub294": 12, "\ub3c4\uc785\ud588\uc2b5\ub2c8\ub2e4": 12, "\uacb0\uacfc\uc801\uc73c\ub85c": 12, "task\uc5d0\uc11c": 12, "pair\uac00": 12, "\uc874\uc7ac\ud558\uc9c0": 12, "\ubcf4\uc5ec\uc92c\ub2e4\uace0": 12, "\uc2a4\ud0c0\uc77c": 12, "\uc18d\uc131": 12, "\ub4f1\uc744": 12, "image\ub85c": 12, "\ubcc0\ud658\ud558\ub294": 12, "\uadf8\ub9bc\uc73c\ub85c": 12, "\ubcc0\ud658\ud55c\ub2e4\uac70\ub098": 12, "\ub0ae\uc5d0": 12, "\ucc0d\uc740": 12, "\ubc24\uc5d0": 12, "\ud754\ud788": 12, "output\uc73c\ub85c": 12, "\ubc14\ud0d5\uc73c\ub85c": 12, "\uc774\ub8e8\uc5b4\uc838": [12, 19], "\uc788\uc5c8\ub294\ub370\uc694": 12, "\uc5b4\ub835\uace0": 12, "\ube44\uc2fc": 12, "\uc77c\uc774": 12, "image\uac00": 12, "\uc77c\ub300\uc77c\ub85c": 12, "\uc9dd\uc9c0\uc5b4\uc9c0\uc9c0": 12, "\ubaa8\uc74c\uc758": 12, "\ucea1\uccd0\ud558\uace0": 12, "\ubaa8\uc74c\uc73c\ub85c": 12, "\ubcc0\ud658\ud560": 12, "\uc81c\uc2dc\ud569\ub2c8\ub2e4": [12, 18], "x\uc5d0": 12, "\uc138\ud2b8": 12, "y\uc5d0": 12, "\uc138\ud2b8\uac00": 12, "\uc81c\uacf5\ub418\uace0": 12, "output\uacfc": [12, 14], "y\uac00": 12, "discriminator\uc5d0": 12, "\uad6c\ubcc4\ud560": 12, "\uc5c6\ub3c4\ub85d": 12, "y\ub97c": [12, 14], "\ud559\uc2b5\ud569\ub2c8\ub2e4": 12, "\uc774\uac8c": 12, "\uac1c\ubcc4": 12, "\ucd9c\ub825": 12, "\ubb34\uc870\uac74": 12, "\uc720\uc758\ubbf8\ud558\uac8c": 12, "\uc30d\uc744": 12, "\uc774\ub8ec\ub2e4\ub294": 12, "\ub73b\ud558\uc9c0\ub294": 12, "\uc54a\uc2b5\ub2c8\ub2e4": 12, "g\uac00": 12, "image\uc5d0\ub294": 12, "\ubb34\ud55c\ud55c": 12, "\uacbd\uc6b0\uc758": 12, "\uc218\uac00": [12, 13], "\ub54c\ubb38": 12, "collapse\uac00": 12, "\uc77c\uc5b4\ub098\uae30\ub3c4": 12, "dl": 12, "ai": 12, "blogspot": 12, "08": 12, "problem": 12, "image\ub4e0": 12, "\ub9e4\ud551\ud558\uba74\uc11c": 12, "\ucd5c\uc801\ud654\uc5d0": 12, "\uc2e4\ud328\ud558\ub294": 12, "\ud604\uc0c1": [12, 15], "\ud604\uc0c1\uc740": 12, "\uc785\uc7a5\uc5d0\uc11c": 12, "discriminator\uac00": 12, "\uc0ac\uc9c4\uc774": [12, 14], "\uc9c4\uc9dc": 12, "y\uc778\uc9c0": 12, "\uac00\uc9dc\uc778": 12, "\uc778\uc9c0": 12, "\uad6c\ubcc4\ud558\ub294": 12, "\uc18d\uc774\uae30\ub9cc": 12, "\uc6b0\ub9ac\uc758": 12, "\ubaa9\uc801\uacfc": 12, "\uc804\ud600": 12, "\uc0c1\uad00\uc774": 12, "\ub9cc\ub4e4\ub354\ub77c\ub3c4": 12, "\ubb38\uc81c\uac00": 12, "\uc0dd\uae30\uc9c0": 12, "\uc54a\uc544\uc11c": 12, "\ubc1c\uc0dd\ud568": 12, "\uc774\uc288\ub85c": 12, "\uc778\ud574": [12, 17], "function\uc774": 12, "\ud544\uc694\ud574": 12, "\uc84c\uc2b5\ub2c8\ub2e4": 12, "task\ub294": 12, "\uc601\uc5b4": 12, "\ud504\ub791\uc2a4\uc5b4": 12, "\uc601\uc5b4\ub85c": 12, "\ubc88\uc5ed\ud588\uc744": 12, "\uc6d0\ub798": [12, 14], "\ub3c4\ub2ec\ud558\ub294": 12, "\uac83\ucc98\ub7fc": 12, "\ub3cc\uc544\uac00\ub294": 12, "\uac19\uc544\uc57c": 12, "\ud55c\ub2e4\ub294": 12, "\uc758\ubbf8\uc758": 12, "cyclic": 12, "consistency\uc774\ub77c\ub294": 12, "\uc18d\uc131\uc744": 12, "\uc774\uc6a9\ud569\ub2c8\ub2e4": 12, "\ubaa9\uc801\uc2dd\uc744": 12, "\uac04\ub2e8\ud558\uac8c": 12, "\uc815\ub9ac\ud558\uba74": 12, "\uc815\ubc29\ud5a5": 12, "\ub17c\ubb38\uacfc": 12, "\uc5f0\uad6c\uc5d0": 12, "\ub0b4\uc6a9\uc774\uc5c8\uc74c": 12, "\uac1c\ub150\ub4e4\uc740": 12, "introduction\uc5d0\uc11c": 12, "\uc124\uba85\ud588\uace0": 12, "\uc2a4\ud130\ub514\uc640\ub294": 12, "\ub531\ud788": 12, "\uad00\ub828\uc774": 12, "\uc2a4\ud0b5\ud588\uc74c": 12, "\ub3c4\uc2dd\ud654": 12, "\uc790\ub8cc": 12, "mapping\ud558\ub294": 12, "function\uc744": [12, 13], "\uc6a9\uc5b4": 12, "\uc815\ub9ac": 12, "pdata": 12, "\ud45c\uc2dc": 12, "dx": [12, 16], "dy\ub294": 12, "dx\ub294": 12, "\uad6c\ubd84": 12, "y\uc640": 12, "\ubaa9\uc801\uc2dd\uc740": 12, "\ub450\uac1c": 12, "domain\uc758": 12, "distribution\uacfc": 12, "\uc77c\uce58\uc2dc\ud0a4\uae30": 12, "g\uc640": 12, "f\uac00": 12, "\ubaa8\uc21c\ub418\ub294": 12, "\ubc29\uc9c0\ud558\uae30": 12, "dy\uc5d0": 12, "l_gan": 12, "gan\uc5d0\uc11c": 12, "function\uacfc": 12, "\ub300\uc2e0\uc5d0": 12, "\uac08": [12, 14], "x\ub85c": 12, "\uc218\uc2dd\uc774": 12, "\ub098\uc624\uba70": 12, "dx\uc5d0": 12, "dx\ub97c": 12, "\ub123\uc740": 12, "\uc55e\uc11c": 12, "\ub9d0\ud588\ub4ef": 12, "\uc81c\ud55c\uc744": 12, "\ub450\uc5b4": 12, "\uc218\uc2dd\uc73c\ub85c\uc11c": 12, "\uc608\ube44": 12, "\uc2e4\ud5d8\uc5d0\uc11c": 12, "l1": 12, "loss\ub85c": 12, "\ub300\uccb4\ud574\ubd24\ub294\ub370": 12, "\ud5a5\uc0c1\uc744": [12, 14], "\uad00\ucc30\ud560": 12, "\uc5c6\uc5c8\uc74c": 12, "\uc720\ub3c4\ub41c": 12, "\ubd99\uc740": 12, "\uac00\uc911\uce58": [12, 17], "loss\uc640\uc758": 12, "\uc0c1\ub300\uc801": 12, "\uc911\uc694\ub3c4\uc5d0": 12, "\uacb0\uc815\ub428": 12, "architecture\ub85c\uc11c": 12, "transfer\uc640": 12, "\ubcf4\uc5ec\uc900": 12, "\uc0ac\uc6a9\ub41c": 12, "\ucc44\ud0dd\ud568": [12, 14], "3\uac1c\uc758": 12, "sever": 12, "block": [12, 14, 16], "fraction": 12, "stride": 12, "feature\ub97c": 12, "rgb\ub85c": 12, "\ub9e4\ud551\ud558\ub294": 12, "128": [12, 16], "\uace0\ud574\uc0c1\ub3c4": 12, "\uc548\uc815\ud654\uc2dc\ud0a4\uae30": 12, "\ud14c\ud06c\ub2c9\uc744": 12, "\uc801\uc6a9\ud569\ub2c8\ub2e4": 12, "function\uc5d0\uc11c": 12, "\ubcc0\uacbd": 12, "\ucd5c\uadfc\uc758": 12, "50\uac1c\ub97c": 12, "\uc800\uc7a5\ud574": 12, "\ud55c\uaebc\ubc88\uc5d0": 12, "\ubd84\ub958": 12, "\uc9c4\ub3d9\uc744": 12, "sjinu": 12, "ysbsb": 12, "02": 12, "lsgan": 12, "generator\uc758": 12, "\uc5c5\ub370\uc774\ud2b8\ub97c": 12, "lsgan\uc744": 12, "\uc774\ud574\ub294": 12, "\ubabb\ud588\uace0": 12, "\uc774\ub7f0\uac8c": 12, "\uc788\uad6c\ub098": 12, "\uc815\ub3c4\ub85c\ub9cc": 12, "\uc54c": [12, 17], "discriminator\ub294": 12, "\uc774\ubcf4\ub2e4": 12, "\uace0\ucc28\uc6d0\uc774\uc9c0\ub9cc": 12, "\uac04\ub7b5\ud788": 12, "2\ucc28\uc6d0\uc744": 12, "\ud45c\ubc29\ud558\uba74": 12, "\uacb0\uc815\uacbd\uacc4\ub97c": 12, "\ub098\ud0c0\ub0bc": 12, "\ucabd\uc774": 12, "\uac00\uc9dc": [12, 16], "\uc601\uc5ed": 12, "\uc601\uc5ed\uc785\ub2c8\ub2e4": 12, "\uc544\ub798\uc5d0": 12, "\uac70\ub9ac\uac00": 12, "\uba3c": 12, "\uc0d8\ud50c\uc774": 12, "\uc874\uc7ac\ud569\ub2c8\ub2e4": [12, 15], "\uc0ac\uc6a9\ud55c\ub2e4\uba74": 12, "\uc785\uc7a5\uc5d0\uc11c\ub294": 12, "discriminator\ub97c": 12, "\uc18d\uc774\uace0": 12, "\ud559\uc2b5\ud560": [12, 16], "\ud544\uc694\uac00": [12, 15], "\uc5c6\uc2b5\ub2c8\ub2e4": 12, "vanish": [12, 16], "\uc77c\uc5b4\ub098\uae30": 12, "\uc18d\uc778\ub2e4\ub294": 12, "\uc774\uc720\ub9cc\uc73c\ub85c": 12, "\ud328\ub110\ud2f0\ub97c": 12, "\uc904": [12, 14, 17], "\uc5c6\uac8c": 12, "ls": 12, "\uc8fc\uac8c": 12, "generator\ub294": 12, "\uc18d\uc774\ub294": 12, "\ub118\uc5b4\uc11c": 12, "\uac00\uc9c0\uac8c\ub054": 12, "\ud574\uc57c\ud569\ub2c8\ub2e4": 12, "\ub78c\ub2e4\ub97c": 12, "10\uc73c\ub85c": 12, "\uc124\uc815\ud588\ub2e4": 12, "\uc544\ub2f4\uc744": 12, "\uc0ac\uc6a9\ud588\ub2e4": 12, "\ub124\ud2b8\uc6cc\ud06c\ub294": 12, "0002\ub85c": 12, "\uc5d0\ud3ec\ud06c": 12, "\ub3d9\uc548\uc5d0\ub294": 12, "ln\uc744": 12, "\uc5d0\ud3ec\ud06c\ub9c8\ub2e4": 12, "\uc870\uae08\uc2dd": 12, "\uc218\ub834\ud558\uac8c": 12, "\ud588\ub2e4": 12, "\ud3c9\uac00\ub97c": [12, 13, 16, 17], "\uc9c0\ud45c\ub97c": 12, "amt": 12, "perceptu": 12, "\ucc38\uac00\uc790\ub4e4\uc740": 12, "\uc0ac\uc9c4\uc774\ubbf8\uc9c0": 12, "\uc9c0\ub3c4": 12, "\uac00\uc9dc\uc774\ubbf8\uc9c0\uc5d0": 12, "\ub178\ucd9c\ub41c": 12, "\uc9c4\uc9dc\ub77c\uace0": 12, "\uc0dd\uac01\ub418\ub294": 12, "\uc120\ud0dd\ud558\uac8c": 12, "1\ubc88": 12, "study\uac00": 12, "\ud14c\uc2a4\ud2b8\uc5d0": 12, "\uc788\uc5b4": 12, "\uae30\uc900\uc784\uc5d0\ub3c4": 12, "\ubd88\uad6c\ud558\uace0": 12, "\uc0ac\ub78c\uc744": 12, "\uc2e4\ud5d8\uc774": 12, "\uc591\uc801\uc778": 12, "\uae30\uc900\uc744": 12, "\ucc3e\uc558\ub294\ub370": 12, "score\uc784": 12, "fcn\uc740": 12, "\uc0ac\uc9c4\uc5d0": 12, "\ub808\uc774\ube14": 12, "\ub9f5\uc744": 12, "\uc608\uce21\ud569\ub2c8\ub2e4": 12, "\ub9f5\uc740": 12, "\uc544\ub798\uc5d0\uc11c": 12, "\ud45c\uc900": 12, "\uc2dc\ub9e8\ud2f1": 12, "\ubd84\ud560": 12, "\uba54\ud2b8\ub9ad\uc744": 12, "label\uacfc": 12, "\ube44\uad50\ud560": 12, "\ub3c4\ub85c": 12, "\uc0c1\uc758": 12, "\uc790\ub3d9\ucc28": 12, "label\uc5d0\uc11c": 12, "fcn\uc774": 12, "\uac10\uc9c0\ud558\uba74": 12, "\uc131\uacf5\ud55c": 12, "\ub77c\ubca8\ub9c1": 12, "pixel\ub2f9": 12, "\uc815\ud655\ub3c4": 12, "\ub2f9": 12, "iou": 12, "intersect": 12, "union": 12, "cityscap": 12, "benchmark\uc758": 12, "cogan": 12, "simgan": 12, "pix2pix": 12, "aginst": 12, "6\uc5d0\uc11c": 12, "\uc788\ub4ef\uc774": 12, "baseline\uc5d0\uc11c\ub3c4": 12, "\uac15\ub825\ud55c": 12, "\ubc18\uba74\uc5d0": [12, 16], "cyclegan\uc740": 12, "supervise\uc778": 12, "pix2pix\uc640": 12, "translation\uc744": 12, "\ud45c": 12, "1\uc740": [12, 14], "realism": 12, "\uc9c0\ub3c4\uc5d0\uc11c": 12, "\ud56d\uacf5": 12, "\uc0ac\uc9c4\uc5d0\uc11c": 12, "\ubaa8\ub450\uc5d0\uc11c": 12, "4\uc758": 12, "\ucc38\uac00\uc790\ub97c": 12, "\uc18d\uc77c": 12, "baseline\uc740": 12, "2\ub294": [12, 14], "\ub3c4\uc2dc": 12, "\ud48d\uacbd\uc5d0": 12, "\ud3c9\uac00\ud558\uace0": 12, "3\uc740": 12, "\ud3c9\uac00\ud568": [12, 17], "cyclegan\uc774": 12, "baseline\ub4e4\uc758": 12, "\ub2a5\uac00\ud55c\ub2e4": 12, "consistency\uc758": 12, "\uc911\uc694\uc131\uc744": 12, "\ubcf4\uc5ec\uc8fc\ub294": [12, 13, 15], "\uc5c6\uc560\uba74": 12, "cycle\uc744": 12, "\uc81c\uac70\ud558\ub294": 12, "\uc800\ud558\ub428": 12, "\uacb0\uacfc\uc5d0": 12, "\uc911\uc694\ud558\ub2e4\uace0": [12, 15], "\uacb0\ub860\uc744": 12, "\ub0b4\ub9b4": 12, "\ubc29\ud5a5\uc5d0\uc11c\ub9cc": 12, "\uba54\uc18c\ub4dc\ub97c": 12, "cycle\ub9cc": 12, "\ub3cc\ub838\uc744": 12, "backward": [12, 15, 16], "\uc774\ub530\uae08\uc529": 12, "\ubcf4\uc774\uace0": [12, 13], "collapse\ub97c": 12, "\uc720\ubc1c\ud558\ub294": 12, "\ubc1c\uacac\ud568": 12, "\uc81c\uac70\ub41c": 12, "\ub9e4\ud551\uc758": 12, "\ubc29\ud5a5\uc5d0": 12, "7\uc744": 12, "\uc787\uc5c8\uc74c": 12, "4\uc5d0\uc11c": 12, "\uc7ac\uad6c\uc131\ub41c": 12, "\uba87\uac00\uc9c0": 12, "\ubb34\uc791\uc704": 12, "\uc0ac\uc9c4\uacfc": 12, "\ub3c4\uba54\uc778\uc774": 12, "\uacbd\uc6b0\uc5d0\ub3c4": 12, "\ud14c\uc2a4\ud2b8": 12, "\ub9ce\uc558\uc74c": 12, "8\uc740": 12, "cmp": 12, "fa\u00e7ad": 12, "database\uc758": 12, "\uac74\ucd95": 12, "ut": 12, "zapoos50k": 12, "dataset\uc758": 12, "\uc2e0\ubc1c\uacfc": 12, "pix2pix\uc5d0": 12, "cyclegan\uc758": 12, "\ud488\uc9c8\uc740": 12, "supervis": 12, "\ub300\uc758": 12, "\uc9f1\uc774\ub2e4": 12, "\ub9ce\uc544": 12, "\uc0dd\ub7b5\ud558\uaca0\uc2b5\ub2c8\ub2e4": 12, "\u3160": 12, "data\uac00": 12, "data\uc5d0\uc11c": 12, "transslation\uc774": 12, "\ud55c\uac83\ubcf4\ub2e4": 12, "\ub9e4\ub825\uc801\uc774\ub2e4": 12, "application\uc740": 12, "\uc6f9\uc0ac\uc774\ud2b8\uc5d0": 12, "\uc2e0\uacbd": 12, "\uc804\ub2ec": 12, "13": [12, 17], "\uc791\uc5c5\uacfc": 12, "\ub2ec\ub9ac": [12, 16, 19], "\uc120\ud0dd\ud55c": 12, "\uc608\uc220": 12, "\uc791\ud488\uc758": 12, "\uc804\ub2ec\ud558\ub294": 12, "\uc791\ud488": 12, "\uceec\ub809\uc158\uc758": 12, "\ubaa8\ubc29\ud558\ub294": 12, "\uadf8\ub798\uc11c": [12, 16], "\ubcc4\uc774": 12, "\ube5b\ub098\ub294": 12, "\uadf8\ub9ac\ub294": 12, "\ubc18": 12, "\uace0\ud750": 12, "\ub530\ub77c\ud558\ub294": 12, "\ub290\ub08c\uc744": 12, "\ub530\ub77c\ud55c\ub2e4": 12, "turmukhambetov": 12, "\uac1d\uccb4\ub97c": 12, "\ubc94\uc8fc\uc758": 12, "\uac1d\uccb4\ub85c": 12, "\uc81c\uc548\ud558\ub294": 12, "\uc2dc\uac01\uc801\uc73c\ub85c": [12, 13], "\ubc94\uc8fc": 12, "\uac1d\uccb4": [12, 18], "\ubcc0\ud615\uc5d0": 12, "\uc911\uc810\uc744": [12, 13], "\ub461\ub2c8\ub2e4": [12, 19], "turn": 12, "hors": 12, "video": 12, "zebra": 12, "\uc0ac\uc9c4\uc73c\ub85c": 12, "\uc785\ub825\uacfc": 12, "\uac04": 12, "\uc0c9": 12, "\uad6c\uc131\uc744": 12, "\ubcf4\uc874\ud558\uae30": 12, "\uc720\uc6a9\ud558\ub2e4\ub294": 12, "\ubc1c\uacac\ud560": 12, "taigman": 12, "49": 12, "\uae30\uc220\uc744": [12, 17], "\ucc44\ud0dd\ud558\uc5ec": [12, 14], "\uc81c\ub108\ub808\uc774\ud130\uac00": 12, "\ub3c4\uba54\uc778\uc758": 12, "\uc785\ub825\uc73c\ub85c": 12, "\uc81c\uacf5\ubc1b\uc744": 12, "\uadfc\ucc98\uc5d0": 12, "\uc815\uaddc\ud654\ud569\ub2c8\ub2e4": 12, "lident": 12, "ey_pdata": 12, "lidentity\uac00": 12, "\uc5c6\uc73c\uba74": 12, "\uc0dd\uc131\uc790": 12, "f\ub294": 12, "\uad73\uc774": 12, "\ud544\uc694\ud558\uc9c0": 12, "\uc54a\uc744": 12, "\uc0c9\uc870\ub97c": 12, "\uc790\uc720\ub86d\uac8c": 12, "\ubcc0\uacbd\ud560": 12, "monet\uc758": 12, "flickr": 12, "\uc0dd\uc131\uc790\ub294": 12, "\uadf8\ub9b0": 12, "\uc77c\ubab0": 12, "\uc2dc\uac04\uc5d0": 12, "\ub9e4\ud551\ud569\ub2c8\ub2e4": 12, "\uc65c\ub0d0\ud558\uba74": 12, "\uc801\ub300\uc801": 12, "\uc190\uc2e4\uacfc": 12, "\uc0ac\uc774\ud074": 12, "\uc77c\uad00\uc131": 12, "\uc190\uc2e4": [12, 13], "\ub9e4\ud551\uc774": 12, "\ub3d9\ub4f1\ud558\uac8c": 12, "\uc720\ud6a8\ud560": 12, "\uc190\uc2e4\uc758": 12, "\ud6a8\uacfc\ub294": 12, "9\uc5d0\uc11c": 12, "\ubcf4\uc5ec\uc9d1\ub2c8\ub2e4": 12, "9\ub294": 12, "\ub370\uc774\ud130\uc14b\uc5d0": 12, "\ud3ec\ud568\ub418\uc5b4": 12, "set\uc740": 12, "\uc624\uc9c1": 12, "set\uc73c\ub85c\ubd80\ud130": 12, "\uadf8\ub824\uc9c4": 12, "datqa\ub97c": 12, "\ud3ec\ud568\ud558\uace0": 12, "\uadf8\ub9bc\uc5d0": 12, "\ud0c0\ub2f9\ud55c": 12, "\uc544\ub2c8\ub2e4": 12, "monet\uc774": 12, "\uc0c8": [12, 13], "\uadf8\ub9b4": 12, "generalization\uc740": 12, "press": 12, "\uc6b0\ub9ac\ub294": [12, 19], "\ubc29\ubc95\uc774": 12, "\uc595\uc740": 12, "\uae4a\uc774\uc758": 12, "\ub370": 12, "flickr\uc5d0\uc11c": 12, "\ub2e4\uc6b4\ub85c\ub4dc\ud55c": 12, "\uaf43": 12, "\ud6c8\ub828\ud569\ub2c8\ub2e4": 12, "\uc18c\uc2a4": 12, "\ub3c4\uba54\uc778\uc740": 12, "\uc2a4\ub9c8\ud2b8\ud3f0\uc73c\ub85c": 12, "\ucc0d\ud78c": 12, "\uad6c\uc131\ub418\uc5b4": 12, "\uc870\ub9ac\uac1c\ub85c": 12, "\uae4a\uc740": 12, "dof": 12, "\ucd08\uc810": 12, "\uae4a\uc774": 12, "\ub300\uc0c1\uc740": 12, "\uc870\ub9ac\uac1c\uac00": 12, "dslr\ub85c": 12, "\ucd2c\uc601\ub41c": 12, "\ud3ec\ud568\ud569\ub2c8\ub2e4": 12, "\uc0ac\uc9c4\uc73c\ub85c\ubd80\ud130": 12, "\uc131\uacf5\uc801\uc73c\ub85c": 12, "\uc0dd\uc131\ud569\ub2c8\ub2e4": [12, 19], "shallow": 12, "field": [12, 18], "\ucd08\uc810\uc774": 12, "\ub9de\uc740": 12, "\ubc30\uacbd\uc774": 12, "\ud750\ub9bf\ud558\uac8c": 12, "\ud65c\uc6a9": [12, 13, 14], "\uad6c\ubaa9\ud558\uace0\uc790": 12, "\uac15\uc870\ud558\uae30": 12, "domain\uc740": 12, "\uc2a4\ub9c8\ud2b8\ud3f0\uc758": 12, "target\uc740": 12, "discuss": 12, "\ud765\ubbf8\ub85c\uc6b4": [12, 15], "\uade0\uc77c\ud558\uac8c": 12, "\uc544\ub2c8\uc5c8\uc2b5\ub2c8\ub2e4": 12, "\ud574\uc11d": 12, "\uac1c": 12, "\uace0\uc591\uc774": 12, "task\uc640": 12, "\uacbd\uc6b0\ub294": 12, "\ucd5c\uc18c\ud55c\uc758": 12, "\ubcc0\ud654\ub9cc": 12, "\uc8fc\uc5b4": 12, "\ubcc0\ud654\uac00": [12, 17], "\uc548\ub418\ub294": 12, "\uacbd\uc6b0\ub3c4": 12, "\uc788\uc5c8\uace0": 12, "\ud615\uccb4\uac00": 12, "\uc560\ub9e4\ud574\uc9c4": 12, "\uc774\ub7f0\uac78": 12, "geometri": 12, "\ud45c\ud604\uc744": 12, "\ubcf4\uc544": 12, "\ub208": 12, "\ucf54": 12, "\uc785\uc5d0": 12, "\uad6c\ud604\ud558\ub294\ub370": 12, "\ub9d0": 12, "\uc5bc\ub8e9\ub9d0": 12, "\uc608\uc81c\uc758": 12, "\ub9d0\uc740": 12, "\ud0c0\ub294": 12, "\ubaa8\uc2b5\uc774": 12, "\ub9ce\uc558\ub294\ub370": 12, "\uc5bc\ub8e9\ub9d0\uc758": 12, "\uc5c6\ub2e4\ubcf4\ub2c8": 12, "\uc0ac\ub78c": [12, 17], "\ubfd0\ub9cc": 12, "\ubc30\uacbd\ub3c4": 12, "\uc5bc\ub8e9": 12, "\uadf8\ub9ac\uac70\ub098": 12, "\uc5bc\ub8e9\ub9d0\uc5d0\uc11c": 12, "\ub178\ub797\uac8c": 12, "\uce60\ud55c": 12, "\uc0dd\uae40": 12, "\ub54c\ub54c\ub85c": 12, "\ub098\ubb34\uc640": 12, "\uac74\ubb3c\uc758": 12, "label\uc744": 12, "\ubaa8\ud638\uc131\uc744": 12, "\ud574\uacb0\ud558\ub824\uba74": 12, "weak": 12, "supervision\uc774": 12, "\ud544\uc694\ud560": 12, "\ub9c8\ubb34\ub9ac": 12, "\uadf8\ub7fc\uc5d0\ub3c4": 12, "\uc644\uc804\ud788": 12, "\ud48d\ubd80\ud558\uac8c": 12, "\uc81c\uacf5\ub418\uba70": 12, "\ud65c\uc6a9\ud574\uc57c": 12, "setting\uc5d0\uc11c": 12, "\uac83\uc758": 12, "\ub298\ub9ac\ub294\ub370": 12, "\uae30\uc5ec\ud569\ub2c8\ub2e4": 12, "icml": 13, "12092": 13, "unoffici": 13, "donggeun": [13, 14, 17], "sean": [13, 14, 17], "ko": [13, 14, 17], "june": 13, "22": 13, "\ubaa8\ub378\uc774\uba70": 13, "120\uc5b5\uac1c": 13, "\uc218\uc640": 13, "5\uc5b5": 13, "\ubaa8\ub378\ub9c1\uc744": 13, "\ud1b5\ud558\uc5ec": 13, "text\ub97c": 13, "\uc774\uc6a9\ud558\uc5ec": 13, "2021\ub144": 13, "diverse\ud55c": 13, "3\uc640": 13, "vae\ub97c": 13, "transformer\uc744": 13, "architecture\uc744": [13, 14], "\uad6c\ucd95": 13, "model\uba70": 13, "few": 13, "learning\uc744": 13, "\ub0c4": 13, "\uc218\ub294": 13, "\ub9de\ucdb0": 13, "shot\uc744": 13, "decod": [13, 15, 19], "\ubd80\ubd84\ub9cc": [13, 14], "1750\uc5b5": 13, "\uac1c\uc218\uc758": 13, "\uc544\ud0a4\ud14d\uccd0": [13, 14, 17], "2005": 13, "14165": 13, "jalammar": 13, "how": 13, "gpt3": 13, "encoder\uc5d0\uc11c": 13, "output\uc740": 13, "discret": 13, "categor": 13, "\uac16\ub294\ub2e4\uace0": 13, "cnn": 13, "\uac70\uce5c": [13, 18], "d\ucc28\uc6d0\uc758": 13, "\uc704\uce58\uc5d0": 13, "\uadf8\ub9ac\ub4dc\ub85c": 13, "\ub098\ub204\uace0": 13, "\ud835\udc52_1": 13, "\ubd80\ud130": 13, "\ud835\udc52_\ud835\udc58": 13, "1\uac1c": 13, "code\ub85c": 13, "\ubcc0\ud658": 13, "z_": 13, "e_j": 13, "\ucc3e\uc544\uc11c": 13, "\ubd80\uc5ec\ud568": 13, "p2yeong": 13, "understand": [13, 17], "explain": 13, "issu": 13, "pixel\uc744": 13, "\uc9c1\uc811\uc801\uc73c\ub85c": 13, "token\uc744": 13, "\uace0\ud654\uc9c8": [13, 14], "\uc774\ubbf8\uc9c0\uc77c\uc218\ub85d": 13, "\uba54\ubaa8\ub9ac\ub7c9\uc774": 13, "\ud544\uc694\ud574\uc11c": 13, "\ube44\ud6a8\uc728\uc801": 13, "short": 13, "depend": [13, 15], "between": [13, 17], "model\ub4e4": 13, "likelihood": [13, 14, 16, 19], "dependency\ub97c": 13, "\uac83\uc774\uba70": 13, "frequenc": 13, "detail\uc5d0": 13, "\ub354\uc6b1": [13, 17], "\uc9d1\uc911\ud558\uac8c": 13, "\ub428": 13, "recognizable\ud574\uc11c": 13, "\ub418\ub294": [13, 14, 15, 18], "2\uac00\uc9c0": [13, 17], "\uadf9\ubcf5\ud558\uace0\uc790": 13, "textbf": 13, "rgb": 13, "rightarrow": 13, "\ud1a0\ud070\uc73c\ub85c": 13, "\uc555\ucd95": 13, "192\uac1c\uc758": 13, "\uac12": 13, "\uc911\uc5d0": 13, "\ubc30\uc815": 13, "\ubc30": 13, "\ub9cc\ud07c": 13, "size\ub97c": 13, "bpe": 13, "\ub4e4\uacfc": [13, 17], "\uc5f0\uc18d\uc801\uc73c\ub85c": 13, "\uc785\ub825\ud568": 13, "concaten": [13, 18], "token\uacfc": 13, "\ub4e4\uc758": 13, "\uacb0\ud569": 13, "\ubaa8\ub378\ub9c1\ud558\uc5ec": [13, 14], "\uc2dc\uac01\ud654": [13, 14], "jiho": 13, "ml": [13, 19], "weekli": 13, "nlp": 13, "40": 13, "\ud30c\uc774\ud504\ub77c\uc778": 13, "cqom0r2kmvi": 13, "1729": 13, "maxim": 13, "caption": [13, 17], "\ud835\udc5e": 13, "\u03c6": 13, "red": 13, "dvae": 13, "token\ub97c": 13, "\ud835\udc5d": 13, "\ud835\udf03": 13, "blue": 13, "token\uc5d0\uc11c": 13, "decoder\uc5d0\uc11c": 13, "\u03c8": 13, "purpl": 13, "\ubaa8\ub378\ub9c1\ud55c": 13, "text\uc640": 13, "token\ub4e4\uc758": 13, "\ud835\udc5e_\u03c6": 13, "\ud835\udc5d_\ud835\udf03": 13, "\ud559\uc2b5\ud568": 13, "elb": 13, "bound\ub97c": 13, "192": 13, "elb\ub97c": 13, "continuous\ub97c": 13, "\ubc14\uafd4\uc57c": 13, "\ud559\uc2b5\uc2dc\uc5d0\ub294": 13, "argmax\ub97c": 13, "\uc778\ub371\uc2a4\ub97c": 13, "\uc120\ud0dd\ud558\uc5ec": 13, "\uacc4\uc0b0\ud558\uba74": 13, "reparameter": 13, "gradient\ub97c": [13, 14], "\uc5f0\uc0b0": 13, "argmax": 13, "gumbel": 13, "\ud574\uacb0": 13, "\uc9c4\ud589\ud560": 13, "\ub54c\uc5d0\ub294": 13, "underset": 13, "g_i": 13, "e_i": 13, "relaxation\ub97c": 13, "q_": [13, 19], "tau": 13, "temperatur": 13, "relaxation\uc744": 13, "tight\ud558\uac8c": 13, "\uc7a1\uc544\uc90c": 13, "psi": 13, "\uc774\ub54c": [13, 15, 16, 18, 19], "120\uc5b5\uac1c\uc758": 13, "token\uc740": 13, "logit\uc5d0\uc11c": 13, "\uc18c\ubb38\uc790\ud654": 13, "384": 13, "vocabulary\ub97c": 13, "\ud55c\ubc88\uc5d0": 13, "causal": 13, "mask": [13, 18], "row": 13, "column": 13, "\ucd94\ub860": 13, "\ub300\ud558\uc5ec": 13, "n\uac1c\ub294": 13, "n\uac1c": 13, "\uace8\ub77c\uc11c": 13, "\uace0\ub974\uae30": 13, "\ubc88\uc9f8\ub85c": 13, "similar": [13, 15], "\uc810\uc218\uac00": [13, 17], "\uc120\ud0dd\ud568": 13, "\uacb0\uacfc\ubb3c": 13, "best\ub97c": 13, "\uace0\ub97c\ub54c": 13, "\uc99d\uac00\ud560\uc218\ub85d": 13, "prompt\ub791": 13, "\uacb0\uacfc\ubb3c\uc774": 13, "\ub098\uc634": [13, 14], "512\uac1c": 13, "\uc54c\uace0\ub9ac\uc998\uc744": 13, "score\uc774": 13, "\uc81c\uc77c": [13, 14], "\ubf51\uc74c": 13, "\uc54c\ub9de\uc740": 13, "\uc120\ud0dd\ud558\ub294": 13, "\uac1c\uc218\uc5d0": [13, 15], "df": 13, "\uc774\ub791": [13, 19], "ms": [13, 17], "coco": [13, 17], "five": 13, "vote": 13, "gan\ubcf4\ub2e4": [13, 14], "\uc555\ub3c4\uc801\uc778": 13, "\ucc28\uc774\ub85c": 13, "\ud22c\ud45c": 13, "\uc218\ub97c": 13, "\ubc1b\uc558\uc74c": 13, "frechet": 13, "distanc": 13, "\ub0ae\uc744\uc218\ub85d": [13, 14], "\uc88b\uc73c\uba70": 13, "IS": 13, "\ub192\uc744\uc218\ub85d": [13, 14], "\ub791": 13, "cub": 13, "\ud2b9\ud654": 13, "e\ub294": 13, "coco\uc5d0\uc11c\ub294": 13, "\ubcf4\uc5ec\uc92c\uc74c": 13, "cub\uc5d0\uc11c\ub294": 13, "\ucc0d\uc9c0": 13, "\ubabb\ud558\uc600\uace0": 13, "score\uc5d0\uc11c\ub294": 13, "\uc810\uc218\ub97c": [13, 17], "\uae30\ub85d\ud568": 13, "cub\uc5d0": 13, "\uacc4\uc120\uc744": 13, "\uc0dd\uac01\ud568": 13, "\uacb0\uacfc\uac12": 13, "\ud655\uc7a5": 13, "parameter\uacfc": 13, "\ub6f0\uc5b4\ub098\uac8c": 13, "\ud574\uacb0\ud568": 13, "\ud6cc\ub96d\ud55c": [13, 17], "\uc77c\ubc18\ud654": 13, "\ud3c9\uac00\uc5d0\uc11c": 13, "\uc900\uc218\ud55c": 13, "\uc2f6\uc740": 13, "\uac1d\uccb4\uac00": 13, "\ud3ec\ud568\ub418\uba74": 13, "\uacaa\uc74c": 13, "\uace0\uc2b4\ub3c4\uce58\uac00": 13, "2\ub9c8\ub9ac\uac70\ub098": 13, "\uac15\uc544\uc9c0\uc640": 13, "\uace0\uc2b4\ub3c4\uce58": 13, "\ub458\ub2e4": 13, "\ud06c\ub9ac\uc2a4\ub9c8\uc2a4": 13, "\uc2a4\uc6e8\ud130\ub97c": 13, "\uc785\uace0": 13, "\uc544\uc26c\uc6b4": 13, "\ubcf4\uc778": 13, "\ub370\uc774\ud130\uc14b\uc774": [13, 18], "tuning\uc73c\ub85c": 13, "limitation\uc744": 13, "nip": [14, 16], "2105": 14, "05233": 14, "\ubaa8\ub378\ub4e4\uc758": 14, "\ub6f0\uc5b4\ub118\uc74c": 14, "\ubd80\ubd84\uc5d0\uc11c\ub3c4": 14, "guidance\ub97c": [14, 17], "\ubcf4\uc5ec\uc900\ub2e4\uace0": [14, 15], "\uc8fc\uc7a5\ud568": 14, "diversity\uc640": 14, "fidelity\uc758": 14, "trade": 14, "off\uc5d0": 14, "model\ub4e4\uc774\uba70": 14, "\uc0dd\uc131\ud574\ub0b4\ub294\ub370\uc5d0": 14, "\uc131\uacf5": 14, "\ud588\uc74c": 14, "deep\uc5d0": 14, "\ub0ae\uc73c\uba70": 14, "\uac1c\uc120\uc0ac\ud56d\uc774": 14, "\ud544\uc694\ud568": 14, "\ub450\uac00\uc9c0": 14, "model\ub4e4\uc758": 14, "\ub04c\uc5b4\uc62c\ub9ac\uba70": 14, "\ub0ae\ucd94\uaca0\ub2e4\uace0": 14, "\uc8fc\uc7a5": [14, 17], "\uc124\uba85\ub418\uc788\uc73c\ubbc0\ub85c": 14, "\ub17c\ubb38\ub4e4\uc758": 14, "\ud575\uc2ec": 14, "\uc124\uba85\ud558\uaca0\uc2b5\ub2c8\ub2e4": 14, "\uadfc\uc0ac\uac12\uc774\ub77c\uace0": 14, "\uac00\uc815\ud558\uba70": 14, "\uacc4\uc0b0\ud55c\ub2e4": 14, "approx": [14, 16, 19], "\ub9cc\ub4e0\ub2e4": 14, "\uc608\uce21\ud55c\ub2e4": 14, "\uacf5\ubd84\uc0b0": 14, "\ubd88\uac00\ub2a5\ud55c": 14, "\ub9e4\uac1c\ubcc0\uc218\ub85c": 14, "\uc124\uc815\ub418\uba70": 14, "\uac00\uc9c4\ub2e4": 14, "pipelin": [14, 17], "\uc9c0\ud45c": 14, "ddpm\uc5d0\uc120": 14, "\uc9c0\ud45c\uac00": 14, "\uc0c1\ub300\uc801\uc73c\ub85c": 14, "\ub0ae\uc558\ub2e4": 14, "scheduling\uc744": 14, "\uc0ac\uc6a9\ud588\uc9c0\ub9cc": 14, "\ud588\ub2e4\uace0": 14, "\uc8fc\uc7a5\ud588\ub2e4": 14, "\ud559\uc2b5\uc5d0\ub3c4": 14, "\ub04a\uace0": 14, "\ud615\ud0dc\ub85c": 14, "\ud558\uac8c": [14, 16, 18, 19], "\ubc14\uafc8": 14, "iteration\uc73c\ub85c": 14, "\uadf8\ub300\ub85c": 14, "\ucc44\ud0dd\ud588\uc9c0\ub9cc": 14, "parameter\uc744": 14, "\ubcc0\uacbd\ud558\uc5ec": 14, "\uc124\uba85": 14, "\ud06c\uae30\ub97c": 14, "\uc77c\uc815\ud558\uac8c": 14, "\uac00\uc838\uac00\uba74\uc11c": 14, "\uc99d\uac00": 14, "\ubcf4\uae30": 14, "\uc2dc\ucf1c\ubcf4\uae30": 14, "head\uc5d0": 14, "8x8": 14, "16x16": 14, "\ud574\ubcf4\uae30": 14, "\uc77c\ubc18": 14, "block\uc774": 14, "biggan\uc758": 14, "block\uc744": 14, "connection\uc744": 14, "rescal": 14, "chang": 14, "32\uc77c\ub54c": 14, "\ub0ae\ub2e4": 14, "160": 14, "resolution\uc744": 14, "block\ub9c8\ub2e4": 14, "\uc904\uc774\uae30": 14, "\ud29c\ub2dd\uc744": 14, "\ud14c\uc774\ube14": 14, "adain\uc774\ub791": 14, "\uc5f0\uc0b0\ud558\ub294": 14, "adagn": 14, "\uc18c\uac1c\ud588\ub2e4": 14, "\ubc29\ubc95\ub860\uc778\uc9c0\ub294": 14, "\ubaa8\ub974\uaca0\ub2e4": 14, "normalization\uc744": 14, "adpative\ud558\uac8c": 14, "embedding\uacfc": 14, "adain": 14, "\uacf1\ud558\uace0": 14, "\ub354\ud568": 14, "y_b": 14, "where": 14, "respect": [14, 17], "adagn\uc758": 14, "adagn\uacfc": 14, "additon": 14, "normalization\ubcf4\ub2e4": 14, "\ubcf4\uc5ec\uc8fc\uace0": [14, 15, 17], "addit": 14, "layer\uc744": 14, "\uc0ac\uc6a9\ud588\ub294\ub370": 14, "\ub0ae\uac8c": 14, "\uc8fc": 14, "contribut": 14, "\ud558\ub098\uac00": 14, "\uc0ac\uc6a9\ud588\ub2e4\ub294": 14, "de": 14, "condition\uc73c\ub85c": 14, "\uc90c\uc73c\ub85c\uc368": 14, "zp_": 14, "normalizing\uc744": 14, "\uc0c1\uc218": 14, "log_": 14, "\uace1\ub960\uc774": 14, "\uac00\uc815\uc744": [14, 19], "\ubb34\ud55c\uc73c\ub85c": 14, "rightarrow0": 14, "\uc774\ubbc0\ub85c": 14, "\ud14c\uc77c\ub7ec": 14, "\uae09\uc218\ub97c": 14, "\uc7ac\uc804\uac1c": 14, "classifier\uc758": [14, 17], "\ud65c\uc6a9\ud574\uc11c": [14, 19], "\ud574\uc900\ub2e4": 14, "\uc2dd": 14, "\uc720\ub3c4\ub294": 14, "\ubcf8\ubb38\uc758": 14, "\ubc88\uc2dd\uc774\ubbc0\ub85c": 14, "\ub17c\ubb38\uc744": 14, "\ucc38\uace0\ud558\uba74": 14, "\ubc29\ubc95": [14, 17, 20], "\ubc29\ubc95\uc774\ub2e4": 14, "\ub611\uac19\uc774": 14, "sample\ud55c\ub2e4": 14, "ddim\uc5d0\uc11c": [14, 17], "gradient\uc758": 14, "\ube7c": 14, "score\uc744": 14, "\uad6c\ud55c\ub2e4": 14, "scaling\uc758": 14, "\uc601\ud5a5": 14, "bf": 14, "\uac12\uc5d0": 14, "classifier\uac00": 14, "scaling\uc774": 14, "\ub2e4\ub974\ub2e4": 14, "\uc8fc\uba74": 14, "\uc6f0\uc2dc\ucf54\uae30\ub77c\ub294": 14, "\ub35c": 14, "\uc6f0\uc2dc\ucf54\uae30\uc2a4\ub7ec\uc6b4": 14, "\uac15\uc544\uc9c0\uac00": 14, "\ub418\uc9c0\ub294": 14, "\uc6f0\uc2dc\ucf54\uae30": 14, "class\ub77c\ub294": 14, "\ubd84\uc704\uae30\uc758": 14, "\uac15\uc544\uc9c0\uc758": 14, "epsilon\uc774\ub77c\ub294": 14, "scale\uc5d0": 14, "\ubc1b\ub294\uc9c0": 14, "sampling\ud560": 14, "fidel": [14, 15, 17], "off": 14, "scale\uc774": 14, "recall\uc740": 14, "\ub0ae\uc9c0\ub9cc": 14, "precision\uc740": 14, "\ub192\ub2e4": 14, "\uc0dd\uae30\ub294\ub370": 14, "recall\uc774": 14, "diveristy\uac00": 14, "\ub0ae\ub2e4\ub294": [14, 19], "\uc758\ubbf8\uc774\uace0": 14, "precision\uc774": 14, "\ub192\ub2e4\ub294": 14, "\ub73b\uc774\ub2e4": 14, "\ub192\uc77c\uc218\ub85d": 14, "label\ucabd\uc73c\ub85c": 14, "guide\uac00": 14, "\uc0dd\uae30\ubbc0\ub85c": 14, "\uc77c\uc815\ud55c": 14, "sfid\ub294": 14, "off\ub85c": 14, "\ub3c4\ucd9c\ub418\ub294": 14, "\uac12\uc774\ubbc0\ub85c": 14, "\ucd5c\uace0\uc758": 14, "\uc9c0\uc810\uc5d0\uc11c": 14, "\ub098\uc654\ub2e4": 14, "adm\uc740": 14, "\uc57d\uc790\uc774\uba70": 14, "adm": 14, "g\ub294": 14, "guidance\uc758": 14, "\uc57d\uc790\uc774\ub2e4": 14, "\uc8fc\uc5c8\uc744": 14, "fid\uac12\uc774": [14, 17], "\ub098\uc654\uc73c\uba70": 14, "vice": 14, "versa": 14, "center": 14, "\ub450\ubc88\uca30": 14, "\ud50c\ub77c\ubc0d\uace0": 14, "\ubcfc\ub54c": 14, "biggan\uc740": 14, "\uc774\ubbf8\uc9c0\uac04\ub4e4\uc758": 14, "\ud50c\ub77c\ubc0d\uace0\uac00": 14, "\ub2e4\uc218": 14, "\ub290\ub08c\uc758": 14, "\uc774\ubbf8\uc9c0\ub9cc": 14, "\ubf51\uc544\ub0b8\ub2e4": 14, "\ub2e4\ucc44\ub85c\uc6b4": 14, "\ud55c\ub9c8\ub9ac\ub9cc": 14, "\uc0ac\uc9c4\ub3c4": 14, "\uc2dc\uac04\uc774": 14, "\ub290\ub9ac\ub2e4": 14, "distil": 14, "\ubc95\uc744": 14, "\uace0\ub824": 14, "guidance\ub294": 14, "classif": [14, 16], "function\uc758": 14, "\uc0ac\uc6a9\ud568\uc73c\ub85c\uc368": [14, 18], "label\uc774": 14, "data\uc5d0\ub294": 14, "\ud655\uc7a5\uc774": 14, "\ubd88\uac00\ub2a5\ud558\ub2e4": 14, "unlabel": 14, "sample\uc744": 14, "cluster": 14, "\ubc29\ubc95\ub860\uc744": 14, "expand": 14, "\ud558\ub824": 14, "subject": 15, "driven": 15, "12242": 15, "huggingfac": 15, "\ucd5c\uadfc\uc5d0": [15, 16, 17], "dall": [15, 17, 18], "e2": [15, 18], "imagen": 15, "\ub4f1\uc7a5\ud558\uc600\uc9c0\ub9cc": 15, "\ubd80\ubd84\uc5d0\uc11c": 15, "\uba74\ub4e4\uc744": 15, "\uac1c\uc120\ud558\uae30": 15, "\uae30\ubc95\uc73c\ub85c": [15, 19], "\uc18c\uac1c\ub418\uc5c8\uace0": 15, "5\uc7a5\uc758": 15, "\ub418\uba70": [15, 18], "nvidia": 15, "5\ubd84": 15, "\uc815\ub3c4\ubc16\uc5d0": 15, "\uc18c\uc694\ub418\uc9c0": 15, "\uc54a\ub294\ub2e4\uace0": 15, "\ubb34\uc5c7\uc778\uc9c0": [15, 19], "\uc54c\uc544\ubcf4\uae30": 15, "\uc804\uc5d0": 15, "\uc815\ub9ac\ub97c": 15, "\ud574\ubcfc": 15, "gamma": 15, "\uc785\ub825\ubc1b\uc544\uc11c": 15, "gen": 15, "\uc218\uc2dd\uc801\uc73c\ub85c": [15, 19], "\ud45c\ud604\ud558\uba74": [15, 19], "w_t": 15, "alpha_tx": 15, "t5": 15, "xxl": 15, "\uc0ac\uc6a9\ud588\ub2e4\uace0": 15, "\ud560\ub54c": 15, "\ub54c\ub85c\ub294": 15, "\ud3ec\ud568": 15, "\uc124\uc815\ud558\uace0": 15, "\ud30c\ub77c\ubbf8\ud130": [15, 19], "\uace0\uc815\uc2dc\ud0a8\ub2e4\uace0": 15, "\uc55e\uc368": [15, 18], "\uc124\uba85\ub4dc\ub838\ub358": 15, "\ub0b4\uc6a9\ub4e4\uc744": 15, "blob": 15, "main": 15, "text_encoder_cl": 15, "import_model_class_from_model_name_or_path": 15, "arg": [15, 19], "noise_schedul": 15, "ddpmschedul": 15, "from_pretrain": 15, "subfold": 15, "text_encod": 15, "autoencoderkl": 15, "unet2dconditionmodel": 15, "epoch": [15, 16], "first_epoch": 15, "num_train_epoch": 15, "train_dataload": 15, "skip": [15, 17], "until": 15, "reach": 15, "resum": 15, "resume_from_checkpoint": 15, "resume_step": 15, "progress_bar": 15, "continu": 15, "accumul": 15, "pixel_valu": 15, "weight_dtyp": 15, "latent_dist": 15, "config": 15, "scaling_factor": 15, "offset_nois": 15, "randn": 15, "bsz": 15, "randint": 15, "num_train_timestep": 15, "accord": 15, "magnitud": 15, "noisy_lat": 15, "add_nois": 15, "get": 15, "encoder_hidden_st": 15, "input_id": 15, "model_pr": 15, "prediction_typ": 15, "v_predict": 15, "get_veloc": 15, "part": 15, "model_pred_prior": 15, "target_prior": 15, "mse_loss": 15, "float": 15, "prior_loss": 15, "sync_gradi": 15, "params_to_clip": 15, "itertool": 15, "clip_grad_norm_": 15, "max_grad_norm": 15, "zero_grad": [15, 16], "set_to_non": 15, "set_grads_to_non": 15, "noun": 15, "\uc720\uc9c0\ud558\uace0\uc790": 15, "\ub300\uc0c1\uc5d0": 15, "\ub2f4\ub294": 15, "rare": [15, 18], "3\uac1c": 15, "unicod": 15, "charact": 15, "\ub79c\ub364\ud558\uac8c": 15, "\uc0d8\ud50c\ub9c1\ud574\uc11c": 15, "\uc815\uc758\ud569\ub2c8\ub2e4": [15, 18, 19], "drift": 15, "\ub178\uc774\uc988": 15, "\uc785\ub825\ud558\uc5ec": 15, "\uacc4\uc0b0\ud569\ub2c8\ub2e4": 15, "\uacfc\uc815\uc73c\ub85c": 15, "\ud559\uc2b5\ud558\uace0\uc790": 15, "\uc2dc\ud0a8": 15, "sigma_t": 15, "w_": 15, "alpha_": 15, "\ucd94\uac00\ud568\uc73c\ub85c\uc368": 15, "\uc720\uc9c0\ud558\uac8c": 15, "\uc774\ub85c\uc368": [15, 19], "encourag": 15, "\uac00\uc9c0\uc758": 15, "\uccab\ubc88\uc9f8\ub85c\ub294": 15, "\uce21\uc815\ud558\ub294": 15, "dino": 15, "\uc0dd\uc131\ub418\uae30": 15, "\uc120\ud638\ub41c\ub2e4\uace0": 15, "\uc790\uc138\ud558\uac8c\ub294": [15, 19], "\uacc4\uc0b0\ub429\ub2c8\ub2e4": 15, "pairwis": 15, "vit": 15, "\ube44\uad50\ud588\uc744\ub54c": 15, "ppl": 15, "\uacb0\uacfc\ub3c4": 15, "\uc801\uc6a9\ub428\uc73c\ub85c\uc368": 15, "\uc18c\uac1c\ub4dc\ub838\ub358": 15, "div": 15, "\ud574\uacb0\ub418\ub294": 15, "\ud588\uc744": 15, "\ub9de\ub294": 15, "\uc785\ub825\ud588\uc744\ub54c\uac00": 15, "\uc124\uba85\ud569\ub2c8\ub2e4": 15, "randomli": 15, "incorrect": 15, "can": 15, "backpack": 15, "correct": 15, "recontextu": 15, "descript": 15, "\uc0ac\uc804\uc5d0": 15, "\ub098": [15, 17], "articul": 15, "art": 15, "famou": 15, "painter": 15, "statu": 15, "sculptor": 15, "\uc720\uc9c0\ud55c": 15, "\ucc44": 15, "\ud615\ud0dc\ub3c4": 15, "\uac00\ub2a5\ud569\ub2c8\ub2e4": 15, "novel": 15, "\uac01\ub3c4\uc5d0\uc11c": 15, "\ubcf4\ub294": 15, "\uc0dd\uc131\ub3c4": [15, 17], "properti": 15, "modif": 15, "dog": 15, "speci": 15, "\uace0\uc720": 15, "\ub4e4\uc774": 15, "\uc5d0\uc11c\ub3c4": 15, "\ubc18\uc601\uc774": 15, "\ud55c\uacc4\uc810\ub3c4": 15, "\uc790\uc8fc": 15, "\ub098\ud0c0\ub098\uc9c0": 15, "appear": 15, "\ub2ec\ub77c\uc9c0\ub294": 15, "\ub370\uc774\ud130\uc640": [15, 16, 19], "\ubcf4\uc778\ub2e4\uace0": 15, "\ubcf8\ubb38\uc5d0": 15, "\uc18c\uac1c\ub418\uace0": 15, "\uc788\uc9c0\ub294": 15, "\uc54a\uc9c0\ub9cc": 15, "\ubd80\ubb38\uc5d0\uc11c\ub3c4": 15, "\ud559\uc2b5\uacb0\uacfc\ub97c": 15, "\ubcf4\uc5ec\uc8fc\ub294\ub370": 15, "\uc7a5\ub9cc\uc73c\ub85c\ub3c4": 15, "18": 15, "\ub9cc\ud654": 15, "\uc0ac\ub840\ub4e4\uc744": 15, "2014": [16, 19], "1406": 16, "2661": 16, "eriklindernoren": 16, "smart": [16, 19], "lab": [16, 19, 20], "kaist": [16, 19], "\ub525\ub7ec\ub2dd": [16, 19], "chp": 16, "ian": 16, "goodfellow": 16, "2014\ub144\uc5d0": 16, "\ubc1c\ud45c\ud55c": 16, "\uc18c\uac1c\ub418\uae30": 16, "\uc804\uae4c\uc9c0": 16, "\ub144": 16, "\ub3d9\uc548": 16, "\uc0dd\uc131\ubd84\uc57c\uc5d0\uc11c": 16, "\ub300\ud45c\uc801\uc778": 16, "\uc790\ub9ac\uc7a1\uc558\uc5c8\uc2b5\ub2c8\ub2e4": 16, "margin": [16, 19], "\uc0d8\ud50c\ub9c1\uc744": 16, "\uad6c\ud558\uac8c": 16, "taxonomi": 16, "\uc7a0\uc7ac\ubcc0\uc218": [16, 19], "\uadf8\ub85c\ubd80\ud130": 16, "\uad6c\ubd84\ud558\ub294": 16, "\uad6c\uc131\uc774": 16, "\ub9d0\ud574\uc11c": 16, "\ub4e4\uc5b4\uc624\uba74": 16, "\uac00\uc9dc\ub85c": 16, "\ucd9c\ub825\ud558\ub294": 16, "binari": 16, "\uc9c4\ud589\ud569\ub2c8\ub2e4": 16, "\ucf54\ub4dc\ub3c4": 16, "\uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 16, "in_feat": 16, "out_feat": 16, "batchnorm1d": 16, "leakyrelu": 16, "inplac": 16, "opt": 16, "latent_dim": 16, "np": 16, "prod": 16, "img_shap": 16, "tanh": 16, "img": 16, "sigmoid": [16, 19], "img_flat": 16, "d\ub97c": 16, "g\ub97c": 16, "\ub2e8\uacc4\ub97c": 16, "\ubc88\uac08\uc544": 16, "\uc190\uc2e4\ud568\uc218": [16, 19], "min_g": 16, "max_d": 16, "p_z": 16, "\uc54c\uace0\ub9ac\uc998\uacfc": 16, "\ube44\uad50\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 16, "n_epoch": 16, "variabl": [16, 19], "fill_": 16, "fake": 16, "real_img": 16, "optimizer_g": 16, "gen_img": 16, "measur": 16, "abil": 16, "fool": 16, "g_loss": 16, "adversarial_loss": 16, "optimizer_d": 16, "real_loss": 16, "fake_loss": 16, "d_loss": 16, "print": 16, "item": 16, "batches_don": 16, "sample_interv": 16, "save_imag": 16, "png": 16, "nrow": 16, "\ucd5c\ub300\ud654\ud558\uace0": 16, "descent": 16, "\uc9c4\ud589\ud558\uac8c": 16, "\uc77c": 16, "\ud559\uc2b5\ud558\uc9c0": 16, "\uc0c1\ud669\uc774": 16, "\ubc1c\uc0dd\ud569\ub2c8\ub2e4": [16, 18], "\ucd5c\uc18c\ud654\ud558\uc9c0": 16, "\ucd5c\ub300\ud654\ud558\ub294": 16, "\uae30\ubc95\ub3c4": 16, "\ucd5c\uc801\ud654\ub41c": 16, "solut": 16, "\uc644\ubcbd\ud788": 16, "\ubcf5\uc6d0\ud558\uace0": 16, "\ud655\ub960\uc744": 16, "\uc5b8\uc81c\ub098": 16, "\ub0b4\ubc49\uac8c": 16, "proposit": 16, "p_g": 16, "\uc99d\uba85\ud558\uc790\uba74": 16, "\uc190\uc2e4\ud568\uc218\ub97c": 16, "\uc4f8": 16, "\uc788\uace0": [16, 18, 19], "int_x": 16, "int_z": 16, "dz": [16, 19], "\uc77c\ub54c": 16, "\uc131\ub9bd\ud558\uace0": 16, "\uc190\uc2e4\ud568\uc218\ub294": 16, "\uac19\uace0": 16, "ast": 16, "jsd": 16, "\ucd5c\uc19f\uac12\uc740": 16, "\uc774\uace0": [16, 19], "\uc131\ub9bd\ud569\ub2c8\ub2e4": 16, "mnist": 16, "toronto": 16, "databas": 16, "tfd": 16, "\ud3c9\uac00\ud588\uc2b5\ub2c8\ub2e4": 16, "\ud3c9\uac00\uc2dc\uc5d0\ub294": 16, "parzen": 16, "densiti": 16, "\uac70\uccd0": 16, "vae\ub294": 16, "\ud750\ub9bf\ud558\ub2e4\ub294": 16, "\ub2e8\uc810\uc744": [16, 19], "\uc9c0\ub2c8\uace0": [16, 18], "unstabl": 16, "converg": [16, 17], "\ucc28\uc6d0\ucd95\uc18c\ub85c": 16, "\ud65c\uc6a9\ub418\uace0": 16, "\uc0dd\uc131\ud558\ub294\ub370\ub294": 16, "\ud65c\uc6a9\ub418\uc5c8\ub2e4\uace0": 16, "editbench": 18, "advanc": 18, "guid": 18, "inpaint": 18, "06909": 18, "sep": [17, 18], "06": 18, "introduct": [], "\uc2dc\uac04\uc5d0\ub294": 18, "googl": 18, "research": 18, "\uc18c\uac1c\ud558\ub294": [18, 19], "\uae30\ubc18\uc758": 18, "impaint": 18, "\ud3c9\uac00\uae30\ubc95": 18, "\uc608\uc815\uc785\ub2c8\ub2e4": 18, "\uae30\uc874\uc5d0\ub294": 18, "\uc601\uc5ed\uc744": 18, "\uc9c0\uc815\ud558\uc5ec": 18, "\ub428\uc73c\ub85c\uc368": 18, "\ucc38\uc870\ud558\uc9c0": 18, "\uc624\ub85c\uc9c0": 18, "\ub9cc\uc73c\ub85c": 18, "\ucc38\uc870\ud560": 18, "\uc720\ub3c4\ud558\ub294": 18, "ssd": 18, "mobilenet": 18, "v2": 18, "detector": 18, "\uac1c\uc120\ub418\ub294": 18, "\ud2b9\uc9d5\uc740": 18, "cascad": 18, "\uc810\uc785\ub2c8\ub2e4": 18, "sr3": 18, "palett": [17, 18], "glide": 18, "\ud558\uba74\uc11c": 18, "\uac00\uc9c4\ub2e4\uace0": 18, "256x256": 18, "\uc791\uc5c5": 18, "\uc785\ub825\ud569\ub2c8\ub2e4": 18, "\ud6a8\uacfc\ub97c": [17, 18], "\ub0b4\uae30": 18, "\uc0c8\ub85c": 18, "\ucd94\uac00\ub418\ub294": 18, "\ucd08\uae30\ud654\ud574\uc11c": 18, "\uc9c4\ud589\ud588\ub2e4\uace0": 18, "\uc18c\uac1c\ub418\uc5c8\ub358": 18, "free": 18, "guidanc": 18, "\ub3d9\uc77c\ud558\uac8c": 18, "1\ubd80\ud130": 18, "30": 18, "\ubc94\uc704": [17, 18], "\ubcc0\ud654\uc2dc\ud0a4\ub294": 18, "oscil": 18, "\uc801\uc6a9\ud568\uc73c\ub85c\uc368": 18, "\ud004\ub9ac\ud2f0": 18, "\uc0c1\uc2b9\ub418\ub294": 18, "\ud3c9\uac00\ud560": 18, "benchmark": [17, 18], "240\uac1c\uc758": 18, "\uc30d\uc73c\ub85c": 18, "\uad6c\ucd95\ub418\uc5b4\uc788\uace0": 18, "\uc30d\ub9c8\ub2e4": 18, "3\uac00\uc9c0\uc758": 18, "\uce21\uc815\ud558\uac8c": 18, "\uc73c\ub85c\ub294": 18, "clipscor": 18, "prec": 18, "\ub370\uc774\ud130\uc14b\uc758": 18, "\uc808\ubc18\uc740": 18, "open": 18, "vision": 18, "\ub370\uc774\ud130\uc14b\uc73c\ub85c\ubd80\ud130": 18, "\uc218\uc9d1\ub418\uc5c8\uace0": 18, "\uc0dd\uc131\ud574\uc11c": 18, "\uad6c\ucd95\ud588\uc2b5\ub2c8\ub2e4": 18, "scene": 18, "\uc694\uc18c\ub4e4\uc744": 18, "\uac16\ucd94\ub3c4\ub85d": 18, "\uc0dd\uc131\ud588\uc2b5\ub2c8\ub2e4": 18, "materi": 18, "count": 18, "common": 18, "render": 18, "indoor": 18, "outdoor": 18, "realist": 18, "\ub4e4\uc5b4\uc11c": 18, "metal": 18, "\ubb38\uad6c\ub97c": 18, "stand": 18, "farm": 18, "3\uac00\uc9c0": [17, 18], "\ud574\ub2f9\uc0ac\uc9c4\ucc98\ub7fc": 18, "rich": 18, "\uad6c\ucd95\uc2dc": 18, "\ud06c\uae30\ub3c4": 18, "\ub2e4\uc591\ud558\uac8c": 18, "\uc124\uc815\ud558\uc5ec": 18, "\ud06c\uae30\uc5d0": 18, "\uce21\uc815\ud574\ubcf8": 18, "medium": 18, "\uc131\ub2a5\uc801\uc73c\ub85c": 18, "\uc6d4\ub4f1\ud788": 18, "\uc88b\ub2e4\ub294": 18, "\uc800\ud558\ub418\ub294": 18, "\uc18d\uc131\ubcf4\ub2e4": 18, "\uc18d\uc131\uc5d0": 18, "\ucde8\uc57d\ud55c": 18, "failur": 18, "\ube44\uad50\ud55c": 18, "\uc0ac\uc9c4\uc785\ub2c8\ub2e4": 18, "maskrich": 18, "auto": 19, "bay": 19, "1312": 19, "6114": 19, "gunhochoi": 19, "fastcampu": 19, "ch": 19, "\ubb38\uad6c\uac00": 19, "\uc801\ud600\uc788\ub294\ub370\uc694": 19, "bayesian": 19, "vb": 19, "approach": [19, 20], "involv": 19, "\uc774\ucc98\ub7fc": 19, "autoencod": 19, "\uc81c\uc2dc\ud558\ub294": 19, "aevb": 19, "\uc54c\uace0\ub9ac\uc998": 19, "\ub274\ub7f4": 19, "\ub124\ud2b8\uc6cc\ud06c\ub85c": 19, "\uadfc\uc0ac\ud568\uc73c\ub85c\uc368": 19, "\uc774\uac00": 19, "\ubc14\uac00": 19, "\uc0b4\ud3b4\ubcf4\ub3c4\ub85d": 19, "\ubd80\ubd84\uc73c\ub85c": 19, "encoder\ub294": 19, "\ub9cc\ub4e4\uc5b4\ub0b4\uace0": 19, "\ubcf5\uc6d0\ud558\uac8c": 19, "assumpt": 19, "\ub4e4\uc744": [17, 19], "\ub0b4\ub9bd\ub2c8\ub2e4": 19, "\uccab\ubc88\uc9f8\ub85c": 19, "parametr": 19, "differenti": 19, "\ud558\ub2e4\ub294": 19, "\ub530\ub974\uace0": 19, "\uc131\uc9c8\uc5d0": 19, "bernoulli": 19, "\ub530\ub974\ub3c4\ub85d": 19, "\uad6c\uc131\ub41c": 19, "\uacc4\uc0b0\uc774": 19, "overview": 19, "\ucd5c\ub300\ud654\uc2dc\ud0a4\ub294": 19, "\uad6c\ud558\ub294": 19, "\uacc4\uc0b0\ud558\uae30": 19, "\ub4f1\uc7a5\ud558\uac8c": 19, "\uc5ed\uc2dc": 19, "\uadfc\uc0ac\ud654\ud558\ub294": 19, "\ub124\ud2b8\uc6cc\ud06c": 19, "\uc815\uc758\ud558\uac8c": 19, "\ub3c4\uc2dd\ud654\ud55c": 19, "\uadf8\ub9bc\uc785\ub2c8\ub2e4": 19, "\uc815\ub9ac\ud558\uc790\uba74": 19, "\uacc4\uc0b0\ub41c": 19, "\ud655\uc778\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 19, "fc1_1": 19, "784": 19, "hidden_s": 19, "fc1_2": 19, "relu": 19, "log_var": 19, "reparametr": 19, "logvar": 19, "std": 19, "mul": 19, "exp_": 19, "ep": 19, "floattensor": 19, "cuda": 19, "add_": 19, "reparam": 19, "fc1": 19, "\ucc3e\uc73c\uba74": 19, "error": 19, "\ubd84\ud560\ud560": 19, "min_": 19, "g_": 19, "\uc720\uc0ac\ud558\ub3c4\ub85d": 19, "\uc7a0\uc7ac\ubcc0\uc218\uc758": 19, "\uc800\ud76c\uac00": 19, "\ubd80\uc5ec\ud55c": 19, "\uac00\uae5d\ub3c4\ub85d": 19, "\uc124\uc815\ud558\ub294": 19, "mont": 19, "carlo": 19, "\uadfc\uc0ac\uac12\uc744": 19, "\uad6c\ud560": 19, "\uc5f0\uc0b0\ub7c9\uc774": 19, "\ub9ce\uc73c\ubbc0\ub85c": 19, "\uc124\uc815\ud569\ub2c8\ub2e4": 19, "\uae30\ubc95\uc740": 19, "\uc0d8\ud50c\ub9c1\ud558\uc9c0": 19, "backpropag": 19, "\uac00\ub2a5\ud558\ub3c4\ub85d": 19, "\uc0d8\ud50c\ub9c1\ud558\uace0": 19, "\ub354\ud558\uace0": 19, "\uacf1\ud558\uac8c": 19, "\ub530\ub978\ub2e4\uace0": 19, "\uc124\uc815\ud588\uc744": 19, "\ub54c\uc774\uace0": 19, "\uac00\uc815\ud560": 19, "\uadf8\uc5d0": 19, "\uc2dc\ub3c4\ud560": 19, "\uba85\uc2dc\ub418\uc5b4": 19, "\uc9c0\uc815\ud574\uc92c\ub2e4\uba74": 19, "\ud30c\ub77c\ubbf8\ud130\ub4e4\uacfc": 19, "\uc7a0\uc7ac\ubcc0\uc218\ub97c": 19, "\uc0ac\uc6a9\ud574\ubcf4\uba74": 19, "repositori": 20, "pseudo": 20, "team": 20, "bulb": 20, "aim": 20, "relat": 20, "them": 20, "theoret": 20, "conduct": 20, "experi": 20, "\ucc38\uc5ec": 20, "\ub9e4\uc8fc": 20, "\uc218\uc694\uc77c": 20, "\uc624\ud6c4": 20, "9\uc2dc": 20, "\uac00\uc9dc\uc5f0\uad6c\uc18c": 20, "discord": 20, "room": 20, "dh": 20, "\uc785\uc7a5": 20, "photorealist": 17, "neurip": 17, "2205": 17, "11487": 17, "learning\uc774": 17, "\ubc1b\uace0": 17, "\ub354\ubd88\uc5b4": 17, "\ub3c5\ucc3d\uc801\uc778": 17, "\uc804\uc6a9": 17, "\ub9d0\ubb49\uce58": 17, "corpu": 17, "llm\ub4e4\uc758": 17, "embedding\ub4e4\uc740": 17, "\ud6a8\uacfc\uc801\uc774\ub77c\uace0": 17, "\ucda9\uc2e4\ub3c4": 17, "frozen": 17, "\uc0ac\uc774\uc988\ub97c": 17, "\uc911\uc694\ud558\ub2e4\ub294": 17, "\uc99d\uba85\ud568": 17, "\uc81c\uc2dc\ud558\uc5ec": 17, "weight\uc744": 17, "leverag": 17, "\ub9cc\ub4e4\uc5b4": 17, "\ud604\uc2e4\uc801\uc778": 17, "\uad6c\uc870\ubcf4\ub2e4": 17, "\uc81c\uc2dc\ud568": 17, "\uc810\uc218": 17, "27": 17, "\ub2ec\uc131\ud568": 17, "evaluation\uc6a9": 17, "\uad6c\uae00": 17, "encoder\uc744": 17, "\ud574\ub193\uc74c": 17, "improv": 17, "ddpm": 17, "sr": 17, "\uc774\ub780": 17, "guidance\uac00": 17, "generation\uc774": 17, "\uc77c\uc815\ud558\uc9c0": 17, "\ubabb\ubc1b\uc544\uc11c": 17, "class\ub098": 17, "object\uc774": 17, "\uc77c\uc815\ud558\uace0": 17, "\ubb34\uc5c7\uc744": 17, "\uc0dd\uc131\ud558\ub294\uac83\uc778\uc9c0": 17, "\uc790\uc138\ud558\uac8c": 17, "guide\uc758": 17, "\ub192\uc774\uba74": 17, "\ubd88\uc77c\uce58\uac00": 17, "\uc0dd\uae34\ub2e4": 17, "\uc774\ub85c": 17, "\uac00\uc911\uce58\uc758": 17, "\ud3c9\uade0\uacfc": 17, "\ubd84\uc0b0\uc744": 17, "\uc774\ub3d9\uc2dc\ucf1c": 17, "\uc544\uc608": 17, "\ube57\ub098\uac00": 17, "\uc774\uc0c1\ud55c": 17, "satur": 17, "\ub35c\ud55c": 17, "\ub40c": 17, "\ud574\uacb0\ud558\uace0\uc790": 17, "\ubc31\ubd84\uc704\uc218": 17, "\uc808\ub300": 17, "\ud53d\uc140": 17, "\uc9c0\uc815\ud558\uace0": 17, "\uc784\uacc4\uac12\uc744": 17, "\uc9c0\uc815\ud55c": 17, "s\ub85c": 17, "\ub098\ub208\ub2e4": 17, "90": 17, "\uc9c0\uc810\uc758": 17, "3\uc73c\ub85c": 17, "\ucc28\uc774\ub294": 17, "among": 17, "net\uc774\ub77c\ub294": 17, "net\uc5d0\uc11c": 17, "\uc5ec\ub7ec\uac00\uc9c0": 17, "modification\uc744": 17, "\ud558\uc600\ub2e4\uace0": 17, "\uadf8\ub807\uc9c0\ub9cc": 17, "effu": 17, "net\uc740": 17, "\uc758\ub8cc\ucabd\uc73c\ub85c": 17, "\uc788\ub294\uac78\ub85c": 17, "\uc544\ub294\ub370": 17, "remov": 17, "keep": 17, "connect": 17, "scaling\uc744": 17, "\ud558\uc5ec": 17, "block\uc5d0\uc11c": 17, "blocks\ub97c": 17, "\ucd94\uac00\ud568": 17, "\ubca4\uce58\ub9c8\ud06c": 17, "\ub370\uc774\ud130\uc14b\uc740": 17, "categori": 17, "\uc774\ub8e8\uc5b4\uc84c\ub2e4": 17, "\uae43\ud5c8\ube0c\uc5d0\uc11c": 17, "\ub2e4\uc6b4": 17, "\ubc1b\uc744": 17, "\uac17\ub2e4": 17, "11": 17, "25\uba85\uc758": 17, "\ud3c9\uac00\uc790": 17, "a\uc5d0\uc11c": 17, "\ud3c9\uac00\uc790\ub294": 17, "\uc9c8\ubb38\uc744": 17, "\uc8fc\uba70": 17, "\uae30\uc900\uc810\uc73c\ub85c": 17, "q1": 17, "higher": 17, "q2": 17, "better": 17, "repres": 17, "\uae30\uc900\uc810": 17, "\ub2f5\ubcc0": 17, "\uc120\ud0dd\ud574\uc57c\ud568": 17, "am": 17, "indiffer": 17, "screenshot": 17, "drawbench\uc5d0\uc11c": 17, "\uccb4\ub9ac\ud53c\ud0b9": 17, "\uc5c6\uc774\ub3c4": 17, "\uce74\ud14c\uace0\ub9ac\uc5d0\uc11c\ub3c4": 17, "\uc8fc\uc7a5\uc778": 17, "coco\ub85c": 17, "\ubaa8\ub378\ub4e4": 17, "\ub192\uc74c": 17, "imagen\uc774": 17, "peopl": 17, "photor": 17, "\uc62c\ub77c\uac10": 17, "people\uc744": 17, "\uc0dd\uc131\ud558\uae30\uc5d0": 17, "rater": 17, "\ub4e4\uc740": 17, "xxl\ub85c": 17, "\uc120\ud638\ud568": 17, "\ubaa8\ub378\uc778": 17, "\ubc1b\uc74c": 17, "evaul": 17, "\uc911\uc694\ud568": 17, "\uc0ac\uc774\uc988\uc758": 17, "\uc810\uc218\uc5d0": 17, "\ub07c\uce68": 17, "boost\uc5d0": 17, "thresholding\uc744": 17, "\ub04c\uc5b4": 17, "\uc62c\ub9b4": 17, "show": 17, "multimod": 17, "allow": 17, "usag": 17, "much": 17}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"inform": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "synthet": 0, "data": [0, 5], "stabl": 0, "diffus": [0, 3, 5, 6, 7, 9, 11, 14, 15, 17, 20], "foliar": 0, "diseas": 0, "classif": 0, "1": [0, 3, 4, 5, 6, 8, 9, 13, 14], "\uac1c\uc694": 0, "2": [0, 3, 4, 5, 6, 8, 9, 13, 14], "baselin": [0, 12], "\uad6c\ucd95": 0, "3": [0, 3, 4, 5, 6, 8, 9, 13, 14], "fine": [0, 3, 15], "tune": [0, 3, 15], "4": [0, 3, 4, 5, 6, 8, 9, 14], "\uc131\ub2a5": 0, "\ube44\uad50": [0, 11], "5": [0, 3, 4, 6, 8, 9, 14], "discuss": [0, 3], "6": [0, 4, 6, 14], "appendix": [0, 1, 15], "train": [1, 2, 3, 5, 12, 13, 16], "dreambooth": [1, 15], "naver": 1, "webtoon": 1, "face": [1, 9], "dataset": 1, "introduct": [1, 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19], "ablat": [1, 15, 17], "studi": [1, 12, 15, 17], "prior": [1, 13], "preserv": 1, "loss": [1, 5, 12], "neg": 1, "prompt": 1, "instanc": 1, "guidanc": [1, 14, 17], "scale": [1, 5, 6], "controlnet": 2, "addit": [2, 8], "control": 2, "imag": [2, 3, 12, 14, 15, 20], "base": 2, "condit": 2, "block": 2, "zero": 2, "convolut": 2, "result": [2, 12, 13, 14, 16, 17], "implement": [2, 12], "custom": 3, "\ud559\uc2b5": [3, 6, 9], "\uc790\ub8cc": [3, 6, 9], "abstract": [3, 4, 6, 8, 9, 11, 12, 14], "relat": [3, 9, 11, 12], "work": [3, 9, 11, 12, 13, 14], "deep": 3, "gener": [3, 4, 12, 20], "model": [3, 5, 6, 7, 9, 11, 14, 15, 17], "edit": 3, "transfer": [3, 12], "learn": [3, 13], "adapt": [3, 14], "text": [3, 11, 15, 20], "method": [3, 8, 9, 11], "singl": 3, "concept": 3, "multipl": 3, "composit": 3, "detail": [3, 12, 13], "experi": [3, 4, 5, 7, 8, 9, 15, 16], "limit": [3, 11, 12, 13, 14, 15], "ddim": [4, 14], "background": [4, 5, 13, 14], "ddpm": [4, 5, 6, 14], "variat": [4, 10], "infer": [4, 8], "For": 4, "non": 4, "markovian": 4, "forward": [4, 5], "process": [4, 5], "sampl": [4, 5, 6], "from": [4, 12, 17], "code": 4, "q": 5, "mathbf": 5, "x": 5, "_t": 5, "_": 5, "t": [5, 8], "revers": 5, "p": 5, "function": [5, 12], "l": 5, "denois": [5, 6], "encod": 5, "l_t": 5, "l_": 5, "decod": 5, "l_0": 5, "simplifi": 5, "object": [5, 12], "qualiti": [5, 12], "i": 6, "probabilist": 6, "improv": [6, 14], "log": 6, "likelihood": 6, "improc": 6, "speed": 6, "comparison": [6, 12], "gan": [6, 11, 14, 16], "size": 6, "latent": [7, 11], "lora": 8, "0": 8, "terminolog": 8, "convent": 8, "problem": 8, "statement": 8, "aren": 8, "exist": 8, "solut": 8, "good": 8, "enough": 8, "our": 8, "low": 8, "rank": 8, "parameter": 8, "updat": 8, "matric": 8, "No": 8, "latenc": 8, "appli": 8, "transform": [8, 13], "empir": 8, "ia3": 8, "aa": 8, "\uc0ac\uc6a9\ubc95": 8, "refer": 8, "styo": 9, "styliz": 9, "framework": 9, "conclus": [9, 13, 17], "stylegan": 10, "map": 10, "network": 10, "style": [10, 12], "adain": 10, "stochast": 10, "mix": 10, "regular": 10, "\uc2e4\ud5d8": 10, "\uacb0\uacfc": [10, 11, 12], "textual": 11, "invers": 11, "cf": 11, "\uc774\ud574": 11, "\ubabb\ud568": 11, "ldm": 11, "embed": 11, "\uc131\ub2a5\ud3c9\uac00": 11, "dall": [11, 13], "e": [11, 13], "2\uc640": 11, "guid": 11, "synthesi": [11, 14], "pseudo": 11, "word": 11, "\ub450": 11, "\uac1c": 11, "\uc0ac\uc6a9": 11, "bia": 11, "reduct": 11, "\uc815\ub7c9\ud3c9\uac00": 11, "\ud3c9\uac00": 11, "setup": 11, "\uc8fc\ubaa9\ud560": 11, "\uc810": 11, "\uc0ac\uc6a9\uc790\ud3c9\uac00": 11, "\ub9c8\ubb34\ub9ac": 11, "cyclegan": 12, "\ucc38\uace0": 12, "translation\uc774\ub780": 12, "mode": 12, "collapse\ub780": 12, "\uad00\ub828": 12, "\uc5f0\uad6c": 12, "formul": 12, "adversari": 12, "cycl": 12, "consist": 12, "full": 12, "\uc804\uccb4": 12, "\ubaa9\uc801\uc2dd": 12, "least": 12, "squar": 12, "\ucd94\uac00": 12, "\uc124\uba85": 12, "\uae30\ud0c0": 12, "against": 12, "human": [12, 17], "fcn": 12, "\ub4f1": 12, "analysi": 12, "reconstruct": 12, "pair": 12, "dataset\uc5d0": 12, "\ub300\ud55c": 12, "applic": [12, 15], "collect": 12, "transfigur": 12, "season": 12, "photo": 12, "paint": 12, "enhanc": 12, "gati": 12, "discusss": 12, "gpt": 13, "vq": 13, "vae": [13, 19], "methodolog": [13, 17], "previou": 13, "overview": 13, "stage": 13, "an": 13, "autoregress": 13, "pipelin": 13, "\uc608\uc2dc": 13, "equat": 13, "\ud559\uc2b5\uacfc\uc815": 13, "visual": 13, "codebook": 13, "beat": 14, "architectur": 14, "group": 14, "normal": 14, "classifi": [14, 17], "algorithm": 14, "7": 14, "impact": 14, "paramet": 14, "s": 14, "8": 14, "9": 14, "futur": 14, "procedur": 16, "theoret": 16, "summari": [16, 19], "imagen": [17, 18], "editor": 18, "intract": 19, "reparameter": 19, "trick": 19, "pseudolab": 20, "feat": 20, "contribut": 17, "pretrain": 17, "t5": 17, "xxl": 17, "cascad": 17, "free": 17, "larg": 17, "weight": 17, "sampler": 17, "static": 17, "threshold": 17, "dynam": 17, "super": 17, "resolut": 17, "drawbench": 17, "qualit": 17, "tabl": 17, "evalu": 17}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx": 56}}) \ No newline at end of file +Search.setIndex({"docnames": ["docs/experiments/js_exp", "docs/experiments/swjo_exp", "docs/review/ControlNet", "docs/review/CustomDiffusion", "docs/review/DALLE2", "docs/review/DDIM", "docs/review/DDPM", "docs/review/I-DDPM", "docs/review/Latent_Diffusion_Model", "docs/review/LoRA", "docs/review/StyO", "docs/review/StyleGAN", "docs/review/Textual_Inversion", "docs/review/cycleGAN", "docs/review/dalle", "docs/review/diffusion_beats_GANs", "docs/review/dreambooth", "docs/review/gan", "docs/review/imagen", "docs/review/imagen_editor", "docs/review/vae", "intro"], "filenames": ["docs\\experiments\\js_exp.md", "docs\\experiments\\swjo_exp.md", "docs\\review\\ControlNet.md", "docs\\review\\CustomDiffusion.md", "docs\\review\\DALLE2.md", "docs\\review\\DDIM.md", "docs\\review\\DDPM.md", "docs\\review\\I-DDPM.md", "docs\\review\\Latent_Diffusion_Model.md", "docs\\review\\LoRA.md", "docs\\review\\StyO.md", "docs\\review\\StyleGAN.md", "docs\\review\\Textual_Inversion.md", "docs\\review\\cycleGAN.md", "docs\\review\\dalle.md", "docs\\review\\diffusion_beats_GANs.md", "docs\\review\\dreambooth.md", "docs\\review\\gan.md", "docs\\review\\imagen.md", "docs\\review\\imagen_editor.md", "docs\\review\\vae.md", "intro.md"], "titles": ["Synthetic Data with Stable Diffusion for Foliar Disease Classification", "Training DreamBooth on Naver Webtoon Face Dataset", "ControlNet", "Custom Diffusion", "DALLE2", "DDIM", "DDPM", "I-DDPM", "Latent Diffusion Model", "LoRA", "StyO", "StyleGAN", "Textual Inversion", "CycleGAN", "DALL-E", "Diffusion Models Beat GANs on Image Synthesis", "DreamBooth", "GAN", "Imagen", "Imagen Editor", "VAE", "[PseudoLab] Text-to-Image Generation (feat. Diffusion)"], "terms": {"titl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "author": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "jisu": [0, 2, 11], "kim": [0, 2, 4, 11], "last": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "updat": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "jul": [0, 1], "05": 0, "2023": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "\uc0ac\uacfc": 0, "\ub098\ubb34\uc758": 0, "\uc78e\uc5d0": 0, "\uc0dd\uae30\ub294": 0, "\uc9c8\ubcd1\uc744": 0, "\uc774\ubbf8\uc9c0\ub85c": [0, 1, 3, 4, 10, 18, 19], "\ud310\ubcc4\ud558\ub294": 0, "kaggl": 0, "competit": [0, 15], "\ub9c1\ud06c": [0, 2], "\uc5d0\uc11c": [0, 2, 4, 6, 7, 9, 14, 16, 18, 19, 20], "\uc544\uc774\ub514\uc5b4\ub97c": 0, "\uc5bb\uc5b4\uc11c": 0, "\uc9c4\ud589\ud55c": 0, "\ud504\ub85c\uc81d\ud2b8\uc785\ub2c8\ub2e4": 0, "\ud574\ub2f9": [0, 3, 4, 6, 8, 12, 16, 20], "competition\uc740": 0, "\uc0ac\uacfc\ub098\ubb34": 0, "\uac78\ub9b0": 0, "\uc9c8\ubcd1\uc5d0": 0, "\ub530\ub77c": [0, 7, 9, 12, 13, 14, 15, 16, 20], "\uc78e": 0, "\uc774\ubbf8\uc9c0\ub97c": [0, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 18], "4\uac1c\uc758": [0, 4, 12], "class\ub85c": 0, "\ubd84\ub958\ud558\ub294": 0, "task\uc785\ub2c8\ub2e4": 0, "class": [0, 2, 3, 5, 6, 7, 11, 13, 15, 16, 17, 18, 20], "leav": 0, "competition\uc744": 0, "\uc124\uba85\ud55c": 0, "articl": 0, "\uc804\uccb4\uc801\uc778": [0, 11], "accuracy\ub294": 0, "97": 0, "\uc774\uc9c0\ub9cc": 0, "multipl": 0, "class\uc758": [0, 15], "\uacbd\uc6b0": [0, 1, 2, 3, 7, 8, 9, 10, 11, 13, 17], "accuracy\uac00": 0, "51": 0, "\uc5d0": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20], "\ubd88\uacfc\ud588\ub2e4\uace0": 0, "\uc5b8\uae09\ud569\ub2c8\ub2e4": 0, "\uc774\ubbf8\uc9c0": [0, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], "\uac1c\uc218\uac00": 0, "\ub2e4\ub978": [0, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20], "class\uc5d0": 0, "\ube44\ud574": [0, 2, 3, 4, 5, 7, 10, 15, 19], "\uc801\uc740": [0, 2, 3, 5, 6, 7, 9, 12, 15], "\uc810\uc5d0": 0, "\uc8fc\ubaa9\ud588\uace0": 0, "diffusion\uc744": 0, "\uc0ac\uc6a9\ud558\uc5ec": [0, 6, 11, 13, 14, 16, 18], "\ud074\ub798\uc2a4\uc758": 0, "\ub370\uc774\ud130": [0, 12, 13, 14, 17, 18, 20], "\uac1c\uc218\ub97c": [0, 6], "\ub298\ub824\uc11c": 0, "classifi": [0, 4, 17, 19], "\ud559\uc2b5\uc5d0": [0, 9, 13], "\uc0ac\uc6a9\ud558\uba74": [0, 12, 14], "\ub354": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20], "\uc88b\uc740": [0, 1, 3, 10, 13, 15, 16, 18], "\uc131\ub2a5\uc758": 0, "classifier\ub97c": 0, "\uc5bb\uc744": [0, 12, 13], "\uc218": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "\uc788\uc744": [0, 1, 2, 6, 9, 11, 13], "\uac83\uc73c\ub85c": [0, 9, 12], "\uae30\ub300\ud588\uc2b5\ub2c8\ub2e4": 0, "\ubb38\uc81c": 0, "\uc0c1\ud669\uc744": 0, "\uc7ac\ud604\ud558\uae30": 0, "\uc704\ud574": [0, 2, 3, 4, 6, 9, 10, 11, 12, 13, 14, 16, 19], "\uae30\uc874": [0, 2, 3, 7, 8, 9, 10, 11, 12, 13, 15, 18], "\ub370\uc774\ud130\ub85c": [0, 1, 2], "imag": [0, 1, 4, 5, 8, 10, 11, 12, 14, 17, 18, 19, 20], "\ud559\uc2b5\ud558\uc5ec": [0, 14, 15], "baseline\uc73c\ub85c": 0, "\uc7a1\uc558\uc2b5\ub2c8\ub2e4": 0, "\ubaa8\ub378\uc740": [0, 7, 8, 9, 11, 12, 13], "pretrained\ub41c": 0, "resnet18\uc5d0": 0, "linear": [0, 6, 7, 9, 11, 15, 17, 20], "layer\ub97c": [0, 9, 11], "\ubd99\uc5ec\uc11c": 0, "\uc0ac\uc6a9\ud588\uc2b5\ub2c8\ub2e4": [0, 4, 19], "\uc804\uccb4": [0, 2, 3, 7], "7": [0, 1, 5, 6, 7, 10, 18], "class\ubcc4": 0, "healthi": 0, "99": 0, "73": [0, 12], "rust": 0, "scab": 0, "98": 0, "class\ub294": 0, "\uac1c\uc218": 0, "91\uac1c\ub85c": 0, "\ud074\ub798\uc2a4\ub4e4\uc5d0": 0, "\ube44\ud574\uc11c": [0, 4], "\uc801\uc2b5\ub2c8\ub2e4": 0, "imbalance\uac00": 0, "\uc131\ub2a5\uc744": [0, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 18, 19], "\ub0ae\ucd94\ub294": 0, "\uc6d0\uc778\uc77c": 0, "\uac83\uc774\ub77c": [0, 9], "\uac00\uc815\ud558\uace0": 0, "diffusion\uc73c\ub85c": 0, "data\ub97c": [0, 3, 13], "\ucd94\uac00\ub85c": [0, 7, 10, 13], "\uc0dd\uc131\ud574\ubcf4\uae30\ub85c": 0, "\ud588\uc2b5\ub2c8\ub2e4": [0, 1, 4, 11], "\uc608\uc2dc": [0, 4, 13, 18, 19], "pretran": 0, "diffusion\uc758": 0, "\ub300\ud55c": [0, 1, 2, 3, 4, 6, 7, 10, 12, 16, 17], "\uc815\ubcf4\uac00": [0, 4, 10, 16], "\uc5c6\uc5b4\uc11c": 0, "\uc0dd\uc131\ud560": [0, 1, 2, 4, 13, 16], "\uc544\ub798\uc640": [0, 2, 8, 11, 13, 15], "\uac19\uc774": [0, 2, 3, 4, 6, 8, 11, 12, 13, 14, 15, 16, 17, 20], "\uad00\ub828\uc5c6\ub294": 0, "\uc774\ubbf8\uc9c0\uac00": [0, 2, 4, 6, 10, 12, 13, 15, 17, 18], "\uc0dd\uc131\ub429\ub2c8\ub2e4": 0, "prompt": [0, 2, 3, 4, 10, 12, 16, 18, 19], "photo": [0, 1, 3, 12], "\ub530\ub77c\uc11c": [0, 2, 4, 6, 7, 10, 12, 13, 19], "model": [0, 2, 4, 5, 9, 14, 17, 19, 21], "\uc815\ubcf4\ub97c": [0, 2, 4, 6, 10, 12, 13, 16], "\ub123\uc5b4\uc8fc\uae30": 0, "dreambooth": [0, 3], "\ub97c": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "tuning\ud588\uc2b5\ub2c8\ub2e4": 0, "training\uc5d0": [0, 5, 15], "\uc0ac\uc6a9\ud55c": [0, 11, 12, 15], "prompt\ub294": 0, "disea": 0, "leaf": 0, "\uc774\uba70": [0, 12], "\uc0dd\uc131\ud55c": [0, 2, 4, 14, 16, 18], "\uc774\ubbf8\uc9c0\uc758": [0, 1, 2, 3, 4, 6, 10, 11, 12, 13, 14, 16, 18], "\uc608\uc2dc\ub294": [0, 18], "\uac19\uc2b5\ub2c8\ub2e4": [0, 1, 2, 4, 11, 13, 16, 17], "\uc0dd\uc131": [0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 18], "engineering\uc744": 0, "\uc218\ud589\ud558\ub358": 0, "\uc911": [0, 3, 5, 7, 9, 10, 11, 13, 14, 15, 16, 18, 20], "\uc758\ub3c4\ud558\uc9c0\uc54a\uc740": 0, "\uacb0\uacfc\ub97c": [0, 2, 4, 5, 7, 10, 11, 12, 13, 18, 19], "\ubc1c\uacac\ud588\uc2b5\ub2c8\ub2e4": [0, 1], "\uc544\ub798\ub294": [0, 2, 20], "\uc774\uc5d0": [0, 2, 10, 16], "\uc608\uc2dc\ub85c": 0, "\uc804\uc758": 0, "model\uc758": [0, 2, 3, 6, 7, 9, 12, 13, 15], "\uacb0\uacfc\uc640": 0, "\ube44\uad50\uc785\ub2c8\ub2e4": 0, "\uc0c1\ud6691": 0, "\uc804": [0, 6, 9, 15], "\ud6c4": [0, 1, 4, 6, 9, 13, 14, 16, 18, 19], "\uc0c1\ud6691\uc744": 0, "\ubcf4\uba74": [0, 3, 7, 11, 12, 13, 14], "\ub2f4\uc740": 0, "uniqu": [0, 1, 16], "identifi": [0, 1, 10, 16], "\uac00": [0, 1, 2, 4, 6, 7, 9, 13, 15, 16, 17, 18, 19, 20], "\uc5c6\uc74c\uc5d0\ub3c4": 0, "diseases\uc758": 0, "\uc78e\ub4e4\ub9cc": 0, "\uc774\ub294": [0, 2, 4, 5, 11, 12, 17, 19, 20], "\uac19\uc740": [0, 1, 2, 4, 6, 7, 8, 9, 11, 12, 13, 15, 16, 19, 20], "\uc18d\ud558\ub294": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc744": [0, 1, 2, 4, 16, 19], "\uc0dd\uc131\ud574\ub0b4\uc9c0": [0, 3], "\ubabb\ud558\uace0": [0, 6], "\uc788\ub2e4\ub294": [0, 4, 9, 11, 12, 18, 19], "\uac83\uc785\ub2c8\ub2e4": [0, 2, 4, 11, 13, 19], "\uc774": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20], "\ud604\uc0c1\uc744": [0, 3, 11], "languag": [0, 3, 4, 9, 12, 14, 16, 18], "drift\ub77c\uace0": 0, "\ud558\uba70": [0, 14], "\ubaa8\ub378\uc774": [0, 1, 2, 3, 4, 5, 6, 10, 11, 15, 16, 19], "leaf\uac00": 0, "\uc544\ub2cc": [0, 1, 2, 5, 9, 12, 13, 15], "\uc77c\ubc18\uc801\uc778": [0, 3, 12, 15], "\uad00\ud55c": [0, 7, 10, 11], "\uc78a\uc5b4\ubc84\ub838\uae30": 0, "\ub54c\ubb38\uc785\ub2c8\ub2e4": [0, 13], "\uc0c1\ud6692": 0, "\uc0c1\ud6692\ub97c": 0, "photo\ub77c\ub294": 0, "prompt\ub9cc": [0, 10], "\uc0ac\uc6a9\ud558\uc600\ub294\ub370\ub3c4": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc5d0": [0, 4], "\ud2b9\uc9d5\ub4e4\uc774": 0, "\ub098\ud0c0\ub0a9\ub2c8\ub2e4": 0, "dreambooth\uc5d0\uc11c\ub294": 0, "drift\ub97c": 0, "prior": [0, 4, 16, 20], "preserv": [0, 16], "loss\ub97c": [0, 6, 12, 13], "\uc0ac\uc6a9\ud574\uc11c": [0, 2, 4, 14, 15, 18], "\ud574\uacb0\ud558\uc600\uc73c\ubbc0\ub85c": 0, "\ubc29\ubc95\uc744": [0, 7, 11, 12, 13, 15], "\ud574\uacb0\ud558\uae30": [0, 4, 9, 12, 16, 19], "train": [0, 4, 5, 7, 9, 10, 11, 12, 15, 16, 18], "prompt\uc5d0\uc11c": 0, "\uc81c\uc678\ud558\uace0": [0, 9], "\ucd5c\ub300\ud55c": [0, 12, 13, 20], "\ub2e8\uc21c\ud55c": [0, 3], "model\uc744": [0, 2, 3, 5, 7, 9, 10, 12, 15], "\ub2e4\uc2dc": [0, 6, 9, 11, 13, 16, 17, 20], "\uacb0\uacfc": [0, 1, 3, 4, 7, 8, 15, 18, 19], "\uc7ac\ud6c8\ub828": 0, "\uc774\ud6c4\uc5d0\ub3c4": 0, "model\ub85c": 0, "\uc0dd\uc131\ud558\uc600\uc744": 0, "\ub54c\uc640": [0, 13], "\ube44\uc2b7\ud55c": [0, 3, 7, 12, 13, 15, 16], "\uc758": [0, 1, 2, 4, 5, 6, 7, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20], "\uacbd\uc6b0\uc5d0\ub294": 0, "\uc5ec\uc804\ud788": [0, 3, 18], "\uc601\ud5a5\uc744": [0, 6, 10, 11, 15, 18], "\ubc1b\uc740": [0, 12], "\uac83\uac19\uc740": 0, "\uc774\ubbf8\uc9c0\ub4e4\uc774": [0, 2], "photo\uc758": 0, "\uc5ec\ub7ec": [0, 8, 12, 16], "\ub300\uc0c1\ub4e4\uacfc": 0, "\uc0ac\uc6a9\ub418\ub294": [0, 12, 16], "\ud2b9\uc131\uc744": [0, 13], "\uac00\uc9c0\uace0\uc788\uc5b4\uc11c": 0, "\uadf8\ub7f0": [0, 11, 13], "\uac83\uc774\ub77c\ub294": 0, "\uc0dd\uac01\uc774": 0, "\ub4e4\uc5c8\uace0": 0, "\uc774\ub97c": [0, 2, 4, 6, 8, 9, 11, 12, 13, 16, 17, 19, 20], "\uccb4\ud06c\ud574\ubcf4\uae30": 0, "\ud2b9\uc815\ud55c": [0, 4, 11, 12], "photo\uc640": 0, "\uc6a9\ub3c4\ub85c": 0, "prompt\ub4e4\ub85c": 0, "\uc0dd\uc131\ubcf4\uc558\uc2b5\ub2c8\ub2e4": 0, "\ub300\uc0c1": [0, 13], "\uc138\uac00\uc9c0\ub85c\ub294": 0, "cat": [0, 4, 6, 19], "sea": 0, "pirate\uc744": 0, "\uc0ac\uc6a9\ud588\uace0": [0, 13], "\ube44\uc2b7\ud558\uac8c": [0, 12], "\ud14d\uc2a4\ud2b8": [0, 4, 12, 18], "\uc138\uac00\uc9c0\ub294": 0, "illustr": 0, "anim": [0, 14], "wallpaper\ub97c": 0, "\uc774\ubbf8\uc9c0\ub294": [0, 3, 10, 13, 18], "\uae00": 0, "\ub9c8\uc9c0\ub9c9": [0, 6, 11], "\ubd80\ubd84\uc758": 0, "appendix\uc5d0": 0, "\uc788\uc2b5\ub2c8\ub2e4": [0, 1, 2, 4, 11, 13, 16, 17, 19, 20], "\ub300\uc0c1\uc744": [0, 13], "\uc9c0\uce6d\ud558\ub294": 0, "\ud14d\uc2a4\ud2b8\uc758": 0, "\ub300\uc0c1\uc758": [0, 16], "\ud2b9\uc9d5\uc774": 0, "\uc798": [0, 1, 2, 3, 7, 10, 11, 12, 13, 16, 17, 20], "\ub4dc\ub7ec\ub098\ub294": 0, "\uc0dd\uc131\ub418\uc5c8\uc9c0\ub9cc": 0, "\ub300\uc0c1\uacfc": [0, 13], "\ud568\uaed8": [0, 9, 13, 20], "\uc4f0\uc774\ub294": [0, 13, 17], "\uc78e\uc0ac\uadc0\uc758": 0, "\ud2b9\uc9d5\uc744": [0, 2, 16], "\uac00\uc9c0\ub294": [0, 1, 11], "\uc77c\ubd80": [0, 9, 11], "\uc0dd\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4": 0, "tuning\ud55c": 0, "400\uc7a5": 0, "\uc0dd\uc131\ud558\uc5ec": 0, "\ud6c8\ub828\ud588\uc2b5\ub2c8\ub2e4": 0, "result_bas": 0, "\ucd94\uac00": [0, 3, 6], "\ud65c\uc6a9\ud55c": [0, 4, 16, 17], "9": [0, 7, 13], "84": 0, "result_now": 0, "kaggle\uc5d0\uc11c": 0, "\uc81c\uacf5\ud558\ub294": [0, 4, 12], "test": [0, 12, 13, 18], "set\uc5d0": 0, "\uc801\uc6a9\ud588\uc744": 0, "\ub54c\ub294": 0, "baseline\uc774": [0, 12], "94": 0, "\uacbd\uc6b0\uac00": [0, 2, 5, 13], "93": 0, "\uc5ec\uc11c": 0, "baseline\ubcf4\ub2e4": 0, "\uc5bb\uc9c0\ub294": 0, "\ubabb": 0, "\ud6c8\ub828": [0, 2, 13, 18], "\uc911\uac04\uc911\uac04\uc5d0": 0, "\uc77c\uc815": 0, "step\ub9c8\ub2e4": 0, "\uc0dd\uc131\ud558\uac8c\ud574\uc11c": 0, "\ud6c8\ub828\uc5d0": [0, 11], "\ubaa8\ub2c8\ud130\ub9c1\uc774": 0, "\uc788\uc73c\uba74": 0, "\uc88b\uaca0\ub2e4\ub294": 0, "\uc0dd\uac01\uc744": 0, "\ud6c8\ub828\uc2dc": 0, "hyperparamet": [0, 5, 10, 15], "tuning\uc744": [0, 2, 9, 12], "\uc880": [0, 2, 4, 10, 18], "\ucca0\uc800\ud558\uac8c": 0, "\ud574\uc57c\uaca0\ub2e4\ub294": 0, "\uc2e4\uc81c\ub85c": [0, 7, 11, 13, 17, 20], "\uc870\uac74\uc744": [0, 12], "\ub9cc\uc871\ud558\ub294\uc9c0": 0, "\uac80\uc218\ud560": 0, "\ubc29\uc548\uc774": 0, "\ud544\uc694\ud569\ub2c8\ub2e4": 0, "\ub0b4\uc5d0\uc11c\ub3c4": 0, "\uce74\ud14c\uace0\ub9ac\ub97c": 0, "\ub098\ub20c": 0, "\uc788\ub2e4\uba74": [0, 6], "\ub098\ub220\uc11c": [0, 18], "\uac01\uac01\uc5d0": [0, 4, 11], "tuning\ud560": [0, 3, 9], "\uc218\ub3c4": [0, 4, 11, 13], "\ud65c\uc6a9\ud574\ubcfc": 0, "submiss": 0, "score\uc5d0\uc11c": 0, "baseline\uc744": 0, "\uc774\uae30\uc9c0": 0, "\ud588\uc9c0\ub9cc": 0, "text": [0, 1, 2, 4, 6, 8, 10, 11, 14, 18, 19], "\uc774\uc6a9\ud55c": [0, 10], "data\uc758": [0, 7, 10], "\uac00\ub2a5\uc131\uc744": [0, 5], "\ubcfc": [0, 1, 4, 11, 12, 13, 14, 15, 19], "\uc788\uc5c8\ub2e4\uace0": [0, 4, 9, 19], "\uc0dd\uac01\ud569\ub2c8\ub2e4": [0, 11], "\uc55e\uc5d0\uc11c": 0, "\uc5b8\uae09\ud55c": [0, 2, 4, 19], "prompt\uc5d0": [0, 3], "\uc608\uc2dc\uc785\ub2c8\ub2e4": [0, 1], "nsfw\ub85c": 0, "\ud310\ub2e8\ub418\uc5b4": 0, "\uac80\uc740\uc0c9\uc73c\ub85c": 0, "\ub098\uc654\uc2b5\ub2c8\ub2e4": [0, 11], "pirat": 0, "wallpap": 0, "sangwoo": [1, 16, 17, 19, 20], "jo": [1, 16, 17, 19, 20], "09": 1, "\uc774\ubc88": [1, 4, 19], "\ud3ec\uc2a4\ud305\uc5d0\uc11c\ub294": 1, "\uc9c1\uc811": [1, 7, 17, 20], "\ud559\uc2b5\ud574\ubcf4\uace0": 1, "\uc2e4\ud5d8\ud55c": 1, "\uacb0\uacfc\ub4e4\uc744": [1, 4, 16], "\uacf5\uc720\ud560\ub824\uace0": 1, "\ud569\ub2c8\ub2e4": [1, 2, 4, 13, 16, 17, 19, 20], "\uc6b0\uc120\uc801\uc73c\ub85c": [1, 14, 20], "\ud559\uc2b5\ub370\uc774\ud130\ub294": 1, "bryandle": 1, "data": [1, 9, 11, 13, 17], "\uacf5\uac1c\ub41c": [1, 4, 9, 19], "yolov5": 1, "\ubaa8\ub378": [1, 3, 4, 5, 7, 9, 12, 13, 14, 15, 16, 17, 18, 19], "\ubc0f": [1, 4, 9, 12, 13, 15, 17, 18, 19], "waifu2x": 1, "\ud6c4\ucc98\ub9ac": 1, "\uae30\ubc95\uc744": [1, 3, 4, 7, 19], "\ud65c\uc6a9\ud558\uc5ec": [1, 14, 15, 16], "\ud504\ub9ac\ub4dc\ub85c\uc6b0\uc5d0": 1, "\ub4f1\uc7a5\ud558\ub294": 1, "\uc778\ubb3c": [1, 13], "\uc0ac\uc9c4\ub4e4\uc744": [1, 16], "\uc218\uc9d1\ud588\uc2b5\ub2c8\ub2e4": 1, "\ub17c\ubb38\uc5d0\uc11c\ub294": [1, 2, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 19, 20], "3": [1, 4, 8, 12, 16, 17, 18, 20], "5": [1, 6, 13, 17, 20], "\uc7a5\uc73c\ub85c": 1, "fine": [1, 2, 4, 9, 10, 11, 12, 14, 18, 21], "tune": [1, 4, 9, 14, 18, 21], "\uac00\ub2a5\ud558\ub2e4\uace0": [1, 11], "\uc81c\uc2dc\ub418\uc5b4\uc788\uc9c0\ub9cc": 1, "\uc0ac\uc9c4": [1, 3, 12, 13, 18], "\ub9ce\uc740": [1, 2, 12, 13, 14, 18], "\ud559\uc2b5\ud558\uba74": [1, 6, 16], "\uc131\ub2a5\uc774": [1, 4, 6, 7, 9, 15, 19], "\uc88b\uc544\uc838\uc11c": 1, "15": 1, "20": [1, 16], "\uc7a5\uc758": [1, 4], "\ud559\uc2b5\ud558\uc600\uc2b5\ub2c8\ub2e4": 1, "\ud559\uc2b5\ud55c": [1, 3, 4, 7, 9, 10, 16, 18, 19], "\uc774\ubbf8\uc9c0\ub4e4": 1, "\uc2e4\ud5d8\ud558\uba74\uc11c": 1, "\ub300\ud45c\uc801\uc73c\ub85c": [1, 16, 20], "\uadf8\ub9ac\uace0": [1, 4, 12, 16, 17, 19, 20], "\ub9c8\uc9c0\ub9c9\uc73c\ub85c": [1, 4, 11, 16, 19, 20], "\ubc18\uc601\ud558\ub294": 1, "\uc815\ub3c4\ub97c": [1, 5, 7], "\uc870\uc808\ud558\ub294": [1, 2, 5], "prior_loss_weight": [1, 16], "\ubc14\uafd4\uac00\uba74\uc11c": 1, "\ud559\uc2b5\ud574\ubcf4\uc558\uc2b5\ub2c8\ub2e4": 1, "\uc0ac\uc804\ud559\uc2b5\ub41c": [1, 16], "\ubaa8\ub378\ub85c": [1, 3, 4, 11, 14, 17, 19], "\ucc98\uc74c\uc5d0\ub294": [1, 9], "hakurei": 1, "waifu": 1, "diffus": [1, 2, 4, 5, 9, 17, 19], "\ubaa8\ub378\uc744": [1, 3, 4, 5, 6, 7, 12, 13, 16, 18, 19], "\uc2dc\ub3c4\ud574\ubd24\uc9c0\ub9cc": 1, "\uacb0\uacfc\uac00": [1, 6, 13, 15], "\ub9cc\uc871\uc2a4\ub7fd\uc9c0": 1, "\ubabb\ud574": 1, "runwayml": 1, "stabl": [1, 2, 4, 7, 9, 16, 19], "v1": 1, "\uc791\uc5c5\uc744": [1, 12], "\uc9c4\ud589\ud588\uc2b5\ub2c8\ub2e4": [1, 4, 17, 19], "\uc81c\uc678\ud55c": 1, "\ub3d9\uc77c\ud55c": [1, 4, 7, 13, 16, 19], "configur": [1, 15, 17], "\uc73c\ub85c": [1, 4, 9, 12, 14, 16, 18, 19], "\uacb0\uacfc\uc785\ub2c8\ub2e4": [1, 8], "model_nam": 1, "instance_prompt": 1, "A": [1, 2, 3, 9, 11, 12, 16, 18], "sk": [1, 10, 12], "girl": 1, "class_prompt": 1, "python3": 1, "train_dreambooth": [1, 16], "py": [1, 16], "pretrained_model_name_or_path": [1, 16], "pretrained_vae_name_or_path": 1, "stabilityai": 1, "sd": 1, "vae": [1, 3, 7, 16, 17], "ft": 1, "mse": [1, 6], "output_dir": 1, "revis": [1, 16], "fp16": 1, "with_prior_preserv": [1, 16], "1": [1, 2, 4, 8, 11, 12, 13, 16, 17, 18, 20], "0": [1, 2, 3, 4, 5, 6, 8, 11, 13, 14, 16, 17, 20], "seed": 1, "1337": 1, "resolut": [1, 4, 7, 8, 15, 19], "512": [1, 17], "train_batch_s": 1, "train_text_encod": [1, 16], "mixed_precis": 1, "use_8bit_adam": 1, "gradient_accumulation_step": [1, 16], "gradient_checkpoint": 1, "learning_r": 1, "1e": [1, 10], "6": [1, 3, 10, 13], "lr_schedul": [1, 16], "constant": [1, 7, 15], "lr_warmup_step": 1, "num_class_imag": 1, "200": [1, 18], "sample_batch_s": 1, "4": [1, 4, 8, 11, 13, 17], "max_train_step": 1, "800": 1, "save_interv": 1, "100": [1, 7, 13], "save_sample_prompt": 1, "concepts_list": 1, "json": 1, "w": [1, 2, 3, 6, 8, 9, 11, 14, 18], "o": [1, 4, 10, 19], "\uc544\ub798": [1, 2, 4, 7, 11, 13, 14, 16, 17, 18, 20], "\uadf8\ub9bc\ucc98\ub7fc": [1, 9, 17, 18], "infer": [1, 6, 20], "\uc785\ub825\ud588\uc744": 1, "\ub54c": [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 20], "\uc81c\uc678\ud568\uc73c\ub85c\uc368": 1, "input": [1, 2, 3, 4, 9, 11, 12, 13, 14, 16, 17, 19], "\uac00\uae4c\uc6b4": [1, 12, 13, 14], "\uc6f9\ud230": 1, "\uc788\uc5c8\uc2b5\ub2c8\ub2e4": [1, 2, 4, 19], "\ub610\ud55c": [1, 2, 3, 4, 6, 8, 9, 13, 16, 19], "\ud551\ud06c\uc0c9": 1, "\uba38\ub9ac\ub97c": 1, "\ud55c": [1, 4, 6, 7, 9, 11, 13, 14, 15, 16, 17, 18, 19, 20], "\uc774\ubbfc\uc9c0": 1, "\uce90\ub9ad\ud130\ub97c": 1, "\uc5b4\ub290": [1, 11, 12], "\uc815\ub3c4": [1, 5, 7, 9, 11], "\uc0dd\uc131\ud558\ub294": [1, 2, 4, 6, 8, 11, 13, 16, 17, 18, 19, 20], "\ubd80\ubd84\ub3c4": [1, 4, 19], "\ud655\uc778\ud560": [1, 4, 7, 16, 19], "pink": 1, "hair": [1, 10, 11], "With": 1, "without": [1, 9, 10, 11], "\ub3c4": [1, 4, 6, 10, 16, 20], "\uce90\ub9ad\ud130\uc758": [1, 16], "\ubd80\uc790\uc5f0\uc2a4\ub7ec\uc6b4": 1, "\ubd80\ubd84\uc774\ub098": 1, "\uc800\ud574\uc0c1\ub3c4": 1, "\uacbd\uc6b0\ub4e4\uc774": 1, "\uc885\uc885": [1, 13], "\ubc1c\uc0dd\ud588\ub294\ub370": 1, "\ud1b5\ud574": [1, 3, 5, 6, 9, 11, 12, 13, 14, 15, 16, 17, 20], "\ud004\ub9ac\ud2f0\uc758": [1, 7, 10], "ugli": 1, "disfigur": 1, "deform": 1, "low": [1, 7, 14], "\ub17c\ubb38\uc5d0\uc11c": [1, 2, 8, 11, 13, 14, 16, 17, 20], "\uc81c\uc2dc\ud55c": [1, 3, 4, 14, 17, 18], "\uc678\uc5d0": 1, "style": [1, 4, 10, 12, 16], "\ub77c\ub294": [1, 2, 4, 12, 13, 15, 18], "\ub85c": [1, 2, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], "\ud559\uc2b5\uc744": [1, 3, 4, 8, 11, 13, 15, 19], "\uc2dc\ub3c4\ud574\ubcf4\uae30\ub3c4": 1, "\ud2b9\uc815": [1, 3, 4, 5, 6, 9, 10, 12, 18], "\uc5ec\uc790": 1, "\uce90\ub9ad\ud130\uc5d0": 1, "\uc815\ubcf4\ubfd0\ub9cc": 1, "\uc544\ub2c8\ub77c": [1, 3, 4, 6, 9, 11, 13, 16], "\ud504\ub9ac\ub4dc\ub85c\uc6b0": 1, "\uadf8\ub9bc\uccb4": 1, "\uc790\uccb4\ub97c": [1, 4, 7], "\ub2f4\uc544\ub0b4\uae30": 1, "\uc704\ud55c": [1, 4, 7, 8, 9, 12, 13, 15, 20], "\ubaa9\uc801\uc774\uc600\uc2b5\ub2c8\ub2e4": 1, "differ": [1, 9, 11], "\uc2dc": [1, 4, 14, 15, 16, 17, 18, 19], "\ud504\ub9ac\ub4dc\ub85c\uc6b0\uc758": 1, "\uadf8\ub9bc\uccb4\uac00": [1, 4], "\ubc18\uc601\ub41c": [1, 4], "\ub0a8\uc790\uac00": 1, "\uc0dd\uc131\ub418\ub3c4\ub85d": 1, "boi": 1, "\uc785\ub825\ud588\uc744\ub54c\uc758": 1, "\ud639\uc740": [1, 3, 4, 8, 16, 20], "\uc791\uac00\ub2d8\uc758": 1, "\uc7a5\uba74\ub4e4\ub85c": 1, "\uc804\uccb4\uc801\uc73c\ub85c": 1, "\ud559\uc2b5\ud558\uac8c": [1, 4, 19], "\ub41c\ub2e4\uba74": 1, "\ub2e4\uc591\ud55c": [1, 3, 4, 7, 8, 10, 12, 13, 14, 15, 16, 18], "\uac83": [1, 4, 6, 12, 13, 18], "num_inference_step": 1, "24": 1, "step": [1, 3, 4, 5, 6, 7, 10, 15, 16, 17], "\uc744": [1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20], "\ub298\ub824\uac00\uba74\uc11c": 1, "\ucd94\ub860\ub41c": 1, "\ud004\ub9ac\ud2f0\uac00": 1, "\uc0c1\uc2b9\ud558\ub294": 1, "\uc2e4\ud5d8\ub3c4": 1, "\uc9c4\ud589\ud588\ub294\ub370": 1, "\uc791\uc744\uc218\ub85d": 1, "\uc640": [1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, 18, 19, 20], "\ubb34\uad00\ud55c": [1, 4, 19], "random": [1, 3, 4, 5, 6, 9, 12, 16, 17, 19], "\uc0dd\uc131\ud558\uac8c": [1, 16, 18, 20], "\ub429\ub2c8\ub2e4": [1, 2, 4, 11, 13, 16, 17, 19, 20], "\ucd5c\uc885\uc801\uc73c\ub85c": [1, 11], "num_infer": 1, "\uac12\uc740": [1, 7, 15, 16], "\uac01\uac01": [1, 2, 3, 4, 12, 16, 17, 20], "\uacfc": [1, 4, 5, 6, 7, 10, 12, 14, 16, 18], "\uc124\uc815\ud558\uc600\uc2b5\ub2c8\ub2e4": 1, "increas": 1, "number": [1, 15], "guidance_scal": 1, "\uc81c\uc678\ud574\ubcf8": 1, "\uc0dd\uc131\ub41c": [1, 4, 11, 12, 13, 15, 16, 17, 18, 19, 20], "\ub0a8\uc790\uc758": 1, "\uba38\ub9ac\uce74\ub77d\uc774": 1, "\uae38\uc5b4\uc9c0\uace0": 1, "\uc5ec\uc131\uc2a4\ub7ec\uc6b4": 1, "\uc0dd\uae40\uc0c8\ub97c": [1, 12], "\ub180\ub77c\uc6b4": [1, 4], "\uc0ac\uc2e4\ub3c4": 1, "\uadf8": [1, 4, 6, 8, 11, 12, 13], "\uc678": [1, 13], "\ub530\ub978": [1, 2, 4, 7, 14, 16, 19, 20], "\uc7ac\ubbf8\uc788\ub294": 1, "\uc2e4\ud5d8\uacb0\uacfc\ub4e4\uc744": 1, "\uacf5\uc720\ud569\ub2c8\ub2e4": [1, 16], "\uc544\uc9c1": [1, 12, 15], "\uc190\uc758": 1, "\ubaa8\uc591\uc744": 1, "\uc0dd\uc131\ud558\uc9c0": 1, "\ubabb\ud558\ub294": [1, 17], "\uc7ac\ucc28": 1, "climb": 1, "up": [1, 6], "mountain": 1, "paint": [1, 4, 16, 19], "2": [1, 4, 8, 11, 12, 13, 16, 17, 18], "hand": 1, "draw": [1, 10], "\ud558\ub2e8\uc758": 1, "\uc88c\uce21\uacfc": 1, "\uc6b0\uce21": 1, "\uc0ac\uc9c4\uc740": 1, "\uc774\ub77c\ub294": [1, 15, 18], "\ub098\ube44\ub97c": 1, "\uc0dd\uc131\ud558\ub77c\ub294": 1, "\ucd94\ub860\ud574\ubcf8": 1, "\uc218\uc2dd\ud558\ub294": 1, "\uba85\uc0ac\uac00": 1, "\uc774\ub3c4\ub85d": 1, "\uc218\uc815\ud568\uc73c\ub85c\uc368": [1, 7], "butterfli": 1, "\uc0ac\uc9c4\uc744": [1, 13, 15], "\uc0dd\uc131\ud560\ub54c": 1, "\uc870\uae08\uc774\ub098\ub9c8": 1, "\uc6f9\ud230\uc758": 1, "\uadf8\ub9bc\uccb4\ub97c": 1, "\ubc18\uc601\ud560": 1, "\uc788\uc5c8\ub358": 1, "ad": 2, "arxiv": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "refer": [2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "paper": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], "http": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "org": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "ab": [2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20], "2302": 2, "05543": 2, "code": [2, 3, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 20, 21], "lllyasviel": 2, "mai": [2, 8, 12, 15, 16], "28": [2, 20], "\uae30\uc874\uc758": [2, 4], "\ubaa8\ub378\ub4e4\uc740": [2, 3, 4, 15], "prompt\ub85c": [2, 10, 12], "\uc870\uc808\ud560": [2, 11], "\ud558\uc9c0\ub9cc": [2, 3, 4, 5, 7, 9, 10, 12, 13, 15, 16, 17, 20], "\uc774\ub7f0": [2, 11], "control\ub9cc\uc73c\ub85c": 2, "\uc870\uc808\ud558\ub294\ub370": 2, "\ud55c\uacc4\uac00": [2, 10, 12, 13, 18], "condition\uc744": [2, 3], "\ucd94\uac00\uc801\uc73c\ub85c": [2, 4], "\uc918\uc11c": 2, "\uc0dd\uc131\ub418\ub294": [2, 10, 11, 15], "controlnet\uc774\ub77c\ub294": 2, "\uc2e0\uacbd\ub9dd": 2, "\uad6c\uc870\ub97c": [2, 8, 11, 13, 14, 16, 18], "\uc81c\uc548\ud569\ub2c8\ub2e4": [2, 4], "\uadf8\ub9bc\uc740": [2, 4, 8, 11], "high": [2, 7, 8, 11, 14, 17, 18], "qualiti": [2, 5, 10, 14, 15, 17, 18, 20], "detail": [2, 4, 10], "profession": 2, "prompt\uc640": [2, 3], "\uc67c\ucabd": 2, "\uc544\ub798\uc758": [2, 4, 8, 18], "canni": 2, "edge\ub97c": 2, "input\uc73c\ub85c": [2, 8, 11], "\ubc1b\uc544\uc11c": [2, 4, 11, 20], "\uc624\ub978\ucabd\uc758": 2, "\uc2dd\uc73c\ub85c": 2, "\ucd94\uac00\uc801\uc778": [2, 3, 6, 8, 9, 11, 12, 13], "\uadf8\ub9bc\uc5d0\uc11c\ub294": 2, "edg": [2, 13], "\ubc1b\uc544": [2, 6, 15], "\uac83\uc774": [2, 4, 6, 9, 11, 12, 13, 15, 16, 18, 19, 20], "controlnet\uc774": 2, "\ud558\ub294": [2, 6, 7, 10, 11, 12, 13, 15, 16, 18, 20], "\uc5ed\ud560\uc785\ub2c8\ub2e4": 2, "gener": [2, 4, 7, 10, 11, 12, 14, 15, 16, 17, 18], "conrolnet": 2, "\uadf8\ub7ec\uba74": [2, 11], "\uc5b4\ub5a4": [2, 4, 6, 9, 12, 13, 20], "\uac00\ub2a5\ud558\uac8c": [2, 9, 11], "\ud588\uc744\uae4c\uc694": [2, 4], "\uc774\uc81c\ubd80\ud130": 2, "\ub300\ud574": [2, 3, 4, 6, 7, 12, 13, 16, 17, 19, 20], "\uc54c\uc544\ubcf4\ub3c4\ub85d": [2, 11], "\ud558\uaca0\uc2b5\ub2c8\ub2e4": [2, 11, 20], "controlnet\uc758": 2, "\uad6c\uc870\ub294": [2, 11], "\ub2e4\uc74c\uacfc": [2, 4, 8, 11, 12, 13, 16, 17, 20], "\ub450": [2, 4, 6, 7, 11, 13, 16], "\uac00\uc9c0": [2, 4, 11, 12, 13, 16], "\uac00\uc9d1\ub2c8\ub2e4": [2, 8], "pretrain": [2, 3, 9, 10, 12, 14], "lock": 2, "copy\uc640": 2, "trainabl": [2, 5, 7, 9], "copy\ub97c": 2, "\uc0ac\uc6a9": [2, 3, 6, 7, 10, 13, 14, 15, 18], "\uc65c": [2, 4, 7], "\uc774\ub807\uac8c": [2, 12, 17], "\uc124\uacc4\ud588\ub294\uc9c0": 2, "\uc54c\uc544\ubd05\uc2dc\ub2e4": 2, "\uc6b0\uc120": [2, 16], "\uc0ac\uc6a9\ud558\ub294": [2, 4, 6, 11, 13, 15, 16, 18, 19], "\uc774\uc720\ub294": [2, 6], "\uae30\uc874\uc5d0": [2, 3, 8, 9, 11], "\ubc29\ub300\ud55c": 2, "\uc591\uc758": 2, "\ud559\uc2b5\uc2dc\ud0a8": 2, "\uc720\uc9c0\ud558\uae30": 2, "\uc704\ud574\uc11c\uc785\ub2c8\ub2e4": 2, "\ud559\uc2b5": [2, 4, 5, 6, 8, 9, 13, 14, 15, 16, 17, 18], "\ub370\uc774\ud130\uac00": [2, 6, 11, 12, 13, 17, 20], "\uc591\uc774": 2, "\uacbd\uc6b0\uc5d0": [2, 13], "\uc624\ubc84\ud53c\ud305\uc744": 2, "\ud53c\ud560": 2, "\uc788\ub294": [2, 4, 7, 11, 12, 13, 15, 16, 19], "\ud6a8\uacfc\ub3c4": 2, "convolution\uc774\ub780": 2, "weight\ub791": 2, "bias\uac00": [2, 11], "0\uc73c\ub85c": [2, 4, 13, 15, 19], "\ucd08\uae30\ud654\ud55c": 2, "1x1": 2, "convolution\uc744": 2, "\ub9d0\ud569\ub2c8\ub2e4": [2, 13], "\uc0ac\uc6a9\ud560": [2, 9], "\ud6c8\ub828\uc774": 2, "\uc2dc\uc791\ub418\uae30": 2, "\uc804\uc5d0\ub294": 2, "input\uc5d0": [2, 14], "model\uacfc": [2, 7, 8], "output\uc774": [2, 13], "\ub611\uac19\uc544\uc9d1\ub2c8\ub2e4": 2, "\ubaa8\ub378\uc774\ub791": 2, "\ub611\uac19\uc740": 2, "output\uc744": 2, "\uac00\uc9c0\uac8c\ub418\ubbc0\ub85c": 2, "\ubaa8\ub378\uc758": [2, 3, 4, 7, 9, 10, 11, 12, 15], "\uc720\uc9c0\ud560": [2, 12], "\uc788\uc73c\uba70": [2, 13, 14, 18], "\uac83\uacfc": [2, 4, 12, 13, 19], "\ube44\uc2b7\ud558\ubbc0\ub85c": 2, "scratch\ubd80\ud130": 2, "\ud559\uc2b5\ud558\ub294": [2, 6, 7, 11, 13, 17], "\uac83\uc5d0": [2, 12, 13], "\ube60\ub974\uac8c": [2, 15, 18], "\ud6c8\ub828\uc2dc\ud0ac": 2, "\uc788\uac8c\ub429\ub2c8\ub2e4": 2, "convolution\uc740": 2, "\uc5b4\ub5bb\uac8c": [2, 4, 6, 12], "\ud558\ub294\uc9c0": 2, "\uc790\uc138\ud788": [2, 4, 11, 16], "\uba3c\uc800": [2, 11, 14, 17], "\uc704\uc758": [2, 5, 7], "\uadf8\ub9bc\uc5d0\uc11c": [2, 11, 13, 16], "\ud574\ub2f9\ud558\ub294": [2, 4, 19], "\ubd80\ubd84\uc744": [2, 4, 16, 19], "\uc218\uc2dd\uc73c\ub85c": 2, "\ud45c\ud604\ud558\uaca0\uc2b5\ub2c8\ub2e4": 2, "mathbf": [2, 11], "y": [2, 4, 5, 6, 9, 11, 13, 14, 15], "mathcal": [2, 6, 8, 9], "f": [2, 5, 6, 8, 9, 13, 16, 17], "x": [2, 4, 5, 8, 9, 11, 13, 14, 15, 16, 17, 18, 20], "theta": [2, 6, 8, 9, 14, 15, 16, 17, 20], "\ub294": [2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20], "featur": [2, 3, 6, 10, 11, 16], "map": [2, 4, 6, 10, 13, 20], "neural": [2, 5, 7, 13], "network": [2, 5, 6, 13, 17], "paramet": [2, 5, 6, 9, 10, 14, 16, 18], "\uc758\ubbf8\ud569\ub2c8\ub2e4": 2, "\uc704": [2, 4, 6, 7, 9, 10, 12, 13], "\uadf8\ub9bc\uc758": 2, "b": [2, 6, 9, 11, 14, 18], "\ud45c\ud604\ud558\uae30\uc704\ud574": 2, "\ub9cc\ub4e4\uc5b4\uc11c": [2, 4, 12], "parameter\ub97c": [2, 3, 6, 14, 15], "theta_": 2, "c": [2, 3, 6, 8, 10, 11, 16], "\ub77c\uace0\ud558\uace0": 2, "\uace0\uc815\uc2dc\ucf1c\ub450\uaca0\uc2b5\ub2c8\ub2e4": 2, "z": [2, 6, 8, 9, 10, 14, 15, 17, 20], "\ud45c\ud604\ud558\uace0": 2, "convolution\uc758": 2, "z1": 2, "z2": 2, "\ub450\uaca0\uc2b5\ub2c8\ub2e4": 2, "output": [2, 4, 6, 9, 13, 14, 16, 19], "_": [2, 8, 9, 11, 16, 17, 20], "\ud45c\ud604\ud560": 2, "\uadf8\ub7f0\ub370": [2, 11], "weight\uc640": 2, "bias\uc758": 2, "\ucd08\uae43\uac12\uc774": 2, "0\uc774\ubbc0\ub85c": 2, "\uc9c4\ud589\ub418\uc9c0": 2, "\uc54a\uc558\uc744": 2, "\uc785\ub2c8\ub2e4": [2, 4, 13, 17, 20], "\uc2dc\uc791": 2, "controlnet\uacfc": 2, "\ub0b4\ubbc0\ub85c": 2, "\ubcf4\uc874\ud560": 2, "\uc804\ubd80": 2, "\ucd08\uae30\ud654\ub418\uc5b4\uc788\uc73c\uba74": 2, "gradient\uac00": [2, 13], "0\uc774\ub77c\uc11c": 2, "\uc548": [2, 4, 13], "\ub418\ub294\uac70": 2, "\uc544\ub2d0\uae4c\uc694": 2, "\ud655\uc778\ud558\uae30": 2, "\uac04\ub2e8\ud55c": [2, 12], "\uacbd\uc6b0\ub97c": 2, "\uc0dd\uac01\ud574\ubcf4\uc8e0": 2, "wx": 2, "gradient\ub294": 2, "frac": [2, 6, 8, 11, 15, 17, 20], "partial": [2, 3, 6], "0\uc774\uace0": 2, "neq0": 2, "\uc774\ub77c\uace0": [2, 4, 12], "\ud558\uba74": [2, 4, 13], "\uccab": [2, 11, 13], "\ubc88\uc9f8": [2, 11], "gradient": [2, 5, 6, 7, 9, 15, 17], "step\uc5d0\uc11c": [2, 6, 7], "weight\ub294": [2, 9], "0\uc774": [2, 5, 6], "\uac12\uc73c\ub85c": [2, 7, 9, 20], "\uac00\uac8c\ub418\uace0": 2, "\ub418\ubbc0\ub85c": 2, "\uc5ec\uae30\uc11c": [2, 6, 8, 11, 12, 13, 20], "\ud575\uc2ec\uc801\uc778": 2, "\uac00\uc815\uc774": 2, "\uc778\ub370": 2, "\ubd80\ubd84\uc740": [2, 8, 11], "\ud6c8\ub828\ub41c": [2, 12], "\uc0ac\uc6a9\ud558\uace0": [2, 3, 4, 9, 10, 12, 16, 19], "\uc788\uae30": [2, 13], "\ub54c\ubb38\uc5d0": [2, 4, 6, 9, 11, 13, 16, 20], "\uc704\ubc30\ub420": 2, "\uac00\ub2a5\uc131\uc774": [2, 7], "\ub0ae\uc744": 2, "\uc9c0\uae08\uae4c\uc9c0": [2, 6], "\uc598\uae30\ud55c": 2, "diffusion\uc5d0": 2, "\uc801\uc6a9\ud55c": [2, 7], "\uadf8\ub9bc\uacfc": [2, 11, 13, 14, 17, 18, 20], "overal": [2, 18], "structur": [2, 8, 9, 11], "loss\ub294": [2, 6], "diffusion\uc5d0\uc11c": 2, "\ucd94\uac00\ub41c": [2, 6], "\ud615\ud0dc\uc785\ub2c8\ub2e4": [2, 11], "loss": [2, 5, 7, 8, 10, 14, 15, 16, 17, 20], "training\uc744": 2, "\ud560": [2, 4, 6, 10, 11, 12, 14, 15, 16, 18], "50": [2, 6, 12, 13], "\ud655\ub960\ub85c": 2, "t": [2, 3, 4, 5, 7, 8, 14, 15, 16], "empti": 2, "string\uc73c\ub85c": 2, "\ubc14\uafd4\uc8fc\uc5c8\ub2e4\uace0": 2, "prompt\uac00": [2, 3], "\uc8fc\uc5b4\uc9c0\uc9c0\uc54a\uc744": 2, "\ub85c\ubd80\ud130": [2, 4, 13, 16, 17, 20], "semantics\ub97c": 2, "\ubc30\uc6b0\ub294": 2, "\uacbd\ud5a5\uc774": [2, 3, 4, 10], "\uc0dd\uc131\uc744": [2, 12, 18], "\ub2a5\ub825\uc744": [2, 4, 12], "\ud5a5\uc0c1\uc2dc\ucf1c\uc904": 2, "\uc788\ub2e4\uace0": [2, 4, 6, 12, 14, 20], "\uacb0\uacfc\ub294": [2, 7, 13], "training\uc774": 2, "\ubc29\ubc95\ubcf4\ub2e4": 2, "\ud6a8\uc728\uc801\uc774\ub77c\ub294": 2, "\uac83\uc744": [2, 4, 6, 7, 11, 12, 13, 14, 15, 16, 18, 19], "\ubcf4\uc5ec\uc90d\ub2c8\ub2e4": [2, 13, 16], "effici": [2, 4, 5, 9, 18], "\uacb0\uacfc\ub4e4\uc740": 2, "task\uc5d0": [2, 8, 9, 12, 13], "\uacb0\uacfc\ub4e4\uc785\ub2c8\ub2e4": 2, "\ub17c\ubb38\uc5d0": [2, 6, 20], "\uc788\uc73c\ub2c8": 2, "\ucc38\uace0\ud558\uc2dc\uae30": 2, "\ubc14\ub78d\ub2c8\ub2e4": 2, "pose": [2, 10, 11, 16], "limitation\uc774\ub77c\uace0": 2, "\uc774\ubbf8\uc9c0\uc785\ub2c8\ub2e4": [2, 4], "\ud14d\uc2a4\ud2b8\ub85c": 2, "\uc8fc\uc5c8\uc74c\uc5d0\ub3c4": 2, "\uc6d0\ud558\ub294": [2, 3, 4, 10, 11, 13], "\uc0dd\uc131\ub418\uc9c0": 2, "\uc54a\ub294": [2, 4, 13, 16], "\ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4": 2, "limit": 2, "\ucf54\ub4dc\ub294": 2, "\uacf5\uc2dd": 2, "\uad6c\ud604": [2, 17, 20], "\uac00\uc838\uc654\uc2b5\ub2c8\ub2e4": 2, "\ucd08\uae30\ud654\ud558\ub294": 2, "\ucf54\ub4dc\ub85c": 2, "\ub9cc\ub4e4": [2, 4, 12, 14], "\uc0ac\uc6a9\ub429\ub2c8\ub2e4": 2, "def": [2, 5, 6, 9, 11, 17, 20], "zero_modul": 2, "modul": [2, 6, 9, 11, 17, 20], "out": [2, 6, 20], "return": [2, 3, 5, 6, 9, 11, 17, 20], "p": [2, 4, 7, 15, 16, 20], "detach": [2, 17], "zero_": 2, "\uae30\ubcf8\uc801\uc73c\ub85c": [2, 9, 10, 18], "nn": [2, 6, 9, 11, 17, 20], "sequential\uacfc": 2, "\uac19\uc740\ub370": 2, "time": [2, 3, 5, 6, 7, 8, 9, 10, 14, 15, 18], "step\uac19\uc740": 2, "input\uc744": 2, "\ubc1b\uc544\uc904": 2, "\uc788\uac8c": [2, 4, 18], "\ub9cc\ub4e0": [2, 11, 13], "timestepembedsequenti": 2, "sequenti": [2, 6, 11, 17], "timestepblock": 2, "pass": [2, 4], "timestep": [2, 3, 4, 16], "embed": [2, 3, 4, 6, 9, 10, 14, 15, 16], "children": 2, "support": 2, "an": [2, 4, 11, 12, 20], "extra": [2, 4], "forward": [2, 7, 9, 11, 13, 16, 17, 20], "self": [2, 5, 6, 9, 11, 17, 18, 20], "emb": [2, 6], "context": [2, 4, 6, 9, 10, 14, 16], "none": [2, 6, 11], "layer": [2, 5, 6, 9, 11, 13, 17, 18], "isinst": 2, "elif": [2, 6, 16], "spatialtransform": 2, "els": [2, 5, 6, 9, 11, 16], "github\uc758": 2, "cldm": 2, "py\uc5d0": 2, "class\uc785\ub2c8\ub2e4": 2, "init": [2, 9], "\uae38\uc5b4\uc11c": 2, "\uc0dd\ub7b5\ud588\uc2b5\ub2c8\ub2e4": 2, "__init__": [2, 5, 6, 11, 17, 20], "make_zero_conv": 2, "channel": [2, 4, 6, 11, 15, 19], "conv_nd": 2, "dim": [2, 6, 11, 16], "pad": [2, 6], "hint": [2, 3], "kwarg": 2, "t_emb": 2, "timestep_embed": 2, "model_channel": 2, "repeat_onli": 2, "fals": [2, 5, 6, 9, 17], "time_emb": 2, "guided_hint": 2, "input_hint_block": 2, "h": [2, 6, 8, 9, 14, 15], "type": [2, 16, 17], "dtype": [2, 6, 16], "zero_conv": 2, "zip": [2, 5, 6], "input_block": 2, "append": [2, 6, 11, 17], "middle_block": 2, "middle_block_out": 2, "multi": [3, 4, 12, 18], "customizi": 3, "To": [3, 4, 5], "vcpr": 3, "2212": [3, 19], "04488": 3, "offici": [3, 5, 14, 15], "seunghwan": [3, 5, 7, 10], "ji": [3, 5, 7, 10], "aug": [3, 7, 10], "pdf": [3, 4, 7, 10, 12, 14, 19], "cvpr": [3, 7, 8, 11, 16, 19], "adob": 3, "larg": 3, "scale": [3, 9, 11, 15, 18], "\ub6f0\uc5b4\ub09c": [3, 5, 7, 14], "\ubcf4\uc774\ub294": [3, 5, 7, 13], "\ucd94\uc138": 3, "user\uc758": 3, "private\ud55c": 3, "concept\uc744": [3, 12], "\uc0dd\uc131\ud558\uace0\uc790\ud558\ub294": 3, "\uc695\uad6c\ub294": 3, "\ud480\uc9c0": 3, "\ubabb\ud568": 3, "diffusion\uc740": 3, "partial\ud55c": 3, "\ubd80\ubd84\ub9cc\uc744": 3, "\ud559\uc2b5\uc2dc\ud0b4\uc73c\ub85c\uc368": 3, "\uae30\uc874\ubcf4\ub2e4": 3, "\ube60\ub978": 3, "finetun": 3, "\ubc29\uc2dd\uc744": 3, "\uc81c\uc548": [3, 5, 7, 12, 13, 14], "\ubfd0": 3, "concept\uc5d0": [3, 12], "\ud559\uc2b5\uc774": [3, 6, 10, 13], "\uac00\ub2a5": [3, 4, 6, 15], "\ud558\ub098\uc758": [3, 6, 9, 10, 11, 12, 13, 20], "compress\ud558\ub294": 3, "\ucd5c\uadfc": [3, 7, 10, 13], "\ubaa8\ub378\ub4e4\uc774": [3, 4, 11, 16], "\ud65c\ubc1c\ud558\uac8c": 3, "\uc5f0\uad6c": [3, 7], "\ub418\uc5b4\uc9d0": 3, "\uc785\ub825\ub9cc\uc73c\ub85c": 3, "\uc0dd\uc131\ud574\ub0b4\ub294": [3, 4, 7], "\uc218\uc900\uae4c\uc9c0": [3, 7], "\uc774\ub984": 3, "\uc774\ub7ec\ud55c": [3, 4, 10, 12, 13, 16, 20], "general\ud55c": 3, "\uc0dd\uc131\ud558\uc9c0\ub9cc": [3, 17], "user\uac00": 3, "specif": [3, 11, 16], "concept\uc758": [3, 12], "e": [3, 4, 5, 6, 7, 8, 10, 11, 16, 17, 18, 20], "g": [3, 5, 7, 10, 11, 13, 16, 17], "\ud589\ubcf5\ud55c": 3, "\uc6b0\ub9ac": [3, 12, 13], "\uac00\uc871": 3, "\uc6b0\ub9ac\uc9d1": 3, "\uac15\uc544\uc9c0": 3, "\ubf40\uc090\uac00": 3, "\ud30c\ub9ac\ub85c": 3, "\uc5ec\ud589\uc744": 3, "\ub5a0\ub098\ub294": 3, "\ub4f1": [3, 5, 9, 10, 12, 16], "\uacfc\uc815\uc911\uc5d0": 3, "\ub370\uc774\ud130\ub97c": [3, 6, 7, 10, 13, 17, 20], "\ubcf4\uc9c0": [3, 13, 16], "\ubabb\ud588\uae30\ub54c\ubb38\uc5d0": 3, "model\uc5d0\uac8c\ub294": 3, "\ub2f9\uc5f0\ud55c": 3, "\uba87\uc7a5\uc758": 3, "\ud3ec\ud568\ud558\ub294": [3, 4, 12, 13, 19], "\uc774\ubbf8\uc9c0\ub9cc\uc73c\ub85c": [3, 10], "finetuning\ud558\ub294": 3, "\ubc29\uc2dd": 3, "In": 3, "person": [3, 4, 12], "\ubaa9\ud45c": [3, 4, 12, 13], "\ud559\uc2b5\ud558\uace0\uc790\ud558\ub294": 3, "\uc0dd\uc131\ud574\ub0b4\uc57c\ud568": 3, "\ud559\uc2b5\ub418\uc5c8\ub358": 3, "finetuning\ud55c": 3, "\ud6c4\uc5d0\ub3c4": 3, "customization\uc774": 3, "\uc5b4\ub824\uc6b4": [3, 12], "\uc774\uc720": [3, 7, 13], "\uc9c4\ud589\ud558\ub2e4\ubcf4\uba74": 3, "\ud559\uc2b5\ud588\ub358": 3, "\uc78a\uc5b4\ubc84\ub9ac\uac70\ub098": 3, "\uc65c\uace1\ud574\ubc84\ub9bc": 3, "draft": 3, "\uc0c8\ub85c\uc6b4": [3, 4, 11, 12, 15, 16, 17, 18, 19, 20], "overfit": [3, 16], "\ub418\uc5b4\uc11c": 3, "\uacb0\uacfc\ubb3c\uc758": 3, "variation\uc774": [3, 11], "\ub0ae\uc544\uc9d0": 3, "\uc880\ub354": [3, 5, 7, 10], "\ub098\uc544\uac00": 3, "\uc5b4\ub824\uc6c0": 3, "text\ub85c": 3, "\uacfc\uc815": [3, 6, 7, 12], "\uc131\ub2a5": [3, 4, 9, 13, 14, 15, 16, 17], "\uc720\uc9c0\ub97c": 3, "real": [3, 10, 17], "image\uc640": [3, 13, 14], "caption\uc744": 3, "regular": [3, 6, 20], "data\ub85c": 3, "tuning\ub3d9\uc548": 3, "augment": [3, 10], "\uc18c\uac1c": [3, 4], "gan": [3, 5, 10, 13, 14], "\ubc29\uc2dd\uc758": [3, 5, 15], "model\ub4e4\uc774": [3, 5], "\ubcf4\uc5ec\uc8fc\uace0\uc788\uc74c": 3, "\uac8c\ub2e4\uac00": [3, 4], "control\ub3c4": 3, "\uac00\ub2a5\ud568": [3, 9, 12, 14, 18], "general\ud558\uc9c0": 3, "\uc54a\uc740": [3, 4, 7, 11, 13], "\uc0dd\uc131\uc740": 3, "\ubd88\uac00\ub2a5\ud568": 3, "new": [3, 5, 11, 12], "global\ud55c": 3, "distribution\uc744": [3, 10, 11, 14], "\uc774\ubbf8": [3, 13, 18], "\ubaa8\ub378\uc5d0": [3, 4, 6, 7, 10, 12, 16, 19], "\ud3ec\ud568\ud55c": 3, "\uc18c\ub7c9\uc758": [3, 6], "\uae30\ubc95": [3, 9], "learning\uc740": 3, "\uc0dd\uac01\ubcf4\ub2e4": 3, "\ud6a8\uacfc\uc801\uc774\uace0": 3, "\uc720\uc6a9\ud568": 3, "\ub300\ubd80\ubd84": [3, 7, 10], "\uc2dc\uc5d0\ub294": [3, 6, 7, 14], "\uc804\uccb4\ub97c": [3, 4, 19], "\ud559\uc2b5\ud558\uac70\ub098": 3, "\ucd94\uac00\ud574": [3, 6], "\uc7ac\ud559\uc2b5": [3, 5, 15], "\uc704\uc5d0\uc11c": 3, "customization\uc758": 3, "\ubb38\uc81c\ub97c": [3, 9, 12, 18], "\uc77c\uc73c\ud0a4\uae30": 3, "\uc26c\uc6c0": 3, "etc": 3, "\uc544\uc8fc": 3, "\uc77c\ubd80\ub9cc\uc744": 3, "\ub300\uc0c1\uc73c\ub85c": [3, 13], "\ucee8\uc149\uc73c\ub85c": 3, "finetuning\uc744": 3, "\ud1b5\ud55c": [3, 12, 15], "\uc5f0\uad6c\ub4e4\uc774": [3, 7, 10], "\uc788\uc74c": [3, 4, 6, 7, 9, 12, 13, 14, 15, 18], "textual": [3, 16], "invers": [3, 4, 16], "vs": [3, 4, 5, 13, 14, 15, 18, 19], "\ubaa8\ub378\ub4e4\uc744": [3, 4, 19], "compress\ud560": 3, "finetuning\ud568\uc73c\ub85c\uc368": 3, "resourse\ub97c": 3, "\uc808\uc57d\ud560": 3, "backbone\uc73c\ub85c": 3, "latent": [3, 4, 10, 11, 16, 19, 20], "\ucc44\ud0dd": [3, 15], "l": [3, 8, 20], "dm\uc758": 3, "equat": [3, 5, 7, 10, 15], "x_": [3, 5, 6, 10, 15, 16], "\uc2dc\uc810\uc5d0": 3, "noise\uac00": [3, 6, 11], "\uc11e\uc778": 3, "condit": [3, 4, 6, 7, 15, 16, 19], "text\ub098": 3, "image\ub97c": [3, 6, 8, 12, 13, 14], "\ubc14\ub85c": [3, 4, 6, 11], "\uc0ac\uc6a9\ud558\uc9c0\uc54a\uace0": 3, "space\ub85c": [3, 12], "embedding\ub41c": 3, "\uac12\uc744": [3, 5, 7, 10, 14, 15, 18], "us": [3, 4, 5, 12, 13, 14, 18, 21], "clip": [3, 4, 12, 14, 16, 18, 19], "\u03b5": [3, 5], "nois": [3, 5, 6, 7, 11, 15, 16, 17, 20], "\u03b5_": 3, "\u03b8": 3, "\ub080": 3, "\u03b5\ub97c": 3, "\uc608\uce21\ud574\ub0b4\ub294": [3, 6], "\uc989": [3, 6, 12, 13, 14, 15, 18], "ldm": [3, 8, 10], "tuning\ud560\ub54c\ub294": 3, "\ubaa8\ub4e0": [3, 5, 9, 10, 11, 12, 13, 15], "layer\uc5d0\ub300\ud574": 3, "update\ud558\ub294\uac8c": 3, "\uae30\ubcf8": 3, "\ubc29\uc2dd\uc740": [3, 9, 12], "resource\uac00": 3, "\ube44\ud6a8\uc728\uc801\uc73c\ub85c": 3, "\ub9ce\uc774\ub4e4\uace0": 3, "\uc774\ubbf8\uc9c0\uc5d0": [3, 5, 7, 10, 12, 13, 14], "overfitting\ub418\uae30": 3, "weight": [3, 4, 5, 9, 19], "\ubcc0\ud654\ub7c9\uc744": 3, "\uccb4\ud06c": 3, "delta": [3, 9], "while": 3, "\ubd80\ubd84\uc5d0\ube44\ud574": 3, "cross": [3, 10, 16, 18], "attent": [3, 6, 8, 9, 10, 14, 15, 18], "\uc5f0\uc0b0\uc758": [3, 8], "wegith": 3, "\ubcc0\ud654\ub7c9\uc774": 3, "\uac00\uc7a5": [3, 4, 11, 12, 13, 16], "\ud07c": 3, "fig": [3, 5, 7], "latent\uc5d0": 3, "\uc8fc\uc785\ud558\ub294": 3, "mechan": 3, "queri": [3, 8, 9, 12], "kei": [3, 8, 9, 10], "valu": [3, 5, 9], "parameter\uc5d0": 3, "\ub2e8": [3, 10, 16], "\ucc28\uc9c0": 3, "\uc758\ubbf8\ud558\ub294": [3, 20], "v": [3, 4, 6, 8, 9, 10, 12, 14, 16, 17], "\ud3ec\ud568\ub418\ub294": 3, "k": [3, 6, 8, 9, 14, 17], "\ub9cc": [3, 4, 6, 9, 16], "\ub098\uba38\uc9c0\ub294": [3, 10, 13], "freez": [3, 9, 16, 18], "\uc740": [3, 4, 6, 11, 12, 13, 15, 16, 17, 18, 20], "\uc2e4\uc81c\ub85c\ub294": [3, 5], "\uc4f0\uc9c0\uc54a\ub294": 3, "\ub2e8\uc5b4\ub85c": 3, "\ud615\uc2dd\uc73c\ub85c": 3, "captioning\ud55c": 3, "\ud6c4\uc5d0": [3, 15], "\ub610": [3, 4, 7, 10, 16, 19], "finetuning\uc911\uc5d0": 3, "\uc78a\uc5b4\ubc84\ub9ac\ub294": 3, "\ud604\uc0c1\uc774": [3, 4, 11, 19], "\uc788\uc744\uc218\uc788\uc74c": 3, "moon": 3, "\uc0dd\uc131\ud558\uba74": [3, 13], "finetuning\ud588\ub358": 3, "moongat": 3, "\uc0dd\uc131\ud574\ubc84\ub9bc": 3, "\ubc29\uc9c0\ud558\uae30\uc704\ud574": 3, "world\uc758": 3, "image\uc5d0\uc11c": [3, 13, 14], "target": [3, 4, 6, 10, 12, 13, 16], "\uc720\uc0ac\ud55c": [3, 8, 12, 13, 14, 16, 20], "200\uc7a5\uc758": [3, 10], "regul": 3, "\uc720\uc0ac\ud558\ub2e4": 3, "clip\uc5d0\uc11c": 3, "\ucd94\ucd9c\ud55c": 3, "space\uc0c1\uc758": 3, "vector\uac00": 3, "similar\ud558\ub2e4": 3, "joint": [3, 14, 15], "trane": [3, 13], "\uac01\uac01\uc758": [3, 10], "\uac16\ub294": [3, 4], "rare\ud55c": 3, "key\ub97c": 3, "\ubd80\uc5ec\ud574": 3, "\ub3d9\uc2dc\uc5d0": [3, 10], "i": [3, 6, 8, 9, 11, 14, 16, 17, 18, 20], "constrain": 3, "optim": [3, 5, 10, 12, 14, 16, 20], "merg": [3, 9], "concept\uc73c\ub85c": 3, "\ud559\uc2b5\ub41c": [3, 12, 13, 15, 18], "weight\ub97c": [3, 9], "w_0": [3, 9], "appendix": 3, "a\uc5d0\ub294": 3, "\ub77c\uace0": [3, 9, 12, 18, 20], "\ub098\uc640\uc788\ub294\ub370": 3, "\uc624\ud0c8\uc790\uc77c": 3, "\uac00\ub2a5\uc131": 3, "c_": [3, 10, 16], "reg": 3, "caption\uc758": 3, "\ubaa8\ub450": [3, 4, 5, 7, 10, 11, 12, 13, 15, 16, 19], "\ubf51\uc544": [3, 15], "concat": [3, 4], "\uacf1\ud55c": 3, "\uac12\uacfc\uc758": 3, "norm\uc744": [3, 13], "\uacc4\uc0b0\ud588\uc744\ub54c": 3, "\uac12\uc774": [3, 5, 7, 10, 13, 14, 15, 18], "\uc791\uc740": [3, 6, 9, 12, 13], "n\uac1c\uc758": [3, 14], "attention\uc774": 3, "\ub3d9\uc791\ud558\ub294": [3, 8], "\ucc3e\uc544": [3, 12], "\ud558\ub098\ub9cc": 3, "\uc0ac\uc6a9\ud558\uc790": 3, "250": 3, "two": [3, 4, 11, 12, 14, 16], "500": 3, "batch": [3, 9, 13, 16, 17], "8": [3, 6, 7, 8, 9, 11, 14, 17], "rate": [3, 5, 10], "10": [3, 6, 7, 15, 17], "resiz": 3, "veri": 3, "small": [3, 4, 12, 19], "far": 3, "awai": 3, "zoom": 3, "techniqu": [3, 6, 18], "qualit": [3, 14], "evalu": [3, 4, 5, 19], "quant": [3, 12], "align": [3, 4, 6, 12, 18, 19], "kid": 3, "\uc5bc\ub9c8\ub098": [3, 4, 6, 12, 15], "\ub300\uc751\ub418\ub294": 3, "\uc0dd\uc131\ud574\ub0c8\ub294\uac00": 3, "image\uc758": [3, 7, 8, 10, 12], "\ud45c\ud604\ud574\ub0c8\ub294\uac00": 3, "tabl": [3, 7, 9, 10, 13, 15], "\uc815\uc131\uc801": [3, 14], "\uc815\ub7c9\uc801": [3, 14], "\ud3c9\uac00": [3, 4, 13, 16], "human": [3, 4, 11, 12, 19], "prefer": [3, 18], "studi": [3, 10], "baselin": [3, 14], "customdiffus": 3, "all": [3, 4, 9], "\uc120\ud638": 3, "inversion\uc740": [3, 12], "alignment\ub294": 3, "\uc120\ud638\ub3c4\uc640": 3, "\ube44\uc2b7\ud558\uc9c0\ub9cc": [3, 13], "alignment\uc218\uce58\ub97c": 3, "diffusion\uc774": 3, "\ub9e4\uc6b0": [3, 4, 5, 6, 9, 12, 13, 18], "\ub192\uc544": 3, "overfitting\ub41c": [3, 10], "ablat": [3, 10, 15], "\u314cgen": 3, "\ub300\uc2e0": [3, 6, 7, 10, 12, 13, 14], "generate\ub41c": 3, "\uc5c6\uc774": [3, 5, 6, 10, 12, 13, 14, 15, 18], "\uc218\uce58\ub294": [3, 7, 15], "regulat": 3, "world": 3, "customizing\uc774": 3, "\uac00\ub2a5\ud558\uace0": 3, "resourse\uac00": 3, "Of": 3, "category\uc758": 3, "object\uc5d0": 3, "\ub300\ud574\uc11c\ub294": [3, 7], "\ub3d9\uc791\ud558\uc9c0": [3, 7], "\uc54a\uc74c": [3, 6, 12, 18], "denois": [5, 9], "implicit": [5, 17], "iclr": [5, 6, 9, 20], "2021": [5, 6, 7, 9, 14, 15], "2010": 5, "02502": 5, "april": 5, "23": [5, 13], "ddpm\uc758": [5, 7, 10, 15], "\ub2e8\uc810\uc778": 5, "markov": [5, 6], "process\ub97c": [5, 6, 15], "process\ub85c": [5, 6, 7, 15], "\uc815\uc758\ud568\uc73c\ub85c\uc11c": 5, "deterministic\ud55c": 5, "sampling\uc774": [5, 15], "\uac00\ub2a5\ud55c": [5, 6, 8, 10, 13], "determinist": [4, 5, 15], "stochast": [4, 5, 17], "\ubd84\uc57c\uc5d0\uc11c": [5, 7, 10], "adversari": [5, 11, 17], "\ubcf4\uc5ec\uc8fc\uace0\uc788\ub2e4": 5, "gan\uc740": [5, 11, 13], "\uacfc\uc815\uc5d0\uc11c": [5, 6, 9, 10, 12, 13], "\ubd88\uc548\uc815\uc131\uc744": [5, 13], "\ub9ce\ub2e4": 5, "generator\uc640": 5, "discriminator\uc758": 5, "imbalanced\uc5d0": 5, "\uc758\ud55c": [5, 12], "mode": [5, 9], "collaps": [5, 13], "\uadf8\ub7ec\ub358": 5, "ddpm\uacfc": 5, "ncsn\uac19\uc740": 5, "training\uad6c\uc870\uac00": 5, "\ub4f1\uc7a5\ud558\uc600\uace0": 5, "\uc131\uacf5\uc758": 5, "\ubcf4\uc5ec\uc8fc\uc5c8\ub2e4": [5, 10], "ddpm\uc740": [5, 15], "process\uc5d0\uc11c": [5, 7, 15], "\uac70\uce58\ub294\ub370": 5, "\uc774\ub54c\ubb38\uc5d0": 5, "gan\uc5d0": 5, "\ub290\ub9b0": 5, "performance\ub97c": 5, "\ubcf4\uc5ec\uc900\ub2e4": [5, 10, 12, 18], "32": [5, 6, 9, 11, 14, 15], "50k": 5, "less": 5, "than": 5, "min": [4, 5, 9], "about": [5, 21], "20h": 5, "256": [5, 13, 14, 17, 18], "1000h": 5, "ddim\uc740": [5, 15], "chain\uc5d0": 5, "\uae30\ubc18\ud55c": 5, "\ub300\uccb4\ud558\uc600\uace0": 5, "\uacb0\uad6d": [5, 7, 14, 15], "\ube60\ub974\uace0": 5, "\ube44\uad50\uc801": 5, "\uc6b0\uc218\ud55c": [5, 13, 14], "quality\uc758": [5, 7, 10], "\uc0dd\uc131\ud574\ub0b4\uace0": [5, 10], "accel": 5, "ddpm\uacfc\ub294": 5, "\ub2e4\ub974\uac8c": [5, 16], "consistency\ud55c": 5, "\ubcf4\uc5ec\uc90c\uc73c\ub85c\uc368": 5, "latent\uac04\uc758": 5, "interpolation\uc774": 5, "\uac00\ub2a5\ud558\ub2e4": [5, 6, 10, 15], "consist": 5, "If": 5, "equival": 5, "architectur": [4, 5, 11, 12, 17, 18, 19, 20], "process\ub294": 5, "\ub3d9\uc791\ud55c\ub2e4": 5, "\ubbf8\ub798": 5, "\uc2dc\uc810\uc744": 5, "\uc608\uce21\ud558\uae30\uc704\ud574": 5, "\ud604\uc7ac": [4, 5, 10], "\uc2dc\uc810\uc758": [5, 15], "\uc774\uc6a9\ud55c\ub2e4": 5, "\uc2dc\uc810\uc740": 5, "\uacfc\uac70": 5, "\uac12\uc5d0\ub294": 5, "\ub3c5\ub9bd\uc801\uc778": 5, "\uac16\ub294\ub2e4": 5, "t\ub294": 5, "ddpm\uc5d0\uc11c": [5, 7, 15], "\uc88c\uc9c0\uc6b0\uc9c0\ud558\ub294": 5, "\uc911\uc694\ud55c": [5, 7, 11, 12, 13], "hyper": [5, 7, 9, 10], "parameter\uc774\ub2e4": 5, "\ub300\ucda9": 5, "1000": [5, 6], "\ubc88\uc758": 5, "\uacfc\uc815\uc744": [5, 6, 12, 20], "sequential\ud558\uac8c": 5, "\uac70\uccd0\uc57c\ud558\uace0": 5, "method": [4, 5, 11, 14, 15], "\ubcf4\ub2e4": [5, 6, 7, 9, 12, 13, 14, 15, 16, 18], "\ud604\uc800\ud788": [5, 7], "\uc18d\ub3c4\ub97c": 5, "\uc694\uc18c\uac00": 5, "\ub41c\ub2e4": [5, 13, 18], "s": [4, 5, 10, 11, 12, 16, 17, 18, 19, 21], "distribut": [4, 5, 6, 14, 15, 20], "\uc815\uc758": [5, 7], "\uad6c\ud558\uae30\uc704\ud574": 5, "\uac12\uacfc": 5, "\ucc38\uc870": 5, "\uac12\ub9cc\uc744": 5, "\u03c3\ub294": 5, "process\uc758": 5, "stochastic\ud55c": 5, "chap": 5, "And": 5, "unifi": 5, "object": [4, 5, 12, 14, 16, 19], "revers": [5, 7], "\uc608\uce21": [4, 5, 6, 14], "\uc2dd\uc744": [5, 15], "\uc774\uc6a9\ud574": [5, 12, 20], "\uc0d8\ud50c\ub9c1": [5, 15, 18], "\uad00\uacc4": 5, "noise\ub97c": [5, 6, 7, 11], "\uc774\ubbf8\uc9c0\uc640": [4, 5, 10, 12, 16, 19, 20], "\uacc4\uc0b0": [5, 6, 12], "fix": [5, 6], "t\uc2dc\uc810\uc758": 5, "\uc608\uce21\ud55c": 5, "\u03c3": 5, "\u03c3\uac00": 5, "\uac00\uc9c8": 5, "\uc218\uc2dd\uacfc": 5, "\ub3d9\uc77c\ud558\ub2e4": 5, "explan": 5, "acceler": [5, 15, 16], "deterministic\ud558\uae30\ub54c\ubb38\uc5d0": [5, 15], "\uacc4\uc0b0\ud560": [5, 15], "\ud544\uc694": [5, 15], "subset\uc758": [5, 15], "\uc2dc\uc810\ub9cc\uc73c\ub85c": [5, 15], "method\ub294": [5, 12, 15], "\uc57d\uac04\uc758": [5, 15], "\uc800\ud558\uac00": [5, 15], "\uc788\uc9c0\ub9cc": [5, 13, 14, 15], "comput": [4, 5, 9, 13, 15, 16, 18, 19], "efficiency\ub97c": [5, 15], "\ucda9\ubd84\ud788": [5, 15], "\uc99d\uac00\uc2dc\ud0ac": [5, 15], "\uc788\ub2e4": [4, 5, 7, 9, 10, 12, 13, 15, 18], "ddim\uc758": [5, 15], "relev": 5, "od": 5, "encoding\uc774": 5, "\uc720\ub3c4\ud560": 5, "table1": 5, "euqat": 5, "\u03b7": [4, 5], "simple\ud558\uac8c": 5, "control\ud558\uae30\uc704\ud55c": 5, "\ube44\uad50": [4, 5, 7, 14, 15, 18], "\ud69f\uc218": 5, "\ucee4\uc9c8\uc218\ub85d": [4, 5, 7, 10], "\ub0ae\uc740": [5, 6, 7, 14, 16], "fid\ub97c": 5, "3\uc758": [5, 14], "\u03b7\uac00": 5, "step\uc5d0": [5, 7], "figur": [5, 7, 10, 12, 13, 16, 18], "step\uacfc": 5, "time\uc774": 5, "linear\ud55c": 5, "\uad00\uacc4\ub97c": [4, 5, 7], "step\uc5d0\uc11c\ub3c4": 5, "\uc5b4\ub290\uc815\ub3c4\uc758": 5, "object\ub97c": 5, "kera": 5, "io": [5, 6, 7, 12, 13, 14], "exampl": [4, 5, 11, 12, 16, 19], "diffusionmodel": 5, "image_s": 5, "width": [5, 15], "block_depth": 5, "super": [4, 5, 6, 11, 13, 17, 19, 20], "normal": [5, 6, 11, 13, 17, 18], "get_network": 5, "unet": [5, 6, 16], "\uad6c\uc870": [4, 5, 11, 13], "denorm": 5, "convert": [5, 16], "pixel": [5, 14], "back": 5, "rang": [5, 14, 16, 17], "mean": [5, 6, 16], "varianc": [5, 6], "tf": 5, "clip_by_valu": 5, "diffusion_schedul": 5, "diffusion_tim": 5, "angl": 5, "start_angl": 5, "aco": 5, "max_signal_r": 5, "end_angl": 5, "min_signal_r": 5, "diffusion_angl": 5, "signal": 5, "signal_r": 5, "co": [5, 6], "noise_r": 5, "sin": [5, 6], "note": 5, "squar": [5, 16], "sum": [5, 9], "alwai": 5, "noisy_imag": 5, "exponenti": 5, "move": 5, "averag": 5, "ar": [4, 5, 6, 9], "ema_network": 5, "predict": [5, 6, 16, 18], "compon": 5, "calcul": 5, "pred_nois": [5, 6], "pred_imag": 5, "train_step": 5, "have": 5, "standard": [5, 11], "deviat": 5, "like": 5, "true": [4, 5, 6, 9, 17], "shape": [4, 5, 6, 11, 12, 16, 17, 19], "batch_siz": [5, 11, 20], "uniform": [4, 5], "minval": 5, "maxval": 5, "mix": 5, "accordingli": 5, "gradienttap": 5, "tape": 5, "separ": [5, 11, 16], "noisi": 5, "noise_loss": 5, "image_loss": 5, "onli": [5, 10, 14], "metric": [4, 5, 6, 13, 16, 19], "trainable_weight": 5, "apply_gradi": 5, "noise_loss_track": 5, "update_st": 5, "image_loss_track": 5, "m": [4, 5, 6, 8, 10], "name": [5, 9], "result": [5, 7, 9], "reverse_diffus": 5, "initial_nois": 5, "diffusion_step": 5, "num_imag": 5, "step_siz": 5, "import": [5, 7, 9], "line": 5, "first": [4, 5, 9], "pure": 5, "its": 5, "assum": 5, "nonzero": 5, "next_noisy_imag": 5, "current": [4, 5, 6], "ones": 5, "eval": [4, 5], "remix": 5, "next": 5, "next_diffusion_tim": 5, "next_noise_r": 5, "next_signal_r": 5, "thi": [5, 6, 9, 12, 16, 21], "generated_imag": 5, "probabilist": [6, 9], "2006": [6, 9], "11239": [6, 9], "pytorch": [6, 9, 11, 14, 17, 20], "implement": [6, 9, 10, 16, 17, 20], "review": [6, 9, 12, 21], "pr": [6, 9, 16], "409": [6, 9], "beomsoo": [6, 9], "park": [6, 9], "apr": [6, 9, 11, 13, 17, 20], "19": [6, 9], "sourc": [4, 6, 10, 11, 12, 13, 14, 19], "velog": [6, 13, 14], "yetsyl0705": 6, "what": 6, "variat": [4, 6, 20], "inference\ub85c": 6, "\ud559\uc2b5\uc2dc\ucf1c": [6, 9], "parameter": 6, "chain": [4, 6, 15, 16], "model\uc740": [6, 8, 9, 12], "markov\uac00": 6, "distribution\uc758": 6, "\ud615\ud0dc\ub97c": 6, "\ub54c\uae4c\uc9c0": 6, "\ub354\ud574\uac00\ub294": 6, "\uc5ed\uc73c\ub85c": 6, "\uac70\uce58\uba70": 6, "\uad6c\uc131\ub428": 6, "\uc815\uc758\ud558\uae30": 6, "\uc27d\uace0": 6, "\ud559\uc2b5\uc2dc\ud0a4\ub294": [6, 13], "\uac83\ub3c4": [6, 20], "\ud3b8\ub9ac\ud568": 6, "\ub192\uc740": [4, 6, 7, 9, 10, 12, 14, 15, 18], "\ud488\uc9c8\uc758": [6, 13], "\uc0dd\uc131\uc774": [6, 10, 14, 15, 18], "\ubcc0\ubd84\ucd94\ub860": [6, 20], "\uc0ac\ud6c4\ud655\ub960": 6, "posterior": [6, 14, 20], "\ubd84\ud3ec": [6, 14], "\ub2e4\ub8e8\uae30": [6, 20], "\uc26c\uc6b4": [6, 13, 20], "\ud655\ub960\ubd84\ud3ec": 6, "\uadfc\uc0ac": 6, "approxim": [6, 20], "\ud45c\ud604\uc2dd\uc5d0": 6, "\ud45c\ud604\ud558\ub294": [6, 12, 16], "\ubcf4\ud1b5": [6, 9, 11, 12, 13], "parameter\uc758": 6, "\ud45c\ud604": [4, 6], "\uc2dd\uc758": 6, "\ucc28\uc218\ubcf4\ub2e4": 6, "\uc218\ub85c": 6, "\uc120\ud0dd": [6, 14], "ex": [4, 6, 13], "3\ucc28": 6, "\ud45c\ud604\uc2dd": 6, "2\uac1c": 6, "\ud558\ubbc0\ub85c": 6, "\ucc28\uc218\ub85c\uc758": 6, "\ud568\uc218": [6, 13, 14, 15], "3d": 6, "2d": 6, "\uc0c1\ud0dc\uc5d0\uc11c": [6, 13], "\uc0c1\ud0dc\ub85c": [6, 16], "\ub118\uc5b4\uac08": 6, "\ub2e8\uacc4\uc758": [6, 12], "\uc0c1\ud0dc\uc5d0\ub9cc": 6, "\ubc1b\ub294": [4, 6, 11], "\ud655\ub960": [6, 20], "graphic": [6, 18], "left": [6, 8, 9, 15, 18, 20], "mid": [6, 9], "_0": 6, "right": [6, 8, 9, 15, 18, 20], "prod_": 6, "quad": 6, "n": [4, 6, 8, 9, 14], "sqrt": [6, 8], "beta_t": 6, "chain\uc73c\ub85c": 6, "data\uc5d0": [6, 13], "\ucd94\uac00\ud560": 6, "schedul": [6, 7, 15, 16], "beta_1": 6, "\ub354\ud574\uc900\ub2e4": 6, "\uc774\uba74": [6, 18], "mean\uc778": 6, "\uc774\uc804": [6, 9, 11], "\uac16\uc9c0": 6, "\ub178\uc774\uc988\uac00": 6, "\uc99d\uac00\ud568": 6, "\ub2e8\uc21c\ud788": [6, 12, 13], "noise\ub9cc\uc744": 6, "\ub354\ud574\uc8fc\ub294\uac8c": 6, "scaling\ud558\ub294": 6, "variance\uac00": 6, "\ubc1c\uc0b0\ud558\ub294": 6, "\ub9c9\uae30": 6, "\uc704\ud568": [6, 13], "x_1": 6, "x_0": 6, "\ub9cc\ub4dc\ub294": [6, 20], "x_t": [4, 6, 8, 15], "\uc644\uc804": 6, "destroy\ub41c": 6, "\uc0c1\ud0dc": 6, "p_": [6, 9, 14, 15, 17, 20], "boldsymbol": 6, "mu": [6, 11, 15, 20], "sigma": [6, 11, 15, 20], "\uac00\uc6b0\uc2dc\uc548": 6, "\ub178\uc774\uc988\ub97c": 6, "1994\ub144": 6, "process\uac00": 6, "\uac00\uc6b0\uc2dc\uc548\uc774\uba74": 6, "process\ub3c4": 6, "\uac00\uc6b0\uc2dc\uc548\uc73c\ub85c": 6, "\uc4f0\uba74": 6, "\ub41c\ub2e4\ub77c\ub294": 6, "\uc99d\uba85\uc774": 6, "\ud568": [4, 6, 9, 12, 13, 14, 15, 18], "\uc6b0\ub9ac\uac00": [4, 6, 13], "\ud574\uc57c": 6, "\uac83\uc740": [4, 6, 12, 13], "\ubcf4\uace0": [4, 6], "\ud3c9\uade0": [6, 16, 20], "mu_": 6, "\ubd84\uc0b0": [6, 15, 20], "sigma_": [6, 15, 16], "hierarach": 6, "vae\uc5d0\uc11c\uc758": 6, "\uacfc\uc815\uacfc": 6, "\ube44\uc2b7\ud568": [6, 12], "\ubaa9\uc801\uc740": 6, "\uc81c\uac70\ud560": 6, "\uac83\uc778\uac00": 6, "\uc774\ub2e4": [6, 9, 15], "\ub4e4\uc5b4\uc654\uc744": 6, "\uc608\uce21\ud560": 6, "\uc608\uce21\uc774": 6, "\uac00\ub2a5\ud574\uc9d0": [4, 6, 12], "mathbb": [6, 8, 9, 16, 17, 20], "log": [6, 9, 14, 15, 17, 20], "leq": 6, "_q": [6, 8], "sum_": [6, 9, 20], "geq": 6, "\ubcf8": [6, 9, 14, 15, 18], "neg": [6, 10], "likelihood\ub97c": 6, "\ucd5c\uc18c\ud654": 6, "\ubc29\ud5a5\uc73c\ub85c": [6, 10, 17], "\uc9c4\ud589": [6, 10, 14, 15, 18], "\uc218\uc2dd\uc744": [6, 13, 15], "elbo": [6, 14], "evid": [6, 14], "lower": [6, 14, 18], "bound": 6, "\uc6b0\ud56d\uacfc": 6, "\uc815\ub9ac\ud558\uace0": 6, "\ud480\uc5b4\ub0b4\uba74": 6, "elbo\uc758": 6, "\uc5ed\ud560\uc740": 6, "\uad00\ucc30\ud55c": 6, "\ud798\ub4e0": 6, "\ubd84\ud3ec\ub97c": [6, 13, 17, 20], "\uc774\ub8e8\uace0": 6, "\uc870\uae08": [4, 6], "\ubd84\ud3ec\uc778": 6, "\ud45c\ud604\ud558\ub824": 6, "\ucc28\uc774": 6, "kl": [6, 8, 17, 20], "diverg": 6, "\ud558\uae30": [6, 14, 16, 20], "\uc0ac\uc6a9\ub41c\ub2e4": 6, "underbrac": 6, "d_": [6, 9, 17], "mathrm": 6, "_1": 6, "\ub098\uc628\ub2e4": [6, 15], "term\uc73c\ub85c": 6, "\ud559\uc2b5\uc2dc\ud0b4": 6, "reconstruct": [6, 12, 16, 20], "\ub9e4": 6, "\ub2e8\uacc4\uc5d0\uc11c": [6, 12], "\uc9c0\uc6b0\ub294": 6, "\uc9c0\uc6c0": 6, "\ucd5c\uc885": 6, "ddpm\uc5d0\uc11c\ub294": [6, 7], "induct": 6, "bias\ub97c": [6, 11, 12], "\ub298\ub824": 6, "stable\ud558\uace0": 6, "\uc131\ub2a5\ub3c4": [4, 6, 19], "\uac1c\uc120\ud560": [6, 7], "\uc788\uc5c8\uc74c": [6, 9, 12, 13], "bia": [4, 6], "\ub9cc\ub098\ubcf4\uc9c0": 6, "\ubabb\ud588\ub358": [6, 16], "\uc0c1\ud669\uc5d0\uc11c": [4, 6], "\uc815\ud655\ud55c": [6, 12, 13], "\uc608\uce21\uc744": 6, "\uac00\uc815": 6, "\ud480\ub824\ub294": 6, "\ubb38\uc81c\uc5d0": 6, "\uc801\uc6a9\ud558\ub294": [6, 9, 16], "\uace0\uc815": [6, 7, 12], "\ud588\ub354\ub2c8": 6, "\uc798\ub428": 6, "02\ub85c": 6, "linear\ud558\uac8c": 6, "image\uc5d0": [6, 12], "\uac00\uae4c\uc6b8\uc218\ub85d": 6, "\uc801\uac8c": [6, 14], "\uc8fc\ub294": 6, "\ubc29\uc2dd\uc73c\ub85c": [4, 6, 9, 10, 15], "\uc124\uc815": [6, 9, 14], "\uc5d0\ub294": [4, 6, 18], "parameter\uac00": 6, "\uc5c6\uc5b4": [4, 6, 13, 18], "\ub418\uae30": [6, 9, 13], "\uc0ad\uc81c": 6, "tild": [6, 7], "beta": 6, "progress": 6, "posterior\ub97c": 6, "\uc608\uce21\ud558\ub294": 6, "\ub354\ud574": 6, "\ub9cc\ub4e4\uc5c8\uc744\ub54c": 6, "\ubcf5\uc6d0": 6, "simplic": 6, "sjina0722": 6, "\ub17c\ubb38": [4, 6, 9, 13, 14, 16], "\ub9ac\ubdf0": [6, 9], "\uc0c1\uc218\ub85c": 6, "\uac00\uc815\ud588\uace0": 6, "\ubc1b\uae30": [6, 10], "\ud559\uc2b5\uc2dc\ud0a4\uc9c0": 6, "\uc54a\uc544\ub3c4": 6, "\ub41c\ub2e4\uace0": 6, "\uc0dd\uac01\ud574": 6, "term\uc744": 6, "\uc81c\uac70": 6, "residu": [6, 13, 15, 16, 18], "estim": [6, 17, 20], "\uad6c\ud558\uc9c0": [6, 17], "\uc54a\uace0": [4, 6, 9, 17, 19, 20], "epsilon_": [6, 8, 15], "\uad6c\ud574": 6, "\uc815\ud655\ub3c4\ub97c": 6, "\ub192\uc784": 6, "begin": 6, "d": [6, 8, 9, 11, 17], "int_": 6, "delta_": 6, "sigma_1": 6, "arrai": 6, "ll": [6, 9, 16], "infti": 6, "255": 6, "end": [6, 11], "case": [4, 6, 19], "\uc0ac\uc774\ub85c": 6, "linearli": 6, "\ub2e8\uacc4\uc5d0\ub294": 6, "\ucd94\uac00\ud558\uc9c0": 6, "\uc0ac\uc774\uc758": [4, 6, 13], "divergence\ub97c": 6, "\ub098\ud0c0\ub0c4": [6, 13], "dimension": [4, 6], "\uc88c\ud45c": 6, "final": 6, "\uc704\uc640": [6, 9, 13, 15], "\ub098\ud0c0\ub09c\ub2e4": 6, "ground": [6, 13, 17], "truth": [6, 13, 17], "output\uac04": 6, "\uc904\uc774\ub294": 6, "\uacfc\uc815\uc774": 6, "denoising\uacfc": 6, "\ube44\uc2b7\ud574": 6, "ddpm\uc774\ub77c\ub294": 6, "\uc774\ub984\uc774": [6, 18], "\ubd99\uc74c": 6, "objective\uc744": 6, "\uc5d0\uc11c\ubfd0\ub9cc": 6, "\ud070": [4, 6, 7, 9, 11, 12, 13], "t\uc5d0": 6, "\ub300\ud574\uc11c\ub3c4": [6, 12, 13, 15], "\uac00\ub2a5\ud558\uae30": 6, "\ud6a8\uacfc\uc801": 6, "psuedo": 6, "algorithm": 6, "\ub354\ud574\ub098\uac00\ub294": 6, "epsilon": [6, 8, 15, 16], "\uc5bc\ub9c8\ub9cc\ud07c": 6, "\ub354\ud574\uc84c\ub294\uc9c0\ub97c": 6, "\ud559\uc2b5\ud55c\ub2e4": 6, "step\uc758": 6, "gaussian": [6, 9, 11, 15, 16, 20], "\ucd94\uac00\ub418\uc5c8\ub294\uc9c0\ub97c": 6, "\uc608\uce21\ud558\ub3c4\ub85d": [6, 7], "\ud559\uc2b5\ub41c\ub2e4": [6, 12], "\ucf54\ub4dc\uc5d0\uc11c\ub294": [6, 9], "\ub79c\ub364": 6, "\ub178\uc774\uc988\uc640": 6, "\uc2dc\uac04": [4, 6, 9, 13], "\ub2e8\uacc4": [6, 17], "t\ub85c": 6, "\uc5bb\uace0": 6, "p_loss": 6, "x_start": 6, "default": [6, 9], "lambda": [6, 13, 16], "torch": [6, 9, 16, 20], "randn_lik": [6, 16], "q_sampl": 6, "do": [6, 11, 12], "from": [4, 6, 11, 17], "set": [6, 9, 13, 16, 18], "slow": 6, "down": 6, "25": [6, 9, 17], "seem": 6, "fid": [6, 7, 8, 11, 14, 15, 18], "significantli": [6, 18], "x_self_cond": 6, "self_condit": 6, "no_grad": 6, "model_predict": 6, "pred_x_start": 6, "detach_": 6, "take": 6, "model_out": 6, "pred_x0": 6, "pred_v": 6, "predict_v": 6, "rais": [6, 16], "valueerror": [6, 16], "unknown": [6, 16], "loss_fn": 6, "reduct": [6, 16], "reduc": [6, 16], "extract": 6, "loss_weight": 6, "network\ub97c": [6, 11], "\ud559\uc2b5\ud558\uace0": [6, 14], "\ub098\uba74": 6, "noise\uc5d0\uc11c": 6, "\uc2dc\uc791\ud574\uc11c": [6, 11], "\uc21c\ucc28\uc801\uc73c\ub85c": [6, 14], "markovian": [6, 15], "\ucd94\uac00\ud558\uace0": [4, 6], "p_sampl": 6, "int": [6, 17, 20], "devic": [6, 16], "batched_tim": 6, "full": [4, 6, 7, 10, 19], "long": [6, 16], "model_mean": 6, "model_log_vari": 6, "p_mean_vari": 6, "clip_denois": 6, "pred_img": 6, "exp": 6, "backbon": 6, "u": [6, 8, 16, 18], "net": [6, 8, 16, 18], "\uac01": [4, 6, 9, 11, 12, 13, 14, 15, 16, 19], "upsampl": [6, 15, 18], "\ub2e8\uacc4\ub294": 6, "resnet": [6, 15], "convnext": 6, "\ube14\ub85d": 6, "groupnorm": [6, 15], "upsampling\uc73c\ub85c": 6, "block_klass": 6, "resnetblock": 6, "group": 6, "resnet_block_group": 6, "modulelist": 6, "dim_in": 6, "time_emb_dim": 6, "time_dim": 6, "prenorm": 6, "linearattent": 6, "downsampl": [4, 6, 15, 19], "dim_out": 6, "is_last": 6, "conv2d": [6, 9], "init_dim": 6, "out_dim": 6, "dim_mult": 6, "learned_vari": 6, "learned_sinusoidal_cond": 6, "random_fourier_featur": 6, "learned_sinusoidal_dim": 6, "16": [6, 8, 9, 11, 14, 15, 16], "determin": 6, "dimens": [6, 9], "input_channel": 6, "init_conv": 6, "in_out": 6, "list": 6, "random_or_learned_sinusoidal_cond": 6, "sinu_pos_emb": 6, "randomorlearnedsinusoidalposemb": 6, "fourier_dim": 6, "sinusoidalposemb": 6, "time_mlp": 6, "gelu": 6, "num_resolut": 6, "len": [6, 17], "ind": 6, "enumer": [6, 16, 17], "mid_dim": 6, "mid_block1": 6, "mid_attn": 6, "mid_block2": 6, "default_out_dim": 6, "final_res_block": 6, "final_conv": 6, "zeros_lik": 6, "r": [4, 6, 7, 8, 9, 10, 19], "clone": 6, "block1": 6, "block2": 6, "attn": [6, 10], "pop": 6, "resolution\uc5d0": [6, 13], "conv\uc5d0\uc11c": 6, "\ucc28\uc6d0\uc744": 6, "3\ubc30\ub85c": 6, "\ub298\ub9ac\uace0": 6, "v\ub85c": 6, "\ubd84\ud574": 6, "head": [6, 10, 15], "dim_head": 6, "hidden_dim": 6, "to_qkv": 6, "to_out": 6, "qkv": 6, "chunk": [6, 16], "rearrang": 6, "sim": [6, 8, 17], "einsum": 6, "j": [4, 6], "softmax": [6, 8, 14], "layernorm": 6, "block\uc5d0": [6, 15], "transform": [6, 7], "sinusoid": 6, "posit": [6, 10], "embedding\uc774": [6, 12], "\ucd94\uac00\ub3fc\uc11c": 6, "\uad6c\ubd84\ub428": 6, "half_dim": 6, "math": 6, "10000": 6, "arang": 6, "score": [6, 13, 14, 18], "is\ub85c": 6, "uncondit": [6, 15], "model\uc778\ub370\ub3c4": 6, "model\ubcf4\ub2e4": 6, "\uc6b0\uc6d4": 6, "codelength\uc5d0\uc11c": 6, "\ucc28\uc774\uac00": [6, 7, 12], "\uc5c6\uae30": [6, 13], "overfitting\uc758": 6, "\uac00\ub2a5\uc131\ub3c4": 6, "\uc801\uc74c": 6, "incept": [6, 14], "v3\uc73c\ub85c": 6, "\uacc4\uc0b0\ud55c": [6, 17], "\ud55c\ubc88": [6, 16, 20], "dataset\uc5d0": [6, 14], "\ud559\uc2b5\ub418\uba74": [6, 12], "label": [6, 13, 15, 18], "\ub4f1\uc758": [6, 12, 13], "\uacc4\uc0b0\ud558\ub294": [6, 20], "\uc131\uc801\uc774": 6, "\uc88b\uace0": 6, "variance\ub97c": [6, 7], "\uc0ac\uc6a9\ud588\uc744": [6, 12, 15], "\ub54c\uc5d0\ub3c4": 6, "\uac10\uc18c\ud558\uc9c0": 6, "2102": [7, 14], "09672": 7, "alex": 7, "nichol": 7, "ddpm\uc744": 7, "\uc57d\uac04": 7, "quality\ub97c": [7, 12], "\uc720\uc9c0\ud558\uace0": [7, 11], "likelihood\uc218\uce58\ub3c4": 7, "\ud5a5\uc0c1\ub41c": [7, 12], "sampling\uc2dc": 7, "base": [4, 7, 10, 11, 12, 15, 18, 19, 21], "step\uc73c\ub85c": [7, 15], "\ub0bc": [7, 15], "scale\uacfc": [7, 11], "quailty\uc640": 7, "\uc218\uce58\uac04\uc758": 7, "ho": 7, "et": [7, 13], "al": [7, 13], "\uc654\ub2e4": 7, "quality\uc5d0": 7, "\ubc18\ud574": 7, "\ubaa8\ub378\uc5d0\ube44\ud574": 7, "\ub5a8\uc5b4\uc84c\ub2e4": 7, "ddpm\uc774": 7, "diversity\uac00": [7, 15], "dataset": [7, 12, 13, 14, 15, 17, 18], "cifar": [7, 17], "lsun": 7, "\uc5d0\uc11c\ub294": [7, 16, 17, 18], "\ub3d9\uc791\ud588\uc9c0\ub9cc": 7, "divers": [4, 7, 15, 16], "dataset\uc5d0\uc11c\uc758": 7, "\ub3d9\uc791\uc740": 7, "\uc99d\uba85\ub418\uc9c0": 7, "\ubabb\ud588\ub2e4": 7, "\uc218\uce58": 7, "\uac1c\uc120": [7, 15], "imagenet\uac19\uc740": 7, "dataset\uc5d0\uc11c\ub3c4": 7, "\ub3d9\uc791": 7, "process\uc5d0\uc11c\uc758": 7, "term": [7, 13, 20], "\uc81c\uc548\ud558\uc600\ub2e4": 7, "\ud6e8\uc52c": [4, 7, 13], "\ub0b4\ub294": [7, 9, 12], "\ud655\uc778": [7, 10, 14, 18], "\uc5f0\uad6c\ub4e4\uc5d0\uc11c": 7, "loglikelihood": 7, "\uc218\uce58\uc640": 7, "sample\uc758": 7, "quality\uac04\uc758": 7, "\uc5f0\uad00\uc131\uc744": 7, "\ub9ce\uc558\ub2e4": 7, "distribution\uc5d0": [7, 13], "model\uc774": 7, "\uc218\uce58\ud654\ud55c": 7, "\ub290\ub08c": 7, "\uc218\uce58\uac00": 7, "\uc88b\uc544\uc9c0\uba74": 7, "quality\ub3c4": 7, "\uc99d\uac00\ud558\ub294": 7, "\uacbd\ud5a5\uc744": [7, 10, 13], "\ubcf4\uc600\ub2e4": [7, 10], "ddpm\uc5d0\uc11c\ub3c4": 7, "\uc218\uce58\ub97c": [7, 15], "\uac1c\uc120\ud55c\ub2e4\uba74": 7, "\uc99d\uac00\ud560": 7, "\uc788\uc9c0": [7, 13], "\uc54a\uc744\uae4c": 7, "angeloyeo": 7, "github": [7, 9, 12, 13, 14, 16], "2020": 7, "07": 7, "17": [7, 15], "mle": 7, "html": [7, 13], "process": [7, 12, 14, 16, 17], "\uc785\ud78c": [7, 10], "\ud615\ud0dc": 7, "denoising\uc5d0": 7, "parameter\ub85c": 7, "b_": 7, "noising\ud560": 7, "denoising\uc744": 7, "\uc544\ub798\uc640\uac19\uc774": 7, "\uc0ac\uc6a9\ud574\ub3c4": 7, "\ubcf4\uc5ec\uc11c": [7, 13], "\ubb38\uc7a5": 7, "\uc758\ubb38\uc810": 7, "\uc0ac\uc2e4": [4, 7], "\uc815": 7, "\ubc18\ub300\uc758": 7, "\uc5ed\ud560\uc744": 7, "parameter\uc778\ub370": 7, "\ubcf4\uc600\uace0": 7, "fix\ub97c": 7, "\ud558\ub294\uac8c": 7, "\ub9de\uc744\uae4c": 7, "step\uac04": 7, "\ucc28\uc774\ub97c": [7, 16], "\ube44\uad50\ud574\ubcf4\uba74": 7, "step\uc774": [7, 15], "\ub450\uac1c\uc758": [7, 13], "\uac70\uc758": [4, 7, 13], "\ub3d9\uc77c\ud574\uc9c4\ub2e4": 7, "2\ub97c": 7, "\uc131\ub2a5\uc740": 7, "\ucd08\ubc18\uc5d0": [7, 17], "\uacb0\uc815\ub418\ub294\ub370": 7, "\ucd08\ubc18\uc5d0\ub294": 7, "\uac12\uc758": 7, "\uacb0\uc815\ub418\ub294": 7, "\ubd80\ubd84": [7, 13, 14], "\uae09\uaca9\ud558\uac8c": 7, "\ub5a8\uc5b4\uc9c0\ub294": 7, "\ub450\uace0": 7, "non": [4, 7, 15], "\ub450\ub294\uac83\uc740": 7, "\uc124\uacc4\uc758": 7, "miss": 7, "\ud559\uc2b5\ud558\uae30\uc5d0\ub294": 7, "\ubc94\uc704\uac00": 7, "\ub108\ubb34": [7, 10, 13, 14], "\uc791\uc544\uc11c": 7, "interpol": [4, 7], "predict\ud558\ub3c4\ub85d": 7, "\uc124\uacc4": 7, "hybrid": [7, 15], "l_": [7, 15], "hyprid": 7, "simpl": [4, 7, 15, 19], "\u03bbl_": 7, "vlb": 7, "\uc774\ubbf8\uc9c0\uc5d0\ub300\ud574": 7, "\ub3d9\uc791\ud558\uc9c0\ub9cc": 7, "32x32": [7, 15], "64x64": [4, 7, 18, 19], "\uc54a\ub294\uac83\uc744": 7, "scheduling\uc5d0\uc11c": 7, "mode\uc758": 7, "limitation\uc774": 7, "\uc788\uc74c\uc744": [7, 12, 13], "\uc9c0\uc801": 7, "direct\ub85c": 7, "\ucd5c\uc801\ud654\ud558\ub3c4\ub85d": 7, "\uc124\uacc4\ud558\uba74": 7, "best": [7, 10, 14, 15], "\uc774\ubbf8\uc9c0\uc640\uac19\uc774": 7, "\uc790\uccb4\uac00": [7, 12], "unstable\ud574\uc11c": 7, "\ucd5c\uc801\ud654\uc5d0\ub294": 7, "\uc5b4\ub824\uc6c0\uc774": 7, "\uc904\uc774\uae30\uc704\ud574": 7, "\ub3c4\uc785": 7, "2\uc5d0\uc11c": 7, "\ub9d0\uae30\ub294": 7, "loss\uc758": 7, "\ubcc0\ud654\uc5d0": 7, "\uc601\ud5a5\uc774": 7, "\uc5c6\uc73c\ubbc0\ub85c": 7, "\ud655\ub960\uc801\uc73c\ub85c": [7, 11], "\ucd08\ubc18\uc758": 7, "sampling\ud574\uc11c": 7, "\ud559\uc2b5\ud558\ub3c4\ub85d": 7, "\uc801\uc6a9\ud574\ubcf8": 7, "\ubcf4\uc784": [7, 13, 14], "sampling\uc744": [7, 14], "\uc801\uc6a9\ud558\uba74": 7, "\uc801\uc6a9": [7, 14], "\uc804\ubcf4\ub2e4": 7, "\uc88b\uc9c0": [7, 10], "\ubcf4\uc778\ub2e4": [7, 10], "\ub2e4\uc18c": [7, 14], "\ucde8\uc57d\ud588\ub358": 7, "imagenet": [7, 12], "64x64\uc640": 7, "cidar": 7, "\uae30\uc900": [7, 14, 15], "convolut": [7, 11, 13, 14], "\ubaa8\ub378\uc774\ub098": 7, "\ubaa8\ub378\uc911\uc5d0\uc11c\ub294": 7, "\ub6f0\uc5b4\ub098\uc9c0\ub9cc": [4, 7], "fulli": [7, 13], "\ube44\ud574\uc11c\ub294": 7, "\ubd80\uc871\ud55c": [7, 16], "\uba74\uc774": 7, "speed\ub97c": 7, "\ub192\uc774\uae30": [4, 7], "\uba87\uba87": 7, "step\ub9cc": 7, "\uac00\ub3c4": 7, "fid\uac12\uc744": 7, "metric\uc73c\ub85c": 7, "biggan": [7, 15], "big": 7, "deep": [7, 18], "\ubaa8\ub378\ubcf4\ub2e4": [4, 7, 14, 19], "\ud0c0\uac9f\uc5d0": 7, "\uc218\uce58\ub098": 7, "recal": 7, "metric\uc5d0\uc11c": 7, "capacity\ub97c": 7, "\uac00\uc9c4": [7, 10, 12, 13, 14, 16, 20], "fid\uc640": [7, 15], "nll": [7, 13], "\ud06c\uae30\uc640": 7, "\ud559\uc2b5\ub7c9": 7, "\uc5b4\ub290\uc815\ub3c4": 7, "\ube44\ub840\ud568": 7, "synthesi": [8, 11, 16], "2022": [4, 8, 13, 18], "2112": 8, "10752": 8, "compvi": 8, "namkyeong": 8, "cho": 8, "31": [8, 12, 16], "\uc624\ub298": [8, 11], "\uc54c\uc544\ubcfc": [4, 8, 11, 19], "model\uc785\ub2c8\ub2e4": 8, "\ub2e4\ub918\ub358": [8, 11], "\uc720\uc0ac\ud558\uac8c": [4, 8, 19], "\ubaa8\ub378\uc785\ub2c8\ub2e4": [4, 8, 11], "\ucef4\ud4e8\ud130": 8, "\uc790\uc6d0\uc758": 8, "\uc18c\ubaa8\ub97c": 8, "\uc904\uc774\uba74\uc11c": 8, "\uc5bb\ub294\uac83\uc774": 8, "\ubaa9\ud45c\uc785\ub2c8\ub2e4": [4, 8, 19], "\uc804\ubc18\uc801\uc73c\ub85c": 8, "\uc8fc\uc5b4\uc84c\uc744\ub54c": 8, "encod": [4, 8, 14, 16, 17, 18, 19, 20], "\ud1b5\ud574\uc11c": [8, 11], "\uc778\ucf54\ub529": [4, 8], "\ud558\uace0": [4, 8], "hat": [8, 16], "\ub514\ucf54\ub529\uc744": 8, "\ud55c\ub2e4": [4, 8, 12, 15, 18], "\ub418\ub3c4\ub85d": [8, 10], "\ub300\ud574\uc11c": [4, 8, 11, 12, 13, 16, 17], "\ud14c\uc2a4\ud2b8\ub97c": 8, "\uc9c4\ud589\ud558\uc600\ub2e4": 8, "space\uc5d0\uc11c": [8, 12], "\ubd84\uc0b0\uc774": 8, "\ucee4\uc9c0\uc9c0": 8, "\uc54a\ub3c4\ub85d": 8, "divergence\uc640": 8, "vector": [4, 8, 11, 12, 14, 16], "quantiz": [8, 14], "vq": 8, "\ud65c\uc6a9\ud558\uc600\ub2e4": 8, "\uc774\ubbf8\uc9c0\uc678": 8, "\ud14d\uc2a4\ud2b8\ub098": 8, "semat": 8, "map\uacfc": 8, "\uc815\ubcf4\ub294": 8, "tau_": 8, "\uc804\ub2ec\uc744": 8, "\ud558\uc600\uace0": 8, "q": [8, 14, 15], "phi_i": 8, "z_i": [4, 8], "_k": 8, "_v": 8, "\uc815\uc758\ub418\uace0": 8, "\uc911\uac04\uc758": 8, "represent": [4, 8, 14], "project": [4, 8, 9, 15], "matrix\uc774\ub2e4": 8, "attention\uc758": 8, "value\uc5d0": 8, "\ud574\ub2f9\ud558\uba70": 8, "qk": 8, "cdot": [8, 17], "\uc5f0\uc0b0\uc774": 8, "\uc9c4\ud589\ub41c\ub2e4": 8, "\ud568\uc218\ub294": 8, "\uac19\uc774\ud45c\ud604\ub41c\ub2e4": 8, "z_t": [4, 8], "\uc8fc\ubaa9\ud560\ub9cc\ud55c": 8, "model\uc5d0\uc11c": 8, "dm": [8, 15], "function\uc73c\ub85c": [8, 14, 15], "\uc9c4\ud589\uc2dc\ud0a4\ub294\ub370": 8, "\ubc14\uafb8\uba74\uc11c": 8, "\uc591\uc744": 8, "\uc904\uc600\ub2e4\ub294": 8, "\uc810\uc774\ub2e4": [8, 15], "\uc2e4\ud5d8\uc744": 8, "\uc9c4\ud589\ud558\uc600\ub294\ub370": 8, "\uadf8\uc911": 8, "\uc77c\ubd80\ub9cc": 8, "\uc18c\uac1c\ud558\ub3c4\ub85d": 8, "\ud558\uaca0\ub2e4": 8, "dataset\uc5d0\uc11c": [8, 10, 12, 14], "\ubf51\uc740": [8, 11], "\uc0d8\ud50c\uacfc": [8, 13], "sample\ub4e4\uc785\ub2c8\ub2e4": 8, "sampl": [4, 8, 10, 15, 16, 17, 18, 20], "laion": [8, 10], "\ub098\uc628": [8, 14, 15, 18, 20], "\uc778": [4, 8], "\uc801\uc808\ud55c": 8, "\uc810\uc218\uc640": 8, "\ud6a8\uc728\uc131\uc744": 8, "\ubcf4\uc5ec\uc8fc\uc5c8\uc2b5\ub2c8\ub2e4": 8, "layout\uc774": 8, "\uc8fc\uc5b4\uc84c\uc744": 8, "\uae30\ubc18\uc73c\ub85c": [4, 8, 10, 13, 16, 20], "layout": 8, "\uc0d8\ud50c": [4, 8, 11], "lora\ub294": 9, "peft": 9, "effeci": 9, "\ud558\ub098": [9, 14], "pre": [9, 10, 12, 16], "\uace0\uc815\ud55c": 9, "\ucc44\ub85c": 9, "\uba87": [9, 12, 13, 17], "\uac1c\uc758": [9, 11, 12, 13, 14, 16], "dens": 9, "fc": 9, "layer\ub9cc": 9, "downstream": 9, "task\uc758": [9, 13], "\uc5f0\uc0b0\ub7c9\uc744": 9, "\uc904\uc77c": [9, 12], "gpt": 9, "3\uc744": 9, "\uae30\uc900\uc73c\ub85c": 9, "parameter\ub294": 9, "10000\ubc30": 9, "gpu": 9, "\uba54\ubaa8\ub9ac\ub294": 9, "3\ubc30\ub97c": 9, "latency\uac00": 9, "\uc5c6\uc74c": 9, "\ud30c\ub77c\ubbf8\ud130\ub97c": 9, "\ud29c\ub2dd\ud558\ub294": 9, "\ud30c\ub77c\ubbf8\ud130\ub9cc\uc744": 9, "\ud29c\ub2dd\ud568\uc73c\ub85c\uc368": 9, "\uc790\uc6d0\uc73c\ub85c\ub3c4": 9, "\ub192\uac8c": 9, "\uc720\uc9c0\ud558\ub294": 9, "\ubc29\ubc95\ub860": 9, "task": [4, 9, 13, 14, 17, 18], "\uc0ac\uc6a9\ud574": [4, 9, 10, 12, 18], "\ud558\ub294\uac83": 9, "upstream": 9, "\ud559\uc2b5\uc2dc\ud0a4\ub294\uac83": 9, "\uc694\uccad\uc758": 9, "\uc2dc\uc791\ubd80\ud130": 9, "\uc644\ub8cc\uae4c\uc9c0": 9, "\uac78\ub9ac\ub294": 9, "llm\uc740": 9, "\ub9de\uac8c": [4, 9], "\uc2dc\ud0b4": 9, "tuning\uc5d0\uc11c": 9, "\ud559\uc2b5\uc2dc\ud0a4\uba74": 9, "roberta": 9, "\ub2ec\uc774": 9, "\uac78\ub9bc": 9, "\uc5f0\uad6c\uc5d0\uc11c": 9, "over": [9, 13, 18], "model\ub4e4\uc740": 9, "intrins": 9, "dimension\uc5d0": 9, "\uae30\ubc18\ud558\uace0": 9, "\uc0ac\uc2e4\uc5d0": 9, "\uae30\ubc18\ud574": 9, "\uc800\uc790\ub294": [9, 12], "\uacfc\uc815\uc5d0\uc11c\ub3c4": 9, "\uac16\uace0": 9, "\uac00\uc815\ud568": [9, 14], "\uace0\uc815\ud558\uace0": [9, 14], "decomposit": 9, "matrices\ub97c": 9, "\ucd5c\uc801\ud654\ud558\ub294": [9, 17], "\uc2dc\ud0a4\uae30\ub85c": 9, "decomposition\ub41c": 9, "\ub354\ud574\uc90c": 9, "\ud06c\uae30\ub294": 9, "\uc791\uc544": 9, "cost\ub97c": 9, "\ucd5c\ub300": [9, 14], "3\ubc30\uae4c\uc9c0": 9, "\ubc14\uafd4\uc8fc\uba74": 9, "storag": 9, "requir": 9, "switch": 9, "overhead\ub97c": 9, "\uc678\uc5d0\ub3c4": 9, "\uc5c6\ub2e4": [9, 15], "\uae30\ubc95\ub4e4\uacfc": 9, "\uc801\uc6a9\uc774": [9, 11], "\uac00\ub2a5\ud558\ub2e4\ub294": 9, "\uc7a5\uc810\uc774": 9, "transformer\uc758": [9, 14], "size": [4, 9, 11, 13, 17, 18, 19, 20], "w_q": 9, "w_k": 9, "w_v": 9, "w_o": 9, "module\uc758": 9, "adapt": [9, 11], "accumulated\ub41c": 9, "\uc5f0\uad6c\uc758": 9, "convention\uc744": 9, "optimizer\ub294": 9, "adam\uc744": 9, "\uc774\uc6a9": 9, "mlp": [9, 20], "feedforward": 9, "ffn": 9, "agnostic\ud558\uc9c0\ub9cc": 9, "model\uc5d0": [9, 12], "\uc9d1\uc911\ud568": 9, "agnost": [9, 14], "\uad6c\uc560\ubc1b\uc9c0": 9, "\ud574\uc11d\uc774": 9, "max": 9, "phi": [9, 14, 15, 20], "y_t": 9, "y_": [9, 15], "parameterized\ub41c": 9, "x_i": [9, 20], "y_i": 9, "target\uc30d\uc73c\ub85c": 9, "\ub41c": [4, 9, 16], "\ub370\uc774\ud130\uc14b": [4, 9, 14, 18, 19], "token": [4, 9, 12, 14, 16], "sequenc": [4, 9], "phi_0": 9, "\ub418\uace0": [9, 10, 16, 18, 20], "objective\ub97c": [9, 12], "maximize\ud558\uae30": 9, "\uc5c5\ub370\uc774\ud2b8\ub428": 9, "task\ub97c": [9, 12, 14], "\ub9e4\ubc88": [9, 14], "\ud06c\uae30\uc758": 9, "\ud559\uc2b5\ud574": [9, 12], "\uc5c4\uccad\ub09c": 9, "cost\uac00": 9, "\ubc1c\uc0dd": [9, 16], "\ubc18\uba74": [9, 13, 15], "\uc804\uccb4\uac00": 9, "\uadf8\ubcf4\ub2e4": 9, "\ucc3e\uc544\ub0b4\ub294": 9, "\ubc14\ub00c\uae30": 9, "memori": [9, 14, 18], "effecient\ud574\uc9d0": 9, "01": 9, "\uae4c\uc9c0": [4, 9, 19], "\uc791\uc544\uc9c8": 9, "\uae30\uc874\uc5d0\ub3c4": 9, "transfer": [9, 10, 12, 16], "learning\uc5d0\uc11c": [9, 14], "effecient\ub97c": 9, "\ubc29\ubc95\uc740": [9, 12, 13, 16], "\uac00\uc9c0\uac00": 9, "perform": [9, 14, 18], "comparison": [9, 10, 15, 16, 18], "\ucd94\uac00\ud558\ub294": 9, "hardwar": 9, "parellelism\uc774": 9, "\uc5c6\ub2e4\uba74": 9, "bottleneck": [9, 14], "\ucd94\uac00\ud574\ub3c4": 9, "\uc0c1\ub2f9\ud788": [9, 12], "\uc99d\uac00\ud574": 9, "\uc0ac\uc6a9\ud558\uae30": 9, "\uc5b4\ub824\uc6e0\uc74c": 9, "prefix": 9, "tuning\uc740": [9, 12], "optimize\uac00": 9, "\uc774\ud6c4": [9, 12], "ba": 9, "\uacf1\ud574\uc9c4": 9, "vector\ub07c\ub9ac": 9, "coordin": 9, "wise\ud558\uac8c": 9, "zero": [4, 9, 14, 18], "\uc774\ub77c": 9, "alpha": 9, "scaling\ub428": 9, "learn": [9, 10, 11, 12, 13, 18], "rate\ucc98\ub7fc": 9, "tuning\ud574\uc11c": 9, "r\uacfc": 9, "\uc2e4\uc81c": [4, 9, 12, 13, 16, 17], "\uc774\ub098": 9, "\uc0ac\uc6a9\ud55c\ub2e4\uace0": 9, "actual": 9, "defin": 9, "lora_a": 9, "new_zero": 9, "num_embed": 9, "lora_b": 9, "embedding_dim": 9, "lora_alpha": 9, "matrix": 9, "requires_grad": [9, 17], "reset_paramet": 9, "initi": 9, "hasattr": 9, "same": 9, "wai": 9, "zeros_": 9, "normal_": [9, 20], "bool": 9, "merge_weight": 9, "make": 9, "sure": 9, "transpos": 9, "mark": 9, "tensor": [9, 17], "after_a": 9, "padding_idx": 9, "max_norm": 9, "norm_typ": 9, "scale_grad_by_freq": 9, "spars": [9, 14], "w_0x": 9, "bax": 9, "lora\ub97c": 9, "\uc774\uc6a9\ud558\uba74": [9, 18], "inference\uc2dc": 9, "\ud558\ub77d\uc774": 9, "\uacbd\uc6b0\uc5d4": 9, "\ucd94\uac00\ud558\uba74": 9, "overhead\uac00": 9, "\ub0ae\uc74c": 9, "\ucd5c\uc18c\ud654\ud558\uae30": [9, 13], "weight\ub9cc": 9, "\uc801\uc6a9\ud558\uace0": 9, "module\uc740": 9, "\uace0\uc815\ud568": 9, "175b\ub97c": 9, "vram\uc740": 9, "2tb\uc5d0\uc11c": 9, "350gb": 9, "checkpoint": [9, 10], "size\ub294": 9, "350gb\uc5d0\uc11c": 9, "35mb\ub85c": 9, "\uc904\uc784": 9, "\uc18d\ub3c4": 9, "\ube68\ub77c\uc9d0": 9, "bert": 9, "\ub300\ubd80\ubd84\uc758": 9, "\uacbd\uc6b0\uc5d0\uc11c": 9, "\uc88b\uc74c": [9, 14], "valid": [9, 17], "accuraci": 9, "transformer\uc5d0\uc11c": [9, 14], "matrix\uc5d0": 9, "r\uc744": 9, "\uac83\ubcf4\ub2e4": [9, 18], "matrices\uc5d0": 9, "\uc88b\uc558\uc74c": 9, "\ub274\ub7f4\ub124\ud2b8\uc6cc\ud06c\uc758": 9, "inner": 9, "activation\uc744": 9, "\uc904\uc774\uae30\ub3c4\ud558\uace0": 9, "\ub298\ub9ac\uae30\ub3c4\ud558\ub294": 9, "\uc5b4\ub311\ud130\ub97c": 9, "\uc911\uac04\uc5d0": 9, "\uc0bd\uc785\ud558\ub294": 9, "lora\ubcf4\ub2e4": 9, "\uc0ac\uc6a9\ud558\uba74\uc11c": [9, 12], "\uc54c\ub824\uc838\uc788\uc73c\uba70": 9, "3\ub97c": 9, "\ud588\uc744\ub54c": 9, "\ubcf4\ub2e4\ub3c4": [9, 18], "\uc88b\ub2e4": [4, 9, 15], "\uc8fc\uc7a5\ud558\uace0": 9, "\ud559\uc2b5\uc2dc\uac04\ub3c4": 9, "\uc9e7\uc544": 9, "a100": [9, 16], "\ud558\ub098\ub85c": [9, 12, 20], "30\ubd84\ub9cc\uc5d0": 9, "\ud29c\ub2dd\ud560": 9, "loralib": 9, "\uc124\uce58": 9, "pip": 9, "instal": 9, "altern": [9, 17], "git": 9, "com": [4, 9, 12, 13, 14, 16], "microsoft": 9, "\ub300\uccb4": 9, "befor": 9, "in_featur": 9, "out_featur": 9, "after": 9, "add": [9, 16], "pair": [4, 9, 18], "parameter\ub9cc": 9, "bigmodel": 9, "string": 9, "lora_": 9, "mark_only_lora_as_train": 9, "loop": 9, "dataload": [9, 17], "checkpoint\ub97c": [9, 10], "\uc800\uc7a5\ud560": 9, "\ub54c\uc5d4": 9, "state_dict": 9, "\uc800\uc7a5\ud558\uac8c": 9, "save": 9, "checkpoint_path": 9, "lora_state_dict": 9, "\ubd88\ub7ec\uc62c": 9, "load_state_dict": 9, "strict": 9, "load": [9, 16], "ckpt_pretrain": 9, "pt": [9, 14], "Then": [4, 9], "ckpt_lora": 9, "llm": [9, 18], "\ud29c\ub2dd": 9, "gpu\ub85c": [9, 10], "\uac00\ub2a5\ud560\uae4c": 9, "\uc18c\uac1c\ud569\ub2c8\ub2e4": [4, 9, 16, 19], "www": [4, 9, 14], "youtub": [4, 9, 14], "watch": [4, 9, 14], "da": 9, "nhctrrve": 9, "your": 10, "One": [10, 12], "shot": [4, 10, 14, 18], "2303": 10, "03231": 10, "1812": [10, 11], "04948": [10, 11], "03231v2": 10, "cs": [10, 12], "cv": [10, 12], "mar": 10, "sty": 10, "lize": 10, "ne": 10, "\ud55c\uc7a5\uc758": 10, "\uc2a4\ud0c0\uc77c\uc744": [10, 13], "\uc785\ud788\uace0\uc790\ud558\ub294": 10, "\ud65c\ubc1c\ud788": 10, "\uc9c4\ud589\uc911\uc774\ub2e4": 10, "\uc774\uc804\uae4c\uc9c0\uc758": 10, "\uc5f0\uad6c\ub4e4\uc740": 10, "\ud55c\uc7a5\uc529\uc744": 10, "\ud65c\uc6a9\ud558\ub824\ub294": 10, "\uc2dd\uc774": 10, "\uc8fc\ub97c": 10, "\uc774\ub8e8\uc5c8\ub2e4": 10, "\ubc29\uc2dd\uc5d0\ub294": 10, "\uc788\ub294\ub370": 10, "face\ub97c": 10, "\uc758\uc874\ub3c4\uac00": 10, "\ucee4\uc11c": [10, 13], "style\uc744": [10, 12], "\uc785\ud788\uae30": 10, "\ud798\ub4e4\ub2e4": 10, "space\uc548\uc5d0\uc11c": 10, "content": [4, 10, 19], "\uc815\ubcf4\uc640": 10, "entangl": [10, 11, 16], "\ub418\uc5b4\uc788\ub2e4": 10, "styo\ub294": 10, "\ud3ec\uc6a9\ud558\ub294": 10, "base\ubaa8\ub378\ub85c": 10, "\ucc44\uc6a9\ud55c\ub2e4": 10, "\ucd1d": [4, 10, 11, 12, 13], "stage\ub85c": 10, "\uad6c\uc131\ub418\ub294\ub370": 10, "disentangl": 10, "learner": 10, "idl": 10, "\ubd84\ub9ac": 10, "grain": 10, "control": [10, 11], "fcc": 10, "idl\ub85c\ubd80\ud130": 10, "\ubd84\ub9ac\ub41c": 10, "content\uc640": 10, "\uc6d0\ud558\ub294\ub300\ub85c": 10, "\uc7ac\uc870\ud569": 10, "src": 10, "detail\ud55c": 10, "\uc815\ubcf4": 10, "color": [4, 10, 16, 19], "\uc720\uc9c0\ud558\uae30\uc704\ud574": 10, "map\uc744": 10, "\uc7ac\uc0ac\uc6a9\ud558\ub294": 10, "trick\uc744": 10, "\uc81c\uc548\ud588\ub2e4": 10, "one": [10, 13], "sota\ub97c": [10, 14, 15], "\uae30\ub85d\ud588\ub2e4": 10, "gan\uc774": [10, 12], "\ubd84\uc57c\ub97c": 10, "\uc7a5\uc545\ud558\ub358": 10, "\ub4f1\uc7a5\uc73c\ub85c": 10, "\uc8fc\ubaa9\uc744": [10, 18], "\uc2dc\uc791\ud588\ub2e4": 10, "prompt\ub97c": [10, 12], "manipul": [4, 10], "\uac00\ub2a5\ud574\uc84c\uc9c0\ub9cc": 10, "\ubd80\ubd84\uae4c\uc9c0": 10, "control\ud558\uae30\uc5d0\ub294": 10, "\uc788\uc5c8\ub2e4": 10, "fine\ud55c": 10, "\uc815\ubcf4\uae4c\uc9c0": 10, "model\uc774\ub2e4": 10, "\ubcf4\uc774\uba74\uc11c": 10, "stylegan\uc744": 10, "\ubca0\uc774\uc2a4\ub85c": 10, "dataset\uc744": [10, 18], "\uc758\uc874\uc131\uc774": 10, "\ucee4": 10, "artist": 10, "\uc785\ud788\ub294\ub370": 10, "\ud55c\uacc4\ub97c": [10, 13], "\uac1c\uc120\ud55c": 10, "\uac04\uc758": [10, 13], "transfer\ub97c": 10, "disentagl": 10, "\uc81c\uc548\ud55c\ub2e4": [10, 12, 15], "\ubd84\ub9ac\ud558\ub294": 10, "s_": 10, "tgt": 10, "portrait": [4, 10], "\ubc18\ub300": [10, 13], "\uc548\uc5d0": [10, 18], "a\uc758": [10, 11], "conext": 10, "\ubc30\uc81c\ud568\uacfc": 10, "\ud3ec\ud568\ud558\uae30\uc704\ud574": 10, "\uc55e\uc5d0": [10, 13, 15], "negat": 10, "\ubd80\uc815\uc758": 10, "\uc758\ubbf8\ub97c": 10, "\ub2e8\uc5b4": [10, 12], "except": 10, "auxiliari": [10, 18], "\uc14b\uc744": [10, 12], "\uad6c\uc131\ud574": 10, "aux": 10, "ffhq": [10, 11], "\uc784\uc758\ub85c": 10, "\ud6a8\uacfc": [10, 13, 18], "\ud559\uc2b5\ud568\uc73c\ub85c\uc368": [10, 12, 17], "prompt\uac04": 10, "disentanglement\ub97c": 10, "\ud5a5\uc0c1": [10, 14], "\uc774\ubbf8\uc9c0\uc5d0\ub294": 10, "\uc5c6\ub294": [10, 13, 15, 16, 18], "\uc774\ubbf8\uc9c0\ub9cc\uc758": 10, "\uc8fc\uc785": 10, "style\uacfc": [10, 11], "\uad6c\ubcc4\ud558\ub294\ub370": 10, "\ub3c4\uc6c0\uc744": 10, "\uc90c": 10, "idl\uc758": 10, "\ud559\uc2b5\ub9cc\uc73c\ub85c": 10, "transfer\uac00": 10, "\uc774\ubbf8\uc9c0\ucc98\ub7fc": 10, "facial": [4, 10], "\uc783\uc5b4\ubc84\ub9ac\ub294": 10, "\ubb38\uc81c\uc810\uc744": [10, 14, 16], "\uac1c\uc120\ud558\uae30\uc704\ud574": 10, "\ub3c4\uc785\ud558\uc600\ub2e4": 10, "idl\ub85c": 10, "\uc870\ud569": 10, "recombin": 10, "\uc720\uc9c0\ud558\ub3c4\ub85d": 10, "trick": 10, "ldm\uc740": [10, 12], "\uc8fc\uc785\ud558\uae30\uc704\ud574": 10, "mechanism\uc744": 10, "promt": 10, "paper\uc5d0\uc11c": 10, "m\uc758": 10, "layout\uc5d0": 10, "\uac15\ud55c": 10, "\ubbf8\uce5c\ub2e4": 10, "\uc810\uc744": 10, "mask\ub97c": 10, "\uacfc\uc815\uc5d0": 10, "\uc8fc\uc785\ud569\uc73c\ub85c\uc368": 10, "\uc720\ub3c4": [10, 15], "map\uc758": 10, "replace\ud558\uc9c0\uc54a\uace0": 10, "content\uc5d0": 10, "index\ub9cc": 10, "\uc120\ud0dd\uc801\uc73c\ub85c": 10, "replac": 10, "index": [10, 12], "time\uc5d0\uc11c": 10, "n\ubc88": 10, "\uc0ac\uc6a9\ud568\uc73c\ub85c\uc11c": 10, "\uac15\ud558\uac8c": 10, "n_": 10, "\uc2e4\ud5d8\uc0c1": 10, "\uc774\ud558\uc758": [10, 16], "\ucd94\ucc9c": 10, "5b": 10, "ak47": 10, "m4a1": 10, "adam": 10, "400": 10, "ldm\uacfc": 10, "\ub3d9\uc77c": [10, 13], "sota": [4, 10, 14, 18], "styo\uac00": 10, "identity\uc640": 10, "local": 10, "\uc720\uc9c0\ud568\uacfc": 10, "\uc790\uc5f0\uc2a4\ub7fd\uac8c": 10, "\uacb0\uacfc\ubb3c\uc744": 10, "\uc0dd\uc131\ud574\ub0b8\ub2e4": [10, 12], "user": [10, 12], "study\ub3c4": 10, "\ubaa8\ub378\ub4e4\uc5d0": 10, "effect": [4, 10, 11, 19], "contrast": [10, 14, 18], "templat": 10, "\ub123\uace0": 10, "\ud559\uc2b5\ud560\uacbd\uc6b0": 10, "overfitting\uc774": 10, "\uc2ec\ud558\uace0": 10, "\uc815\ubcf4\uc758": 10, "\ubd84\ub9ac\uc5d0": 10, "\uc5b4\ub824\uc6c0\uc744": [10, 14], "detail\uc744": [10, 12], "set\uc758": 10, "trick\ub3c4": 10, "\uc801\uc6a9\ud558\ub294\uac83\uc774": 10, "\uc0dd\uc131\ud574\ub0c8\ub2e4": 10, "inference\ud560": 10, "diversity\ub97c": 10, "\ubcf4\uc774\uc9c0\ub9cc": 10, "fcc\ub97c": 10, "\ud3ec\ud568\ud560": 10, "fidelity\uac00": [10, 12, 15, 18], "\ub192\uc544\uc838": 10, "significant\ud55c": 10, "\uc0dd\uc131\ub418\ub294\uac83\uc744": 10, "photorealistic\uc5d0\uc11c": 10, "artistic\ud558\uac8c": 10, "\ubc14\ub00c\uace0": 10, "\ub9c8\ucc2c\uac00\uc9c0\ub85c": [10, 12], "\ub098\uc624\ub294": [10, 14, 15, 16], "idl\uacfc": 10, "gan\uc744": [10, 11, 13], "\ubaa8\ub378\ub4e4\ubcf4\ub2e4": 10, "\uc790\uc5f0\uc2a4\ub7fd\uace0": 10, "\uc0dd\uc131\ud574\ub0bc": 10, "singl": [10, 12], "10\ubd84\uc774": 10, "\uac78\ub9ac\ubbc0\ub85c": 10, "efficiency\uac00": 10, "\ubabb\ud558\ub2e4\ub294": 10, "\ub2e8\uc810\uc774": 10, "2019": 11, "huangzh13": 11, "12": [11, 13, 17, 20], "stylegan\uc785\ub2c8\ub2e4": 11, "gan\uacfc": 11, "\ubcc0\uacbd\ud568\uc73c\ub85c\uc368": 11, "\uc62c\ub9ac\uace0": 11, "feature\uc758": 11, "control\uc774": 11, "loss\ub098": 11, "discrimin": [11, 13, 17], "\uac1c\uc120\uc5d0": 11, "\ub17c\ubb38\uc740": [11, 13, 16], "\uc544\ub2d9\ub2c8\ub2e4": [4, 11], "\ubcf4\ub3c4\ub85d": 11, "\ud558\uc8e0": 11, "\ub17c\ubb38\uc758": [11, 15, 20], "contribution\uc740": 11, "\uc81c\uc548\ud558\uc5ec": 11, "\ub192\uc774\uba74\uc11c": 11, "\uac00\ub2a5\ud574\uc84c\uc2b5\ub2c8\ub2e4": 11, "\ub370\uc774\ud130\uc14b\uc744": 11, "\uc81c\uc548\ud588\uc2b5\ub2c8\ub2e4": 11, "\uc911\uc5d0\uc11c": [11, 14], "contribution\uc744": [11, 15], "abstract\uc5d0\ub294": 11, "\ubb38\uc7a5\uc774": 11, "The": [4, 11], "lead": 11, "automat": [4, 11, 19], "unsupervis": [11, 13], "level": 11, "attribut": [4, 11, 19], "ident": [11, 13, 16], "when": [11, 17, 18], "face": [4, 11, 17], "freckl": 11, "enabl": [11, 12], "intuit": 11, "\uc81c\uc548\ud55c": 11, "\uad6c\uc870\uac00": 11, "\uc77c\uc744": 11, "\uc124\uba85\ud558\ub294": [11, 12, 13], "\ubd80\ubd84\uc785\ub2c8\ub2e4": 11, "\ubcf4\uc2dc\uba74": 11, "attribute\uc758": 11, "separation\uc774": 11, "\uc598\uae30\ud558\uace0": 11, "\uc800\ub294": [4, 11], "\uac1c\uc778\uc801\uc73c\ub85c": [4, 11], "\ubd80\ubd84\uc774": 11, "stylegan\uc758": 11, "\ud2b9\uc9d5\uc774\ub77c\uace0": 11, "\uc0dd\uc131\ud558\uace0\uc790": [11, 20], "\uc0ac\uc6a9\uc790\ub294": [11, 12], "\uc5b4\ub5a0\ud55c": [11, 16], "\ubaa9\uc801\uc744": 11, "\uac00\uc9c0\uace0": [4, 11, 13, 14, 17, 20], "\uc790\uc2e0\uc774": 11, "\ub9cc\ub4e4\uace0\uc790": 11, "\ud488\uc9c8\uc774": 11, "\uc88b\ub354\ub77c\ub3c4": 11, "\uc0ac\uc6a9\uc790\uc758": 11, "\uc758\ub3c4\uc640": 11, "\uc0c1\uad00\uc5c6\ub294": 11, "\ub79c\ub364\ud55c": 11, "\ub0b4\ubc49\uc5b4\uc900\ub2e4\uba74": 11, "\uc2e4\uc6a9\uc131\uc774": 11, "\uc88b\ub2e4\uace0": 11, "\uc5c6\uc744": [4, 11, 18, 19], "\uadfc\ub798\uc5d0": 11, "\uc778\uae30\ub97c": 11, "\uc5bb\uc5c8\ub358": 11, "\uc774\uc720\ub3c4": 11, "\ub204\uad6c\ub098": 11, "\uc27d\uac8c": [11, 12], "\ud14d\uc2a4\ud2b8\ub97c": [4, 11, 12], "\uc810\ub3c4": 11, "\ud55c\ubaab\ud588\ub2e4\uace0": 11, "stylegan\uc740": 11, "controllability\ub97c": 11, "\ubaa8\ub378\uc774\ub77c\ub294": 11, "\uce21\uba74\uc5d0\uc11c": 11, "\uc758\ubbf8\uc788\ub2e4\uace0": 11, "network\ub294": 11, "\ud574\uc0c1\ub3c4\ub97c": [4, 11, 19], "4x4\uc5d0\uc11c": 11, "1024x1024\uae4c\uc9c0": 11, "\ub192\uc5ec\uc90d\ub2c8\ub2e4": 11, "1024x1024": [4, 11, 19], "\uac16\uac8c\ub429\ub2c8\ub2e4": 11, "gan\ud558\uace0": 11, "\ube44\uad50\ud574\uc11c": [11, 14], "\ud2b9\uc774\ud55c": 11, "\uc810\uc774": 11, "\uc138": [4, 11, 13, 16], "z\ub97c": 11, "noise\uc640": 11, "\ud569\uc2dc\ub2e4": 11, "\uc0dd\uac01\ud574\ubcf4\uba74": 11, "generator\ub97c": [11, 17], "\uac70\uccd0\uc11c": 11, "\uad6c\uc870\uc785\ub2c8\ub2e4": 11, "z\ub294": 11, "distribution\uc5d0\uc11c": [11, 15], "\uc0d8\ud50c\ub9c1\uc73c\ub85c": 11, "\uc5bb\uc2b5\ub2c8\ub2e4": 11, "distribution\uc73c\ub85c": 11, "\ubcf4\ub0b4\ub294": 11, "\ubc30\uc6b0\uac8c": 11, "\ub420": [11, 12], "\uac83\uc774\uace0": 11, "\ubd84\ud3ec\ub294": 11, "\ucc98\ub7fc": [4, 11, 13, 14, 19], "\uc0dd\uae30\uac8c": 11, "\uc8fc\uc5b4\uc838\uc11c": 11, "\uc5c6\uac70\ub098": 11, "\uc801\uc744": 11, "\uc608\ub97c": [4, 11, 13, 19], "\ub4e4\uc5b4": [11, 13], "\ub370\uc774\ud130\uc5d0": 11, "\ud53c\ubd80\uac00": 11, "\ud76c\uba74\uc11c": 11, "\uba38\ub9ac\uac00": 11, "\uae34": 11, "\uc0d8\ud50c\ub4e4\uc774": 11, "\uc5c6\ub2e4\uace0": [4, 11], "\ud574\ubd05\uc2dc\ub2e4": 11, "\ud53c\ubd80\uc0c9\uacfc": 11, "\uba38\ub9ac": 11, "\uae38\uc774\ub77c\ub294": 11, "feature\ub294": 11, "\uc11c\ub85c": [4, 11, 13], "\uc5bd\ud788\uac8c": 11, "\ub418\uc5b4": [4, 11, 17], "\ud558\ub098\ub97c": [11, 18], "\ubc14\uafc0": [11, 13], "\ud558\ub098\ub3c4": [11, 12], "\ubc14\ub00c\ub294": 11, "\uc77c\uc5b4\ub098\uac8c": 11, "\uc644\ud654\ud558\uae30": 11, "gaussian\uc5d0\uc11c": 11, "learnabl": [11, 16], "w\ub97c": 11, "\uc0ac\uc6a9\ud569\ub2c8\ub2e4": [11, 16], "instanc": [11, 13, 16], "normalization\uc740": 11, "\ucc44\ub110\ub9c8\ub2e4": 11, "\uc815\uaddc\ud654\ub97c": 11, "\ucde8\ud574\uc8fc\ub294": 11, "\ubc29\ubc95\uc785\ub2c8\ub2e4": 11, "normalization\uc5d0": 11, "scale\uc744": [11, 15], "\uacf1\ud574\uc8fc\uace0": 11, "\ub354\ud574\uc8fc\ub294": 11, "vector\uc758": 11, "transformation\uc73c\ub85c": 11, "\uc8fc\uc5b4\uc9c0\ub294": 11, "w\ub294": 11, "\ubcf4\ub0b4\uc9c0\uac8c": 11, "adain\uc758": 11, "\uc218\uc2dd\uc740": 11, "adain\uc740": 11, "\ube14\ub85d\ub9c8\ub2e4": 11, "\uac1c\uc529": 11, "\ub4e4\uc5b4\uac00\uc11c": [11, 12], "style\uc740": 11, "\uc5f4\uc5ec\ub35f": 11, "\ubc88": 11, "adain\uc744": 11, "generator\uc5d0": [11, 12], "\ub4e4\uc5b4\uac00\uac8c": [4, 11, 19], "localization\uc774\ub77c\ub294": 11, "\ud2b9\uc9d5\uacfc\ub3c4": 11, "\uc5f0\uad00\uc774": 11, "\ub9d0\ud558\ub294": 11, "localization\uc774\ub780": 11, "\uc77c\ubd80\ub97c": 11, "\ubc14\uafc8\uc73c\ub85c\uc368": 11, "\ud2b9\uc9d5\ub4e4\uc744": 11, "\uc758\ubbf8\uc785\ub2c8\ub2e4": 11, "\ub2e4\uc74c\uc5d0": 11, "map\ub4e4\uc740": 11, "normalization\ub418\uace0": 11, "style\uc5d0": 11, "\uc758\ud574": [11, 13, 16], "statistics\ub97c": 11, "\uac00\uc9c0\uac8c": 11, "convolution\uc5d0": 11, "\uc801\uc6a9\ub418\uace0": 11, "\ub2e4\uc74c": [11, 12, 13, 18], "convolution\uc5d0\uc11c": 11, "normalization\uc774": 11, "\uc218\ud589\ub418\uae30": 11, "layer\uc5d0": 11, "\uc801\uc6a9\ub41c": [11, 13], "style\uc774": 11, "\ubd84\ub9ac\ub418\uac8c": 11, "\ud559\uc2b5\ub420": 11, "\uad00\ub828": 11, "\ucf54\ub4dc": 11, "stylemod": 11, "latent_s": 11, "use_wscal": 11, "lin": 11, "equalizedlinear": 11, "gain": 11, "n_channel": 11, "view": [11, 16, 17, 20], "layerepilogu": 11, "thing": 11, "each": [4, 11, 16], "dlatent_s": 11, "use_nois": 11, "use_pixel_norm": 11, "use_instance_norm": 11, "use_styl": 11, "activation_lay": 11, "noiselay": 11, "activ": 11, "pixel_norm": 11, "pixelnormlay": 11, "instance_norm": 11, "instancenorm2d": 11, "top_epi": 11, "ordereddict": 11, "style_mod": 11, "dlatents_in_slic": 11, "assert": 11, "b\uc758": 11, "style\ub85c": 11, "\ubcc0\uacbd\ud574\uc11c": 11, "\uc774\ubbf8\uc9c0\ub4e4\uc785\ub2c8\ub2e4": 11, "18\uacf3\uc5d0\uc11c": 11, "\uc0ac\uc6a9\ub418\ub294\ub370": 11, "\ucc98\uc74c": 11, "4\uacf3": 11, "coars": 11, "\uadf8\ub2e4\uc74c": 11, "middl": [4, 11, 19], "10\uacf3": 11, "64": [11, 18], "1024": [11, 14, 17, 18], "\uc815\uc758\ud558\uc600\uc2b5\ub2c8\ub2e4": 11, "\uadf8\ub9bc\uc744": [4, 11, 13], "\uc717": [11, 13], "\ubd80\ubd84\uc5d0\uc11c\ub294": 11, "\ud3ec\uc988\ub098": 11, "\uc2a4\ud0c0\uc77c\uac19\uc774": 11, "\uc544\ub798\ub85c": 11, "\uac08\uc218\ub85d": 11, "\ud2c0\uc744": 11, "\uc720\uc9c0\ud558\uba74\uc11c": 11, "\uc138\ubd80\uc801\uc778": [11, 13], "\ubd80\ubd84\ub4e4\uc744": 11, "b\uc5d0\uc11c": [11, 18], "\uac00\uc838\uc654\uc74c\uc744": 11, "\uc0ac\ub78c\uc758": [4, 11], "\uc548\uc5d0\ub294": 11, "\ubc14\ub014": 11, "\uc8fc\uadfc\uae68": 11, "\uba38\ub9bf\uacb0": 11, "\ud53c\ubd80": 11, "\ubaa8\ub378\ub9c1\ud558\uae30": 11, "\uc704\ud574\uc11c": [4, 11, 13], "\ub354\ud574\uc9d1\ub2c8\ub2e4": 11, "\uc548\uc5d0\uc11c\ub3c4": 11, "\ub514\ud14c\uc77c\ub4e4\uc740": 11, "\ub2ec\ub77c\uc9c8": 11, "deviation\uc744": 11, "\uad6c\ud574\ubd24\uc744": 11, "\uc5bc\uad74\ud615\uacfc": 11, "attribute\ub294": 11, "\ubcc0\ud558\uc9c0\uc54a\uc9c0\ub9cc": 11, "noise\uc5d0": 11, "\uc758\ud574\uc11c": 11, "\uba38\ub9ac\uce74\ub77d\uacfc": 11, "\uc0dd\uae40\uc744": 11, "\uc900": [11, 15], "\uc8fc\uc9c0": 11, "\uc5d0\ub9cc": 11, "\uacbd\uc6b0\uc785\ub2c8\ub2e4": 11, "\uba38\ub9ac\uce74\ub77d\uac19\uc740": 11, "\ub514\ud14c\uc77c\uc774": 11, "\uc81c\ub300\ub85c": 11, "\uc0b4\uc544\uc788\uc9c0": 11, "layers\uc5d0": 11, "\ub4e4\uc5b4\uac04": 11, "\uba38\ub9ac\uce74\ub77d\uc758": 11, "\uc138\ubc00\ud55c": 11, "\ubd80\ubd84\uc5d0": [11, 20], "\ub07c\uce5c\ub2e4\ub294": 11, "localization\uc774": 11, "\ub418\uac8c\ud558\uae30": 11, "mixing\uc774\ub77c\ub294": 11, "\uc55e": 11, "\ucabd": 11, "layer\uc5d0\ub294": 11, "\ub4a4": 11, "generator\uac00": [11, 13], "\uc778\uc811\ud55c": 11, "style\ub07c\ub9ac": 11, "correlated\ub418\uc5b4\uc788\ub2e4\uace0": 11, "\ub9c9\uc544\uc11c": 11, "localization\uc744": 11, "\ub418\uac8c": 11, "\ubaa9\uc801\uc785\ub2c8\ub2e4": [11, 20], "\uc800\uc790\ub4e4\uc774": [11, 18], "\ubc29\ubc95\ub4e4\uc774": 11, "\ud6a8\uacfc\uac00": 11, "\uc788\uc5c8\ub294\uc9c0": 11, "\ud655\uc778\ud574\ubd05\uc2dc\ub2e4": 11, "\ud45c\uc640": 11, "\uc2e4\ud5d8\uc801\uc73c\ub85c": [11, 18], "\ubcf4\uc558\uc744": [11, 13], "\ubc29\ubc95\ub4e4\uc744": 11, "fid\uac00": [11, 15], "\uc6b0\uc218\ud558\uac8c": 11, "variou": [11, 15, 21], "design": [11, 17, 20], "worth": 12, "2208": [12, 16], "01618": 12, "devocean": 12, "blog": [4, 12], "techboarddetail": 12, "page": 12, "id": 12, "164320": 12, "boardtyp": 12, "writer": 12, "searchdata": 12, "sam56903": 12, "subindex": 12, "idlist": 12, "pnwriterid": 12, "kwang": 12, "su": 12, "mun": [12, 13], "5\uc7a5\uc73c\ub85c": 12, "\uac1c\ub150": [12, 16], "\ub610\ub294": [12, 13], "\ucf58\uc149\ud2b8": 12, "concept": [12, 18], "\uad00\ub828\ub41c": [12, 13], "\ubf51\uc544\ub0b4\ub294": 12, "\uc790\uc5f0\uc5b4\ub97c": 12, "creation\uc5d0": 12, "\uc804\ub840\uc5c6\ub294": 12, "\uc790\uc720\ub3c4\ub97c": 12, "\uc8fc\uc5c8\ub2e4": 12, "contept\ub97c": 12, "\uc0dd\uc131\ud558\uace0": [12, 14, 16], "\uadf8\uac83\uc758": 12, "\ubc14\uafb8\uac70\ub098": 12, "\uc5ed\ud560\uc774": 12, "\uc8fc\uc5b4\uc9c0\uac70\ub098": 12, "\ucc38\uc2e0\ud55c": 12, "\uc7a5\uba74\uc774": 12, "\uadf8\ub824\uc9c0\ub294\uac74": 12, "\ubd88\ubd84\uba85\ud558\ub2e4": 12, "\uc774\uac83\uc744": 12, "\uadf8\ub824\uc918": 12, "\ub9d0\ud560": 12, "\uc774\uac83": 12, "\uc124\uba85\uc744": 12, "\uac83\uc774\ub0d0\ub294": 12, "\ubb3c\uc74c\uc5d0\ub294": 12, "\uac19\ub2e4": [12, 15, 18], "5\uac1c\ub9cc\uc73c\ub85c": 12, "\uc0ac\ubb3c\uc774\ub098": 12, "\uc2a4\ud0c0\uc77c\uacfc": 12, "\uace0\uc815\ub41c": [12, 17], "\uc790\uc5f0\uc5b4": 12, "\ubb38\uc7a5\uc5d0": [12, 13], "\ub179\uc544\ub4e4\uc5b4\uac00": 12, "\uc9c1\uad00\uc801\uc778": 12, "\ubc29\ubc95\uc73c\ub85c": [4, 12, 15], "\uac1c\uc778\ud654\ub41c": 12, "\uc774\ub04c\uc5b4": 12, "\ub0b8\ub2e4": 12, "\ud2b9\ud788": [4, 12, 13, 18], "\ub3c5\uc790\uc801\uc774\uba74\uc11c": 12, "\ucf58\uc149\ud2b8\ub97c": 12, "capture\ud558\uae30": 12, "\uc704\ud574\uc11c\ub294": [12, 14], "\ucda9\ubd84\ud558\ub2e4\ub294": 12, "\uc54c\uac8c": 12, "\ub418\uc5c8\ub2e4": 12, "\ub300\uaddc\ubaa8": 12, "\uac1c\ub150\uc744": 12, "\ub3c4\uc785\ud558\ub294": [12, 13], "\uc77c\uc740": 12, "\uc77c\uc774\ub2e4": 12, "\uac1c\ub150\uc5d0": 12, "\ud655\uc7a5\ub41c": 12, "retraining\ud558\ub294": 12, "\uc5c4\uccad\ub098\uac8c": 12, "\ube44\uc6a9\uc774": 12, "\ub9ce\uc774": [4, 12, 15, 17], "\ub4e4\uace0": 12, "\uc608\uc81c\uc5d0": 12, "\ud574\uc11c": [4, 12, 15, 17], "\uce58\uba85\uc801\uc778": 12, "\ub9dd\uac01\uc744": 12, "\ucd08\ub798\ud55c\ub2e4": 12, "\uc800\uc790\ub4e4\uc740": [4, 12, 14, 15, 18], "\uc0ac\uc804": [4, 12, 16], "\uc784\ubca0\ub529": 12, "\uacf5\uac04\uc5d0\uc11c": 12, "\ub2e8\uc5b4\ub97c": 12, "\uadf9\ubcf5\ud560": 12, "figure\uc5d0\uc11c": 12, "tokenizer\ub97c": 12, "\uc9c0\ub098\uba74\uc11c": 12, "508": 12, "701": 12, "\ud615\ud0dc\uc758": [12, 16], "set\uc73c\ub85c": [12, 14], "\ubcc0\ud658\ub418\uace0": 12, "\ud1a0\ud070\uc740": [12, 14], "\uc790\uccb4": 12, "\ubca1\ud130\ub85c": 12, "\ubca1\ud130\ub294": 12, "\ub2e4\uc6b4\uc2a4\ud2b8\ub9bc": 12, "\uc81c\uacf5\ub428": 12, "concept\ub97c": 12, "\ub098\ud0c0\ub0b4\ub294": [12, 13], "word\uc778": 12, "\ub098\ud0c0\ub0b8\ub2e4": 12, "vector\ub294": 12, "\ub2e8\uc5b4\uc640": 12, "\ucc98\ub9ac\ub418\uba70": 12, "query\ub97c": 12, "\uad6c\uc131\ud558\ub294\ub370": 12, "\uc0ac\uc6a9\ub420": [12, 13], "query\ub294": 12, "\uc0ac\uc6a9\uc790\uac00": 12, "\uc758\ub3c4\ud55c\ubc14\uc640": 12, "\uc77c\uce58\ud558\ub3c4\ub85d": 12, "\uc0dd\uc131\ud558\ub3c4\ub85d": 12, "\uc804\ubc18\uc801\uc778": [12, 16], "\uadf8\ub9bc\uc774\ub77c\uace0": 12, "\uc0dd\uc131\ubaa8\ub378": 12, "\uc5ec\uae30\uc11c\ub294": 12, "ldm\uc774": 12, "\uc4f0\uc784": 12, "untouched\ub418\uc5b4": 12, "\ub530\ub85c": [12, 13], "\uc218\uc815\uc774": 12, "\ub4e4\uc5b4\uac00\uc9c0": 12, "\uc54a\ub294\ub4ef\ud568": 12, "\uadf8\ub807\uac8c": 12, "\ud568\uc73c\ub85c\uc368": [4, 12, 19], "\uc77c\ubc18\uc801\uc73c\ub85c": 12, "\uc190\uc2e4\ub418\ub294": 12, "text\uc5d0": [12, 14], "\uc774\ud574\ub3c4\ub098": 12, "generalization\uc744": 12, "\uc720\uc0ac\ub2e8\uc5b4": 12, "\ucc3e\uae30": 12, "inversion\uc2dc\ucf1c": 12, "\ud504\ub808\uc784\ud654": 12, "5\uac1c\uc758": 12, "set\uc774": [12, 13], "\uc8fc\uc5b4\uc9c4\ub2e4": 12, "\ubb38\uc7a5\uc744": 12, "\uc124\uc815\ud574": 12, "\uc8fc\uc5b4\uc9c4": [4, 12, 14], "\uc7ac\uad6c\uc131": 12, "\uc774\uc5b4\uc9c0\ub294": 12, "embedding\uc744": [12, 15], "\ucc3e\ub294": [12, 13], "\ubaa9\ud45c\ub85c": [12, 13, 16], "\ubaa9\ud45c\ub294": 12, "concept\uc778": 12, "\uc785\ub825": [4, 12, 13, 16, 19, 20], "\ud55c\ub2e4\uace0": 12, "found": 12, "through": [4, 12], "which": [4, 12, 18], "we": [4, 12, 16], "palavra": 12, "\ubc14\uafb8\ub294\ub370": 12, "\uae30\uc220\ub85c": 12, "\ucd94\uc815": 12, "\uc774\uc6a9\ud574\uc11c": 12, "object\uc758": 12, "\ubcf5\uad6c": 12, "segmentation\uc744": 12, "\uc218\ud589": [4, 12, 14, 17], "palavra\ub294": 12, "\uac1c\uccb4\ub97c": 12, "\ucc38\uc870\ud558\ub294": 12, "clip\uc758": 12, "word\ub97c": 12, "\uc2dd\ubcc4\ud568": 12, "\uac80\uc0c9\uc744": 12, "\uc124\uba85\ud558\uac70\ub098": 12, "\uc7a5\uba74\uc5d0\uc11c": 12, "\ubd84\ud560\ud558\uae30": 12, "\uc0ac\uc6a9\ub428": 12, "5\uc5d0\uc11c": [12, 13], "\ubcf4\ub4ef\uc774": 12, "\uadf8\ub4e4\uc758": [4, 12], "\uc811\uadfc": 12, "\uadf8\ub7f4\ub4ef\ud55c": 12, "\ud569\uc131\uc5d0": [12, 18], "\ud544\uc694\ud55c": [4, 12, 13], "\uc138\ubd80": 12, "\ucea1\ucc98\ud558\uc9c0": 12, "our": [12, 14, 21], "goal": 12, "specifi": 12, "\uc758\uc5ed": 12, "\uc720\uc800\uac00": 12, "\uc758\ub3c4\ud55c": 12, "\ucd08\ucca8\uc744": 12, "\ub9de\ucd98": 12, "embedding\uc73c\ub85c": 12, "\uac00\uc774\ub4dc\ud574\uc11c": 12, "\uad1c\ucc2e\uc740": 12, "\uc131\uacfc\ubb3c\uc744": 12, "\uc911\uac04": [12, 15], "representation\uc73c\ub85c": 12, "\uc778\ucf54\ub529\ud558\ub294\ub370": 12, "\ucd08\uc810\uc744": [12, 13, 20], "\ub9de\ucda4": 12, "model\uc5d0\uc11c\ub294": 12, "representation\uc5d0": 12, "\ud6c4\ubcf4\uad70\uc744": 12, "encoder\uc758": 12, "\ucc3e\ub294\ub2e4": 12, "\uadf8\ub7ec\ub098": 12, "depth": [12, 13, 15], "visual": [12, 18], "understanding\uc744": 12, "\ud544\uc694\ub85c": 12, "\ud558\uc9c0": 12, "\uc54a\ub294\ub2e4": [12, 15], "\uc0dd\uc131\uc790\uac00": 12, "\uc2dc\uac01\uc801\uc778": 12, "\uadf8\ub9b0\ub2e4": 12, "inversion\uc5d0\uc11c": 12, "\uc601\uac10\uc744": 12, "\uc81c\uc2dc": [12, 15], "\ucd9c\ucc98": [12, 13], "hyoseok": 12, "tistori": 12, "entri": 12, "\uc788\ub3c4\ub85d": [4, 12, 13, 19], "vector\ub97c": 12, "vector\ub85c\ubd80\ud130": 12, "\uc774\uc758": 12, "\uc5ed\uacfc\uc815\uc73c\ub85c\uc368": 12, "gan\uc758": [12, 13], "inverting\uc2dc\ucf1c": 12, "\uc54c\uc544\uac00\ub294": 12, "\uc0dd\uc131\ubaa8\ub378\ub85c\uc11c": 12, "\uc0ac\uc6a9\ud568": [12, 13, 14, 18], "\uc774\uc804\uc5d0": [12, 15], "\ub9d0\ud588\ub4ef\uc774": 12, "\uac74\ub4e4\uc9c0": 12, "function": [4, 12, 17, 20], "\uc785\ub825\ub41c": [4, 12, 19], "\ubb38\uc790\uc5f4\uc758": 12, "\ud558\uc704": 12, "\ub2e8\uc5b4\ub294": 12, "\ud1b5\uacfc\ud558\uba70": 12, "\ubbf8\ub9ac": 12, "\uc815\uc758\ub41c": 12, "dictionary\uc5d0\uc11c": 12, "token\uc73c\ub85c": 12, "\ubcc0\ud658\ud568": 12, "\ud1a0\ud070\uc744": 12, "\ucc3e\uc744": 12, "\uace0\uc720\ud55c": 12, "\ubca1\ud130\uc5d0": 12, "\uc5f0\uacb0\ub428": 12, "index\uc5d0": 12, "encoder\uc778": 12, "c_\u03b8\uc758": 12, "\uc77c\ubd80\ub85c": 12, "space\ub97c": 12, "target\uc73c\ub85c": 12, "\uc0bc\uc558\uc74c": 12, "\ub098\ud0c0\ub0b4\uae30": 12, "\uc790\ub9ac\ud45c\uc2dc\uc790": 12, "\ubb38\uc790\uc5f4\uc778": 12, "\uc0c8\ub86d\uac8c": 12, "\uc9c0\uc815\ud568": 12, "palavra\ub97c": 12, "\ucd94\uc815\ud568": 12, "process\uc5d0": 12, "\uac1c\uc785\ud574\uc11c": 12, "tokenize\ub41c": 12, "\ubb38\uc790\uc5f4\uacfc": 12, "\ub300\uccb4\ud558\uc5ec": 12, "\ubcf8\uc9c8\uc801\uc73c\ub85c": 12, "\uc5b4\ud718": 12, "\uc8fc\uc785\ud568": 12, "\uaddc\ubaa8\uc758": 12, "5\uc7a5": 12, "\ubc30\uacbd": 12, "\ud3ec\uc988\uc640": 12, "\uc124\uc815\uc5d0": 12, "\uac78\uccd0": 12, "\ubb18\uc0ac\ud568": 12, "\ucd5c\uc18c\ud654\ud558\ub294": [12, 17], "v\ub97c": 12, "\ucd5c\uc801\ud654\ud568": 12, "\uace0\uc815\ud558\uae30": 12, "\ud15c\ud50c\ub9bf\uc5d0\uc11c": 12, "\ud30c\uc0dd\ub41c": 12, "\uc911\ub9bd": 12, "\ucee8\ud14d\uc2a4\ud2b8": 12, "\ubb34\uc791\uc704\ub85c": 12, "\uc0d8\ud50c\ub9c1\ud55c\ub2e4": 12, "\uc5ec\uae30\uc5d0\ub294": 12, "rendit": [12, 16], "\ud615\uc2dd": 12, "\ud504\ub86c\ud504\ud2b8\uac00": 12, "\ud3ec\ud568\ub41c\ub2e4": 12, "\uc544\ub9c8": [12, 18], "\uc6d0\ubcf8": [4, 12, 16, 20], "\uc6d0\ubcf8\uacfc": 12, "\ube44\uad50\ud558\uae30": 12, "\ubaa9\uc801\uc774": 12, "\uc544\ub2d0\uae4c": 12, "\uc2f6\uc74c": 12, "\ucd5c\uc801\ud654": 12, "\ubaa9\ud45c\uc2dd\uc740": 12, "\uac19\uc74c": [12, 13], "loss\ud568\uc218\uc640": 12, "\uc720\uc0ac\ud568": 12, "c\u03b8\uc640": 12, "e\u03b8\ub294": 12, "\ubbf8\uc138\ud55c": 12, "\uc2dc\uac01\uc801": [4, 12], "\ud3ec\ucc29\ud560": 12, "\uc788\uc744\uac83\uc73c\ub85c": 12, "\uae30\ub300\ud568": 12, "compar": [4, 12, 13], "\ub514\ud14c\uc77c\uc744": [4, 12], "\ud3ec\ucc29\ud558\ub294": 12, "\ubaa8\uc2b5\uc744": [4, 12], "\uc720\uc0ac\ud558\uba74\uc11c\ub3c4": 12, "guide\uc5d0": 12, "\ub9de\ucdb0\uc11c": 12, "\uc9c4\ud589\ud568": 12, "\uc8fc\uc81c\uc5d0": 12, "\uc815\ud655\ud558\uac8c": 12, "\ubcf4\uc874\ud558\uace0": 12, "\uc784\ubca0\ub529\uacfc": 12, "\ub098\uba38\uc9c0": [4, 12, 19], "\ucea1\uc158\ub4e4\uc5d0": 12, "\ucd94\ub860\uc774": 12, "\uac00\ub2a5\ud588\uc74c": 12, "\ub370\uc774\ud130\uc14b\uc73c\ub85c\ub3c4": 12, "\ubcf4\uc874\ud558\uba74\uc11c": 12, "\ud45c\ud604\ud55c": 12, "\uadf8\ub9bc": [12, 13], "\uc0ac\uc9c4\uc5d0\uc11c\uc640": 12, "\uc758\uc0ac": 12, "\ubc31\uc778": 12, "\ub0a8\uc131": 12, "\uc758\uc0ac\ub97c": 12, "\uadf8\ub824\ub0c8\uc74c": 12, "\ub370\uc774\ud130\uc14b\uc5d0\uc11c": [12, 18], "\ub9ce\uc558\uc74c\uc744": 12, "imageset\uc5d0\uc11c": 12, "\uc131\ubcc4": 12, "\uc778\uc885\uc801": 12, "\ub2e4\uc591\uc131\uc5d0": 12, "\uc778\uc2dd\uc744": 12, "\ub192\uc77c": 12, "space": [4, 12, 14, 16, 20], "embedding\uc758": 12, "\ud488\uc9c8\uc744": 12, "\ubd84\uc11d": [4, 12, 15], "y\ucd95": 12, "\ubcf5\uc81c\ud558\ub294\uc9c0": 12, "\ubcc0\ud615\uc744": 12, "\uc0dd\uc131\ud558\ubbc0\ub85c": 12, "\uc758\ubbf8\uc801": 12, "\uacf5\uac04": [12, 13], "\uac70\ub9ac\ub97c": 12, "\uace0\ub824\ud558\uc5ec": 12, "\uc720\uc0ac\uc131\uc744": 12, "\uce21\uc815": [4, 12], "\ucee8\uc149\uc5d0": 12, "64\uac1c\uc758": 12, "edit": 12, "x\ucd95": 12, "\uc218\uc815\ud558\ub294": 12, "\ub09c\uc774\ub3c4\uc640": 12, "\uc124\uc815\uc758": 12, "\uc77c\ub828\uc758": 12, "\ubcc4\ub85c": 12, "ddim": [4, 12], "step\uc744": 12, "\uc0d8\ud50c\uc744": [12, 13, 20], "\ub9cc\ub4e4\uace0": 12, "prompt\uc758": 12, "embedding\uc5d0\uc11c": 12, "cosin": [4, 12, 15, 16], "similarity\ub97c": 12, "\uc2a4\ucf54\uc5b4\ub294": 12, "capability\uc640": 12, "\uc2e0\ub8b0\ub3c4\ub97c": 12, "\ubcf4\uc5ec\uc90c": [4, 12, 13, 18], "\uc2e4\ud5d8": [4, 12, 15, 17], "\ud658\uacbd": 12, "\ub530\ub984": 12, "\uc0dd\ub7b5": 12, "evaluation1": 12, "baseline\uacfc": 12, "\ubc29\ubc95\uc758": 12, "semant": [4, 12, 13], "quality\ub294": 12, "set\uc5d0\uc11c": 12, "\uc784\uc758\uc758": 12, "\uc0d8\ud50c\ub9c1\ud558\ub294": 12, "\uc5c6\uc5c8\ub2e4": [12, 13], "\ub2ec\uc131\ud558\uace0": 12, "baseline\uc5d0\uc11c": 12, "editablity\uc744": 12, "\ub2ec\uc131": [12, 14], "\uc810\uc740": 12, "space\uc758": 12, "\uc778\uc0c1\uc801\uc778": [12, 13], "\uc720\uc5f0\uc131\uc744": 12, "\ub098\ud0c0\ub0b4\uace0": 12, "\ub2e8\uc77c": [12, 13], "word\ub9cc": 12, "\uc815\ud655\ub3c4\ub85c": 12, "\ucea1\ucc98\ud558\ub294\ub370": 12, "\ub3c4\uc6c0\uc774": [12, 14], "distort": 12, "tradeoff": 12, "\uace1\uc120\uc758": 12, "outline\uc744": 12, "\uadf8\ub9ac\uba70": 12, "\ubd84\ud3ec\uc5d0": 12, "\uc218\uc815\ub420": 12, "target\uc758": 12, "\ucea1\ucc98\ud558\uc9c0\ub294": 12, "\ubc18\ub300\ub85c": 12, "\ubd84\ud3ec\uc5d0\uc11c": 12, "\uba40\ub9ac": 12, "\ubc97\uc5b4\ub098\uba74": 12, "editability\uac00": 12, "\ud06c\uac8c": [4, 12, 13, 17, 19, 20], "\uac10\uc18c\ud558\ub294": 12, "reconstruction\uc774": 12, "rate\ub97c": [12, 13], "\ubcc0\uacbd\ud574": 12, "\uace1\uc120\uc744": 12, "\uc774\ub3d9\ud560": 12, "\uc788\uc73c\ubbc0\ub85c": 12, "\uc0ac\uc6a9\uc790\uc5d0\uac8c": 12, "tradeoff\uc5d0": 12, "\uc815\ub3c4\uc758": 12, "\uc81c\uc5b4\ub97c": 12, "\uc81c\uacf5\ud568": 12, "description\uc744": 12, "\ud3ec\ucc29\ud558\uc9c0": 12, "\ubabb\ud558\uba74\uc11c\ub3c4": 12, "\uac10\uc18c\ud568": 12, "\uc124\ubb38\uc9c0": 12, "\uc81c\uacf5\ubc1b\uc558\uace0": 12, "\uc774\ubbf8\uc9c0\uc640\uc758": [12, 16], "\uc720\uc0ac\uc131\uc5d0": 12, "\ubaa8\ub378\uc5d0\uc11c": [12, 15, 18], "\uacb0\uacfc\uc758": 12, "\uc21c\uc704\ub97c": 12, "\ub9e4\uae40": 12, "context\ub97c": 12, "\ud14d\uc2a4\ud2b8\uc640": [4, 12], "\uc9c8\ubb38\ubcc4\ub85c": 12, "600\uac1c\uc529": 12, "200\uac1c\uc758": 12, "\uc751\ub2f5\uc744": 12, "\uc218\uc9d1": [4, 12, 19], "\uc0dd\uc131\uc5d0": 12, "\uc81c\uacf5\ud558\uc9c0\ub9cc": 12, "\uc758\ubbf8\ub860\uc801\uc778": 12, "\ubcf8\uc9c8\uc744": 12, "\ud30c\uc545\ud558\uac70\ub098": 12, "shape\ub97c": 12, "\ud559\uc2b5\ud558\ub294\ub370": [4, 12, 16], "\ud55c\uacc4": 12, "\ucd5c\uc801\ud654\uac00": 12, "\uc624\ub798": 12, "\uac78\ub9b0\ub2e4": 12, "\uc57d": [12, 13, 14], "2\uc2dc\uac04\uc774": 12, "\uc18c\uc694\ub428": 12, "\uc124\uc815\uacfc": 12, "\uc0dd\uc131\ud558\uae30": [12, 13], "model\ub97c": 12, "\ud65c\uc6a9\ud558\ub294": 12, "\uac1c\uc778\ud654\ub418\uba70": 12, "generation\uc744": 12, "\uc18c\uac1c\ud568": 12, "\ub0b4\uc5d0\uc11c": [4, 12, 19], "word\ub85c": 12, "inverse\ud558\uc5ec": 12, "\uc791\ub3d9\ud568": 12, "word\ub294": 12, "\uc7a5\uba74\uc5d0": 12, "\uc0bd\uc785\ud560": 12, "\uac04\ub2e8\ud558\uace0": 12, "\uc758\ubbf8\uc5d0\uc11c": 12, "\ud3b8\uc9d1\ud558\uae30": 12, "\uc27d\ub3c4\ub85d": 12, "\uae30\ubc18": [12, 14], "interpace\ub97c": 12, "\uc0ac\uc6a9\ud558\uc9c0\ub9cc": 12, "\uc790\uc5f0": 12, "\uc5b8\uc5b4\uc758": 12, "\ud55c\uacc4\uc5d0": 12, "\uc811\uadfc\ud560": 12, "\ub2e8\uc11c\ub97c": 12, "modal": [4, 12, 18], "\ud65c\uc6a9\ud560": [4, 12], "\uacf5\uac1c\uc801\uc73c\ub85c": 12, "\uc0ac\uc6a9\uac00\ub2a5\ud55c": 12, "model\uc778": 12, "ldm\uc744": 12, "\uad6c\ud604\ub428": 12, "\ubc29\uc2dd\uc5d0": [4, 12], "\uc544\ud0a4\ud14d\ucc98": 12, "\uc815\ubcf4\uc5d0": 12, "\uc758\uc874\ud558\uc9c0": 12, "\uc801\uc6a9\ud560": 12, "\uc0dd\uac01": 12, "\uac70\uae30\uc5d0\uc11c": 12, "preserav": 12, "\ud5a5\uc0c1\ub420": 12, "unpair": 13, "translat": 13, "iccv": 13, "2017": 13, "1703": 13, "10593": 13, "tensorflow": 13, "tutori": 13, "\ub17c\ubb38\ub9ac\ubdf0": 13, "cyclegan\uc744": 13, "\uc0ac\ub78c\uc774": [4, 13, 18, 19], "\ud55c\uad6d\uc778\uc774\ub77c\uace0": 13, "\ub72f\uc5b4\ubcf4\uae30": 13, "kwangsu": 13, "\uc774\ud558": 13, "\ub3c4\uba54\uc778\uc744": 13, "\ub3c4\uba54\uc778\uc73c\ub85c": 13, "\ubcc0\ud658\uc2dc\ud0a4\ub294": 13, "vision\uc758": 13, "translation\uc740": 13, "input\uacfc": 13, "\uc9dd\uc774": 13, "\uc9c0\uc5b4\uc9c4": 13, "\uc5bb\ub294": [13, 18], "\uc5b4\ub835\uc2b5\ub2c8\ub2e4": 13, "\uc9dd\uc9c0\uc5b4\uc9c4": 13, "x\ub77c\ub294": 13, "domain\uc73c\ub85c\ubd80\ud130": 13, "\uc5bb\uc740": 13, "domain": 13, "y\ub85c": 13, "\ubc14\uafb8\ub294": [13, 16], "\uc5f0\uad6c\ub294": 13, "\ud65c\uc6a9\ud574": [4, 13, 15], "\ub370\uc774\ud130\uc758": 13, "\ubd84\ud3ec\uc640": 13, "y\ub85c\ubd80\ud130\uc758": 13, "\ubd84\ud3ec\uac00": [13, 20], "\uad6c\ubd84\uc774": 13, "\ubd88\uac00\ub2a5\ud558\ub3c4\ub85d": 13, "y\ub85c\uc758": 13, "mapping\uc5d0": 13, "\uc81c\uc57d\uc744": 13, "\uac00\ud574\uc11c": 13, "\uac15\uc81c\ud558\uae30": 13, "x\uc640": 13, "\uc5ed\ubc29\ud5a5": 13, "\ub9e4\ud551\uc744": 13, "\uc9c4\ud589\ud558\uace0": 13, "\uc720\uc0ac\ud574\uc9c0\ub3c4\ub85d": 13, "\uac15\uc81c\ud558\ub294": 13, "\ub3c4\uc785\ud588\uc2b5\ub2c8\ub2e4": 13, "\uacb0\uacfc\uc801\uc73c\ub85c": 13, "task\uc5d0\uc11c": 13, "pair\uac00": 13, "\uc874\uc7ac\ud558\uc9c0": [4, 13], "\ubcf4\uc5ec\uc92c\ub2e4\uace0": 13, "\uc2a4\ud0c0\uc77c": 13, "\uc18d\uc131": [4, 13], "\ub4f1\uc744": 13, "image\ub85c": 13, "\ubcc0\ud658\ud558\ub294": 13, "\uadf8\ub9bc\uc73c\ub85c": 13, "\ubcc0\ud658\ud55c\ub2e4\uac70\ub098": 13, "\ub0ae\uc5d0": 13, "\ucc0d\uc740": 13, "\ubc24\uc5d0": 13, "\ud754\ud788": 13, "output\uc73c\ub85c": 13, "\ubc14\ud0d5\uc73c\ub85c": 13, "\uc774\ub8e8\uc5b4\uc838": [13, 20], "\uc788\uc5c8\ub294\ub370\uc694": 13, "\uc5b4\ub835\uace0": 13, "\ube44\uc2fc": 13, "\uc77c\uc774": 13, "image\uac00": 13, "\uc77c\ub300\uc77c\ub85c": 13, "\uc9dd\uc9c0\uc5b4\uc9c0\uc9c0": 13, "\ubaa8\uc74c\uc758": 13, "\ucea1\uccd0\ud558\uace0": 13, "\ubaa8\uc74c\uc73c\ub85c": 13, "\ubcc0\ud658\ud560": 13, "\uc81c\uc2dc\ud569\ub2c8\ub2e4": [4, 13, 19], "x\uc5d0": 13, "\uc138\ud2b8": 13, "y\uc5d0": 13, "\uc138\ud2b8\uac00": 13, "\uc81c\uacf5\ub418\uace0": 13, "output\uacfc": [13, 15], "y\uac00": 13, "discriminator\uc5d0": 13, "\uad6c\ubcc4\ud560": 13, "\uc5c6\ub3c4\ub85d": 13, "y\ub97c": [13, 15], "\ud559\uc2b5\ud569\ub2c8\ub2e4": 13, "\uc774\uac8c": 13, "\uac1c\ubcc4": 13, "\ucd9c\ub825": 13, "\ubb34\uc870\uac74": 13, "\uc720\uc758\ubbf8\ud558\uac8c": 13, "\uc30d\uc744": 13, "\uc774\ub8ec\ub2e4\ub294": 13, "\ub73b\ud558\uc9c0\ub294": 13, "\uc54a\uc2b5\ub2c8\ub2e4": 13, "g\uac00": 13, "image\uc5d0\ub294": 13, "\ubb34\ud55c\ud55c": 13, "\uacbd\uc6b0\uc758": 13, "\uc218\uac00": [13, 14], "\ub54c\ubb38": 13, "collapse\uac00": 13, "\uc77c\uc5b4\ub098\uae30\ub3c4": 13, "dl": 13, "ai": [4, 13], "blogspot": 13, "08": 13, "problem": 13, "image\ub4e0": 13, "\ub9e4\ud551\ud558\uba74\uc11c": 13, "\ucd5c\uc801\ud654\uc5d0": 13, "\uc2e4\ud328\ud558\ub294": 13, "\ud604\uc0c1": [13, 16], "\ud604\uc0c1\uc740": 13, "\uc785\uc7a5\uc5d0\uc11c": 13, "discriminator\uac00": 13, "\uc0ac\uc9c4\uc774": [13, 15], "\uc9c4\uc9dc": 13, "y\uc778\uc9c0": 13, "\uac00\uc9dc\uc778": 13, "\uc778\uc9c0": 13, "\uad6c\ubcc4\ud558\ub294": 13, "\uc18d\uc774\uae30\ub9cc": 13, "\uc6b0\ub9ac\uc758": 13, "\ubaa9\uc801\uacfc": 13, "\uc804\ud600": 13, "\uc0c1\uad00\uc774": 13, "\ub9cc\ub4e4\ub354\ub77c\ub3c4": 13, "\ubb38\uc81c\uac00": 13, "\uc0dd\uae30\uc9c0": 13, "\uc54a\uc544\uc11c": 13, "\ubc1c\uc0dd\ud568": 13, "\uc774\uc288\ub85c": 13, "\uc778\ud574": [13, 18], "function\uc774": 13, "\ud544\uc694\ud574": 13, "\uc84c\uc2b5\ub2c8\ub2e4": 13, "task\ub294": 13, "\uc601\uc5b4": 13, "\ud504\ub791\uc2a4\uc5b4": 13, "\uc601\uc5b4\ub85c": 13, "\ubc88\uc5ed\ud588\uc744": 13, "\uc6d0\ub798": [13, 15], "\ub3c4\ub2ec\ud558\ub294": 13, "\uac83\ucc98\ub7fc": 13, "\ub3cc\uc544\uac00\ub294": 13, "\uac19\uc544\uc57c": 13, "\ud55c\ub2e4\ub294": 13, "\uc758\ubbf8\uc758": 13, "cyclic": 13, "consistency\uc774\ub77c\ub294": 13, "\uc18d\uc131\uc744": 13, "\uc774\uc6a9\ud569\ub2c8\ub2e4": 13, "\ubaa9\uc801\uc2dd\uc744": 13, "\uac04\ub2e8\ud558\uac8c": 13, "\uc815\ub9ac\ud558\uba74": 13, "\uc815\ubc29\ud5a5": 13, "\ub17c\ubb38\uacfc": 13, "\uc5f0\uad6c\uc5d0": 13, "\ub0b4\uc6a9\uc774\uc5c8\uc74c": 13, "\uac1c\ub150\ub4e4\uc740": 13, "introduction\uc5d0\uc11c": 13, "\uc124\uba85\ud588\uace0": 13, "\uc2a4\ud130\ub514\uc640\ub294": 13, "\ub531\ud788": 13, "\uad00\ub828\uc774": 13, "\uc2a4\ud0b5\ud588\uc74c": 13, "\ub3c4\uc2dd\ud654": 13, "\uc790\ub8cc": 13, "mapping\ud558\ub294": 13, "function\uc744": [13, 14], "\uc6a9\uc5b4": 13, "\uc815\ub9ac": 13, "pdata": 13, "\ud45c\uc2dc": 13, "dx": [13, 17], "dy\ub294": 13, "dx\ub294": 13, "\uad6c\ubd84": 13, "y\uc640": 13, "\ubaa9\uc801\uc2dd\uc740": 13, "\ub450\uac1c": 13, "domain\uc758": 13, "distribution\uacfc": 13, "\uc77c\uce58\uc2dc\ud0a4\uae30": 13, "g\uc640": 13, "f\uac00": 13, "\ubaa8\uc21c\ub418\ub294": 13, "\ubc29\uc9c0\ud558\uae30": 13, "dy\uc5d0": 13, "l_gan": 13, "gan\uc5d0\uc11c": 13, "function\uacfc": 13, "\ub300\uc2e0\uc5d0": 13, "\uac08": [13, 15], "x\ub85c": 13, "\uc218\uc2dd\uc774": 13, "\ub098\uc624\uba70": 13, "dx\uc5d0": 13, "dx\ub97c": 13, "\ub123\uc740": 13, "\uc55e\uc11c": 13, "\ub9d0\ud588\ub4ef": 13, "\uc81c\ud55c\uc744": 13, "\ub450\uc5b4": 13, "\uc218\uc2dd\uc73c\ub85c\uc11c": 13, "\uc608\ube44": 13, "\uc2e4\ud5d8\uc5d0\uc11c": 13, "l1": 13, "loss\ub85c": 13, "\ub300\uccb4\ud574\ubd24\ub294\ub370": 13, "\ud5a5\uc0c1\uc744": [13, 15], "\uad00\ucc30\ud560": 13, "\uc5c6\uc5c8\uc74c": 13, "\uc720\ub3c4\ub41c": 13, "\ubd99\uc740": [4, 13], "\uac00\uc911\uce58": [13, 18], "loss\uc640\uc758": 13, "\uc0c1\ub300\uc801": 13, "\uc911\uc694\ub3c4\uc5d0": 13, "\uacb0\uc815\ub428": 13, "architecture\ub85c\uc11c": 13, "transfer\uc640": 13, "\ubcf4\uc5ec\uc900": 13, "\uc0ac\uc6a9\ub41c": 13, "\ucc44\ud0dd\ud568": [13, 15], "3\uac1c\uc758": 13, "sever": 13, "block": [13, 15, 17], "fraction": 13, "stride": 13, "feature\ub97c": 13, "rgb\ub85c": 13, "\ub9e4\ud551\ud558\ub294": 13, "128": [13, 17], "\uace0\ud574\uc0c1\ub3c4": 13, "\uc548\uc815\ud654\uc2dc\ud0a4\uae30": 13, "\ud14c\ud06c\ub2c9\uc744": 13, "\uc801\uc6a9\ud569\ub2c8\ub2e4": 13, "function\uc5d0\uc11c": 13, "\ubcc0\uacbd": 13, "\ucd5c\uadfc\uc758": [4, 13], "50\uac1c\ub97c": 13, "\uc800\uc7a5\ud574": 13, "\ud55c\uaebc\ubc88\uc5d0": 13, "\ubd84\ub958": 13, "\uc9c4\ub3d9\uc744": 13, "sjinu": 13, "ysbsb": 13, "02": 13, "lsgan": 13, "generator\uc758": 13, "\uc5c5\ub370\uc774\ud2b8\ub97c": 13, "lsgan\uc744": 13, "\uc774\ud574\ub294": 13, "\ubabb\ud588\uace0": 13, "\uc774\ub7f0\uac8c": 13, "\uc788\uad6c\ub098": 13, "\uc815\ub3c4\ub85c\ub9cc": 13, "\uc54c": [13, 18], "discriminator\ub294": 13, "\uc774\ubcf4\ub2e4": 13, "\uace0\ucc28\uc6d0\uc774\uc9c0\ub9cc": 13, "\uac04\ub7b5\ud788": 13, "2\ucc28\uc6d0\uc744": 13, "\ud45c\ubc29\ud558\uba74": 13, "\uacb0\uc815\uacbd\uacc4\ub97c": 13, "\ub098\ud0c0\ub0bc": 13, "\ucabd\uc774": 13, "\uac00\uc9dc": [13, 17], "\uc601\uc5ed": 13, "\uc601\uc5ed\uc785\ub2c8\ub2e4": 13, "\uc544\ub798\uc5d0": 13, "\uac70\ub9ac\uac00": 13, "\uba3c": 13, "\uc0d8\ud50c\uc774": 13, "\uc874\uc7ac\ud569\ub2c8\ub2e4": [13, 16], "\uc0ac\uc6a9\ud55c\ub2e4\uba74": 13, "\uc785\uc7a5\uc5d0\uc11c\ub294": 13, "discriminator\ub97c": 13, "\uc18d\uc774\uace0": 13, "\ud559\uc2b5\ud560": [13, 17], "\ud544\uc694\uac00": [13, 16], "\uc5c6\uc2b5\ub2c8\ub2e4": [4, 13], "vanish": [13, 17], "\uc77c\uc5b4\ub098\uae30": 13, "\uc18d\uc778\ub2e4\ub294": 13, "\uc774\uc720\ub9cc\uc73c\ub85c": 13, "\ud328\ub110\ud2f0\ub97c": 13, "\uc904": [13, 15, 18], "\uc5c6\uac8c": 13, "ls": 13, "\uc8fc\uac8c": 13, "generator\ub294": 13, "\uc18d\uc774\ub294": 13, "\ub118\uc5b4\uc11c": 13, "\uac00\uc9c0\uac8c\ub054": 13, "\ud574\uc57c\ud569\ub2c8\ub2e4": 13, "\ub78c\ub2e4\ub97c": 13, "10\uc73c\ub85c": 13, "\uc124\uc815\ud588\ub2e4": 13, "\uc544\ub2f4\uc744": 13, "\uc0ac\uc6a9\ud588\ub2e4": 13, "\ub124\ud2b8\uc6cc\ud06c\ub294": 13, "0002\ub85c": 13, "\uc5d0\ud3ec\ud06c": 13, "\ub3d9\uc548\uc5d0\ub294": 13, "ln\uc744": 13, "\uc5d0\ud3ec\ud06c\ub9c8\ub2e4": 13, "\uc870\uae08\uc2dd": 13, "\uc218\ub834\ud558\uac8c": 13, "\ud588\ub2e4": 13, "\ud3c9\uac00\ub97c": [13, 14, 17, 18], "\uc9c0\ud45c\ub97c": 13, "amt": 13, "perceptu": [4, 13], "\ucc38\uac00\uc790\ub4e4\uc740": 13, "\uc0ac\uc9c4\uc774\ubbf8\uc9c0": 13, "\uc9c0\ub3c4": 13, "\uac00\uc9dc\uc774\ubbf8\uc9c0\uc5d0": 13, "\ub178\ucd9c\ub41c": 13, "\uc9c4\uc9dc\ub77c\uace0": 13, "\uc0dd\uac01\ub418\ub294": 13, "\uc120\ud0dd\ud558\uac8c": 13, "1\ubc88": 13, "study\uac00": 13, "\ud14c\uc2a4\ud2b8\uc5d0": 13, "\uc788\uc5b4": 13, "\uae30\uc900\uc784\uc5d0\ub3c4": 13, "\ubd88\uad6c\ud558\uace0": [4, 13], "\uc0ac\ub78c\uc744": 13, "\uc2e4\ud5d8\uc774": 13, "\uc591\uc801\uc778": 13, "\uae30\uc900\uc744": 13, "\ucc3e\uc558\ub294\ub370": 13, "score\uc784": 13, "fcn\uc740": 13, "\uc0ac\uc9c4\uc5d0": 13, "\ub808\uc774\ube14": 13, "\ub9f5\uc744": 13, "\uc608\uce21\ud569\ub2c8\ub2e4": 13, "\ub9f5\uc740": 13, "\uc544\ub798\uc5d0\uc11c": 13, "\ud45c\uc900": 13, "\uc2dc\ub9e8\ud2f1": 13, "\ubd84\ud560": 13, "\uba54\ud2b8\ub9ad\uc744": 13, "label\uacfc": 13, "\ube44\uad50\ud560": 13, "\ub3c4\ub85c": 13, "\uc0c1\uc758": 13, "\uc790\ub3d9\ucc28": 13, "label\uc5d0\uc11c": 13, "fcn\uc774": 13, "\uac10\uc9c0\ud558\uba74": 13, "\uc131\uacf5\ud55c": 13, "\ub77c\ubca8\ub9c1": 13, "pixel\ub2f9": 13, "\uc815\ud655\ub3c4": 13, "\ub2f9": 13, "iou": 13, "intersect": 13, "union": 13, "cityscap": 13, "benchmark\uc758": 13, "cogan": 13, "simgan": 13, "pix2pix": 13, "aginst": 13, "6\uc5d0\uc11c": 13, "\uc788\ub4ef\uc774": 13, "baseline\uc5d0\uc11c\ub3c4": 13, "\uac15\ub825\ud55c": 13, "\ubc18\uba74\uc5d0": [13, 17], "cyclegan\uc740": 13, "supervise\uc778": 13, "pix2pix\uc640": 13, "translation\uc744": 13, "\ud45c": 13, "1\uc740": [13, 15], "realism": 13, "\uc9c0\ub3c4\uc5d0\uc11c": 13, "\ud56d\uacf5": 13, "\uc0ac\uc9c4\uc5d0\uc11c": 13, "\ubaa8\ub450\uc5d0\uc11c": 13, "4\uc758": 13, "\ucc38\uac00\uc790\ub97c": 13, "\uc18d\uc77c": 13, "baseline\uc740": 13, "2\ub294": [13, 15], "\ub3c4\uc2dc": 13, "\ud48d\uacbd\uc5d0": 13, "\ud3c9\uac00\ud558\uace0": 13, "3\uc740": 13, "\ud3c9\uac00\ud568": [13, 18], "cyclegan\uc774": 13, "baseline\ub4e4\uc758": 13, "\ub2a5\uac00\ud55c\ub2e4": 13, "consistency\uc758": 13, "\uc911\uc694\uc131\uc744": 13, "\ubcf4\uc5ec\uc8fc\ub294": [13, 14, 16], "\uc5c6\uc560\uba74": 13, "cycle\uc744": 13, "\uc81c\uac70\ud558\ub294": 13, "\uc800\ud558\ub428": 13, "\uacb0\uacfc\uc5d0": 13, "\uc911\uc694\ud558\ub2e4\uace0": [4, 13, 16], "\uacb0\ub860\uc744": 13, "\ub0b4\ub9b4": 13, "\ubc29\ud5a5\uc5d0\uc11c\ub9cc": 13, "\uba54\uc18c\ub4dc\ub97c": 13, "cycle\ub9cc": 13, "\ub3cc\ub838\uc744": 13, "backward": [13, 16, 17], "\uc774\ub530\uae08\uc529": 13, "\ubcf4\uc774\uace0": [13, 14], "collapse\ub97c": 13, "\uc720\ubc1c\ud558\ub294": 13, "\ubc1c\uacac\ud568": 13, "\uc81c\uac70\ub41c": 13, "\ub9e4\ud551\uc758": 13, "\ubc29\ud5a5\uc5d0": 13, "7\uc744": 13, "\uc787\uc5c8\uc74c": 13, "4\uc5d0\uc11c": 13, "\uc7ac\uad6c\uc131\ub41c": 13, "\uba87\uac00\uc9c0": 13, "\ubb34\uc791\uc704": 13, "\uc0ac\uc9c4\uacfc": 13, "\ub3c4\uba54\uc778\uc774": 13, "\uacbd\uc6b0\uc5d0\ub3c4": 13, "\ud14c\uc2a4\ud2b8": 13, "\ub9ce\uc558\uc74c": 13, "8\uc740": 13, "cmp": 13, "fa\u00e7ad": 13, "database\uc758": 13, "\uac74\ucd95": 13, "ut": 13, "zapoos50k": 13, "dataset\uc758": 13, "\uc2e0\ubc1c\uacfc": 13, "pix2pix\uc5d0": 13, "cyclegan\uc758": 13, "\ud488\uc9c8\uc740": 13, "supervis": 13, "\ub300\uc758": 13, "\uc9f1\uc774\ub2e4": 13, "\ub9ce\uc544": 13, "\uc0dd\ub7b5\ud558\uaca0\uc2b5\ub2c8\ub2e4": 13, "\u3160": 13, "data\uac00": 13, "data\uc5d0\uc11c": 13, "transslation\uc774": 13, "\ud55c\uac83\ubcf4\ub2e4": 13, "\ub9e4\ub825\uc801\uc774\ub2e4": 13, "application\uc740": 13, "\uc6f9\uc0ac\uc774\ud2b8\uc5d0": 13, "\uc2e0\uacbd": 13, "\uc804\ub2ec": 13, "13": [13, 18], "\uc791\uc5c5\uacfc": 13, "\ub2ec\ub9ac": [13, 17, 20], "\uc120\ud0dd\ud55c": 13, "\uc608\uc220": 13, "\uc791\ud488\uc758": 13, "\uc804\ub2ec\ud558\ub294": 13, "\uc791\ud488": 13, "\uceec\ub809\uc158\uc758": 13, "\ubaa8\ubc29\ud558\ub294": 13, "\uadf8\ub798\uc11c": [4, 13, 17], "\ubcc4\uc774": 13, "\ube5b\ub098\ub294": 13, "\uadf8\ub9ac\ub294": 13, "\ubc18": 13, "\uace0\ud750": 13, "\ub530\ub77c\ud558\ub294": 13, "\ub290\ub08c\uc744": 13, "\ub530\ub77c\ud55c\ub2e4": 13, "turmukhambetov": 13, "\uac1d\uccb4\ub97c": [4, 13], "\ubc94\uc8fc\uc758": 13, "\uac1d\uccb4\ub85c": 13, "\uc81c\uc548\ud558\ub294": 13, "\uc2dc\uac01\uc801\uc73c\ub85c": [13, 14], "\ubc94\uc8fc": 13, "\uac1d\uccb4": [4, 13, 19], "\ubcc0\ud615\uc5d0": 13, "\uc911\uc810\uc744": [13, 14], "\ub461\ub2c8\ub2e4": [13, 20], "turn": 13, "hors": 13, "video": [4, 13], "zebra": 13, "\uc0ac\uc9c4\uc73c\ub85c": [4, 13], "\uc785\ub825\uacfc": 13, "\uac04": 13, "\uc0c9": 13, "\uad6c\uc131\uc744": 13, "\ubcf4\uc874\ud558\uae30": 13, "\uc720\uc6a9\ud558\ub2e4\ub294": 13, "\ubc1c\uacac\ud560": 13, "taigman": 13, "49": 13, "\uae30\uc220\uc744": [13, 18], "\ucc44\ud0dd\ud558\uc5ec": [13, 15], "\uc81c\ub108\ub808\uc774\ud130\uac00": 13, "\ub3c4\uba54\uc778\uc758": 13, "\uc785\ub825\uc73c\ub85c": 13, "\uc81c\uacf5\ubc1b\uc744": 13, "\uadfc\ucc98\uc5d0": 13, "\uc815\uaddc\ud654\ud569\ub2c8\ub2e4": 13, "lident": 13, "ey_pdata": 13, "lidentity\uac00": 13, "\uc5c6\uc73c\uba74": 13, "\uc0dd\uc131\uc790": 13, "f\ub294": 13, "\uad73\uc774": 13, "\ud544\uc694\ud558\uc9c0": 13, "\uc54a\uc744": 13, "\uc0c9\uc870\ub97c": 13, "\uc790\uc720\ub86d\uac8c": 13, "\ubcc0\uacbd\ud560": 13, "monet\uc758": 13, "flickr": 13, "\uc0dd\uc131\uc790\ub294": 13, "\uadf8\ub9b0": 13, "\uc77c\ubab0": 13, "\uc2dc\uac04\uc5d0": 13, "\ub9e4\ud551\ud569\ub2c8\ub2e4": 13, "\uc65c\ub0d0\ud558\uba74": 13, "\uc801\ub300\uc801": 13, "\uc190\uc2e4\uacfc": 13, "\uc0ac\uc774\ud074": 13, "\uc77c\uad00\uc131": 13, "\uc190\uc2e4": [13, 14], "\ub9e4\ud551\uc774": 13, "\ub3d9\ub4f1\ud558\uac8c": 13, "\uc720\ud6a8\ud560": 13, "\uc190\uc2e4\uc758": 13, "\ud6a8\uacfc\ub294": 13, "9\uc5d0\uc11c": 13, "\ubcf4\uc5ec\uc9d1\ub2c8\ub2e4": 13, "9\ub294": 13, "\ub370\uc774\ud130\uc14b\uc5d0": 13, "\ud3ec\ud568\ub418\uc5b4": 13, "set\uc740": 13, "\uc624\uc9c1": 13, "set\uc73c\ub85c\ubd80\ud130": 13, "\uadf8\ub824\uc9c4": 13, "datqa\ub97c": 13, "\ud3ec\ud568\ud558\uace0": 13, "\uadf8\ub9bc\uc5d0": 13, "\ud0c0\ub2f9\ud55c": 13, "\uc544\ub2c8\ub2e4": 13, "monet\uc774": 13, "\uc0c8": [13, 14], "\uadf8\ub9b4": 13, "generalization\uc740": 13, "press": 13, "\uc6b0\ub9ac\ub294": [4, 13, 20], "\ubc29\ubc95\uc774": 13, "\uc595\uc740": 13, "\uae4a\uc774\uc758": 13, "\ub370": 13, "flickr\uc5d0\uc11c": 13, "\ub2e4\uc6b4\ub85c\ub4dc\ud55c": 13, "\uaf43": 13, "\ud6c8\ub828\ud569\ub2c8\ub2e4": 13, "\uc18c\uc2a4": 13, "\ub3c4\uba54\uc778\uc740": 13, "\uc2a4\ub9c8\ud2b8\ud3f0\uc73c\ub85c": 13, "\ucc0d\ud78c": 13, "\uad6c\uc131\ub418\uc5b4": 13, "\uc870\ub9ac\uac1c\ub85c": 13, "\uae4a\uc740": 13, "dof": 13, "\ucd08\uc810": 13, "\uae4a\uc774": 13, "\ub300\uc0c1\uc740": 13, "\uc870\ub9ac\uac1c\uac00": 13, "dslr\ub85c": 13, "\ucd2c\uc601\ub41c": 13, "\ud3ec\ud568\ud569\ub2c8\ub2e4": 13, "\uc0ac\uc9c4\uc73c\ub85c\ubd80\ud130": 13, "\uc131\uacf5\uc801\uc73c\ub85c": 13, "\uc0dd\uc131\ud569\ub2c8\ub2e4": [4, 13, 20], "shallow": 13, "field": [4, 13, 19], "\ucd08\uc810\uc774": 13, "\ub9de\uc740": 13, "\ubc30\uacbd\uc774": 13, "\ud750\ub9bf\ud558\uac8c": 13, "\ud65c\uc6a9": [13, 14, 15], "\uad6c\ubaa9\ud558\uace0\uc790": 13, "\uac15\uc870\ud558\uae30": 13, "domain\uc740": 13, "\uc2a4\ub9c8\ud2b8\ud3f0\uc758": 13, "target\uc740": 13, "discuss": 13, "\ud765\ubbf8\ub85c\uc6b4": [13, 16], "\uade0\uc77c\ud558\uac8c": 13, "\uc544\ub2c8\uc5c8\uc2b5\ub2c8\ub2e4": 13, "\ud574\uc11d": 13, "\uac1c": 13, "\uace0\uc591\uc774": 13, "task\uc640": 13, "\uacbd\uc6b0\ub294": 13, "\ucd5c\uc18c\ud55c\uc758": 13, "\ubcc0\ud654\ub9cc": 13, "\uc8fc\uc5b4": [4, 13], "\ubcc0\ud654\uac00": [13, 18], "\uc548\ub418\ub294": 13, "\uacbd\uc6b0\ub3c4": 13, "\uc788\uc5c8\uace0": 13, "\ud615\uccb4\uac00": 13, "\uc560\ub9e4\ud574\uc9c4": 13, "\uc774\ub7f0\uac78": 13, "geometri": 13, "\ud45c\ud604\uc744": 13, "\ubcf4\uc544": 13, "\ub208": 13, "\ucf54": 13, "\uc785\uc5d0": 13, "\uad6c\ud604\ud558\ub294\ub370": 13, "\ub9d0": 13, "\uc5bc\ub8e9\ub9d0": 13, "\uc608\uc81c\uc758": 13, "\ub9d0\uc740": 13, "\ud0c0\ub294": 13, "\ubaa8\uc2b5\uc774": [4, 13], "\ub9ce\uc558\ub294\ub370": 13, "\uc5bc\ub8e9\ub9d0\uc758": 13, "\uc5c6\ub2e4\ubcf4\ub2c8": 13, "\uc0ac\ub78c": [13, 18], "\ubfd0\ub9cc": 13, "\ubc30\uacbd\ub3c4": 13, "\uc5bc\ub8e9": 13, "\uadf8\ub9ac\uac70\ub098": 13, "\uc5bc\ub8e9\ub9d0\uc5d0\uc11c": 13, "\ub178\ub797\uac8c": 13, "\uce60\ud55c": 13, "\uc0dd\uae40": 13, "\ub54c\ub54c\ub85c": 13, "\ub098\ubb34\uc640": 13, "\uac74\ubb3c\uc758": 13, "label\uc744": 13, "\ubaa8\ud638\uc131\uc744": 13, "\ud574\uacb0\ud558\ub824\uba74": 13, "weak": 13, "supervision\uc774": 13, "\ud544\uc694\ud560": 13, "\ub9c8\ubb34\ub9ac": 13, "\uadf8\ub7fc\uc5d0\ub3c4": [4, 13], "\uc644\uc804\ud788": 13, "\ud48d\ubd80\ud558\uac8c": 13, "\uc81c\uacf5\ub418\uba70": 13, "\ud65c\uc6a9\ud574\uc57c": 13, "setting\uc5d0\uc11c": 13, "\uac83\uc758": 13, "\ub298\ub9ac\ub294\ub370": 13, "\uae30\uc5ec\ud569\ub2c8\ub2e4": 13, "icml": 14, "12092": 14, "unoffici": 14, "donggeun": [14, 15, 18], "sean": [14, 15, 18], "ko": [14, 15, 18], "june": 14, "22": 14, "\ubaa8\ub378\uc774\uba70": 14, "120\uc5b5\uac1c": 14, "\uc218\uc640": 14, "5\uc5b5": 14, "\ubaa8\ub378\ub9c1\uc744": 14, "\ud1b5\ud558\uc5ec": 14, "text\ub97c": 14, "\uc774\uc6a9\ud558\uc5ec": 14, "2021\ub144": 14, "diverse\ud55c": 14, "3\uc640": 14, "vae\ub97c": 14, "transformer\uc744": 14, "architecture\uc744": [14, 15], "\uad6c\ucd95": 14, "model\uba70": 14, "few": 14, "learning\uc744": 14, "\ub0c4": 14, "\uc218\ub294": 14, "\ub9de\ucdb0": 14, "shot\uc744": 14, "decod": [4, 14, 16, 20], "\ubd80\ubd84\ub9cc": [14, 15], "1750\uc5b5": 14, "\uac1c\uc218\uc758": 14, "\uc544\ud0a4\ud14d\uccd0": [4, 14, 15, 18], "2005": 14, "14165": 14, "jalammar": 14, "how": 14, "gpt3": 14, "encoder\uc5d0\uc11c": 14, "output\uc740": 14, "discret": 14, "categor": 14, "\uac16\ub294\ub2e4\uace0": 14, "cnn": 14, "\uac70\uce5c": [4, 14, 19], "d\ucc28\uc6d0\uc758": 14, "\uc704\uce58\uc5d0": 14, "\uadf8\ub9ac\ub4dc\ub85c": 14, "\ub098\ub204\uace0": 14, "\ud835\udc52_1": 14, "\ubd80\ud130": 14, "\ud835\udc52_\ud835\udc58": 14, "1\uac1c": 14, "code\ub85c": 14, "\ubcc0\ud658": 14, "z_": 14, "e_j": 14, "\ucc3e\uc544\uc11c": 14, "\ubd80\uc5ec\ud568": 14, "p2yeong": 14, "understand": [14, 18], "explain": 14, "issu": 14, "pixel\uc744": 14, "\uc9c1\uc811\uc801\uc73c\ub85c": 14, "token\uc744": 14, "\uace0\ud654\uc9c8": [14, 15], "\uc774\ubbf8\uc9c0\uc77c\uc218\ub85d": 14, "\uba54\ubaa8\ub9ac\ub7c9\uc774": 14, "\ud544\uc694\ud574\uc11c": 14, "\ube44\ud6a8\uc728\uc801": 14, "short": 14, "depend": [14, 16], "between": [4, 14, 18], "model\ub4e4": 14, "likelihood": [14, 15, 17, 20], "dependency\ub97c": 14, "\uac83\uc774\uba70": 14, "frequenc": 14, "detail\uc5d0": 14, "\ub354\uc6b1": [14, 18], "\uc9d1\uc911\ud558\uac8c": 14, "\ub428": 14, "recognizable\ud574\uc11c": 14, "\ub418\ub294": [4, 14, 15, 16, 19], "2\uac00\uc9c0": [14, 18], "\uadf9\ubcf5\ud558\uace0\uc790": 14, "textbf": 14, "rgb": 14, "rightarrow": 14, "\ud1a0\ud070\uc73c\ub85c": 14, "\uc555\ucd95": 14, "192\uac1c\uc758": 14, "\uac12": 14, "\uc911\uc5d0": 14, "\ubc30\uc815": 14, "\ubc30": 14, "\ub9cc\ud07c": 14, "size\ub97c": 14, "bpe": 14, "\ub4e4\uacfc": [14, 18], "\uc5f0\uc18d\uc801\uc73c\ub85c": 14, "\uc785\ub825\ud568": 14, "concaten": [4, 14, 19], "token\uacfc": 14, "\ub4e4\uc758": 14, "\uacb0\ud569": 14, "\ubaa8\ub378\ub9c1\ud558\uc5ec": [14, 15], "\uc2dc\uac01\ud654": [14, 15], "jiho": 14, "ml": [14, 20], "weekli": 14, "nlp": 14, "40": 14, "\ud30c\uc774\ud504\ub77c\uc778": 14, "cqom0r2kmvi": 14, "1729": 14, "maxim": [4, 14], "caption": [4, 14, 18], "\ud835\udc5e": 14, "\u03c6": 14, "red": 14, "dvae": 14, "token\ub97c": 14, "\ud835\udc5d": 14, "\ud835\udf03": 14, "blue": 14, "token\uc5d0\uc11c": 14, "decoder\uc5d0\uc11c": 14, "\u03c8": 14, "purpl": 14, "\ubaa8\ub378\ub9c1\ud55c": 14, "text\uc640": 14, "token\ub4e4\uc758": 14, "\ud835\udc5e_\u03c6": 14, "\ud835\udc5d_\ud835\udf03": 14, "\ud559\uc2b5\ud568": 14, "elb": 14, "bound\ub97c": 14, "192": 14, "elb\ub97c": 14, "continuous\ub97c": 14, "\ubc14\uafd4\uc57c": 14, "\ud559\uc2b5\uc2dc\uc5d0\ub294": 14, "argmax\ub97c": 14, "\uc778\ub371\uc2a4\ub97c": 14, "\uc120\ud0dd\ud558\uc5ec": 14, "\uacc4\uc0b0\ud558\uba74": 14, "reparameter": 14, "gradient\ub97c": [14, 15], "\uc5f0\uc0b0": 14, "argmax": 14, "gumbel": 14, "\ud574\uacb0": 14, "\uc9c4\ud589\ud560": 14, "\ub54c\uc5d0\ub294": 14, "underset": 14, "g_i": 14, "e_i": 14, "relaxation\ub97c": 14, "q_": [14, 20], "tau": 14, "temperatur": 14, "relaxation\uc744": 14, "tight\ud558\uac8c": 14, "\uc7a1\uc544\uc90c": 14, "psi": 14, "\uc774\ub54c": [4, 14, 16, 17, 19, 20], "120\uc5b5\uac1c\uc758": 14, "token\uc740": 14, "logit\uc5d0\uc11c": 14, "\uc18c\ubb38\uc790\ud654": 14, "384": 14, "vocabulary\ub97c": 14, "\ud55c\ubc88\uc5d0": 14, "causal": 14, "mask": [4, 14, 19], "row": 14, "column": 14, "\ucd94\ub860": [4, 14], "\ub300\ud558\uc5ec": 14, "n\uac1c\ub294": 14, "n\uac1c": 14, "\uace8\ub77c\uc11c": 14, "\uace0\ub974\uae30": 14, "\ubc88\uc9f8\ub85c": 14, "similar": [4, 14, 16], "\uc810\uc218\uac00": [14, 18], "\uc120\ud0dd\ud568": 14, "\uacb0\uacfc\ubb3c": [4, 14], "best\ub97c": 14, "\uace0\ub97c\ub54c": 14, "\uc99d\uac00\ud560\uc218\ub85d": 14, "prompt\ub791": 14, "\uacb0\uacfc\ubb3c\uc774": [4, 14], "\ub098\uc634": [14, 15], "512\uac1c": 14, "\uc54c\uace0\ub9ac\uc998\uc744": 14, "score\uc774": 14, "\uc81c\uc77c": [14, 15], "\ubf51\uc74c": 14, "\uc54c\ub9de\uc740": 14, "\uc120\ud0dd\ud558\ub294": 14, "\uac1c\uc218\uc5d0": [14, 16], "df": 14, "\uc774\ub791": [4, 14, 20], "ms": [14, 18], "coco": [14, 18], "five": 14, "vote": 14, "gan\ubcf4\ub2e4": [14, 15], "\uc555\ub3c4\uc801\uc778": 14, "\ucc28\uc774\ub85c": 14, "\ud22c\ud45c": 14, "\uc218\ub97c": 14, "\ubc1b\uc558\uc74c": 14, "frechet": 14, "distanc": 14, "\ub0ae\uc744\uc218\ub85d": [14, 15], "\uc88b\uc73c\uba70": 14, "IS": 14, "\ub192\uc744\uc218\ub85d": [14, 15], "\ub791": 14, "cub": 14, "\ud2b9\ud654": 14, "e\ub294": 14, "coco\uc5d0\uc11c\ub294": 14, "\ubcf4\uc5ec\uc92c\uc74c": 14, "cub\uc5d0\uc11c\ub294": 14, "\ucc0d\uc9c0": 14, "\ubabb\ud558\uc600\uace0": 14, "score\uc5d0\uc11c\ub294": 14, "\uc810\uc218\ub97c": [14, 18], "\uae30\ub85d\ud568": 14, "cub\uc5d0": 14, "\uacc4\uc120\uc744": 14, "\uc0dd\uac01\ud568": 14, "\uacb0\uacfc\uac12": 14, "\ud655\uc7a5": 14, "parameter\uacfc": 14, "\ub6f0\uc5b4\ub098\uac8c": 14, "\ud574\uacb0\ud568": 14, "\ud6cc\ub96d\ud55c": [14, 18], "\uc77c\ubc18\ud654": 14, "\ud3c9\uac00\uc5d0\uc11c": 14, "\uc900\uc218\ud55c": 14, "\uc2f6\uc740": 14, "\uac1d\uccb4\uac00": 14, "\ud3ec\ud568\ub418\uba74": 14, "\uacaa\uc74c": 14, "\uace0\uc2b4\ub3c4\uce58\uac00": 14, "2\ub9c8\ub9ac\uac70\ub098": 14, "\uac15\uc544\uc9c0\uc640": 14, "\uace0\uc2b4\ub3c4\uce58": 14, "\ub458\ub2e4": 14, "\ud06c\ub9ac\uc2a4\ub9c8\uc2a4": 14, "\uc2a4\uc6e8\ud130\ub97c": 14, "\uc785\uace0": 14, "\uc544\uc26c\uc6b4": 14, "\ubcf4\uc778": 14, "\ub370\uc774\ud130\uc14b\uc774": [4, 14, 19], "tuning\uc73c\ub85c": 14, "limitation\uc744": 14, "nip": [15, 17], "2105": 15, "05233": 15, "\ubaa8\ub378\ub4e4\uc758": 15, "\ub6f0\uc5b4\ub118\uc74c": 15, "\ubd80\ubd84\uc5d0\uc11c\ub3c4": 15, "guidance\ub97c": [15, 18], "\ubcf4\uc5ec\uc900\ub2e4\uace0": [15, 16], "\uc8fc\uc7a5\ud568": 15, "diversity\uc640": 15, "fidelity\uc758": 15, "trade": 15, "off\uc5d0": 15, "model\ub4e4\uc774\uba70": 15, "\uc0dd\uc131\ud574\ub0b4\ub294\ub370\uc5d0": 15, "\uc131\uacf5": 15, "\ud588\uc74c": 15, "deep\uc5d0": 15, "\ub0ae\uc73c\uba70": 15, "\uac1c\uc120\uc0ac\ud56d\uc774": 15, "\ud544\uc694\ud568": 15, "\ub450\uac00\uc9c0": 15, "model\ub4e4\uc758": 15, "\ub04c\uc5b4\uc62c\ub9ac\uba70": 15, "\ub0ae\ucd94\uaca0\ub2e4\uace0": 15, "\uc8fc\uc7a5": [4, 15, 18], "\uc124\uba85\ub418\uc788\uc73c\ubbc0\ub85c": 15, "\ub17c\ubb38\ub4e4\uc758": 15, "\ud575\uc2ec": 15, "\uc124\uba85\ud558\uaca0\uc2b5\ub2c8\ub2e4": 15, "\uadfc\uc0ac\uac12\uc774\ub77c\uace0": 15, "\uac00\uc815\ud558\uba70": 15, "\uacc4\uc0b0\ud55c\ub2e4": 15, "approx": [15, 17, 20], "\ub9cc\ub4e0\ub2e4": 15, "\uc608\uce21\ud55c\ub2e4": 15, "\uacf5\ubd84\uc0b0": 15, "\ubd88\uac00\ub2a5\ud55c": 15, "\ub9e4\uac1c\ubcc0\uc218\ub85c": 15, "\uc124\uc815\ub418\uba70": 15, "\uac00\uc9c4\ub2e4": 15, "pipelin": [15, 18], "\uc9c0\ud45c": 15, "ddpm\uc5d0\uc120": 15, "\uc9c0\ud45c\uac00": 15, "\uc0c1\ub300\uc801\uc73c\ub85c": [4, 15], "\ub0ae\uc558\ub2e4": 15, "scheduling\uc744": 15, "\uc0ac\uc6a9\ud588\uc9c0\ub9cc": 15, "\ud588\ub2e4\uace0": 15, "\uc8fc\uc7a5\ud588\ub2e4": 15, "\ud559\uc2b5\uc5d0\ub3c4": 15, "\ub04a\uace0": 15, "\ud615\ud0dc\ub85c": 15, "\ud558\uac8c": [4, 15, 17, 19, 20], "\ubc14\uafc8": 15, "iteration\uc73c\ub85c": 15, "\uadf8\ub300\ub85c": [4, 15], "\ucc44\ud0dd\ud588\uc9c0\ub9cc": 15, "parameter\uc744": 15, "\ubcc0\uacbd\ud558\uc5ec": 15, "\uc124\uba85": [4, 15], "\ud06c\uae30\ub97c": 15, "\uc77c\uc815\ud558\uac8c": 15, "\uac00\uc838\uac00\uba74\uc11c": 15, "\uc99d\uac00": 15, "\ubcf4\uae30": 15, "\uc2dc\ucf1c\ubcf4\uae30": 15, "head\uc5d0": 15, "8x8": 15, "16x16": 15, "\ud574\ubcf4\uae30": 15, "\uc77c\ubc18": 15, "block\uc774": 15, "biggan\uc758": 15, "block\uc744": 15, "connection\uc744": 15, "rescal": 15, "chang": 15, "32\uc77c\ub54c": 15, "\ub0ae\ub2e4": 15, "160": 15, "resolution\uc744": 15, "block\ub9c8\ub2e4": 15, "\uc904\uc774\uae30": 15, "\ud29c\ub2dd\uc744": 15, "\ud14c\uc774\ube14": 15, "adain\uc774\ub791": 15, "\uc5f0\uc0b0\ud558\ub294": 15, "adagn": 15, "\uc18c\uac1c\ud588\ub2e4": 15, "\ubc29\ubc95\ub860\uc778\uc9c0\ub294": 15, "\ubaa8\ub974\uaca0\ub2e4": 15, "normalization\uc744": 15, "adpative\ud558\uac8c": 15, "embedding\uacfc": 15, "adain": 15, "\uacf1\ud558\uace0": 15, "\ub354\ud568": 15, "y_b": 15, "where": 15, "respect": [4, 15, 18], "adagn\uc758": 15, "adagn\uacfc": 15, "additon": 15, "normalization\ubcf4\ub2e4": 15, "\ubcf4\uc5ec\uc8fc\uace0": [15, 16, 18], "addit": 15, "layer\uc744": 15, "\uc0ac\uc6a9\ud588\ub294\ub370": 15, "\ub0ae\uac8c": 15, "\uc8fc": 15, "contribut": [4, 15], "\ud558\ub098\uac00": 15, "\uc0ac\uc6a9\ud588\ub2e4\ub294": 15, "de": 15, "condition\uc73c\ub85c": 15, "\uc90c\uc73c\ub85c\uc368": 15, "zp_": 15, "normalizing\uc744": 15, "\uc0c1\uc218": 15, "log_": 15, "\uace1\ub960\uc774": 15, "\uac00\uc815\uc744": [15, 20], "\ubb34\ud55c\uc73c\ub85c": 15, "rightarrow0": 15, "\uc774\ubbc0\ub85c": [4, 15], "\ud14c\uc77c\ub7ec": 15, "\uae09\uc218\ub97c": 15, "\uc7ac\uc804\uac1c": 15, "classifier\uc758": [15, 18], "\ud65c\uc6a9\ud574\uc11c": [4, 15, 20], "\ud574\uc900\ub2e4": 15, "\uc2dd": 15, "\uc720\ub3c4\ub294": 15, "\ubcf8\ubb38\uc758": 15, "\ubc88\uc2dd\uc774\ubbc0\ub85c": 15, "\ub17c\ubb38\uc744": 15, "\ucc38\uace0\ud558\uba74": 15, "\ubc29\ubc95": [4, 15, 18, 21], "\ubc29\ubc95\uc774\ub2e4": 15, "\ub611\uac19\uc774": 15, "sample\ud55c\ub2e4": 15, "ddim\uc5d0\uc11c": [15, 18], "gradient\uc758": 15, "\ube7c": 15, "score\uc744": 15, "\uad6c\ud55c\ub2e4": 15, "scaling\uc758": 15, "\uc601\ud5a5": 15, "bf": 15, "\uac12\uc5d0": 15, "classifier\uac00": 15, "scaling\uc774": 15, "\ub2e4\ub974\ub2e4": 15, "\uc8fc\uba74": 15, "\uc6f0\uc2dc\ucf54\uae30\ub77c\ub294": 15, "\ub35c": 15, "\uc6f0\uc2dc\ucf54\uae30\uc2a4\ub7ec\uc6b4": 15, "\uac15\uc544\uc9c0\uac00": 15, "\ub418\uc9c0\ub294": 15, "\uc6f0\uc2dc\ucf54\uae30": 15, "class\ub77c\ub294": 15, "\ubd84\uc704\uae30\uc758": 15, "\uac15\uc544\uc9c0\uc758": 15, "epsilon\uc774\ub77c\ub294": 15, "scale\uc5d0": 15, "\ubc1b\ub294\uc9c0": 15, "sampling\ud560": 15, "fidel": [15, 16, 18], "off": 15, "scale\uc774": 15, "recall\uc740": 15, "\ub0ae\uc9c0\ub9cc": 15, "precision\uc740": 15, "\ub192\ub2e4": 15, "\uc0dd\uae30\ub294\ub370": 15, "recall\uc774": 15, "diveristy\uac00": 15, "\ub0ae\ub2e4\ub294": [15, 20], "\uc758\ubbf8\uc774\uace0": 15, "precision\uc774": 15, "\ub192\ub2e4\ub294": 15, "\ub73b\uc774\ub2e4": 15, "\ub192\uc77c\uc218\ub85d": 15, "label\ucabd\uc73c\ub85c": 15, "guide\uac00": 15, "\uc0dd\uae30\ubbc0\ub85c": 15, "\uc77c\uc815\ud55c": 15, "sfid\ub294": 15, "off\ub85c": 15, "\ub3c4\ucd9c\ub418\ub294": 15, "\uac12\uc774\ubbc0\ub85c": 15, "\ucd5c\uace0\uc758": 15, "\uc9c0\uc810\uc5d0\uc11c": 15, "\ub098\uc654\ub2e4": 15, "adm\uc740": 15, "\uc57d\uc790\uc774\uba70": 15, "adm": 15, "g\ub294": 15, "guidance\uc758": 15, "\uc57d\uc790\uc774\ub2e4": 15, "\uc8fc\uc5c8\uc744": 15, "fid\uac12\uc774": [15, 18], "\ub098\uc654\uc73c\uba70": 15, "vice": 15, "versa": 15, "center": 15, "\ub450\ubc88\uca30": 15, "\ud50c\ub77c\ubc0d\uace0": 15, "\ubcfc\ub54c": 15, "biggan\uc740": 15, "\uc774\ubbf8\uc9c0\uac04\ub4e4\uc758": 15, "\ud50c\ub77c\ubc0d\uace0\uac00": 15, "\ub2e4\uc218": 15, "\ub290\ub08c\uc758": 15, "\uc774\ubbf8\uc9c0\ub9cc": 15, "\ubf51\uc544\ub0b8\ub2e4": 15, "\ub2e4\ucc44\ub85c\uc6b4": 15, "\ud55c\ub9c8\ub9ac\ub9cc": 15, "\uc0ac\uc9c4\ub3c4": 15, "\uc2dc\uac04\uc774": 15, "\ub290\ub9ac\ub2e4": 15, "distil": 15, "\ubc95\uc744": 15, "\uace0\ub824": 15, "guidance\ub294": 15, "classif": [15, 17], "function\uc758": 15, "\uc0ac\uc6a9\ud568\uc73c\ub85c\uc368": [4, 15, 19], "label\uc774": 15, "data\uc5d0\ub294": 15, "\ud655\uc7a5\uc774": 15, "\ubd88\uac00\ub2a5\ud558\ub2e4": 15, "unlabel": 15, "sample\uc744": 15, "cluster": 15, "\ubc29\ubc95\ub860\uc744": 15, "expand": 15, "\ud558\ub824": 15, "subject": 16, "driven": 16, "12242": 16, "huggingfac": 16, "\ucd5c\uadfc\uc5d0": [16, 17, 18], "dall": [4, 16, 18, 19], "e2": [4, 16, 19], "imagen": [4, 16], "\ub4f1\uc7a5\ud558\uc600\uc9c0\ub9cc": 16, "\ubd80\ubd84\uc5d0\uc11c": 16, "\uba74\ub4e4\uc744": 16, "\uac1c\uc120\ud558\uae30": 16, "\uae30\ubc95\uc73c\ub85c": [16, 20], "\uc18c\uac1c\ub418\uc5c8\uace0": 16, "5\uc7a5\uc758": 16, "\ub418\uba70": [4, 16, 19], "nvidia": 16, "5\ubd84": 16, "\uc815\ub3c4\ubc16\uc5d0": 16, "\uc18c\uc694\ub418\uc9c0": 16, "\uc54a\ub294\ub2e4\uace0": 16, "\ubb34\uc5c7\uc778\uc9c0": [16, 20], "\uc54c\uc544\ubcf4\uae30": 16, "\uc804\uc5d0": 16, "\uc815\ub9ac\ub97c": 16, "\ud574\ubcfc": 16, "gamma": 16, "\uc785\ub825\ubc1b\uc544\uc11c": 16, "gen": 16, "\uc218\uc2dd\uc801\uc73c\ub85c": [16, 20], "\ud45c\ud604\ud558\uba74": [16, 20], "w_t": 16, "alpha_tx": 16, "t5": 16, "xxl": 16, "\uc0ac\uc6a9\ud588\ub2e4\uace0": [4, 16], "\ud560\ub54c": 16, "\ub54c\ub85c\ub294": 16, "\ud3ec\ud568": 16, "\uc124\uc815\ud558\uace0": 16, "\ud30c\ub77c\ubbf8\ud130": [16, 20], "\uace0\uc815\uc2dc\ud0a8\ub2e4\uace0": 16, "\uc55e\uc368": [4, 16, 19], "\uc124\uba85\ub4dc\ub838\ub358": 16, "\ub0b4\uc6a9\ub4e4\uc744": 16, "blob": 16, "main": 16, "text_encoder_cl": 16, "import_model_class_from_model_name_or_path": 16, "arg": [16, 20], "noise_schedul": 16, "ddpmschedul": 16, "from_pretrain": 16, "subfold": 16, "text_encod": 16, "autoencoderkl": 16, "unet2dconditionmodel": 16, "epoch": [16, 17], "first_epoch": 16, "num_train_epoch": 16, "train_dataload": 16, "skip": [16, 18], "until": 16, "reach": 16, "resum": 16, "resume_from_checkpoint": 16, "resume_step": 16, "progress_bar": 16, "continu": 16, "accumul": 16, "pixel_valu": 16, "weight_dtyp": 16, "latent_dist": 16, "config": 16, "scaling_factor": 16, "offset_nois": 16, "randn": 16, "bsz": 16, "randint": 16, "num_train_timestep": 16, "accord": 16, "magnitud": 16, "noisy_lat": 16, "add_nois": 16, "get": 16, "encoder_hidden_st": 16, "input_id": 16, "model_pr": 16, "prediction_typ": 16, "v_predict": 16, "get_veloc": 16, "part": 16, "model_pred_prior": 16, "target_prior": 16, "mse_loss": 16, "float": 16, "prior_loss": 16, "sync_gradi": 16, "params_to_clip": 16, "itertool": 16, "clip_grad_norm_": 16, "max_grad_norm": 16, "zero_grad": [16, 17], "set_to_non": 16, "set_grads_to_non": 16, "noun": 16, "\uc720\uc9c0\ud558\uace0\uc790": 16, "\ub300\uc0c1\uc5d0": 16, "\ub2f4\ub294": 16, "rare": [4, 16, 19], "3\uac1c": 16, "unicod": 16, "charact": 16, "\ub79c\ub364\ud558\uac8c": 16, "\uc0d8\ud50c\ub9c1\ud574\uc11c": 16, "\uc815\uc758\ud569\ub2c8\ub2e4": [4, 16, 19, 20], "drift": 16, "\ub178\uc774\uc988": 16, "\uc785\ub825\ud558\uc5ec": 16, "\uacc4\uc0b0\ud569\ub2c8\ub2e4": 16, "\uacfc\uc815\uc73c\ub85c": 16, "\ud559\uc2b5\ud558\uace0\uc790": 16, "\uc2dc\ud0a8": 16, "sigma_t": 16, "w_": 16, "alpha_": 16, "\ucd94\uac00\ud568\uc73c\ub85c\uc368": 16, "\uc720\uc9c0\ud558\uac8c": 16, "\uc774\ub85c\uc368": [16, 20], "encourag": 16, "\uac00\uc9c0\uc758": 16, "\uccab\ubc88\uc9f8\ub85c\ub294": 16, "\uce21\uc815\ud558\ub294": [4, 16], "dino": 16, "\uc0dd\uc131\ub418\uae30": 16, "\uc120\ud638\ub41c\ub2e4\uace0": 16, "\uc790\uc138\ud558\uac8c\ub294": [16, 20], "\uacc4\uc0b0\ub429\ub2c8\ub2e4": 16, "pairwis": 16, "vit": 16, "\ube44\uad50\ud588\uc744\ub54c": 16, "ppl": 16, "\uacb0\uacfc\ub3c4": 16, "\uc801\uc6a9\ub428\uc73c\ub85c\uc368": 16, "\uc18c\uac1c\ub4dc\ub838\ub358": 16, "div": 16, "\ud574\uacb0\ub418\ub294": 16, "\ud588\uc744": [4, 16], "\ub9de\ub294": 16, "\uc785\ub825\ud588\uc744\ub54c\uac00": 16, "\uc124\uba85\ud569\ub2c8\ub2e4": 16, "randomli": 16, "incorrect": [4, 16], "can": 16, "backpack": 16, "correct": [4, 16], "recontextu": 16, "descript": 16, "\uc0ac\uc804\uc5d0": 16, "\ub098": [16, 18], "articul": 16, "art": 16, "famou": 16, "painter": 16, "statu": 16, "sculptor": 16, "\uc720\uc9c0\ud55c": 16, "\ucc44": 16, "\ud615\ud0dc\ub3c4": 16, "\uac00\ub2a5\ud569\ub2c8\ub2e4": 16, "novel": 16, "\uac01\ub3c4\uc5d0\uc11c": 16, "\ubcf4\ub294": 16, "\uc0dd\uc131\ub3c4": [16, 18], "properti": 16, "modif": 16, "dog": 16, "speci": 16, "\uace0\uc720": 16, "\ub4e4\uc774": 16, "\uc5d0\uc11c\ub3c4": 16, "\ubc18\uc601\uc774": 16, "\ud55c\uacc4\uc810\ub3c4": 16, "\uc790\uc8fc": 16, "\ub098\ud0c0\ub098\uc9c0": 16, "appear": 16, "\ub2ec\ub77c\uc9c0\ub294": 16, "\ub370\uc774\ud130\uc640": [16, 17, 20], "\ubcf4\uc778\ub2e4\uace0": 16, "\ubcf8\ubb38\uc5d0": 16, "\uc18c\uac1c\ub418\uace0": 16, "\uc788\uc9c0\ub294": 16, "\uc54a\uc9c0\ub9cc": 16, "\ubd80\ubb38\uc5d0\uc11c\ub3c4": 16, "\ud559\uc2b5\uacb0\uacfc\ub97c": 16, "\ubcf4\uc5ec\uc8fc\ub294\ub370": 16, "\uc7a5\ub9cc\uc73c\ub85c\ub3c4": 16, "18": [4, 16], "\ub9cc\ud654": 16, "\uc0ac\ub840\ub4e4\uc744": 16, "2014": [17, 20], "1406": 17, "2661": 17, "eriklindernoren": 17, "smart": [17, 20], "lab": [17, 20, 21], "kaist": [17, 20], "\ub525\ub7ec\ub2dd": [17, 20], "chp": 17, "ian": 17, "goodfellow": 17, "2014\ub144\uc5d0": 17, "\ubc1c\ud45c\ud55c": 17, "\uc18c\uac1c\ub418\uae30": 17, "\uc804\uae4c\uc9c0": 17, "\ub144": 17, "\ub3d9\uc548": [4, 17], "\uc0dd\uc131\ubd84\uc57c\uc5d0\uc11c": 17, "\ub300\ud45c\uc801\uc778": 17, "\uc790\ub9ac\uc7a1\uc558\uc5c8\uc2b5\ub2c8\ub2e4": 17, "margin": [17, 20], "\uc0d8\ud50c\ub9c1\uc744": 17, "\uad6c\ud558\uac8c": 17, "taxonomi": 17, "\uc7a0\uc7ac\ubcc0\uc218": [17, 20], "\uadf8\ub85c\ubd80\ud130": 17, "\uad6c\ubd84\ud558\ub294": 17, "\uad6c\uc131\uc774": 17, "\ub9d0\ud574\uc11c": 17, "\ub4e4\uc5b4\uc624\uba74": 17, "\uac00\uc9dc\ub85c": 17, "\ucd9c\ub825\ud558\ub294": 17, "binari": 17, "\uc9c4\ud589\ud569\ub2c8\ub2e4": 17, "\ucf54\ub4dc\ub3c4": 17, "\uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 17, "in_feat": 17, "out_feat": 17, "batchnorm1d": 17, "leakyrelu": 17, "inplac": 17, "opt": 17, "latent_dim": 17, "np": 17, "prod": 17, "img_shap": 17, "tanh": 17, "img": 17, "sigmoid": [17, 20], "img_flat": 17, "d\ub97c": 17, "g\ub97c": 17, "\ub2e8\uacc4\ub97c": 17, "\ubc88\uac08\uc544": 17, "\uc190\uc2e4\ud568\uc218": [17, 20], "min_g": 17, "max_d": 17, "p_z": 17, "\uc54c\uace0\ub9ac\uc998\uacfc": 17, "\ube44\uad50\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 17, "n_epoch": 17, "variabl": [17, 20], "fill_": 17, "fake": 17, "real_img": 17, "optimizer_g": 17, "gen_img": 17, "measur": 17, "abil": 17, "fool": 17, "g_loss": 17, "adversarial_loss": 17, "optimizer_d": 17, "real_loss": 17, "fake_loss": 17, "d_loss": 17, "print": 17, "item": 17, "batches_don": 17, "sample_interv": 17, "save_imag": 17, "png": 17, "nrow": 17, "\ucd5c\ub300\ud654\ud558\uace0": 17, "descent": 17, "\uc9c4\ud589\ud558\uac8c": 17, "\uc77c": [4, 17], "\ud559\uc2b5\ud558\uc9c0": 17, "\uc0c1\ud669\uc774": 17, "\ubc1c\uc0dd\ud569\ub2c8\ub2e4": [4, 17, 19], "\ucd5c\uc18c\ud654\ud558\uc9c0": 17, "\ucd5c\ub300\ud654\ud558\ub294": 17, "\uae30\ubc95\ub3c4": 17, "\ucd5c\uc801\ud654\ub41c": 17, "solut": 17, "\uc644\ubcbd\ud788": 17, "\ubcf5\uc6d0\ud558\uace0": 17, "\ud655\ub960\uc744": [4, 17], "\uc5b8\uc81c\ub098": 17, "\ub0b4\ubc49\uac8c": 17, "proposit": 17, "p_g": 17, "\uc99d\uba85\ud558\uc790\uba74": 17, "\uc190\uc2e4\ud568\uc218\ub97c": 17, "\uc4f8": [4, 17], "\uc788\uace0": [4, 17, 19, 20], "int_x": 17, "int_z": 17, "dz": [17, 20], "\uc77c\ub54c": 17, "\uc131\ub9bd\ud558\uace0": 17, "\uc190\uc2e4\ud568\uc218\ub294": 17, "\uac19\uace0": 17, "ast": 17, "jsd": 17, "\ucd5c\uc19f\uac12\uc740": 17, "\uc774\uace0": [17, 20], "\uc131\ub9bd\ud569\ub2c8\ub2e4": 17, "mnist": 17, "toronto": 17, "databas": 17, "tfd": 17, "\ud3c9\uac00\ud588\uc2b5\ub2c8\ub2e4": 17, "\ud3c9\uac00\uc2dc\uc5d0\ub294": 17, "parzen": 17, "densiti": 17, "\uac70\uccd0": 17, "vae\ub294": 17, "\ud750\ub9bf\ud558\ub2e4\ub294": 17, "\ub2e8\uc810\uc744": [17, 20], "\uc9c0\ub2c8\uace0": [4, 17, 19], "unstabl": 17, "converg": [17, 18], "\ucc28\uc6d0\ucd95\uc18c\ub85c": 17, "\ud65c\uc6a9\ub418\uace0": 17, "\uc0dd\uc131\ud558\ub294\ub370\ub294": 17, "\ud65c\uc6a9\ub418\uc5c8\ub2e4\uace0": 17, "editbench": [4, 19], "advanc": 19, "guid": [4, 19], "inpaint": [4, 19], "06909": 19, "sep": [4, 18, 19], "06": 19, "introduct": [], "\uc2dc\uac04\uc5d0\ub294": [4, 19], "googl": [4, 19], "research": [4, 19], "\uc18c\uac1c\ud558\ub294": [4, 19, 20], "\uae30\ubc18\uc758": [4, 19], "impaint": [4, 19], "\ud3c9\uac00\uae30\ubc95": [4, 19], "\uc608\uc815\uc785\ub2c8\ub2e4": [4, 19], "\uae30\uc874\uc5d0\ub294": [4, 19], "\uc601\uc5ed\uc744": [4, 19], "\uc9c0\uc815\ud558\uc5ec": [4, 19], "\ub428\uc73c\ub85c\uc368": [4, 19], "\ucc38\uc870\ud558\uc9c0": [4, 19], "\uc624\ub85c\uc9c0": [4, 19], "\ub9cc\uc73c\ub85c": [4, 19], "\ucc38\uc870\ud560": [4, 19], "\uc720\ub3c4\ud558\ub294": [4, 19], "ssd": [4, 19], "mobilenet": [4, 19], "v2": [4, 19], "detector": [4, 19], "\uac1c\uc120\ub418\ub294": [4, 19], "\ud2b9\uc9d5\uc740": [4, 19], "cascad": [4, 19], "\uc810\uc785\ub2c8\ub2e4": [4, 19], "sr3": [4, 19], "palett": [4, 18, 19], "glide": [4, 19], "\ud558\uba74\uc11c": [4, 19], "\uac00\uc9c4\ub2e4\uace0": [4, 19], "256x256": [4, 19], "\uc791\uc5c5": [4, 19], "\uc785\ub825\ud569\ub2c8\ub2e4": [4, 19], "\ud6a8\uacfc\ub97c": [4, 18, 19], "\ub0b4\uae30": [4, 19], "\uc0c8\ub85c": [4, 19], "\ucd94\uac00\ub418\ub294": [4, 19], "\ucd08\uae30\ud654\ud574\uc11c": [4, 19], "\uc9c4\ud589\ud588\ub2e4\uace0": [4, 19], "\uc18c\uac1c\ub418\uc5c8\ub358": [4, 19], "free": [4, 19], "guidanc": [4, 19], "\ub3d9\uc77c\ud558\uac8c": [4, 19], "1\ubd80\ud130": [4, 19], "30": [4, 19], "\ubc94\uc704": [4, 18, 19], "\ubcc0\ud654\uc2dc\ud0a4\ub294": [4, 19], "oscil": [4, 19], "\uc801\uc6a9\ud568\uc73c\ub85c\uc368": [4, 19], "\ud004\ub9ac\ud2f0": [4, 19], "\uc0c1\uc2b9\ub418\ub294": [4, 19], "\ud3c9\uac00\ud560": [4, 19], "benchmark": [4, 18, 19], "240\uac1c\uc758": [4, 19], "\uc30d\uc73c\ub85c": [4, 19], "\uad6c\ucd95\ub418\uc5b4\uc788\uace0": [4, 19], "\uc30d\ub9c8\ub2e4": [4, 19], "3\uac00\uc9c0\uc758": [4, 19], "\uce21\uc815\ud558\uac8c": [4, 19], "\uc73c\ub85c\ub294": [4, 19], "clipscor": [4, 19], "prec": [4, 19], "\ub370\uc774\ud130\uc14b\uc758": [4, 19], "\uc808\ubc18\uc740": [4, 19], "open": [4, 19], "vision": [4, 19], "\ub370\uc774\ud130\uc14b\uc73c\ub85c\ubd80\ud130": [4, 19], "\uc218\uc9d1\ub418\uc5c8\uace0": [4, 19], "\uc0dd\uc131\ud574\uc11c": [4, 19], "\uad6c\ucd95\ud588\uc2b5\ub2c8\ub2e4": [4, 19], "scene": [4, 19], "\uc694\uc18c\ub4e4\uc744": [4, 19], "\uac16\ucd94\ub3c4\ub85d": [4, 19], "\uc0dd\uc131\ud588\uc2b5\ub2c8\ub2e4": [4, 19], "materi": [4, 19], "count": [4, 19], "common": [4, 19], "render": [4, 19], "indoor": [4, 19], "outdoor": [4, 19], "realist": [4, 19], "\ub4e4\uc5b4\uc11c": [4, 19], "metal": [4, 19], "\ubb38\uad6c\ub97c": [4, 19], "stand": [4, 19], "farm": [4, 19], "3\uac00\uc9c0": [4, 18, 19], "\ud574\ub2f9\uc0ac\uc9c4\ucc98\ub7fc": [4, 19], "rich": [4, 19], "\uad6c\ucd95\uc2dc": [4, 19], "\ud06c\uae30\ub3c4": [4, 19], "\ub2e4\uc591\ud558\uac8c": [4, 19], "\uc124\uc815\ud558\uc5ec": [4, 19], "\ud06c\uae30\uc5d0": [4, 19], "\uce21\uc815\ud574\ubcf8": [4, 19], "medium": [4, 19], "\uc131\ub2a5\uc801\uc73c\ub85c": [4, 19], "\uc6d4\ub4f1\ud788": [4, 19], "\uc88b\ub2e4\ub294": [4, 19], "\uc800\ud558\ub418\ub294": [4, 19], "\uc18d\uc131\ubcf4\ub2e4": [4, 19], "\uc18d\uc131\uc5d0": [4, 19], "\ucde8\uc57d\ud55c": [4, 19], "failur": [4, 19], "\ube44\uad50\ud55c": [4, 19], "\uc0ac\uc9c4\uc785\ub2c8\ub2e4": [4, 19], "maskrich": [4, 19], "auto": 20, "bay": 20, "1312": 20, "6114": 20, "gunhochoi": 20, "fastcampu": 20, "ch": 20, "\ubb38\uad6c\uac00": 20, "\uc801\ud600\uc788\ub294\ub370\uc694": 20, "bayesian": 20, "vb": 20, "approach": [20, 21], "involv": 20, "\uc774\ucc98\ub7fc": 20, "autoencod": 20, "\uc81c\uc2dc\ud558\ub294": 20, "aevb": 20, "\uc54c\uace0\ub9ac\uc998": 20, "\ub274\ub7f4": 20, "\ub124\ud2b8\uc6cc\ud06c\ub85c": 20, "\uadfc\uc0ac\ud568\uc73c\ub85c\uc368": 20, "\uc774\uac00": 20, "\ubc14\uac00": 20, "\uc0b4\ud3b4\ubcf4\ub3c4\ub85d": 20, "\ubd80\ubd84\uc73c\ub85c": 20, "encoder\ub294": 20, "\ub9cc\ub4e4\uc5b4\ub0b4\uace0": 20, "\ubcf5\uc6d0\ud558\uac8c": 20, "assumpt": 20, "\ub4e4\uc744": [18, 20], "\ub0b4\ub9bd\ub2c8\ub2e4": 20, "\uccab\ubc88\uc9f8\ub85c": 20, "parametr": 20, "differenti": 20, "\ud558\ub2e4\ub294": 20, "\ub530\ub974\uace0": 20, "\uc131\uc9c8\uc5d0": 20, "bernoulli": 20, "\ub530\ub974\ub3c4\ub85d": 20, "\uad6c\uc131\ub41c": 20, "\uacc4\uc0b0\uc774": 20, "overview": 20, "\ucd5c\ub300\ud654\uc2dc\ud0a4\ub294": 20, "\uad6c\ud558\ub294": 20, "\uacc4\uc0b0\ud558\uae30": 20, "\ub4f1\uc7a5\ud558\uac8c": 20, "\uc5ed\uc2dc": [4, 20], "\uadfc\uc0ac\ud654\ud558\ub294": 20, "\ub124\ud2b8\uc6cc\ud06c": 20, "\uc815\uc758\ud558\uac8c": 20, "\ub3c4\uc2dd\ud654\ud55c": 20, "\uadf8\ub9bc\uc785\ub2c8\ub2e4": [4, 20], "\uc815\ub9ac\ud558\uc790\uba74": 20, "\uacc4\uc0b0\ub41c": 20, "\ud655\uc778\ud574\ubcf4\uaca0\uc2b5\ub2c8\ub2e4": 20, "fc1_1": 20, "784": 20, "hidden_s": 20, "fc1_2": 20, "relu": 20, "log_var": 20, "reparametr": 20, "logvar": 20, "std": 20, "mul": 20, "exp_": 20, "ep": 20, "floattensor": 20, "cuda": 20, "add_": 20, "reparam": 20, "fc1": 20, "\ucc3e\uc73c\uba74": 20, "error": 20, "\ubd84\ud560\ud560": 20, "min_": 20, "g_": 20, "\uc720\uc0ac\ud558\ub3c4\ub85d": 20, "\uc7a0\uc7ac\ubcc0\uc218\uc758": 20, "\uc800\ud76c\uac00": 20, "\ubd80\uc5ec\ud55c": 20, "\uac00\uae5d\ub3c4\ub85d": 20, "\uc124\uc815\ud558\ub294": 20, "mont": 20, "carlo": 20, "\uadfc\uc0ac\uac12\uc744": 20, "\uad6c\ud560": 20, "\uc5f0\uc0b0\ub7c9\uc774": 20, "\ub9ce\uc73c\ubbc0\ub85c": 20, "\uc124\uc815\ud569\ub2c8\ub2e4": 20, "\uae30\ubc95\uc740": 20, "\uc0d8\ud50c\ub9c1\ud558\uc9c0": 20, "backpropag": 20, "\uac00\ub2a5\ud558\ub3c4\ub85d": 20, "\uc0d8\ud50c\ub9c1\ud558\uace0": [4, 20], "\ub354\ud558\uace0": 20, "\uacf1\ud558\uac8c": 20, "\ub530\ub978\ub2e4\uace0": 20, "\uc124\uc815\ud588\uc744": 20, "\ub54c\uc774\uace0": 20, "\uac00\uc815\ud560": 20, "\uadf8\uc5d0": [4, 20], "\uc2dc\ub3c4\ud560": 20, "\uba85\uc2dc\ub418\uc5b4": 20, "\uc9c0\uc815\ud574\uc92c\ub2e4\uba74": 20, "\ud30c\ub77c\ubbf8\ud130\ub4e4\uacfc": 20, "\uc7a0\uc7ac\ubcc0\uc218\ub97c": 20, "\uc0ac\uc6a9\ud574\ubcf4\uba74": 20, "repositori": 21, "pseudo": 21, "team": 21, "bulb": 21, "aim": 21, "relat": [4, 21], "them": 21, "theoret": 21, "conduct": 21, "experi": 21, "\ucc38\uc5ec": 21, "\ub9e4\uc8fc": 21, "\uc218\uc694\uc77c": 21, "\uc624\ud6c4": 21, "9\uc2dc": 21, "\uac00\uc9dc\uc5f0\uad6c\uc18c": 21, "discord": 21, "room": 21, "dh": 21, "\uc785\uc7a5": 21, "photorealist": [4, 18], "neurip": 18, "2205": 18, "11487": 18, "learning\uc774": 18, "\ubc1b\uace0": 18, "\ub354\ubd88\uc5b4": 18, "\ub3c5\ucc3d\uc801\uc778": 18, "\uc804\uc6a9": 18, "\ub9d0\ubb49\uce58": 18, "corpu": 18, "llm\ub4e4\uc758": 18, "embedding\ub4e4\uc740": 18, "\ud6a8\uacfc\uc801\uc774\ub77c\uace0": 18, "\ucda9\uc2e4\ub3c4": 18, "frozen": 18, "\uc0ac\uc774\uc988\ub97c": 18, "\uc911\uc694\ud558\ub2e4\ub294": 18, "\uc99d\uba85\ud568": 18, "\uc81c\uc2dc\ud558\uc5ec": 18, "weight\uc744": 18, "leverag": 18, "\ub9cc\ub4e4\uc5b4": 18, "\ud604\uc2e4\uc801\uc778": 18, "\uad6c\uc870\ubcf4\ub2e4": 18, "\uc81c\uc2dc\ud568": 18, "\uc810\uc218": 18, "27": 18, "\ub2ec\uc131\ud568": 18, "evaluation\uc6a9": 18, "\uad6c\uae00": 18, "encoder\uc744": 18, "\ud574\ub193\uc74c": 18, "improv": 18, "ddpm": 18, "sr": 18, "\uc774\ub780": 18, "guidance\uac00": 18, "generation\uc774": 18, "\uc77c\uc815\ud558\uc9c0": 18, "\ubabb\ubc1b\uc544\uc11c": 18, "class\ub098": 18, "object\uc774": 18, "\uc77c\uc815\ud558\uace0": 18, "\ubb34\uc5c7\uc744": 18, "\uc0dd\uc131\ud558\ub294\uac83\uc778\uc9c0": 18, "\uc790\uc138\ud558\uac8c": 18, "guide\uc758": 18, "\ub192\uc774\uba74": 18, "\ubd88\uc77c\uce58\uac00": 18, "\uc0dd\uae34\ub2e4": 18, "\uc774\ub85c": 18, "\uac00\uc911\uce58\uc758": 18, "\ud3c9\uade0\uacfc": 18, "\ubd84\uc0b0\uc744": 18, "\uc774\ub3d9\uc2dc\ucf1c": 18, "\uc544\uc608": 18, "\ube57\ub098\uac00": 18, "\uc774\uc0c1\ud55c": 18, "satur": 18, "\ub35c\ud55c": 18, "\ub40c": 18, "\ud574\uacb0\ud558\uace0\uc790": 18, "\ubc31\ubd84\uc704\uc218": 18, "\uc808\ub300": 18, "\ud53d\uc140": 18, "\uc9c0\uc815\ud558\uace0": 18, "\uc784\uacc4\uac12\uc744": 18, "\uc9c0\uc815\ud55c": 18, "s\ub85c": 18, "\ub098\ub208\ub2e4": 18, "90": 18, "\uc9c0\uc810\uc758": 18, "3\uc73c\ub85c": 18, "\ucc28\uc774\ub294": 18, "among": 18, "net\uc774\ub77c\ub294": 18, "net\uc5d0\uc11c": 18, "\uc5ec\ub7ec\uac00\uc9c0": 18, "modification\uc744": 18, "\ud558\uc600\ub2e4\uace0": 18, "\uadf8\ub807\uc9c0\ub9cc": 18, "effu": 18, "net\uc740": 18, "\uc758\ub8cc\ucabd\uc73c\ub85c": 18, "\uc788\ub294\uac78\ub85c": 18, "\uc544\ub294\ub370": 18, "remov": 18, "keep": 18, "connect": 18, "scaling\uc744": 18, "\ud558\uc5ec": 18, "block\uc5d0\uc11c": 18, "blocks\ub97c": 18, "\ucd94\uac00\ud568": 18, "\ubca4\uce58\ub9c8\ud06c": 18, "\ub370\uc774\ud130\uc14b\uc740": 18, "categori": 18, "\uc774\ub8e8\uc5b4\uc84c\ub2e4": 18, "\uae43\ud5c8\ube0c\uc5d0\uc11c": 18, "\ub2e4\uc6b4": 18, "\ubc1b\uc744": [4, 18], "\uac17\ub2e4": 18, "11": 18, "25\uba85\uc758": 18, "\ud3c9\uac00\uc790": 18, "a\uc5d0\uc11c": 18, "\ud3c9\uac00\uc790\ub294": 18, "\uc9c8\ubb38\uc744": 18, "\uc8fc\uba70": 18, "\uae30\uc900\uc810\uc73c\ub85c": 18, "q1": 18, "higher": 18, "q2": 18, "better": 18, "repres": 18, "\uae30\uc900\uc810": 18, "\ub2f5\ubcc0": 18, "\uc120\ud0dd\ud574\uc57c\ud568": 18, "am": 18, "indiffer": 18, "screenshot": 18, "drawbench\uc5d0\uc11c": 18, "\uccb4\ub9ac\ud53c\ud0b9": 18, "\uc5c6\uc774\ub3c4": 18, "\uce74\ud14c\uace0\ub9ac\uc5d0\uc11c\ub3c4": 18, "\uc8fc\uc7a5\uc778": 18, "coco\ub85c": 18, "\ubaa8\ub378\ub4e4": 18, "\ub192\uc74c": 18, "imagen\uc774": 18, "peopl": 18, "photor": [4, 18], "\uc62c\ub77c\uac10": 18, "people\uc744": 18, "\uc0dd\uc131\ud558\uae30\uc5d0": 18, "rater": 18, "\ub4e4\uc740": 18, "xxl\ub85c": 18, "\uc120\ud638\ud568": 18, "\ubaa8\ub378\uc778": 18, "\ubc1b\uc74c": 18, "evaul": 18, "\uc911\uc694\ud568": 18, "\uc0ac\uc774\uc988\uc758": 18, "\uc810\uc218\uc5d0": 18, "\ub07c\uce68": 18, "boost\uc5d0": 18, "thresholding\uc744": 18, "\ub04c\uc5b4": 18, "\uc62c\ub9b4": 18, "show": 18, "multimod": [4, 18], "allow": 18, "usag": 18, "much": 18, "hierarch": 4, "2204": 4, "06125v1": 4, "seonhoon": 4, "2022\ub144\uc5d0": 4, "\uacf5\uac1c\ub418\uc5b4": 4, "\uc138\uc0c1\uc744": 4, "\ub180\ub77c\uac8c": 4, "\ub2a5\ub825\ub3c4": 4, "\ub6f0\uc5b4\ub0ac\uace0": 4, "\uc0ac\uc6a9\uc790": 4, "\uc785\ub9db\uc5d0": 4, "\uc870\uc791\ud560": 4, "\ub418\uc5c8\uc8e0": 4, "\uc774\ub984\uc740": 4, "\uc77c\uae4c\uc694": 4, "\ucd08\ud604\uc2e4\uc8fc\uc758": 4, "\ud654\uac00": 4, "salvador": 4, "dali": 4, "wall": 4, "\ud569\uc131\uc5b4\uc785\ub2c8\ub2e4": 4, "\uc0dd\uc131\ud574\ub0b8": 4, "\uacfc\uc5f0": 4, "\uc5b4\ub5bb\uae38\ub798": 4, "\uc5d0\uac8c": 4, "vibrant": 4, "robot": 4, "half": 4, "\uc8fc\uace0": 4, "\ubcf4\uc774\ub124\uc694": 4, "\ucd08\ud604\uc2e4\uc8fc\uc758\uc801": 4, "\uac19\uae30\ub3c4": 4, "corgi": 4, "\uc5b4\ub5a4\uac00\uc694": 4, "\uc131\uc6b4\uc758": 4, "\ud3ed\ubc1c\ub85c": 4, "\ubb18\uc0ac\ud574\ub2ec\ub77c\uace0": 4, "nasa": 4, "\ucd2c\uc601\ud55c": 4, "\ucd08\uc2e0\uc131": 4, "\ud3ed\ubc1c\uc758": 4, "\uc794\ud574\uc785\ub2c8\ub2e4": 4, "\uc815\ub9d0": 4, "\uadf8\ub7f4\ub4ef\ud558\uc9c0": 4, "\uc54a\ub098\uc694": 4, "\uc8fc\uc758\uc0ac\ud56d": 4, "\uc694\uc57d\uc740": 4, "openai": 4, "assemblyai": 4, "eden": 4, "meyer": 4, "\ucc38\uace0\ud588\uc2b5\ub2c8\ub2e4": 4, "\ud1b5\ud569\uc2dc\ucf30\uc2b5\ub2c8\ub2e4": 4, "\ucd5c\ucd08\ub294": 4, "fundament": 4, "principl": 4, "quit": 4, "associ": 4, "simultan": 4, "minim": 4, "\uc815\ub2f5\uc740": 4, "22\ub144": 4, "5\uc6d4": 4, "\uc0ac\uc6a9\ud558\uc9c0": 4, "\ub0b4\uc8fc\uc5c8\uc2b5\ub2c8\ub2e4": 4, "\ucc0d\uba39\ud558\uae30": 4, "\ub0b4\uc758": 4, "\ud3ec\ucc29\ud574\ub0bc": 4, "\ub04c\uc5b4\uc62c\ub9ac\uae30": 4, "\ud1b5\ud569\ud55c": 4, "stage": 4, "\uc774\uac83\uc774": 4, "\uc778\ub370\uc694": 4, "unclip": 4, "\ubd80\ub985\ub2c8\ub2e4": 4, "\ubcf5\uc7a1\ud574\ubcf4\uc774\ub2c8": 4, "assembl": 4, "\ub2e8\uc21c\ud654\ub41c": 4, "\uc0b4\ud3b4\ubcfc\uac8c\uc694": 4, "f1x4fhzf4mq": 4, "360": 4, "ab_channel": 4, "\ucea1\uc158\uc744": 4, "\uc0c1\uc751\ud558\ub294": 4, "autogregress": 4, "\ube44\uad50\ud558\ub294": 4, "\uc218\ud589\ud588\uc2b5\ub2c8\ub2e4": 4, "computation": 4, "\uace0\ud488\uc9c8": 4, "\ud6c4\ubc18\ubd80\uc5d0\ub294": 4, "\uc2e4\ud5d8\ud569\ub2c8\ub2e4": 4, "\ubaa8\ub378\ub9cc": 4, "\uc0ac\uc6a9\ud588\uc744\uae4c\uc694": 4, "\uc131\uacf5\uc744": 4, "\uac70\ub450\uace0": 4, "shift": 4, "robust": 4, "capabl": 4, "\ub6f0\uc5b4\ub0ac\uc2b5\ub2c8\ub2e4": 4, "\ub2ec\uc131\ud574\ub0c8\uc2b5\ub2c8\ub2e4": 4, "tak": 4, "\uac31\uc2e0\ud558\ub294": 4, "\uc911\uc774\uc5c8\uc8e0": 4, "\ub355\ubd84\uc5d0": 4, "essenti": 4, "\ubcc0\uc8fc\ud558\uba74\uc11c": 4, "\uc720\uc9c0": 4, "\uc788\uc8e0": 4, "\ud574\uc918": 4, "\uc790\uccb4\uc758": 4, "\uc870\uac74\uc73c\ub85c": 4, "\uc790\uccb4\ub3c4": 4, "\ubc1b\uc2b5\ub2c8\ub2e4": 4, "\ubb3c\ub860": 4, "1\ub3001": 4, "\ub300\uc751\ub418\uae30": 4, "duel": 4, "\ubb38\uc81c\ub420": 4, "\ubcc0\ub860\ud569\ub2c8\ub2e4": 4, "\ud004\ub9ac\ud2f0\ub97c": 4, "2\uac1c\uc758": 4, "dot": 4, "product": 4, "modifi": 4, "\ud1b5\ud569\uc2dc\ud0ac": 4, "\uc8fc\uc7a5\ud569\ub2c8\ub2e4": 4, "\ud1b5\ud569\uc2dc\ud0a4\ub0d0\ud558\uba74": 4, "\ud558\ub294\uac70\uc8e0": 4, "\uc601\uc0c1\uc744": 4, "\uc218\uc815\ud574": 4, "\uc788\ub358": 4, "\uadf8\ub807\ub2e4\uba74": 4, "\ud544\uc694\ud560\uae4c\uc694": 4, "obtain": 4, "combin": 4, "possibl": 4, "given": 4, "\uc544\ud0a4\ud14d\uccd0\ub97c": 4, "\ubaa8\ub378\ucc98\ub7fc": 4, "\uac16\ucd94\uace0": 4, "\ud6cc\ub96d\ud588\uc2b5\ub2c8\ub2e4": 4, "95": 4, "\uc801\uc6a9\ud574": 4, "\uc2e4\ud5d8\ud588\uc2b5\ub2c8\ub2e4": 4, "\uacf5\uc815\ud55c": 4, "\uc2e4\ud5d8\uc774\ub77c\uace0": 4, "\ubcf4\uae34": 4, "\uc5b4\ub824\uc6b8": 4, "\ud559\uc2b5\uc2dc\ucf30\uc744": 4, "\ub54c\uc758": 4, "\uc2e4\ud5d8\uc740": 4, "\ubc18\ub4dc\uc2dc": 4, "\uc368\uc57c\ud558\ub294": 4, "\uadfc\uac70\uc5d0": 4, "\uc124\ub4dd\ub825\uc774": 4, "\ub5a8\uc5b4\uc9c4\ub2e4\uace0": 4, "\uc0dd\uac01\ud588\uc2b5\ub2c8\ub2e4": 4, "\uc368\uc57c\ud560\uac00\uc694": 4, "\ubb18\uc0ac\ud55c": 4, "\uac1d\uccb4\uc758": 4, "\ubc1c\ud604": 4, "\uc758\ubbf8\ub860\uc801": 4, "\ud559\uc2b5\ud588\uc2b5\ub2c8\ub2e4": 4, "\ub2a5\ub825\uc774": 4, "\uc88b\uc544": 4, "\uc0dd\uc131\ubb3c\uacfc": 4, "\uc0dd\uc131\ubb3c\uc744": 4, "\uc0ac\ub78c\ub4e4\uc5d0\uac8c": 4, "\uc81c\uc2dc\ud558\uace0": 4, "\ud558\ub3c4\ub85d": 4, "\ud558\ub2e4": 4, "\ub6f0\uc5b4\ub098\ub2e4": 4, "bipartit": 4, "\uc218\ud589\ud560": 4, "\uc5bb\uc73c\uba70": 4, "\ubcf5\uc6d0\ud558\ub294\ub370": 4, "\uc794\uc5ec": 4, "\uc815\ubcf4\ub4e4\uc744": 4, "\uc9c0\ub2d8": 4, "\ubcc0\uc8fc\ud558\uae30": 4, "\uc801\uc6a9\ud55c\ub2e4": 4, "\ud574\uc9c0\uace0": 4, "\ubcf5\uc6d0\ud574\ub0b8\ub2e4": 4, "\uc0dd\uae30\uace0": 4, "\uadfc\ucc98\uc5d0\uc11c": 4, "centere": 4, "\ub9cc\ub4e4\uc5b4\ub0bc": 4, "\uac83\uc774\ub2e4": 4, "\ud0a4\uc6b0\uba74": 4, "\uc874\uc7ac\ud558\uace0": 4, "\uc720\uc2e4\ub418\uc5c8\ub294\uc9c0": 4, "\ud0d0\uc0c9": 4, "\ud0d0\uc0c9\ud574\ub0bc": 4, "\uc900\ub2e4\uba74": 4, "diff": 4, "\ucea1\uc158\uc774": 4, "\uc8fc\uc5b4\uc838\uc788\uc744": 4, "z_t0": 4, "embd": 4, "\uc870\uc791\ub41c\ub2e4": 4, "against": 4, "typograph": 4, "attak": 4, "attack": 4, "\ub0b4": 4, "\uc0ac\ubb3c": 4, "\uc704\uc5d0": 4, "\uae00\uc528\uac00": 4, "\uc4f0\uc5ec": 4, "\uacbd\uc6b0\uc774\ub2e4": 4, "\ud14d\uc2a4\ud2b8\uc5d0": 4, "\uc0ac\ubb3c\uc744": 4, "\ud310\ub2e8\ud558\ub294": 4, "ipod": 4, "\uc885\uc774\uac00": 4, "\uc0ac\uacfc\ub97c": 4, "\ubd84\ub958\ub97c": 4, "\uc218\ud589\ud574\ubcf4\uc558\ub2e4": 4, "granni": 4, "smith": 4, "\uac00\uae5d\ub2e4\uace0": 4, "\ud310\ub2e8\ud588\ub2e4": 4, "\uc0ac\uacfc\uc758": 4, "recov": 4, "\ud574\ub0b8\ub2e4": 4, "\ub2e8\uc810\uc740": 4, "cube": 4, "\ub9e4\uce6d\uc2dc\ud0a4\ub294": 4, "\ub5a8\uc5b4\uc9d0": 4, "\uc77c\uad00\uc131\uc788\uac8c": 4, "\ubcf5\uc7a1\ud55c": 4, "\ubb18\uc0ac\ud558\ub294": 4, "\uc544\ud0a4\ud14d\uccd0\uc5d0": 4, "\uc218\ud559\uc801": 4, "justifi": 4, "\ub77c": 4, "\uc800\uc790\uc758": 4, "\uc0d8\ud50c\ub9c1\ud560": 4, "equal": 4, "hold": 4, "becaus": 4, "second": 4, "rule": 4, "\ubd80\uac00": 4, "\uc0d8\ud50c\ub9c1\ud568\uc73c\ub85c\uc368": 4, "\uc0d8\ud50c\ub9c1\uc774": 4, "preview": 4, "safeti": 4, "\ub178\ub825": 4, "\ub370\uc774\ud130\uc5d0\uc11c": 4, "violent": 4, "hate": 4, "adult": 4, "\uc81c\uac70\ud568\uc73c\ub85c\uc368": 4, "\ub178\ucd9c\ub418\ub294": 4, "\uc2dc\uac04\uc744": 4, "\ucd5c\uc18c\ud654\ud568": 4, "polici": 4, "\uc704\ubc18\ud55c": 4, "\uc790\uc815\ud558\ub294": 4, "\uc2dc\uc2a4\ud15c": 4, "\ubcf4\uc720": 4, "\uc2e0\ub8b0\ud560": 4, "\uc804\ubb38\uac00\ub4e4\uacfc": 4, "\uac80\ud1a0\ub97c": 4, "\uc9c4\ud589\ud588\uc74c": 4, "\uc0dd\uc131\ud615": 4, "\ud3c9\uac00\ud558\ub294": 4, "2202": 4, "04053": 4, "dallev": 4, "\ub2a5\ub825": 4, "3\uac00\uc9c0\ub97c": 4, "\ud3c9\uac00\ud558\uae30": 4, "\uc81c\uacf5": 4, "recognit": 4, "skill": 4, "spaial": 4, "\uc774\ud574": 4, "\ub2a5\ub825\uc740": 4, "\ub5a8\uc5b4\uc9d0\uc744": 4, "\ubc1c\uacac": 4, "\uc874\uc7ac\ud558\ub294": 4, "gender": 4, "skin": 4, "tone": 4, "bias": 4, "\ucd5c\ucd08\uc758": 4, "web": 4, "t2i": 4, "\ud559\uc2b5\ud588\uc74c\uc744": 4, "social": 4, "sec": 4, "\ucc38\uace0": 4, "diagnost": 4, "\uc0dd\uc131\ud55c\ub2e4": 4, "who": 4, "work": 4, "nurs": 4, "252\uac1c\uc758": 4, "\uc774\ubbf8\uc9c0\ub85c\ubd80\ud130": 4, "\ud0d0\uc9c0": 4, "autom": 4, "detect": 4, "verifi": 4, "reliabl": 4, "blip": 4, "\uc8fc\uba74\uc11c": 4, "\uc601\uc0c1": 4, "\uc131\ubcc4\uc744": 4, "\ub9de\ucd94\uac8c": 4, "\ub2f5\ubcc0\uc744": 4, "\uc2e0\uacbd\ub9dd\uc73c\ub85c": 4, "landmark": 4, "\ucd94\ucd9c\ud558\uace0": 4, "illumin": 4, "\ubcf5\uc7a5\uc744": 4, "\ud0d0\uc9c0\ub41c": 4, "unbias": 4, "\uc73c\ub85c\ubd80\ud130": 4, "skew": 4, "\ub418\uc5b4\uc788\ub294\uc9c0": 4, "\uce21\uc815\ud55c\ub2e4": 4, "editor": 4}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"inform": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "synthet": 0, "data": [0, 6], "stabl": 0, "diffus": [0, 3, 6, 7, 8, 10, 12, 15, 16, 18, 21], "foliar": 0, "diseas": 0, "classif": 0, "1": [0, 3, 5, 6, 7, 9, 10, 14, 15], "\uac1c\uc694": 0, "2": [0, 3, 5, 6, 7, 9, 10, 14, 15], "baselin": [0, 13], "\uad6c\ucd95": 0, "3": [0, 3, 5, 6, 7, 9, 10, 14, 15], "fine": [0, 3, 16], "tune": [0, 3, 16], "4": [0, 3, 5, 6, 7, 9, 10, 15], "\uc131\ub2a5": 0, "\ube44\uad50": [0, 12], "5": [0, 3, 5, 7, 9, 10, 15], "discuss": [0, 3], "6": [0, 5, 7, 15], "appendix": [0, 1, 16], "train": [1, 2, 3, 6, 13, 14, 17], "dreambooth": [1, 16], "naver": 1, "webtoon": 1, "face": [1, 10], "dataset": 1, "introduct": [1, 3, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 20], "ablat": [1, 16, 18], "studi": [1, 13, 16, 18], "prior": [1, 14], "preserv": 1, "loss": [1, 6, 13], "neg": 1, "prompt": 1, "instanc": 1, "guidanc": [1, 15, 18], "scale": [1, 6, 7], "controlnet": 2, "addit": [2, 9], "control": 2, "imag": [2, 3, 13, 15, 16, 21], "base": 2, "condit": 2, "block": 2, "zero": 2, "convolut": 2, "result": [2, 13, 14, 15, 17, 18], "implement": [2, 13], "custom": 3, "\ud559\uc2b5": [3, 7, 10], "\uc790\ub8cc": [3, 7, 10], "abstract": [3, 5, 7, 9, 10, 12, 13, 15], "relat": [3, 10, 12, 13], "work": [3, 10, 12, 13, 14, 15], "deep": 3, "gener": [3, 5, 13, 21], "model": [3, 6, 7, 8, 10, 12, 15, 16, 18], "edit": 3, "transfer": [3, 13], "learn": [3, 14], "adapt": [3, 15], "text": [3, 12, 16, 21], "method": [3, 9, 10, 12], "singl": 3, "concept": 3, "multipl": 3, "composit": 3, "detail": [3, 13, 14], "experi": [3, 5, 6, 8, 9, 10, 16, 17], "limit": [3, 12, 13, 14, 15, 16], "ddim": [5, 15], "background": [5, 6, 14, 15], "ddpm": [5, 6, 7, 15], "variat": [5, 11], "infer": [5, 9], "For": 5, "non": 5, "markovian": 5, "forward": [5, 6], "process": [5, 6], "sampl": [5, 6, 7], "from": [5, 13, 18], "code": 5, "q": 6, "mathbf": 6, "x": 6, "_t": 6, "_": 6, "t": [6, 9], "revers": 6, "p": 6, "function": [6, 13], "l": 6, "denois": [6, 7], "encod": 6, "l_t": 6, "l_": 6, "decod": 6, "l_0": 6, "simplifi": 6, "object": [6, 13], "qualiti": [6, 13], "i": 7, "probabilist": 7, "improv": [7, 15], "log": 7, "likelihood": 7, "improc": 7, "speed": 7, "comparison": [7, 13], "gan": [7, 12, 15, 17], "size": 7, "latent": [8, 12], "lora": 9, "0": 9, "terminolog": 9, "convent": 9, "problem": 9, "statement": 9, "aren": 9, "exist": 9, "solut": 9, "good": 9, "enough": 9, "our": 9, "low": 9, "rank": 9, "parameter": 9, "updat": 9, "matric": 9, "No": 9, "latenc": 9, "appli": 9, "transform": [9, 14], "empir": 9, "ia3": 9, "aa": 9, "\uc0ac\uc6a9\ubc95": 9, "refer": 9, "styo": 10, "styliz": 10, "framework": 10, "conclus": [10, 14, 18], "stylegan": 11, "map": 11, "network": 11, "style": [11, 13], "adain": 11, "stochast": 11, "mix": 11, "regular": 11, "\uc2e4\ud5d8": 11, "\uacb0\uacfc": [11, 12, 13], "textual": 12, "invers": 12, "cf": 12, "\uc774\ud574": 12, "\ubabb\ud568": 12, "ldm": 12, "embed": 12, "\uc131\ub2a5\ud3c9\uac00": 12, "dall": [12, 14], "e": [12, 14], "2\uc640": 12, "guid": 12, "synthesi": [12, 15], "pseudo": 12, "word": 12, "\ub450": 12, "\uac1c": 12, "\uc0ac\uc6a9": 12, "bia": 12, "reduct": 12, "\uc815\ub7c9\ud3c9\uac00": 12, "\ud3c9\uac00": 12, "setup": 12, "\uc8fc\ubaa9\ud560": 12, "\uc810": 12, "\uc0ac\uc6a9\uc790\ud3c9\uac00": 12, "\ub9c8\ubb34\ub9ac": 12, "cyclegan": 13, "\ucc38\uace0": 13, "translation\uc774\ub780": 13, "mode": 13, "collapse\ub780": 13, "\uad00\ub828": 13, "\uc5f0\uad6c": 13, "formul": 13, "adversari": 13, "cycl": 13, "consist": 13, "full": 13, "\uc804\uccb4": 13, "\ubaa9\uc801\uc2dd": 13, "least": 13, "squar": 13, "\ucd94\uac00": 13, "\uc124\uba85": 13, "\uae30\ud0c0": 13, "against": 13, "human": [13, 18], "fcn": 13, "\ub4f1": 13, "analysi": 13, "reconstruct": 13, "pair": 13, "dataset\uc5d0": 13, "\ub300\ud55c": 13, "applic": [13, 16], "collect": 13, "transfigur": 13, "season": 13, "photo": 13, "paint": 13, "enhanc": 13, "gati": 13, "discusss": 13, "gpt": 14, "vq": 14, "vae": [14, 20], "methodolog": [14, 18], "previou": 14, "overview": 14, "stage": 14, "an": 14, "autoregress": 14, "pipelin": 14, "\uc608\uc2dc": 14, "equat": 14, "\ud559\uc2b5\uacfc\uc815": 14, "visual": 14, "codebook": 14, "beat": 15, "architectur": 15, "group": 15, "normal": 15, "classifi": [15, 18], "algorithm": 15, "7": 15, "impact": 15, "paramet": 15, "s": 15, "8": 15, "9": 15, "futur": 15, "procedur": 17, "theoret": 17, "summari": [17, 20], "imagen": [18, 19], "editor": 19, "intract": 20, "reparameter": 20, "trick": 20, "pseudolab": 21, "feat": 21, "contribut": 18, "pretrain": 18, "t5": 18, "xxl": 18, "cascad": 18, "free": 18, "larg": 18, "weight": 18, "sampler": 18, "static": 18, "threshold": 18, "dynam": 18, "super": 18, "resolut": 18, "drawbench": 18, "qualit": 18, "tabl": 18, "evalu": 18, "dalle2": 4}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx": 56}}) \ No newline at end of file