Example #1
0
 def test_calc_padding_err_strides_list(self):
     from tf_conv_dims import calc_padding_4d
     x = tf.zeros([1, 5, 6, 1])
     err_raised = False
     try:
         calc_padding_4d(tf.shape(x), [2, 3, 1, 1], [2, 1, 1, 1], 'SAME')
     except AssertionError as e:
         self.assertEqual(
             e.message, 'Expect first and last dimension of `strides` = 1.')
         err_raised = True
     self.assertTrue(err_raised)
Example #2
0
 def test_calc_padding_err_ksize_list(self):
     from tf_conv_dims import calc_padding_4d
     x = tf.zeros([1, 5, 6, 1])
     err_raised = False
     try:
         calc_padding_4d(tf.shape(x), [2, 3, 1, 1, 1], [2, 1, 1, 1], 'SAME')
     except AssertionError as e:
         self.assertEqual(e.message,
                          'Expect `ksize` a list/tuple of length 4.')
         err_raised = True
     self.assertTrue(err_raised)
Example #3
0
 def test_calc_padding(self):
     from tf_conv_dims import calc_padding_4d
     x = tf.zeros([1, 5, 6, 1])
     p_exp = np.array([0, 1, 1, 1], dtype=np.int32)
     p = calc_padding_4d(tf.shape(x), [2, 3, 1, 1], [1, 1, 1, 1], 'SAME')
     p = tf.stack(p)
     with self.test_session():
         p_act = p.eval()
         np.testing.assert_array_equal(p_act, p_exp)
Example #4
0
    def test_calc_padding_err_strides_tensor(self):
        from tf_conv_dims import calc_padding_4d
        x = tf.zeros([1, 5, 6, 1])
        err_raised = False
        p = calc_padding_4d(tf.shape(x), [2, 3, 1, 1],
                            tf.constant(np.array([2, 1, 1, 1])), 'SAME')
        p = tf.stack(p)
        with self.test_session():
            try:
                p.eval()
            except tf.errors.InvalidArgumentError as e:
                self.assertTrue(
                    e.message.startswith(
                        'assertion failed: [Expect first and last dimension of `strides` = 1.]'
                    ))
                err_raised = True

        self.assertTrue(err_raised)
Example #5
0
def _pad_input(x, ksize, strides, padding, bsize=None, bstrides=None):
    """Pads the input tensor.
    Optional to pass in block strides. The right hand side padding will be increased if the last
    block does not fit in (no effect on the convolution results.

    :param x:        [Tensor]   [N, H, W, C]. input tensor, dtype float32.
    :param ksize:    [list]     List of 4 int. Sparse convolution kernel size.
    :param strides:  [list]     List of 4 int. Sparse convolution stride size.
    :param padding:  [string]   `VALID` or `SAME`, padding method for sparse convolution.
    :param bsize     [list]     List of 4 int. Block size. Optional.
    :param bstrides: [list]     List of 4 int. Block strides. Optional.

    :return          [Tensor]   [N, H+Ph, W+Pw, C]. Padded input tensor.
    """
    x_shape = tf.shape(x)
    if padding == 'SAME':
        pad_h0, pad_h1, pad_w0, pad_w1 = calc_padding_4d(
            x_shape, ksize, strides, padding)

        if bstrides is not None:
            # Here we do not use the standard padding on the right hand side.
            # If the convolution results is larger than expected, the scatter function will not use
            # out-of-boundary points.
            assert bsize is not None, 'Must pass in bsize and bstrides together.'
            h = x_shape[1] + pad_h0 + pad_h1
            w = x_shape[2] + pad_w0 + pad_w1
            pad_h1 += tf.mod(-h + bsize[1], bstrides[1])
            pad_w1 += tf.mod(-w + bsize[2], bstrides[2])
        return tf.pad(x, [[0, 0], [pad_h0, pad_h1], [pad_w0, pad_w1], [0, 0]])
    else:
        if bstrides is not None:
            assert bsize is not None, 'Must pass in bsize and bstrides together.'
            h = x_shape[1]
            w = x_shape[2]
            pad_h1 = tf.mod(-h + bsize[1], bstrides[1])
            pad_w1 = tf.mod(-w + bsize[2], bstrides[2])
            return tf.cond(
                tf.logical_or(tf.greater(pad_h1, 0), tf.greater(pad_w1, 0)),
                lambda: tf.pad(x, [[0, 0], [0, pad_h1], [0, pad_w1], [0, 0]]),
                lambda: x)
        else:
            return x
Example #6
0
def calc_block_params(in_size, bsize, ksize, strides, padding, static=True):
    """
    Calculates block parameters for a single convolution layer.

    :param in_size:  [list]     List of 4 int. Size of the convolution input.
    :param bsize:    [list]     List of 4 int. Size of blocks, or downsample ratio.
    :param ksize:    [list]     List of 4 int. Sparse convolution kernel size.
    :param strides:  [list]     List of 4 int. Sparse convolution stride size.
                                Currently only supports when,
                                1) (bsize[1] - ksize[0]) % strides[1] == 0 and,
                                2) (bsize[2] - ksize[1]) % strides[2] == 0
    :param padding:  [string]   `VALID` or `SAME`, padding method for sparse convolution.

    :return          [tuple]
        bsize:
        bsize_out:
        boffset:
        bcount:
        bstrides:
    """

    assert ((bsize[1] - ksize[0]) % strides[1] == 0)
    assert ((bsize[2] - ksize[1]) % strides[2] == 0)

    bstrides = _calc_block_strides(bsize, ksize, strides)
    pad_h0, pad_h1, pad_w0, pad_w1 = calc_padding_4d(in_size, ksize, strides,
                                                     padding)
    h = in_size[1]
    w = in_size[2]
    # Make padding divides blocks.
    pad_h1 += (-h + bsize[1]) % bstrides[1]
    pad_w1 += (-w + bsize[2]) % bstrides[2]
    boffset = [-pad_h0, -pad_w0]
    x_pad_shape = [
        in_size[0], in_size[1] + pad_h0 + pad_h1, in_size[2] + pad_w0 + pad_w1,
        in_size[3]
    ]
    if static:
        out_shape = calc_out_size_4d_np(x_pad_shape,
                                        [bsize[1], bsize[2], 1, 1], bstrides,
                                        'VALID')
    else:
        out_shape = calc_out_size_4d(x_pad_shape, [bsize[1], bsize[2], 1, 1],
                                     bstrides, 'VALID')
    bcount = [out_shape[1], out_shape[2]]
    bsize_out = calc_out_size_4d_np(bsize, ksize, strides, 'VALID')
    bsize = bsize[1:3]
    bstrides = bstrides[1:3]
    bsize_out = bsize_out[1:3]
    # print('h w', h, w)
    # print('bcount', bcount)
    # print('bsize', bsize)
    # print('bsize_out', bsize_out)
    # print('boffset', boffset)
    # print('bstrides', bstrides)
    # print(pad_h0, pad_w0, boffset)
    if static:
        assert (pad_h0 == -boffset[0])
        assert (pad_w0 == -boffset[1])
    for i, siz in zip([0, 1], [h, w]):
        # make sure last block is inside
        err_msg = 'Making sure last block is inside boffset {} bstrides {} bcount {} size {}'.format(
            boffset[i], bstrides[i], bcount[i], siz)
        assert (boffset[i] + bstrides[i] * (bcount[i] - 1) < siz), err_msg
    return BlockParams(bsize=bsize,
                       bsize_out=bsize_out,
                       boffset=boffset,
                       bcount=bcount,
                       bstrides=bstrides)