Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature inversion pipeline for modular iCNN construction #81

Merged
merged 120 commits into from
Jul 29, 2024

Conversation

ganow
Copy link
Contributor

@ganow ganow commented Dec 15, 2023

#77

TODO:

Copy link

github-actions bot commented Dec 15, 2023

Coverage

Coverage Report
FileStmtsMissCoverMissing
bdpy/bdata
   bdata.py40032020%73–79, 86, 90, 95, 99, 104, 109, 113, 118, 122, 132–134, 155–172, 190, 206–207, 232–248, 252–262, 276–277, 293, 310, 314, 318–356, 388–477, 508, 539, 547–551, 560, 577–584, 589–598, 604–614, 618, 622–625, 628, 632–653, 656–665, 668–677, 683–691, 696–729, 735–744, 750–757, 761–767, 771–799, 803–824, 828–862, 866–868, 872–874, 878–887
   featureselector.py645711%43–47, 52–93, 98–124
   metadata.py674828%21–30, 34, 38, 42, 46, 50, 54, 74–115, 135–144, 149, 154
   utils.py1131039%44–110, 127–173, 201, 217–253, 258, 263
bdpy/dataform
   datastore.py1078521%59–75, 90–93, 97–98, 102–113, 116–119, 122–127, 131–132, 137–158, 190–197, 222–259, 262–265
   features.py29823322%29–32, 41–47, 74–103, 107, 111, 115, 119, 137–163, 168–197, 213–238, 241–269, 272–275, 278–289, 305–319, 323, 327, 331, 335, 339, 343, 347, 351, 355, 359, 364–394, 398–418, 422–462, 465, 470–477, 491–493, 496–499, 502–505, 508–512, 515–516, 536–549
   kvs.py1401400%4–272
   pd.py9544%25–27, 43–44
   sparse.py675124%19–29, 35–46, 52–58, 65–74, 78, 81–87, 90–93, 96–98, 101–126
   utils.py12120%3–18
bdpy/dataset
   utils.py45450%3–98
bdpy/distcomp
   distcomp.py927815%20–29, 32–49, 52–70, 73–93, 96–107, 111, 114–117, 121–127
bdpy/dl
   caffe.py60600%4–129
bdpy/dl/torch
   base.py432444%31–41, 48, 54, 60, 63, 73–83, 90, 96, 102, 105
   dataset.py74740%1–195
   models.py33329811%28–84, 114–140, 148–169, 175–238, 249–253, 259–279, 288–292, 297–316, 327–331, 340–405, 427–431, 442–494, 515–517, 528–587, 611–614, 625–684, 708–711, 722–771, 790–793, 804–853, 872–875
   torch.py1219224%43–60, 63, 80–95, 105–111, 116, 123, 126, 131, 138, 141, 188–225, 228, 231–243, 246–281
bdpy/dl/torch/domain
   core.py462057%47, 63, 74, 77, 89–90, 99, 102, 137–138, 141–143, 146–148, 164–165, 168, 173
   feature_domain.py241346%14, 18, 27–38, 41, 44
   image_domain.py643742%26, 31, 36, 41, 84–108, 111, 114, 121, 124, 137, 140–150, 179, 211–216, 223, 229
bdpy/evals
   metrics.py95878%12–34, 40–73, 82–112, 118–159, 172–179
bdpy/feature
   feature.py30287%33–74
bdpy/fig
   __init__.py440%6–9
   draw_group_image_set.py88880%3–182
   fig.py88880%16–164
   makeplots.py3363360%1–729
   tile_images.py59590%1–193
bdpy/ml
   crossvalidation.py59548%34–61, 104–128, 138, 164–196
   ensemble.py13931%33–46
   learning.py30926514%43–44, 48, 52, 59, 91–104, 109–125, 128, 158–170, 184–209, 260–284, 290–433, 436–461, 465–504, 507–508, 524–536, 541–613
   model.py14012014%29–39, 54–70, 86–144, 156–169, 184–222, 225, 230–250, 254–258, 271–285
   regress.py11827%29–38
   searchlight.py161319%32–51
bdpy/mri
   fmriprep.py4974529%25–34, 38, 44–62, 65–75, 78–89, 92–160, 163–194, 230–360, 367–380, 384, 388–390, 394, 398–400, 410–434, 437–454, 457–464, 471–472, 475–491, 494, 498, 502–815, 819–831, 842–862, 866
   glm.py403610%46–95
   image.py241921%29–54
   load_epi.py281836%36–50, 56–63, 82–88
   load_mri.py191616%16–36
   roi.py2482346%37–100, 122–148, 165–235, 241–314, 320–387, 399–466, 473–499
   spm.py15813912%26–155, 162–166, 170, 174–179, 183–300
bdpy/opendata
   __init__.py110%1
   openneuro.py2102100%1–329
bdpy/pipeline
   config.py362919%15–64
bdpy/preproc
   interface.py524415%31–40, 60–69, 96–105, 111–123, 148–157, 208–217
   preprocessor.py12910717%35, 43–65, 74–78, 85–97, 104–132, 138–189, 196–227, 234–239
   select_top.py231822%35–60
   util.py6267%14, 22
bdpy/recon
   utils.py55550%4–146
bdpy/recon/torch
   icnn.py1611610%15–478
