Esempio n. 1
0
def test_mask_conv_1d_out_lens(data, conv1d: torch.nn.Conv1d) -> None:
    """Ensures out_lens returns correct output sequence lengths."""
    # PyTorch conv1d requires input size to be greater than effective kernel
    # size. Force this to be True.
    effective_ks = conv1d.dilation[0] * (conv1d.kernel_size[0] - 1) + 1

    padding = data.draw(st.integers(0, effective_ks + 100))

    seq_lens = data.draw(
        st.lists(
            elements=st.integers(max(0, effective_ks - padding), 256),
            min_size=0,
            max_size=32,
        ))

    exp = []
    for seq_len in seq_lens:
        out = conv1d(torch.empty([1, conv1d.in_channels, seq_len + padding]))
        exp.append(out.size(2))
    act = list(
        out_lens(
            seq_lens=torch.tensor(seq_lens),
            kernel_size=conv1d.kernel_size[0],
            stride=conv1d.stride[0],
            dilation=conv1d.dilation[0],
            padding=padding,
        ))

    assert exp == act
Esempio n. 2
0
def test_mask_conv_output_size_and_seq_lens(
    mask_conv1d_input: Tuple[MaskConv1d, Tuple[torch.Tensor, torch.Tensor]]
) -> None:
    """Ensures the MaskConv1d output size and seq_len values are correct."""
    mask_conv1d, inputs = mask_conv1d_input
    batch, channels, seq_len = inputs[0].size()

    out_tensor, out_seq_lens = mask_conv1d(inputs)
    out_batch, out_channels, out_seq_len = out_tensor.size()
    assert out_batch == len(out_seq_lens) == batch
    assert out_channels == mask_conv1d.out_channels

    # test out_seq_len dimension of tensor output and set padding value ready
    # for testing out_seq_lens
    if mask_conv1d._padding_mode == PaddingMode.NONE:
        padding = (0, 0)
        # out_lens function returns correct expected length if the tests pass
        exp_len = out_lens(
            seq_lens=torch.tensor(seq_len),
            kernel_size=mask_conv1d.kernel_size[0],
            stride=mask_conv1d.stride[0],
            dilation=mask_conv1d.dilation[0],
            padding=0,
        ).item()
        assert out_seq_len == exp_len
    elif mask_conv1d._padding_mode == PaddingMode.SAME:
        padding = pad_same(
            length=seq_len,
            kernel_size=mask_conv1d.kernel_size[0],
            stride=mask_conv1d.stride[0],
            dilation=mask_conv1d.dilation[0],
        )
        # by definition of SAME padding
        assert out_seq_len == math.ceil(float(seq_len) / mask_conv1d.stride[0])
    else:
        raise ValueError(f"unknown PaddingMode {mask_conv1d._padding_mode}")

    # test out_seq_lens
    exp_out_seq_lens = out_lens(
        seq_lens=inputs[1],
        kernel_size=mask_conv1d.kernel_size[0],
        stride=mask_conv1d.stride[0],
        dilation=mask_conv1d.dilation[0],
        padding=sum(padding),
    )
    assert torch.all(out_seq_lens == exp_out_seq_lens)
Esempio n. 3
0
def _build_cnn(conv_blocks, input_features: int, input_channels: int):
    act_dims = 4  # batch, channels, features, seq_len

    layers = []
    for conv_block in conv_blocks:
        convnd_str = conv_block.WhichOneof("convnd")

        if convnd_str == "conv1d":
            if act_dims == 4:
                layers.append(Conv2dTo1d())
                act_dims = 3
                input_channels *= input_features
                input_features = 1

            conv_cfg = conv_block.conv1d

            if conv_cfg.padding_mode == conv_layer_pb2.PADDING_MODE.NONE:
                padding_mode = PaddingMode.NONE
            elif conv_cfg.padding_mode == conv_layer_pb2.PADDING_MODE.SAME:
                padding_mode = PaddingMode.SAME

            layers.append(
                MaskConv1d(
                    in_channels=input_channels,
                    out_channels=conv_cfg.output_channels,
                    kernel_size=conv_cfg.kernel_time,
                    stride=conv_cfg.stride_time,
                    padding_mode=padding_mode,
                    bias=conv_cfg.bias,
                ))

            input_channels = conv_cfg.output_channels

        elif convnd_str == "conv2d":
            if act_dims == 3:
                layers.append(Conv1dTo2d())
                act_dims = 4
                input_features = input_channels
                input_channels = 1

            conv_cfg = conv_block.conv2d

            if conv_cfg.padding_mode == conv_layer_pb2.PADDING_MODE.NONE:
                padding_mode = PaddingMode.NONE
                input_features = out_lens(
                    torch.tensor([input_features]),
                    kernel_size=conv_cfg.kernel_feature,
                    stride=conv_cfg.stride_feature,
                    dilation=1,
                    padding=0,
                ).item()
            elif conv_cfg.padding_mode == conv_layer_pb2.PADDING_MODE.SAME:
                padding_mode = PaddingMode.SAME
                input_features = math.ceil(input_features /
                                           conv_cfg.stride_feature)

            layers.append(
                MaskConv2d(
                    in_channels=input_channels,
                    out_channels=conv_cfg.output_channels,
                    kernel_size=[
                        conv_cfg.kernel_feature,
                        conv_cfg.kernel_time,
                    ],
                    stride=[conv_cfg.stride_feature, conv_cfg.stride_time],
                    padding_mode=padding_mode,
                    bias=conv_cfg.bias,
                ))

            input_channels = conv_cfg.output_channels

        layers.append(
            SeqLenWrapper(build_activation(conv_block.activation),
                          torch.nn.Identity()))

    if act_dims == 3:
        layers.append(Conv1dTo2d())
        input_features = input_channels
        input_channels = 1

    return torch.nn.Sequential(*layers), input_features * input_channels