Backbone add mixin tests (#22542)
* Add out_indices to backbones, deprecate out_features * Update - can specify both out_features and out_indices but not both * Add backbone mixin tests * Test tidy up * Add test_backbone for convnext * Remove redefinition of method * Update for Dinat and Nat backbones * Update tests * Smarter indexing * Add checks on config creation for backbone * PR comments
This commit is contained in:
@@ -22,6 +22,7 @@ from transformers import BitConfig
|
||||
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -55,6 +56,7 @@ class BitModelTester:
|
||||
num_labels=3,
|
||||
scope=None,
|
||||
out_features=["stage2", "stage3", "stage4"],
|
||||
out_indices=[2, 3, 4],
|
||||
num_groups=1,
|
||||
):
|
||||
self.parent = parent
|
||||
@@ -71,6 +73,7 @@ class BitModelTester:
|
||||
self.scope = scope
|
||||
self.num_stages = len(hidden_sizes)
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
self.num_groups = num_groups
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
@@ -93,6 +96,7 @@ class BitModelTester:
|
||||
hidden_act=self.hidden_act,
|
||||
num_labels=self.num_labels,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
num_groups=self.num_groups,
|
||||
)
|
||||
|
||||
@@ -317,3 +321,14 @@ class BitModelIntegrationTest(unittest.TestCase):
|
||||
expected_slice = torch.tensor([[-0.6526, -0.5263, -1.4398]]).to(torch_device)
|
||||
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
class BitBackboneTest(BackboneTesterMixin, unittest.TestCase):
|
||||
all_model_classes = (BitBackbone,) if is_torch_available() else ()
|
||||
config_class = BitConfig
|
||||
|
||||
has_attentions = False
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = BitModelTester(self)
|
||||
|
||||
@@ -22,6 +22,7 @@ from transformers import ConvNextConfig
|
||||
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -57,6 +58,7 @@ class ConvNextModelTester:
|
||||
num_labels=10,
|
||||
initializer_range=0.02,
|
||||
out_features=["stage2", "stage3", "stage4"],
|
||||
out_indices=[2, 3, 4],
|
||||
scope=None,
|
||||
):
|
||||
self.parent = parent
|
||||
@@ -73,6 +75,7 @@ class ConvNextModelTester:
|
||||
self.num_labels = num_labels
|
||||
self.initializer_range = initializer_range
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
self.scope = scope
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
@@ -95,6 +98,7 @@ class ConvNextModelTester:
|
||||
is_decoder=False,
|
||||
initializer_range=self.initializer_range,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
num_labels=self.num_labels,
|
||||
)
|
||||
|
||||
@@ -224,6 +228,10 @@ class ConvNextModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.TestCase
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_model(*config_and_inputs)
|
||||
|
||||
def test_backbone(self):
|
||||
config_and_inputs = self.model_tester.prepare_config_and_inputs()
|
||||
self.model_tester.create_and_check_backbone(*config_and_inputs)
|
||||
|
||||
def test_hidden_states_output(self):
|
||||
def check_hidden_states_output(inputs_dict, config, model_class):
|
||||
model = model_class(config)
|
||||
@@ -299,3 +307,14 @@ class ConvNextModelIntegrationTest(unittest.TestCase):
|
||||
expected_slice = torch.tensor([-0.0260, -0.4739, 0.1911]).to(torch_device)
|
||||
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
class ConvNextBackboneTest(unittest.TestCase, BackboneTesterMixin):
|
||||
all_model_classes = (ConvNextBackbone,) if is_torch_available() else ()
|
||||
config_class = ConvNextConfig
|
||||
|
||||
has_attentions = False
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = ConvNextModelTester(self)
|
||||
|
||||
@@ -58,6 +58,7 @@ class ConvNextV2ModelTester:
|
||||
num_labels=10,
|
||||
initializer_range=0.02,
|
||||
out_features=["stage2", "stage3", "stage4"],
|
||||
out_indices=[2, 3, 4],
|
||||
scope=None,
|
||||
):
|
||||
self.parent = parent
|
||||
@@ -74,6 +75,7 @@ class ConvNextV2ModelTester:
|
||||
self.num_labels = num_labels
|
||||
self.initializer_range = initializer_range
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
self.scope = scope
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
@@ -97,6 +99,7 @@ class ConvNextV2ModelTester:
|
||||
is_decoder=False,
|
||||
initializer_range=self.initializer_range,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
num_labels=self.num_labels,
|
||||
)
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ from transformers import DinatConfig
|
||||
from transformers.testing_utils import require_natten, require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -67,6 +68,7 @@ class DinatModelTester:
|
||||
use_labels=True,
|
||||
num_labels=10,
|
||||
out_features=["stage1", "stage2"],
|
||||
out_indices=[1, 2],
|
||||
):
|
||||
self.parent = parent
|
||||
self.batch_size = batch_size
|
||||
@@ -92,6 +94,7 @@ class DinatModelTester:
|
||||
self.use_labels = use_labels
|
||||
self.num_labels = num_labels
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])
|
||||
@@ -125,6 +128,7 @@ class DinatModelTester:
|
||||
layer_norm_eps=self.layer_norm_eps,
|
||||
initializer_range=self.initializer_range,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
)
|
||||
|
||||
def create_and_check_model(self, config, pixel_values, labels):
|
||||
@@ -383,3 +387,13 @@ class DinatModelIntegrationTest(unittest.TestCase):
|
||||
self.assertEqual(outputs.logits.shape, expected_shape)
|
||||
expected_slice = torch.tensor([-0.1545, -0.7667, 0.4642]).to(torch_device)
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
@require_natten
|
||||
class DinatBackboneTest(unittest.TestCase, BackboneTesterMixin):
|
||||
all_model_classes = (DinatBackbone,) if is_torch_available() else ()
|
||||
config_class = DinatConfig
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = DinatModelTester(self)
|
||||
|
||||
@@ -23,6 +23,7 @@ from transformers import MaskFormerSwinConfig
|
||||
from transformers.testing_utils import require_torch, require_torch_multi_gpu, torch_device
|
||||
from transformers.utils import is_torch_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -64,6 +65,7 @@ class MaskFormerSwinModelTester:
|
||||
type_sequence_label_size=10,
|
||||
encoder_stride=8,
|
||||
out_features=["stage1", "stage2", "stage3"],
|
||||
out_indices=[1, 2, 3],
|
||||
):
|
||||
self.parent = parent
|
||||
self.batch_size = batch_size
|
||||
@@ -90,6 +92,7 @@ class MaskFormerSwinModelTester:
|
||||
self.type_sequence_label_size = type_sequence_label_size
|
||||
self.encoder_stride = encoder_stride
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])
|
||||
@@ -123,6 +126,7 @@ class MaskFormerSwinModelTester:
|
||||
initializer_range=self.initializer_range,
|
||||
encoder_stride=self.encoder_stride,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
)
|
||||
|
||||
def create_and_check_model(self, config, pixel_values, labels):
|
||||
@@ -395,3 +399,48 @@ class MaskFormerSwinModelTest(ModelTesterMixin, PipelineTesterMixin, unittest.Te
|
||||
tuple_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True)
|
||||
dict_inputs = self._prepare_for_class(inputs_dict, model_class, return_labels=True)
|
||||
check_equivalence(model, tuple_inputs, dict_inputs, {"output_hidden_states": True})
|
||||
|
||||
|
||||
@require_torch
|
||||
class MaskFormerSwinBackboneTest(unittest.TestCase, BackboneTesterMixin):
|
||||
all_model_classes = (MaskFormerSwinBackbone,) if is_torch_available() else ()
|
||||
config_class = MaskFormerSwinConfig
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = MaskFormerSwinModelTester(self)
|
||||
|
||||
# Overriding as returned hidden states are tuples of tensors instead of a single tensor
|
||||
def test_backbone_outputs(self):
|
||||
config, inputs_dict = self.model_tester.prepare_config_and_inputs_for_common()
|
||||
batch_size = inputs_dict["pixel_values"].shape[0]
|
||||
|
||||
for backbone_class in self.all_model_classes:
|
||||
backbone = backbone_class(config)
|
||||
backbone.to(torch_device)
|
||||
backbone.eval()
|
||||
|
||||
outputs = backbone(**inputs_dict)
|
||||
|
||||
# Test default outputs and verify feature maps
|
||||
self.assertIsInstance(outputs.feature_maps, tuple)
|
||||
self.assertTrue(len(outputs.feature_maps) == len(backbone.channels))
|
||||
for feature_map, n_channels in zip(outputs.feature_maps, backbone.channels):
|
||||
self.assertTrue(feature_map.shape[:2], (batch_size, n_channels))
|
||||
self.assertIsNone(outputs.hidden_states)
|
||||
self.assertIsNone(outputs.attentions)
|
||||
|
||||
# Test output_hidden_states=True
|
||||
outputs = backbone(**inputs_dict, output_hidden_states=True)
|
||||
self.assertIsNotNone(outputs.hidden_states)
|
||||
self.assertTrue(len(outputs.hidden_states), len(backbone.stage_names))
|
||||
# We skip the stem layer
|
||||
for hidden_states, n_channels in zip(outputs.hidden_states[1:], backbone.channels):
|
||||
for hidden_state in hidden_states:
|
||||
# Hidden states are in the format (batch_size, (height * width), n_channels)
|
||||
h_batch_size, _, h_n_channels = hidden_state.shape
|
||||
self.assertTrue((h_batch_size, h_n_channels), (batch_size, n_channels))
|
||||
|
||||
# Test output_attentions=True
|
||||
if self.has_attentions:
|
||||
outputs = backbone(**inputs_dict, output_attentions=True)
|
||||
self.assertIsNotNone(outputs.attentions)
|
||||
|
||||
@@ -22,6 +22,7 @@ from transformers import NatConfig
|
||||
from transformers.testing_utils import require_natten, require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -66,6 +67,7 @@ class NatModelTester:
|
||||
use_labels=True,
|
||||
num_labels=10,
|
||||
out_features=["stage1", "stage2"],
|
||||
out_indices=[1, 2],
|
||||
):
|
||||
self.parent = parent
|
||||
self.batch_size = batch_size
|
||||
@@ -90,6 +92,7 @@ class NatModelTester:
|
||||
self.use_labels = use_labels
|
||||
self.num_labels = num_labels
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])
|
||||
@@ -122,6 +125,7 @@ class NatModelTester:
|
||||
layer_norm_eps=self.layer_norm_eps,
|
||||
initializer_range=self.initializer_range,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
)
|
||||
|
||||
def create_and_check_model(self, config, pixel_values, labels):
|
||||
@@ -380,3 +384,13 @@ class NatModelIntegrationTest(unittest.TestCase):
|
||||
self.assertEqual(outputs.logits.shape, expected_shape)
|
||||
expected_slice = torch.tensor([0.3805, -0.8676, -0.3912]).to(torch_device)
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
@require_natten
|
||||
class NatBackboneTest(unittest.TestCase, BackboneTesterMixin):
|
||||
all_model_classes = (NatBackbone,) if is_torch_available() else ()
|
||||
config_class = NatConfig
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = NatModelTester(self)
|
||||
|
||||
@@ -22,6 +22,7 @@ from transformers import ResNetConfig
|
||||
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -57,6 +58,7 @@ class ResNetModelTester:
|
||||
num_labels=3,
|
||||
scope=None,
|
||||
out_features=["stage2", "stage3", "stage4"],
|
||||
out_indices=[2, 3, 4],
|
||||
):
|
||||
self.parent = parent
|
||||
self.batch_size = batch_size
|
||||
@@ -72,6 +74,7 @@ class ResNetModelTester:
|
||||
self.scope = scope
|
||||
self.num_stages = len(hidden_sizes)
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])
|
||||
@@ -93,6 +96,7 @@ class ResNetModelTester:
|
||||
hidden_act=self.hidden_act,
|
||||
num_labels=self.num_labels,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
)
|
||||
|
||||
def create_and_check_model(self, config, pixel_values, labels):
|
||||
@@ -323,3 +327,13 @@ class ResNetModelIntegrationTest(unittest.TestCase):
|
||||
expected_slice = torch.tensor([-11.1069, -9.7877, -8.3777]).to(torch_device)
|
||||
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
class ResNetBackboneTest(BackboneTesterMixin, unittest.TestCase):
|
||||
all_model_classes = (ResNetBackbone,) if is_torch_available() else ()
|
||||
has_attentions = False
|
||||
config_class = ResNetConfig
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = ResNetModelTester(self)
|
||||
|
||||
@@ -22,6 +22,7 @@ from transformers import SwinConfig
|
||||
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
|
||||
from transformers.utils import cached_property, is_torch_available, is_vision_available
|
||||
|
||||
from ...test_backbone_common import BackboneTesterMixin
|
||||
from ...test_configuration_common import ConfigTester
|
||||
from ...test_modeling_common import ModelTesterMixin, _config_zero_init, floats_tensor, ids_tensor
|
||||
from ...test_pipeline_mixin import PipelineTesterMixin
|
||||
@@ -69,6 +70,7 @@ class SwinModelTester:
|
||||
type_sequence_label_size=10,
|
||||
encoder_stride=8,
|
||||
out_features=["stage1", "stage2"],
|
||||
out_indices=[1, 2],
|
||||
):
|
||||
self.parent = parent
|
||||
self.batch_size = batch_size
|
||||
@@ -95,6 +97,7 @@ class SwinModelTester:
|
||||
self.type_sequence_label_size = type_sequence_label_size
|
||||
self.encoder_stride = encoder_stride
|
||||
self.out_features = out_features
|
||||
self.out_indices = out_indices
|
||||
|
||||
def prepare_config_and_inputs(self):
|
||||
pixel_values = floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size])
|
||||
@@ -128,6 +131,7 @@ class SwinModelTester:
|
||||
initializer_range=self.initializer_range,
|
||||
encoder_stride=self.encoder_stride,
|
||||
out_features=self.out_features,
|
||||
out_indices=self.out_indices,
|
||||
)
|
||||
|
||||
def create_and_check_model(self, config, pixel_values, labels):
|
||||
@@ -502,3 +506,12 @@ class SwinModelIntegrationTest(unittest.TestCase):
|
||||
self.assertEqual(outputs.logits.shape, expected_shape)
|
||||
expected_slice = torch.tensor([-0.0948, -0.6454, -0.0921]).to(torch_device)
|
||||
self.assertTrue(torch.allclose(outputs.logits[0, :3], expected_slice, atol=1e-4))
|
||||
|
||||
|
||||
@require_torch
|
||||
class SwinBackboneTest(unittest.TestCase, BackboneTesterMixin):
|
||||
all_model_classes = (SwinBackbone,) if is_torch_available() else ()
|
||||
config_class = SwinConfig
|
||||
|
||||
def setUp(self):
|
||||
self.model_tester = SwinModelTester(self)
|
||||
|
||||
Reference in New Issue
Block a user