Summary
ShallowFBCSPNet(split_first_layer=False) still constructs the historical unsplit first layer as self.conv_time, but the post-CombinedConv initialization and legacy checkpoint mapping assume self.conv_time_spat exists unconditionally.
This makes the documented non-split path fail during construction, and legacy conv_time.* checkpoint keys are remapped to a module that does not exist.
Regression
In Braindecode v0.7.0, the unsplit path initialized self.conv_time directly:
init.xavier_uniform_(self.conv_time.weight, gain=1)
if self.split_first_layer or (not self.batch_norm):
init.constant_(self.conv_time.bias, 0)
The current implementation creates conv_time_spat = CombinedConv(...) only when split_first_layer=True, but later does:
init.xavier_uniform_(self.conv_time_spat.conv_time.weight, gain=1)
regardless of the mode. The current compatibility mapping similarly rewrites conv_time.* -> conv_time_spat.conv_time.* even for the unsplit model.
Expected behavior
split_first_layer=True: keep the current CombinedConv initialization and legacy key migration.
split_first_layer=False: initialize the direct conv_time layer and leave legacy conv_time.* keys on that module.
- classifier key migration remains unchanged in both modes.
Proposed regression coverage
- construct and run
ShallowFBCSPNet(..., split_first_layer=False);
- verify the unsplit model owns
conv_time and not conv_time_spat;
- load a legacy-style state dict where
conv_time.* remains unsplit while conv_classifier.* migrates to final_layer.conv_classifier.*.
I have a focused patch prepared that only branches the CombinedConv-specific initialization/remapping and leaves the default split-first-layer behavior unchanged.
Summary
ShallowFBCSPNet(split_first_layer=False)still constructs the historical unsplit first layer asself.conv_time, but the post-CombinedConv initialization and legacy checkpoint mapping assumeself.conv_time_spatexists unconditionally.This makes the documented non-split path fail during construction, and legacy
conv_time.*checkpoint keys are remapped to a module that does not exist.Regression
In Braindecode v0.7.0, the unsplit path initialized
self.conv_timedirectly:The current implementation creates
conv_time_spat = CombinedConv(...)only whensplit_first_layer=True, but later does:regardless of the mode. The current compatibility mapping similarly rewrites
conv_time.* -> conv_time_spat.conv_time.*even for the unsplit model.Expected behavior
split_first_layer=True: keep the current CombinedConv initialization and legacy key migration.split_first_layer=False: initialize the directconv_timelayer and leave legacyconv_time.*keys on that module.Proposed regression coverage
ShallowFBCSPNet(..., split_first_layer=False);conv_timeand notconv_time_spat;conv_time.*remains unsplit whileconv_classifier.*migrates tofinal_layer.conv_classifier.*.I have a focused patch prepared that only branches the CombinedConv-specific initialization/remapping and leaves the default split-first-layer behavior unchanged.