bdpy/recon/torch/modules
   critic.py442055%19, 36, 58, 64–65, 68, 71, 96–110, 132, 157, 184–185
   encoder.py291162%29, 44, 63, 66, 104–109, 124–125, 175
   generator.py723650%15–22, 28–38, 47, 52, 68, 83, 90, 93, 96, 122–124, 128, 143, 186–189, 193, 208, 247–248, 252, 256, 306–309
   latent.py341362%16, 21, 32, 42, 49, 52, 55, 80–83, 87, 97
bdpy/recon/torch/task
   inversion.py834941%19, 32, 37, 42, 47, 54, 59, 64, 69, 86–89, 92–95, 98, 101–102, 159–167, 185–214, 218–220
bdpy/stats
   corr.py433812%29–77, 96–112
bdpy/task
   callback.py714438%15–20, 53, 102–116, 154–156, 161, 166, 212–218, 233–247, 264–265
   core.py16475%41, 45, 50, 60
bdpy/util
   info.py473623%19–79
   math.py131023%23–38
   utils.py362628%48–66, 93–96, 116–121, 137–145
TOTAL5644478215% 

Tests Skipped Failures Errors Time
1 0 💤 0 ❌ 1 🔥 7.334s ⏱️

@ganow ganow changed the title [WIP] Feature inversion pipeline for modular construction [WIP] Feature inversion pipeline for modular iCNN construction Dec 15, 2023
@ShuntaroAoki
Copy link
Member

@ganow
ありがとうございます。
現状の Base クラスの実装では、__call__() を abstractmethod として具象クラス側で実装するよう強制していますが、この部分をそれぞれの基底クラスで (各々の役割に応じた名前の) パブリックメソッドとして定義しておき、__call__() でそれを呼ぶ、とするのはどう思われますか? 以下のようなイメージです。

class BaseGenerator(ABC):
    """Generator module."""

    @abstractmethod
    def reset_states(self) -> None:
        """Reset the state of the generator."""
        pass

    @abstractmethod
    def parameters(self, recurse: bool = True) -> Iterator[nn.Parameter]:
        """Return the parameters of the generator."""
        pass

    @abstractmethod
    def generate(self, latent: torch.Tensor) -> torch.Tensor:
        """Forward pass through the generator network.

        Parameters
        ----------
        latent : torch.Tensor
            Latent vector.

        Returns
        -------
        torch.Tensor
            Generated image. The generated images must be in the range [0, 1].
        """

    def __call__(self, latent: torch.Tensor) -> torch.Tensor:
        """Call self.generate().

        Parameters
        ----------
        latent : torch.Tensor
            Latent vector.

        Returns
        -------
        torch.Tensor
            Generated image. The generated images must be in the range [0, 1].
        """
        return self.generate(latent)

意図は、メソッドに名前をあたえることでそれぞれのメソッドの役割を明確化することです。あとこれはほとんど私情ですが、親クラスのプライベートメソッドをオーバーライドすることに気持ち悪さがあります。

@ganow
Copy link
Contributor Author

ganow commented Dec 19, 2023

なるほど。実装するメソッド名はモジュールごとに変えずにforwardで共通化するのはどう思いますか?nn.moduleと透過的に扱うことを意識したAPIです

@myaokai
Copy link
Contributor

myaokai commented Mar 7, 2024

sample codeを作成してのコメント

  • 画像のresizeを行うdomainが欲しい
  • encoder_moduleのlayer名がfeatures[0]のような扱いに対し、今までのconfigなどではconv1_1のように指定しているので変換が面倒
  • モジュール内部の挙動についてデバッグがしづらい
  • FeatureInversionTaskのreset_statesでgeneratorのパラメータもresetされているがicnnの場合latentのみのresetでいいのではないでしょうか
  • FeatureInversionTaskのgeneratorに画像生成後のドメイン変換が含まれていますが、最終的な出力用のドメイン変換も必要ではないでしょうか

myaokai and others added 12 commits March 21, 2024 15:23
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Co-authored-by: Yoshihiro Nagano <nagano@i.kyoto-u.ac.jp>
Feature inversion task (#81) に関わるPR内のテストコードの作成
self._callback_handler = CallbackHandler(callbacks)

@abstractmethod
def __call__(self, *inputs, **parameters) -> Any:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of directly overriding __call__, I prefer the implementation of having an abstract method (e.g., run) and calling it in __call__.

bdpy/recon/torch/modules/generator.py Show resolved Hide resolved
self._callback_handler.fire("on_task_end")
return generated_image

def reset_states(self) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remind me of the reason why reset_states is not called in the beginning of __call__ (i.e., why users need to explicitly call reset_states)?

return self.compare(features, target_features)

@abstractmethod
def compare(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name "comapre" sounds a bit ambiguous (but I don't have any alternative yet).

bdpy/recon/torch/modules/critic.py Show resolved Hide resolved
bdpy/recon/torch/modules/encoder.py Show resolved Hide resolved
bdpy/recon/torch/modules/generator.py Show resolved Hide resolved
bdpy/recon/torch/modules/latent.py Show resolved Hide resolved

self._num_iterations = num_iterations

def __call__(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments on bdpy/task/core.py

@ganow ganow changed the title [WIP] Feature inversion pipeline for modular iCNN construction Feature inversion pipeline for modular iCNN construction Jul 29, 2024
@ganow ganow marked this pull request as ready for review July 29, 2024 01:49
@ShuntaroAoki ShuntaroAoki merged commit 3cd3c8d into dev Jul 29, 2024
0 of 9 checks passed
@ShuntaroAoki ShuntaroAoki deleted the feature-inversion-pipeline branch August 20, 2024 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants