libcom 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libcom/__init__.py +23 -0
- libcom/color_transfer/__init__.py +3 -0
- libcom/color_transfer/reinhard.py +57 -0
- libcom/fopa_heat_map/__init__.py +4 -0
- libcom/fopa_heat_map/fopa_heat_map.py +212 -0
- libcom/fopa_heat_map/source/__init__.py +0 -0
- libcom/fopa_heat_map/source/backbone/ResNet.py +229 -0
- libcom/fopa_heat_map/source/backbone/__init__.py +0 -0
- libcom/fopa_heat_map/source/data/OBdataset.py +292 -0
- libcom/fopa_heat_map/source/data/__init__.py +0 -0
- libcom/fopa_heat_map/source/data/all_transforms.py +25 -0
- libcom/fopa_heat_map/source/network/BaseBlocks.py +26 -0
- libcom/fopa_heat_map/source/network/DynamicModules.py +43 -0
- libcom/fopa_heat_map/source/network/ObPlaNet_simple.py +112 -0
- libcom/fopa_heat_map/source/network/__init__.py +1 -0
- libcom/fopa_heat_map/source/network/tensor_ops.py +37 -0
- libcom/fopa_heat_map/source/prepare_multi_fg_scales.py +85 -0
- libcom/fos_score/__init__.py +4 -0
- libcom/fos_score/fos_score_prediction.py +218 -0
- libcom/fos_score/source/__init__.py +0 -0
- libcom/fos_score/source/config/__init__.py +1 -0
- libcom/fos_score/source/config/config.py +68 -0
- libcom/fos_score/source/config/config.sfosd.yaml +43 -0
- libcom/fos_score/source/config/config_rfosd.yaml +43 -0
- libcom/fos_score/source/loss_function.py +118 -0
- libcom/fos_score/source/networks.py +355 -0
- libcom/harmony_score/__init__.py +3 -0
- libcom/harmony_score/harmony_score_prediction.py +119 -0
- libcom/harmony_score/source/__init__.py +0 -0
- libcom/harmony_score/source/bargainnet.py +226 -0
- libcom/image_harmonization/__init__.py +4 -0
- libcom/image_harmonization/image_harmonization.py +193 -0
- libcom/image_harmonization/source/__init__.py +0 -0
- libcom/image_harmonization/source/functions.py +747 -0
- libcom/image_harmonization/source/pct_net.py +85 -0
- libcom/image_harmonization/source/src/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/config.py +141 -0
- libcom/image_harmonization/source/src/lbm/data/__init__.py +62 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/__init__.py +9 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/collation_fn.py +41 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/dataset.py +243 -0
- libcom/image_harmonization/source/src/lbm/data/datasets/datasets_config.py +42 -0
- libcom/image_harmonization/source/src/lbm/data/filters/__init__.py +12 -0
- libcom/image_harmonization/source/src/lbm/data/filters/base.py +21 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filter_wrapper.py +36 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filters.py +33 -0
- libcom/image_harmonization/source/src/lbm/data/filters/filters_config.py +32 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/__init__.py +19 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/base.py +26 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers.py +135 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers_config.py +109 -0
- libcom/image_harmonization/source/src/lbm/data/mappers/mappers_wrapper.py +31 -0
- libcom/image_harmonization/source/src/lbm/inference/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/inference/inference.py +70 -0
- libcom/image_harmonization/source/src/lbm/inference/utils.py +222 -0
- libcom/image_harmonization/source/src/lbm/models/__init__.py +0 -0
- libcom/image_harmonization/source/src/lbm/models/base/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/base/base_model.py +66 -0
- libcom/image_harmonization/source/src/lbm/models/base/model_config.py +8 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner.py +60 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/base/base_conditioner_config.py +27 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/conditioners_wrapper.py +114 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_config.py +31 -0
- libcom/image_harmonization/source/src/lbm/models/embedders/latents_concat/latents_concat_embedder_model.py +80 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/lbm_config.py +101 -0
- libcom/image_harmonization/source/src/lbm/models/lbm/lbm_model.py +359 -0
- libcom/image_harmonization/source/src/lbm/models/unets/__init__.py +14 -0
- libcom/image_harmonization/source/src/lbm/models/unets/unet.py +148 -0
- libcom/image_harmonization/source/src/lbm/models/utils.py +377 -0
- libcom/image_harmonization/source/src/lbm/models/vae/__init__.py +4 -0
- libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL.py +136 -0
- libcom/image_harmonization/source/src/lbm/models/vae/autoencoderKL_config.py +27 -0
- libcom/image_harmonization/source/src/lbm/trainer/__init__.py +85 -0
- libcom/image_harmonization/source/src/lbm/trainer/loggers.py +324 -0
- libcom/image_harmonization/source/src/lbm/trainer/trainer.py +199 -0
- libcom/image_harmonization/source/src/lbm/trainer/training_config.py +82 -0
- libcom/image_harmonization/source/src/lbm/trainer/utils.py +193 -0
- libcom/inharmonious_region_localization/__init__.py +4 -0
- libcom/inharmonious_region_localization/inharmonious_region_localization.py +97 -0
- libcom/inharmonious_region_localization/source/__init__.py +0 -0
- libcom/inharmonious_region_localization/source/blocks.py +368 -0
- libcom/inharmonious_region_localization/source/functions.py +679 -0
- libcom/inharmonious_region_localization/source/madis_net.py +79 -0
- libcom/kontext_blending_harmonization/__init__.py +3 -0
- libcom/kontext_blending_harmonization/kontext_blending_harmonization.py +148 -0
- libcom/kontext_blending_harmonization/source/__init__.py +0 -0
- libcom/kontext_blending_harmonization/source/pipeline.py +1135 -0
- libcom/naive_composition/__init__.py +3 -0
- libcom/naive_composition/generate_composite_image.py +116 -0
- libcom/opa_score/__init__.py +3 -0
- libcom/opa_score/opa_score_prediction.py +101 -0
- libcom/opa_score/source/__init__.py +3 -0
- libcom/opa_score/source/object_place_net.py +55 -0
- libcom/opa_score/source/oblect_place_config.py +66 -0
- libcom/opa_score/source/resnet_4ch.py +213 -0
- libcom/os_insert/__init__.py +3 -0
- libcom/os_insert/diffusers_osinsert/__init__.py +78 -0
- libcom/os_insert/diffusers_osinsert/_patched_pipeline_flux_fill.py +878 -0
- libcom/os_insert/os_insert.py +534 -0
- libcom/os_insert/source/__init__.py +1 -0
- libcom/os_insert/source/ia_utils.py +183 -0
- libcom/os_insert/source/insertanything_infer.py +529 -0
- libcom/os_insert/source/ldm/__init__.py +0 -0
- libcom/os_insert/source/ldm/data/__init__.py +0 -0
- libcom/os_insert/source/ldm/data/base.py +23 -0
- libcom/os_insert/source/ldm/data/datamodule.py +128 -0
- libcom/os_insert/source/ldm/data/imagenet.py +394 -0
- libcom/os_insert/source/ldm/data/lsun.py +92 -0
- libcom/os_insert/source/ldm/data/open_images.py +728 -0
- libcom/os_insert/source/ldm/lr_scheduler.py +98 -0
- libcom/os_insert/source/ldm/models/__init__.py +0 -0
- libcom/os_insert/source/ldm/models/autoencoder.py +443 -0
- libcom/os_insert/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/os_insert/source/ldm/models/diffusion/classifier.py +267 -0
- libcom/os_insert/source/ldm/models/diffusion/ddim.py +263 -0
- libcom/os_insert/source/ldm/models/diffusion/ddpm.py +1417 -0
- libcom/os_insert/source/ldm/models/diffusion/plms.py +252 -0
- libcom/os_insert/source/ldm/modules/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/attention.py +261 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/model.py +835 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/openaimodel.py +1108 -0
- libcom/os_insert/source/ldm/modules/diffusionmodules/util.py +267 -0
- libcom/os_insert/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/os_insert/source/ldm/modules/ema.py +76 -0
- libcom/os_insert/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/os_insert/source/ldm/modules/encoders/modules.py +190 -0
- libcom/os_insert/source/ldm/modules/encoders/xf.py +130 -0
- libcom/os_insert/source/ldm/modules/losses/__init__.py +1 -0
- libcom/os_insert/source/ldm/modules/losses/contperceptual.py +111 -0
- libcom/os_insert/source/ldm/modules/losses/vqperceptual.py +167 -0
- libcom/os_insert/source/ldm/modules/x_transformer.py +641 -0
- libcom/os_insert/source/ldm/util.py +203 -0
- libcom/os_insert/source/objectstitch_data.py +66 -0
- libcom/os_insert/source/objectstitch_infer.py +618 -0
- libcom/os_insert/source/sam_on_objectstitch.py +253 -0
- libcom/os_insert/source/utils.py +41 -0
- libcom/os_insert/source/v1.yaml +108 -0
- libcom/painterly_image_harmonization/__init__.py +4 -0
- libcom/painterly_image_harmonization/painterly_image_harmonization.py +215 -0
- libcom/painterly_image_harmonization/source/PHDNet/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDNet/networks.py +202 -0
- libcom/painterly_image_harmonization/source/PHDNet/phdnet.py +47 -0
- libcom/painterly_image_harmonization/source/PHDNet/phdnet_config.py +18 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/inference_base.py +300 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/lr_scheduler.py +98 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/autoencoder.py +211 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/__init__.py +3 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddim.py +336 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/ddpm.py +1400 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/dpm_solver.py +1217 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/plms.py +243 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/models/diffusion/scheduling_pndm.py +518 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/attention.py +378 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/model.py +857 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/openaimodel.py +823 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/diffusionmodules/util.py +270 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/distributions/distributions.py +92 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/ema.py +80 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/adapter.py +213 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/encoders/modules.py +82 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/__init__.py +1 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/api.py +269 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/api.py +175 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/base_model.py +16 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/blocks.py +342 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/dpt_depth.py +109 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net.py +76 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/midas_net_custom.py +128 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/transforms.py +234 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/midas/vit.py +491 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/midas/utils.py +189 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/model_edge.py +653 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/api.py +35 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/body.py +209 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/hand.py +75 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/model.py +178 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/openpose/util.py +203 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/extra_condition/utils.py +72 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/__init__.py +0 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/fusion/dual_encoder_fusion.py +93 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/__init__.py +2 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/ldm/util.py +200 -0
- libcom/painterly_image_harmonization/source/PHDiffusion/stable_diffusion.yaml +75 -0
- libcom/painterly_image_harmonization/source/__init__.py +0 -0
- libcom/reflection_generation/__init__.py +3 -0
- libcom/reflection_generation/reflection_generation.py +174 -0
- libcom/reflection_generation/source/PostProcessModel.py +513 -0
- libcom/reflection_generation/source/__init__.py +0 -0
- libcom/reflection_generation/source/cldm/__init__.py +0 -0
- libcom/reflection_generation/source/cldm/base_network.py +166 -0
- libcom/reflection_generation/source/cldm/cldm.py +509 -0
- libcom/reflection_generation/source/cldm/ddim_hacked.py +317 -0
- libcom/reflection_generation/source/cldm/hack.py +111 -0
- libcom/reflection_generation/source/cldm/logger.py +127 -0
- libcom/reflection_generation/source/cldm/model.py +26 -0
- libcom/reflection_generation/source/cldm_v15.yaml +81 -0
- libcom/reflection_generation/source/cluster_feature.py +109 -0
- libcom/reflection_generation/source/ldm/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/autoencoder.py +219 -0
- libcom/reflection_generation/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ddim.py +340 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ddpm.py +1892 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
- libcom/reflection_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/reflection_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
- libcom/reflection_generation/source/ldm/models/diffusion/plms.py +244 -0
- libcom/reflection_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
- libcom/reflection_generation/source/ldm/modules/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/attention.py +341 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
- libcom/reflection_generation/source/ldm/modules/diffusionmodules/util.py +280 -0
- libcom/reflection_generation/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/reflection_generation/source/ldm/modules/ema.py +80 -0
- libcom/reflection_generation/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/encoders/modules.py +214 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/__init__.py +0 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/reflection_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/reflection_generation/source/ldm/util.py +198 -0
- libcom/reflection_generation/source/local_clip.py +749 -0
- libcom/reflection_generation/source/tool_add_control.py +49 -0
- libcom/shadow_generation/__init__.py +3 -0
- libcom/shadow_generation/shadow_generation.py +754 -0
- libcom/shadow_generation/source/PostProcessModel.py +511 -0
- libcom/shadow_generation/source/__init__.py +0 -0
- libcom/shadow_generation/source/attention_processor.py +234 -0
- libcom/shadow_generation/source/cldm/__init__.py +0 -0
- libcom/shadow_generation/source/cldm/base_network.py +166 -0
- libcom/shadow_generation/source/cldm/cldm.py +524 -0
- libcom/shadow_generation/source/cldm/model.py +28 -0
- libcom/shadow_generation/source/ldm/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/autoencoder.py +219 -0
- libcom/shadow_generation/source/ldm/models/diffusion/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/models/diffusion/attention_processor.py +188 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ddim.py +340 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ddpm.py +1893 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/__init__.py +1 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/dpm_solver.py +1154 -0
- libcom/shadow_generation/source/ldm/models/diffusion/dpm_solver/sampler.py +87 -0
- libcom/shadow_generation/source/ldm/models/diffusion/ip_adapter.py +57 -0
- libcom/shadow_generation/source/ldm/models/diffusion/plms.py +244 -0
- libcom/shadow_generation/source/ldm/models/diffusion/sampling_util.py +22 -0
- libcom/shadow_generation/source/ldm/modules/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/attention.py +341 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/model.py +852 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/openaimodel.py +786 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/upscaling.py +81 -0
- libcom/shadow_generation/source/ldm/modules/diffusionmodules/util.py +270 -0
- libcom/shadow_generation/source/ldm/modules/distributions/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/distributions/distributions.py +92 -0
- libcom/shadow_generation/source/ldm/modules/ema.py +80 -0
- libcom/shadow_generation/source/ldm/modules/encoders/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/encoders/modules.py +214 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/__init__.py +2 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan.py +730 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/bsrgan_light.py +651 -0
- libcom/shadow_generation/source/ldm/modules/image_degradation/utils_image.py +916 -0
- libcom/shadow_generation/source/ldm/modules/midas/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/midas/api.py +170 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/__init__.py +0 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/base_model.py +16 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/blocks.py +342 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/dpt_depth.py +109 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net.py +76 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/midas_net_custom.py +128 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/transforms.py +234 -0
- libcom/shadow_generation/source/ldm/modules/midas/midas/vit.py +491 -0
- libcom/shadow_generation/source/ldm/modules/midas/utils.py +189 -0
- libcom/shadow_generation/source/ldm/util.py +199 -0
- libcom/utils/__init__.py +0 -0
- libcom/utils/environment.py +12 -0
- libcom/utils/model_download.py +67 -0
- libcom/utils/process_image.py +108 -0
- libcom-0.1.8.dist-info/METADATA +157 -0
- libcom-0.1.8.dist-info/RECORD +310 -0
- libcom-0.1.8.dist-info/WHEEL +5 -0
- libcom-0.1.8.dist-info/licenses/LICENSE +201 -0
- libcom-0.1.8.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import time
|
|
5
|
+
from typing import Dict, List, Literal, Optional, Tuple
|
|
6
|
+
|
|
7
|
+
import torch
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StateDictAdapter:
|
|
11
|
+
"""
|
|
12
|
+
StateDictAdapter for adapting the state dict of a model to a checkpoint state dict.
|
|
13
|
+
|
|
14
|
+
This class will iterate over all keys in the checkpoint state dict and filter them by a list of regex keys.
|
|
15
|
+
For each matching key, the class will adapt the checkpoint state dict to the model state dict.
|
|
16
|
+
Depending on the target size, the class will add missing blocks or cut the block.
|
|
17
|
+
When adding missing blocks, the class will use a strategy to fill the missing blocks: either adding zeros or normal random values.
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
adapter = StateDictAdapter()
|
|
23
|
+
new_state_dict = adapter(
|
|
24
|
+
model_state_dict=model.state_dict(),
|
|
25
|
+
checkpoint_state_dict=state_dict,
|
|
26
|
+
regex_keys=[
|
|
27
|
+
r"class_embedding.linear_1.weight",
|
|
28
|
+
r"conv_in.weight",
|
|
29
|
+
r"(down_blocks|up_blocks)\.\d+\.attentions\.\d+\.transformer_blocks\.\d+\.attn\d+\.(to_k|to_v)\.weight",
|
|
30
|
+
r"mid_block\.attentions\.\d+\.transformer_blocks\.\d+\.attn\d+\.(to_k|to_v)\.weight"
|
|
31
|
+
]
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
model_state_dict (Dict[str, torch.Tensor]): The model state dict.
|
|
37
|
+
checkpoint_state_dict (Dict[str, torch.Tensor]): The checkpoint state dict.
|
|
38
|
+
regex_keys (Optional[List[str]]): A list of regex keys to adapt the checkpoint state dict. Defaults to None.
|
|
39
|
+
Passing a list of regex will drastically reduce the latency.
|
|
40
|
+
If None, all keys in the checkpoint state dict will be adapted.
|
|
41
|
+
strategy (Literal["zeros", "normal"], optional): The strategy to fill the missing blocks. Defaults to "normal".
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def _create_block(
|
|
46
|
+
self,
|
|
47
|
+
shape: List[int],
|
|
48
|
+
strategy: Literal["zeros", "normal"],
|
|
49
|
+
input: torch.Tensor = None,
|
|
50
|
+
):
|
|
51
|
+
if strategy == "zeros":
|
|
52
|
+
return torch.zeros(shape)
|
|
53
|
+
elif strategy == "normal":
|
|
54
|
+
if input is not None:
|
|
55
|
+
mean = input.mean().item()
|
|
56
|
+
std = input.std().item()
|
|
57
|
+
return torch.randn(shape) * std + mean
|
|
58
|
+
else:
|
|
59
|
+
return torch.randn(shape)
|
|
60
|
+
else:
|
|
61
|
+
raise ValueError(f"Unknown strategy {strategy}")
|
|
62
|
+
|
|
63
|
+
def __call__(
|
|
64
|
+
self,
|
|
65
|
+
model_state_dict: Dict[str, torch.Tensor],
|
|
66
|
+
checkpoint_state_dict: Dict[str, torch.Tensor],
|
|
67
|
+
regex_keys: Optional[List[str]] = None,
|
|
68
|
+
strategy: Literal["zeros", "normal"] = "normal",
|
|
69
|
+
):
|
|
70
|
+
start = time.perf_counter()
|
|
71
|
+
# if no regex keys are provided, we use all keys in the model state dict
|
|
72
|
+
if regex_keys is None:
|
|
73
|
+
regex_keys = list(model_state_dict.keys())
|
|
74
|
+
|
|
75
|
+
# iterate over all keys in the checkpoint state dict
|
|
76
|
+
for checkpoint_key in list(checkpoint_state_dict.keys()):
|
|
77
|
+
# iterate over all regex keys
|
|
78
|
+
for regex_key in regex_keys:
|
|
79
|
+
if re.match(regex_key, checkpoint_key):
|
|
80
|
+
dst_shape = model_state_dict[checkpoint_key].shape
|
|
81
|
+
src_shape = checkpoint_state_dict[checkpoint_key].shape
|
|
82
|
+
|
|
83
|
+
## Sizes adapter
|
|
84
|
+
# if length of shapes are different, we need to unsqueeze or squeeze the tensor
|
|
85
|
+
if len(dst_shape) != len(src_shape):
|
|
86
|
+
# in the case [a] vs [a, b] -> unsqueeze [a, 1]
|
|
87
|
+
if len(src_shape) == 1:
|
|
88
|
+
checkpoint_state_dict[checkpoint_key] = (
|
|
89
|
+
checkpoint_state_dict[checkpoint_key].unsqueeze(1)
|
|
90
|
+
)
|
|
91
|
+
logging.info(
|
|
92
|
+
f"Unsqueeze {checkpoint_key}: {src_shape} -> {checkpoint_state_dict[checkpoint_key].shape}"
|
|
93
|
+
)
|
|
94
|
+
# in the case [a, b] vs [a] -> squeeze [a]
|
|
95
|
+
elif len(dst_shape) == 1:
|
|
96
|
+
checkpoint_state_dict[checkpoint_key] = (
|
|
97
|
+
checkpoint_state_dict[checkpoint_key][:, 0]
|
|
98
|
+
)
|
|
99
|
+
logging.info(
|
|
100
|
+
f"Squeeze {checkpoint_key}: {src_shape} -> {checkpoint_state_dict[checkpoint_key].shape}"
|
|
101
|
+
)
|
|
102
|
+
# in the other cases, raise an error
|
|
103
|
+
else:
|
|
104
|
+
raise ValueError(
|
|
105
|
+
f"Shapes of {checkpoint_key} are different: {dst_shape} != {src_shape}"
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# update the shapes
|
|
109
|
+
dst_shape = model_state_dict[checkpoint_key].shape
|
|
110
|
+
src_shape = checkpoint_state_dict[checkpoint_key].shape
|
|
111
|
+
assert len(dst_shape) == len(
|
|
112
|
+
src_shape
|
|
113
|
+
), f"Shapes of {checkpoint_key} are different: {dst_shape} != {src_shape}"
|
|
114
|
+
|
|
115
|
+
## Shapes adapter
|
|
116
|
+
# modify the checkpoint state dict only if the shapes are different
|
|
117
|
+
if dst_shape != src_shape:
|
|
118
|
+
# create a copy of the tensor
|
|
119
|
+
tmp = torch.clone(checkpoint_state_dict[checkpoint_key])
|
|
120
|
+
|
|
121
|
+
# iterate over all dimensions
|
|
122
|
+
for i in range(len(dst_shape)):
|
|
123
|
+
if dst_shape[i] != src_shape[i]:
|
|
124
|
+
diff = dst_shape[i] - src_shape[i]
|
|
125
|
+
|
|
126
|
+
# if the difference is greater than 0, we need to add missing blocks
|
|
127
|
+
if diff > 0:
|
|
128
|
+
missing_shape = list(tmp.shape)
|
|
129
|
+
missing_shape[i] = diff
|
|
130
|
+
missing = self._create_block(
|
|
131
|
+
shape=missing_shape,
|
|
132
|
+
strategy=strategy,
|
|
133
|
+
input=tmp,
|
|
134
|
+
)
|
|
135
|
+
tmp = torch.cat((tmp, missing), dim=i)
|
|
136
|
+
logging.info(
|
|
137
|
+
f"Adapting {checkpoint_key} with strategy:{strategy} from shape {src_shape} to {dst_shape}"
|
|
138
|
+
)
|
|
139
|
+
# if the difference is less than 0, we need to cut the block
|
|
140
|
+
else:
|
|
141
|
+
tmp = tmp.narrow(i, 0, dst_shape[i])
|
|
142
|
+
logging.info(
|
|
143
|
+
f"Adapting {checkpoint_key} by narrowing from shape {src_shape} to {dst_shape}"
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
checkpoint_state_dict[checkpoint_key] = tmp
|
|
147
|
+
end = time.perf_counter()
|
|
148
|
+
logging.info(f"StateDictAdapter took {end-start:.2f} seconds")
|
|
149
|
+
return checkpoint_state_dict
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class StateDictRenamer:
|
|
153
|
+
"""
|
|
154
|
+
StateDictRenamer for renaming keys in a checkpoint state dict.
|
|
155
|
+
This class will iterate over all keys in the checkpoint state dict and rename them according to a rename dict.
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
renamer = StateDictRenamer()
|
|
161
|
+
new_state_dict = renamer(
|
|
162
|
+
checkpoint_state_dict=state_dict,
|
|
163
|
+
rename_dict={
|
|
164
|
+
"add_embedding.linear_1.weight": "class_embedding.linear_1.weight",
|
|
165
|
+
"add_embedding.linear_1.bias": "class_embedding.linear_1.bias",
|
|
166
|
+
"add_embedding.linear_2.weight": "class_embedding.linear_2.weight",
|
|
167
|
+
"add_embedding.linear_2.bias": "class_embedding.linear_2.bias",
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
|
|
174
|
+
checkpoint_state_dict (Dict[str, torch.Tensor]): The checkpoint state dict.
|
|
175
|
+
rename_dict (Dict[str, str]): The dictionary mapping the old keys to new keys
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
def __call__(
|
|
179
|
+
self,
|
|
180
|
+
checkpoint_state_dict: Dict[str, torch.Tensor],
|
|
181
|
+
rename_dict: Dict[str, str],
|
|
182
|
+
) -> Dict[str, torch.Tensor]:
|
|
183
|
+
for old_key, new_key in rename_dict.items():
|
|
184
|
+
if old_key not in checkpoint_state_dict:
|
|
185
|
+
logging.warning(f"Key {old_key} not found in checkpoint state dict")
|
|
186
|
+
continue
|
|
187
|
+
else:
|
|
188
|
+
assert (
|
|
189
|
+
new_key not in checkpoint_state_dict
|
|
190
|
+
), f"Key {new_key} already exists in checkpoint state dict"
|
|
191
|
+
checkpoint_state_dict[new_key] = checkpoint_state_dict.pop(old_key)
|
|
192
|
+
logging.info(f"Renaming {old_key} to {new_key}")
|
|
193
|
+
return checkpoint_state_dict
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torchvision
|
|
3
|
+
from libcom.utils.model_download import download_pretrained_model
|
|
4
|
+
from libcom.utils.process_image import *
|
|
5
|
+
from libcom.utils.environment import *
|
|
6
|
+
import os
|
|
7
|
+
import torchvision.transforms as transforms
|
|
8
|
+
from .source.madis_net import *
|
|
9
|
+
|
|
10
|
+
cur_dir = os.path.dirname(os.path.abspath(__file__))
|
|
11
|
+
model_dir = os.environ.get('LIBCOM_MODEL_DIR',cur_dir)
|
|
12
|
+
model_set = ['IHDRNet']
|
|
13
|
+
|
|
14
|
+
class InharmoniousLocalizationModel:
|
|
15
|
+
"""
|
|
16
|
+
Inharmonious region localization model.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
device (str | torch.device): gpu id
|
|
20
|
+
model_type (str): predefined model type
|
|
21
|
+
kwargs (dict): other parameters for building model
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
>>> from libcom import InharmoniousLocalizationModel
|
|
25
|
+
>>> import cv2
|
|
26
|
+
>>> net = InharmoniousLocalizationModel(device=0)
|
|
27
|
+
>>> comp_img1 = '../tests/source/composite/comp1_MadisNet.png'
|
|
28
|
+
>>> inharmonious_localization1 = net(comp_img1)
|
|
29
|
+
>>> comp_img2 = '../tests/source/composite/comp2_MadisNet.png'
|
|
30
|
+
>>> inharmonious_localization2 = net(comp_img2)
|
|
31
|
+
>>> cv2.imwrite('../docs/_static/image/inharmonious_localization_result1.jpg', np.concatenate([cv2.resize(cv2.imread(comp_img1),(256,256)), inharmonious_localization1],axis=1))
|
|
32
|
+
>>> cv2.imwrite('../docs/_static/image/inharmonious_localization_result2.jpg', np.concatenate([cv2.resize(cv2.imread(comp_img2),(256,256)), inharmonious_localization2],axis=1))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Expected result:
|
|
36
|
+
|
|
37
|
+
.. image:: _static/image/inharmonious_localization_result3_4.jpg
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
def __init__(self, device=0, model_type='IHDRNet', **kwargs):
|
|
41
|
+
assert model_type in model_set, f'Not implementation for {model_type}'
|
|
42
|
+
self.model_type = model_type
|
|
43
|
+
self.option = kwargs
|
|
44
|
+
weight_path_g = os.path.join(model_dir, 'pretrained_models', 'Inharmonious_G.pth')
|
|
45
|
+
download_pretrained_model(weight_path_g)
|
|
46
|
+
weight_path_ihdrnet = os.path.join(model_dir, 'pretrained_models', 'IHDRNet.pth')
|
|
47
|
+
download_pretrained_model(weight_path_ihdrnet)
|
|
48
|
+
self.device = check_gpu_device(device)
|
|
49
|
+
self.build_pretrained_model(weight_path_g, weight_path_ihdrnet)
|
|
50
|
+
self.build_data_transformer()
|
|
51
|
+
|
|
52
|
+
def build_pretrained_model(self, weight_path_g, weight_path_ihdrnet):
|
|
53
|
+
model = MadisNet()
|
|
54
|
+
model.g.load_state_dict(torch.load(weight_path_g, weights_only=True)['state_dict'])
|
|
55
|
+
model.ihdrnet.load_state_dict(torch.load(weight_path_ihdrnet, weights_only=True)['state_dict'])
|
|
56
|
+
self.MadisNet_model = model.to(self.device).eval()
|
|
57
|
+
|
|
58
|
+
def build_data_transformer(self):
|
|
59
|
+
self.transformer = transforms.Compose([
|
|
60
|
+
transforms.ToTensor(),
|
|
61
|
+
transforms.Normalize(
|
|
62
|
+
(0.485, 0.456, 0.406),
|
|
63
|
+
(0.229, 0.224, 0.225)
|
|
64
|
+
)
|
|
65
|
+
])
|
|
66
|
+
|
|
67
|
+
def inputs_preprocess(self, composite_image):
|
|
68
|
+
img = read_image_opencv(composite_image)
|
|
69
|
+
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
|
70
|
+
img = cv2.resize(img, (256,256))
|
|
71
|
+
img = self.transformer(img).float().to(self.device).unsqueeze(0)
|
|
72
|
+
return img
|
|
73
|
+
|
|
74
|
+
def outputs_postprocess(self, outputs):
|
|
75
|
+
if len(outputs.shape) == 4:
|
|
76
|
+
outputs = outputs.squeeze(0)
|
|
77
|
+
outputs = (torch.clamp(255.0 * outputs.permute(1, 2, 0), 0, 255)).cpu().numpy()
|
|
78
|
+
outputs = cv2.cvtColor(outputs, cv2.COLOR_RGB2BGR)
|
|
79
|
+
return outputs
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@torch.no_grad()
|
|
83
|
+
def __call__(self, composite_image):
|
|
84
|
+
"""
|
|
85
|
+
Given a composite image, predict the mask of the inharmonious region.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
composite_image (str | numpy.ndarray): The path to composite image or the compposite image in ndarray form.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
inharmonious_mask (np.array): The inharmonious mask.
|
|
92
|
+
|
|
93
|
+
"""
|
|
94
|
+
img = self.inputs_preprocess(composite_image)
|
|
95
|
+
outputs = self.MadisNet_model(img)[0]
|
|
96
|
+
preds = self.outputs_postprocess(outputs)
|
|
97
|
+
return preds
|
|
File without changes
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import torch
|
|
2
|
+
import torch.nn.functional as F
|
|
3
|
+
from torch import nn
|
|
4
|
+
import math
|
|
5
|
+
|
|
6
|
+
def conv3x3(in_planes, out_planes, stride=1):
|
|
7
|
+
"3x3 convolution with padding"
|
|
8
|
+
return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
|
|
9
|
+
padding=1, bias=False)
|
|
10
|
+
|
|
11
|
+
class BasicBlock(nn.Module):
|
|
12
|
+
expansion = 1
|
|
13
|
+
|
|
14
|
+
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
|
|
15
|
+
base_width=64, dilation=1, norm_layer=nn.BatchNorm2d):
|
|
16
|
+
super(BasicBlock, self).__init__()
|
|
17
|
+
self.conv1 = conv3x3(inplanes, planes, stride)
|
|
18
|
+
self.bn1 = norm_layer(planes)
|
|
19
|
+
self.relu = nn.ReLU(inplace=True)
|
|
20
|
+
self.conv2 = conv3x3(planes, planes)
|
|
21
|
+
self.bn2 = norm_layer(planes)
|
|
22
|
+
if downsample is None and inplanes != planes:
|
|
23
|
+
self.downsample = nn.Conv2d(inplanes, planes, 1,1,0)
|
|
24
|
+
else:
|
|
25
|
+
self.downsample = downsample
|
|
26
|
+
self.stride = stride
|
|
27
|
+
|
|
28
|
+
def forward(self, x):
|
|
29
|
+
residual = x
|
|
30
|
+
|
|
31
|
+
out = self.conv1(x)
|
|
32
|
+
out = self.bn1(out)
|
|
33
|
+
out = self.relu(out)
|
|
34
|
+
|
|
35
|
+
out = self.conv2(out)
|
|
36
|
+
out = self.bn2(out)
|
|
37
|
+
|
|
38
|
+
if self.downsample is not None:
|
|
39
|
+
residual = self.downsample(x)
|
|
40
|
+
|
|
41
|
+
out += residual
|
|
42
|
+
out = self.relu(out)
|
|
43
|
+
|
|
44
|
+
return out
|
|
45
|
+
|
|
46
|
+
class Bottleneck(nn.Module):
|
|
47
|
+
# Bottleneck in torchvision places the stride for downsampling at 3x3 convolution(self.conv2)
|
|
48
|
+
# while original implementation places the stride at the first 1x1 convolution(self.conv1)
|
|
49
|
+
# according to "Deep residual learning for image recognition"https://arxiv.org/abs/1512.03385.
|
|
50
|
+
# This variant is also known as ResNet V1.5 and improves accuracy according to
|
|
51
|
+
# https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch.
|
|
52
|
+
|
|
53
|
+
expansion = 4
|
|
54
|
+
|
|
55
|
+
def __init__(self, inplanes, planes, stride=1, downsample=None, groups=1,
|
|
56
|
+
base_width=64, dilation=1, norm_layer=None):
|
|
57
|
+
super(Bottleneck, self).__init__()
|
|
58
|
+
if norm_layer is None:
|
|
59
|
+
norm_layer = nn.BatchNorm2d
|
|
60
|
+
width = int(planes * (base_width / 64.)) * groups
|
|
61
|
+
# Both self.conv2 and self.downsample layers downsample the input when stride != 1
|
|
62
|
+
self.conv1 = conv1x1(inplanes, width)
|
|
63
|
+
self.bn1 = norm_layer(width)
|
|
64
|
+
self.conv2 = conv3x3(width, width, stride, groups, dilation)
|
|
65
|
+
self.bn2 = norm_layer(width)
|
|
66
|
+
self.conv3 = conv1x1(width, planes * self.expansion)
|
|
67
|
+
self.bn3 = norm_layer(planes * self.expansion)
|
|
68
|
+
self.relu = nn.ReLU(inplace=True)
|
|
69
|
+
self.downsample = downsample
|
|
70
|
+
self.stride = stride
|
|
71
|
+
|
|
72
|
+
def forward(self, x):
|
|
73
|
+
identity = x
|
|
74
|
+
|
|
75
|
+
out = self.conv1(x)
|
|
76
|
+
out = self.bn1(out)
|
|
77
|
+
out = self.relu(out)
|
|
78
|
+
|
|
79
|
+
out = self.conv2(out)
|
|
80
|
+
out = self.bn2(out)
|
|
81
|
+
out = self.relu(out)
|
|
82
|
+
|
|
83
|
+
out = self.conv3(out)
|
|
84
|
+
out = self.bn3(out)
|
|
85
|
+
|
|
86
|
+
if self.downsample is not None:
|
|
87
|
+
identity = self.downsample(x)
|
|
88
|
+
|
|
89
|
+
out += identity
|
|
90
|
+
out = self.relu(out)
|
|
91
|
+
|
|
92
|
+
return out
|
|
93
|
+
|
|
94
|
+
# Used for spatial attention
|
|
95
|
+
class BasicConv(nn.Module):
|
|
96
|
+
def __init__(self, in_planes, out_planes, kernel_size, stride=1, padding=0, dilation=1, groups=1, relu=True, bn=True, bias=False):
|
|
97
|
+
super(BasicConv, self).__init__()
|
|
98
|
+
self.out_channels = out_planes
|
|
99
|
+
self.conv = nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)
|
|
100
|
+
self.bn = nn.BatchNorm2d(out_planes,eps=1e-5, momentum=0.01, affine=True) if bn else None
|
|
101
|
+
self.relu = nn.ReLU() if relu else None
|
|
102
|
+
|
|
103
|
+
def forward(self, x):
|
|
104
|
+
x = self.conv(x)
|
|
105
|
+
if self.bn is not None:
|
|
106
|
+
x = self.bn(x)
|
|
107
|
+
if self.relu is not None:
|
|
108
|
+
x = self.relu(x)
|
|
109
|
+
return x
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# Central Difference Convolutional Network
|
|
113
|
+
class Conv2d_cd(nn.Module):
|
|
114
|
+
def __init__(self, in_channels, out_channels, kernel_size=3, stride=1,
|
|
115
|
+
padding=1, dilation=1, groups=1, bias=False, theta=0.7, use_bn=True, actv='relu'):
|
|
116
|
+
|
|
117
|
+
super(Conv2d_cd, self).__init__()
|
|
118
|
+
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, groups=groups, bias=bias)
|
|
119
|
+
self.theta = theta
|
|
120
|
+
self.bn = nn.BatchNorm2d(out_channels)
|
|
121
|
+
if actv == 'relu':
|
|
122
|
+
self.actv = nn.ReLU(True)
|
|
123
|
+
elif actv == 'lrelu':
|
|
124
|
+
self.actv = nn.LeakyReLU(0.2)
|
|
125
|
+
elif actv == 'tanh':
|
|
126
|
+
self.actv = nn.Tanh()
|
|
127
|
+
elif actv == 'sigmoid':
|
|
128
|
+
self.actv = nn.Sigmoid()
|
|
129
|
+
elif actv == 'elu':
|
|
130
|
+
self.actv = nn.ELU()
|
|
131
|
+
else:
|
|
132
|
+
self.actv = nn.Identity()
|
|
133
|
+
|
|
134
|
+
def forward(self, x):
|
|
135
|
+
out_normal = self.conv(x)
|
|
136
|
+
|
|
137
|
+
if math.fabs(self.theta - 0.0) < 1e-6:
|
|
138
|
+
diff = out_normal
|
|
139
|
+
else:
|
|
140
|
+
#pdb.set_trace()
|
|
141
|
+
[C_out,C_in, kernel_size,kernel_size] = self.conv.weight.shape
|
|
142
|
+
kernel_diff = self.conv.weight.sum(2).sum(2)
|
|
143
|
+
kernel_diff = kernel_diff[:, :, None, None]
|
|
144
|
+
out_diff = F.conv2d(input=x, weight=kernel_diff, bias=self.conv.bias, stride=self.conv.stride, padding=0, groups=self.conv.groups)
|
|
145
|
+
|
|
146
|
+
diff = out_normal - self.theta * out_diff
|
|
147
|
+
out = self.bn(diff)
|
|
148
|
+
out = self.actv(out)
|
|
149
|
+
return out
|
|
150
|
+
|
|
151
|
+
class PartialConv2d(nn.Module):
|
|
152
|
+
def __init__(self, conv_module):
|
|
153
|
+
super(PartialConv2d, self).__init__()
|
|
154
|
+
# whether the mask is multi-channel or not
|
|
155
|
+
self.multi_channel = False
|
|
156
|
+
self.return_mask = True
|
|
157
|
+
self.kernel_size = conv_module.kernel_size
|
|
158
|
+
self.stride = conv_module.stride
|
|
159
|
+
self.padding = conv_module.padding
|
|
160
|
+
self.dilation = conv_module.dilation
|
|
161
|
+
self.bias = conv_module.bias
|
|
162
|
+
self.in_channels = conv_module.in_channels
|
|
163
|
+
self.out_channels = conv_module.out_channels
|
|
164
|
+
|
|
165
|
+
self.conv = conv_module
|
|
166
|
+
|
|
167
|
+
self.weight_maskUpdater = torch.ones(1, 1, self.kernel_size[0], self.kernel_size[1])
|
|
168
|
+
|
|
169
|
+
self.slide_winsize = self.weight_maskUpdater.shape[1] * self.weight_maskUpdater.shape[2] * \
|
|
170
|
+
self.weight_maskUpdater.shape[3]
|
|
171
|
+
|
|
172
|
+
self.last_size = (None, None, None, None)
|
|
173
|
+
self.update_mask = None
|
|
174
|
+
self.mask_ratio = None
|
|
175
|
+
|
|
176
|
+
def forward(self, input, mask_in=None):
|
|
177
|
+
assert len(input.shape) == 4
|
|
178
|
+
if mask_in is not None or self.last_size != tuple(input.shape):
|
|
179
|
+
self.last_size = tuple(input.shape)
|
|
180
|
+
|
|
181
|
+
with torch.no_grad():
|
|
182
|
+
if self.weight_maskUpdater.type() != input.type():
|
|
183
|
+
self.weight_maskUpdater = self.weight_maskUpdater.to(input)
|
|
184
|
+
|
|
185
|
+
if mask_in is None:
|
|
186
|
+
# if mask is not provided, create a mask
|
|
187
|
+
mask = torch.ones(1, 1, input.data.shape[2], input.data.shape[3]).to(input)
|
|
188
|
+
else:
|
|
189
|
+
mask = mask_in
|
|
190
|
+
|
|
191
|
+
self.update_mask = F.conv2d(mask, self.weight_maskUpdater, bias=None, stride=self.stride,
|
|
192
|
+
padding=self.padding, dilation=self.dilation, groups=1)
|
|
193
|
+
|
|
194
|
+
self.mask_ratio = self.slide_winsize / (self.update_mask + 1e-8)
|
|
195
|
+
self.update_mask = torch.clamp(self.update_mask, 0, 1)
|
|
196
|
+
self.mask_ratio = torch.mul(self.mask_ratio, self.update_mask)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
raw_out = self.conv.forward(torch.mul(input, mask) if mask_in is not None else input)
|
|
200
|
+
|
|
201
|
+
if self.bias is not None:
|
|
202
|
+
bias_view = self.bias.view(1, self.out_channels, 1, 1)
|
|
203
|
+
output = torch.mul(raw_out - bias_view, self.mask_ratio) + bias_view
|
|
204
|
+
output = torch.mul(output, self.update_mask)
|
|
205
|
+
else:
|
|
206
|
+
output = torch.mul(raw_out, self.mask_ratio)
|
|
207
|
+
|
|
208
|
+
if self.return_mask:
|
|
209
|
+
return output, self.update_mask
|
|
210
|
+
else:
|
|
211
|
+
return output
|
|
212
|
+
|
|
213
|
+
class ResNetBlock(nn.Module):
|
|
214
|
+
def __init__(self, in_channels, out_channels, stride = 1, bias=False, actv='relu'):
|
|
215
|
+
super(ResNetBlock, self).__init__()
|
|
216
|
+
self.bn1 = nn.BatchNorm2d(int(in_channels*(1.5)))
|
|
217
|
+
self.bn2 = nn.BatchNorm2d(out_channels)
|
|
218
|
+
self.conv1 = nn.Conv2d(in_channels, int(in_channels*(1.5)), 3,1,1, bias=False)
|
|
219
|
+
self.conv2 = nn.Conv2d(int(in_channels*(1.5)), out_channels, 3,1,1, bias=False)
|
|
220
|
+
self.adapt = nn.Conv2d(in_channels, out_channels, 1,1,0, bias=False) if in_channels != out_channels else nn.Identity()
|
|
221
|
+
if actv == 'relu':
|
|
222
|
+
self.actv = nn.ReLU(True)
|
|
223
|
+
elif actv == 'lrelu':
|
|
224
|
+
self.actv = nn.LeakyReLU(0.2)
|
|
225
|
+
elif actv == 'tanh':
|
|
226
|
+
self.actv = nn.Tanh()
|
|
227
|
+
elif actv == 'sigmoid':
|
|
228
|
+
self.actv = nn.Sigmoid()
|
|
229
|
+
elif actv == 'elu':
|
|
230
|
+
self.actv = nn.ELU()
|
|
231
|
+
|
|
232
|
+
def forward(self, x):
|
|
233
|
+
res = x
|
|
234
|
+
x = self.conv1(x)
|
|
235
|
+
x = self.bn1(x)
|
|
236
|
+
x = self.actv(x)
|
|
237
|
+
x = self.conv2(x)
|
|
238
|
+
x = self.bn2(x)
|
|
239
|
+
|
|
240
|
+
res = self.adapt(x)
|
|
241
|
+
out = res + x
|
|
242
|
+
return self.actv(out)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class Conv2dBlock(nn.Module):
|
|
249
|
+
def __init__(self, in_dim, out_dim, ks, st, padding=0, dilation=1,
|
|
250
|
+
norm='none', activation='relu', pad_type='zero',
|
|
251
|
+
use_bias=True, activation_first=False):
|
|
252
|
+
super(Conv2dBlock, self).__init__()
|
|
253
|
+
self.use_bias = use_bias
|
|
254
|
+
self.activation_first = activation_first
|
|
255
|
+
# initialize padding
|
|
256
|
+
if pad_type == 'reflect':
|
|
257
|
+
self.pad = nn.ReflectionPad2d(padding)
|
|
258
|
+
elif pad_type == 'replicate':
|
|
259
|
+
self.pad = nn.ReplicationPad2d(padding)
|
|
260
|
+
elif pad_type == 'zero':
|
|
261
|
+
self.pad = nn.ZeroPad2d(padding)
|
|
262
|
+
elif pad_type == 'none':
|
|
263
|
+
self.pad = None
|
|
264
|
+
else:
|
|
265
|
+
assert 0, "Unsupported padding type: {}".format(pad_type)
|
|
266
|
+
|
|
267
|
+
# initialize normalization
|
|
268
|
+
norm_dim = out_dim
|
|
269
|
+
if norm == 'bn':
|
|
270
|
+
self.norm = nn.BatchNorm2d(norm_dim)
|
|
271
|
+
elif norm == 'in':
|
|
272
|
+
self.norm = nn.InstanceNorm2d(norm_dim)
|
|
273
|
+
elif norm == 'adain':
|
|
274
|
+
self.norm = AdaptiveInstanceNorm2d(norm_dim)
|
|
275
|
+
elif norm == 'none':
|
|
276
|
+
self.norm = None
|
|
277
|
+
else:
|
|
278
|
+
assert 0, "Unsupported normalization: {}".format(norm)
|
|
279
|
+
|
|
280
|
+
# initialize activation
|
|
281
|
+
if activation == 'relu':
|
|
282
|
+
if activation_first == True:
|
|
283
|
+
self.activation = nn.ReLU(inplace=False)
|
|
284
|
+
else:
|
|
285
|
+
self.activation = nn.ReLU(inplace=True)
|
|
286
|
+
elif activation == 'lrelu':
|
|
287
|
+
self.activation = nn.LeakyReLU(0.2, inplace=True)
|
|
288
|
+
elif activation == 'tanh':
|
|
289
|
+
self.activation = nn.Tanh()
|
|
290
|
+
elif activation == 'none':
|
|
291
|
+
self.activation = None
|
|
292
|
+
else:
|
|
293
|
+
assert 0, "Unsupported activation: {}".format(activation)
|
|
294
|
+
|
|
295
|
+
self.conv = nn.Conv2d(in_dim, out_dim, ks, st, dilation=dilation, bias=self.use_bias)
|
|
296
|
+
|
|
297
|
+
def forward(self, x):
|
|
298
|
+
if self.activation_first:
|
|
299
|
+
if self.activation:
|
|
300
|
+
x = self.activation(x)
|
|
301
|
+
if self.pad is not None:
|
|
302
|
+
x = self.conv(self.pad(x))
|
|
303
|
+
else:
|
|
304
|
+
x = self.conv(x)
|
|
305
|
+
|
|
306
|
+
if self.norm:
|
|
307
|
+
x = self.norm(x)
|
|
308
|
+
else:
|
|
309
|
+
if self.pad is not None:
|
|
310
|
+
x = self.conv(self.pad(x))
|
|
311
|
+
else:
|
|
312
|
+
x = self.conv(x)
|
|
313
|
+
|
|
314
|
+
if self.norm:
|
|
315
|
+
x = self.norm(x)
|
|
316
|
+
if self.activation:
|
|
317
|
+
x = self.activation(x)
|
|
318
|
+
return x
|
|
319
|
+
|
|
320
|
+
class Swish(nn.Module):
|
|
321
|
+
def forward(self, x):
|
|
322
|
+
return x * torch.sigmoid(x)
|
|
323
|
+
|
|
324
|
+
class SwishImplementation(torch.autograd.Function):
|
|
325
|
+
@staticmethod
|
|
326
|
+
def forward(ctx, i):
|
|
327
|
+
result = i * torch.sigmoid(i)
|
|
328
|
+
ctx.save_for_backward(i)
|
|
329
|
+
return result
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def backward(ctx, grad_output):
|
|
333
|
+
i = ctx.saved_variables[0]
|
|
334
|
+
sigmoid_i = torch.sigmoid(i)
|
|
335
|
+
return grad_output * (sigmoid_i * (1 + i * (1 - sigmoid_i)))
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class MemoryEfficientSwish(nn.Module):
|
|
339
|
+
def forward(self, x):
|
|
340
|
+
return SwishImplementation.apply(x)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
class AdaptiveInstanceNorm2d(nn.Module):
|
|
345
|
+
def __init__(self, num_features, eps=1e-5, momentum=0.1):
|
|
346
|
+
super(AdaptiveInstanceNorm2d, self).__init__()
|
|
347
|
+
self.num_features = num_features
|
|
348
|
+
self.eps = eps
|
|
349
|
+
self.momentum = momentum
|
|
350
|
+
self.weight = None
|
|
351
|
+
self.bias = None
|
|
352
|
+
self.register_buffer('running_mean', torch.zeros(num_features))
|
|
353
|
+
self.register_buffer('running_var', torch.ones(num_features))
|
|
354
|
+
|
|
355
|
+
def forward(self, x):
|
|
356
|
+
assert self.weight is not None and \
|
|
357
|
+
self.bias is not None, "Please assign AdaIN weight first"
|
|
358
|
+
b, c = x.size(0), x.size(1)
|
|
359
|
+
running_mean = self.running_mean.repeat(b)
|
|
360
|
+
running_var = self.running_var.repeat(b)
|
|
361
|
+
x_reshaped = x.contiguous().view(1, b * c, *x.size()[2:])
|
|
362
|
+
out = F.batch_norm(
|
|
363
|
+
x_reshaped, running_mean, running_var, self.weight, self.bias,
|
|
364
|
+
True, self.momentum, self.eps)
|
|
365
|
+
return out.view(b, c, *x.size()[2:])
|
|
366
|
+
|
|
367
|
+
def __repr__(self):
|
|
368
|
+
return self.__class__.__name__ + '(' + str(self.num_features) + ')'
|