composer icon indicating copy to clipboard operation
composer copied to clipboard

ModelHparams isn't a general interface as it implies

Open A-Jacobson opened this issue 4 years ago • 7 comments

@dataclass
class ModelHparams(hp.Hparams, ABC):
    initializers: List[Initializer] = hp.optional(
        default_factory=lambda: [],
        doc="The initialization strategy for the model",
    )

    num_classes: Optional[int] = hp.optional(
        doc="The number of classes.  Needed for classification tasks",
        default=None,
    )

    @abstractmethod
    def initialize_object(self) -> ComposerModel:
        pass

num_classes is classification specific (mostly) and using initializers with torchvision or other integrated models will require wrapping them in constructor functions like landen did for deeplab. Right now many of our models are subclassing ModelHparams and overwriting or not using the built in properties.

perhaps ModelHparams should be:

@dataclass
class ModelHparams(hp.Hparams, ABC):
    @abstractmethod
    def initialize_object(self) -> ComposerModel:
        pass

and we could have task specific interfaces to go with them?

@dataclass
class ClassifierHparams(ModelHparams):
      num_classes: Optional[int] = hp.optional(
        doc="The number of classes.  Needed for classification tasks",
        default=None,
    )
    
    @abstractmethod
    def initialize_object(self) -> ComposerModel:
        pass

@ravi-mosaicml , @Landanjs

A-Jacobson avatar Feb 10 '22 09:02 A-Jacobson

I agree it makes sense to remove num classes from the base class. I would like to keep the initializers (for #472) but otherwise sg.

ravi-mosaicml avatar Feb 11 '22 23:02 ravi-mosaicml

I'm in favor of remove num_classes and initializers, but would like to discuss more about keeping initializers in the base ModelHparams.

Additionally, removing optional arguments from the base class allows us to use required arguments 🎉 . To me, it would be great if task specific models like ClassifierHparams only had required hparams like num_classes. Then, subclasses should be adjusted to have required classes when desired.

Do you need help with this @A-Jacobson?

Landanjs avatar Feb 14 '22 21:02 Landanjs

Re: initializers, would it make sense to allow the user to pass the path to a python function (that can be dynamically imported), in addition to the enum values? This would more easily allow for custom initialization when using yahp.

ravi-mosaicml avatar Feb 15 '22 17:02 ravi-mosaicml

I can see defining a model level weight initialization scheme in one function as a callable but what do you mean by "in addition to the enum values"? I'm having a hard time imagining what this interface looks like.

A-Jacobson avatar Feb 15 '22 23:02 A-Jacobson

Currently via the hparams path you can provide an Initializer enum to describe the initialization scheme. The hparams field would be a string -- it would first attempt to match against an enum, and if that fails, then it would attempt to match against a path to a python function.

ravi-mosaicml avatar Feb 28 '22 20:02 ravi-mosaicml

Maybe? Perhaps with some kind of initializer registry? I'm still skeptical that these would be used across models but it may be good to cover the case where someone explicitly writes multiple initialization schemes for a specific model and wants to test the difference between them.

People would still have to write that argument into the initialization of their composermodel and or pytorch model though which isn't very common externally.

A-Jacobson avatar Feb 28 '22 23:02 A-Jacobson

Since there's still design needed for the initializers (see #472 ), I propose we move num_classes out of the base, and then defer the initializers change until v0.5 to align with #472 .

hanlint avatar Mar 03 '22 19:03 hanlint

YAHP is gone

mvpatel2000 avatar Nov 03 '22 03:11 mvpatel2000