Ejemplo n.º 1
0
def space_to_patch(x, patchsz, paddings=None):
    """
    [batch, imgsz0, imgsz1, depth]
    => [newbatch, patchsz0, patchsz1, depth]
    => [batch x blocks, imgsz0 / blocksz0, imgsz1 / blocksz1, depth]
    :param tf.Tensor x:
    :param patchsz:
    :param paddings: [(top, bottom), (left, right)] if None then when need, auto paddings
    :return:
    """
    if paddings is not None:
        if len(paddings) == 2:
            paddings = [(0, 0), paddings[0], paddings[1], (0, 0)]
        x = tf.pad(x, paddings)

    inshape = x.dims
    batch, imgsz, depth = inshape[0], inshape[1:3], inshape[3]
    patchsz = [patchsz[0] or imgsz[0], patchsz[1] or imgsz[1]]
    blocksz = (imgsz[0] // patchsz[0], imgsz[1] // patchsz[1])

    if paddings is None:
        # add padding if necessary
        pd = [
            imgsz[0] - blocksz[0] * patchsz[0],
            imgsz[1] - blocksz[1] * patchsz[1]
        ]
        if pd[0] or pd[1]:
            pd = [patchsz[0] - pd[0], patchsz[1] - pd[1]]
            paddings = [(0, 0), (pd[0] // 2, pd[0] - pd[0] // 2),
                        (pd[1] // 2, pd[1] - pd[1] // 2), (0, 0)]

            x = tf.pad(x, paddings)
            inshape = x.dims
            batch, imgsz, depth = inshape[0], inshape[1:3], inshape[3]
            blocksz = (imgsz[0] // patchsz[0], imgsz[1] // patchsz[1])

    assert blocksz[0] * patchsz[0] == imgsz[0]
    assert blocksz[1] * patchsz[1] == imgsz[1]

    # batch *= (blocksz[0] * blocksz[1])
    # [batch, imgsz0, imgsz1, d] => [batch, block0, patch0, block1, patch1, d]

    data = x.reshape(batch or -1, blocksz[0], patchsz[0], blocksz[1],
                     patchsz[1], depth)
    # dim to [batch, block0, block1, patch0, patch1, d]
    data = data.transpose(0, 1, 3, 2, 4, 5)
    # new batch size
    if batch is not None:
        batch *= (blocksz[0] * blocksz[1])
    data = data.reshape(batch or -1, patchsz[0], patchsz[1], depth)

    return data
Ejemplo n.º 2
0
def dwconv(x,
           kernel,
           multiplier=1,
           stride=1,
           pad=0,
           padding='SAME',
           initializer=tf.he_uniform,
           bias=False,
           **kwargs):

    if pad:
        pads = [(0, 0), (pad, pad), (pad, pad), (0, 0)]
        x = tf.pad(x, pads, mode='CONSTANT')

    kernel = _kernel_shape(2, kernel, x.dims[-1], multiplier)
    stride = _stride_shape(2, stride)

    W = tf.get_weight('W',
                      shape=kernel,
                      initializer=initializer(kernel),
                      **kwargs)
    out = tf.nn.depthwise_conv2d(x, W, stride, padding)
    if bias:
        outdim = kernel[2] * multiplier
        b = tf.get_bias('b',
                        shape=(outdim, ),
                        initializer=tf.zeros_initializer(),
                        **kwargs)
        out = tf.nn.bias_add(out, b)

    return out
Ejemplo n.º 3
0
def time_to_batch(data3d, dilation, paddings=None):
    """
    :param data3d: [batch, time, channel]
    :param dilation: int, rate or dilation
    :param paddings: None or padding formats
    :return: roughly [batch * dilation, time / dilation, channel] with padding if need
    """

    # calc additional pad for depth dim
    batch, width, channel = data3d.dims

    # padding = dilation - (width - (width//dilation) * dilation)
    # if padding != dilation:
    #     # if need, add padding
    #     data3d = tf.pad(data3d, [(0,0), (0, padding), (0, 0)])

    if paddings is not None:
        data3d = tf.pad(data3d, paddings)

    # reshape, dim of time is shrinked along with dilation rate
    data3d = data3d.reshape(-1, dilation, channel)
    data3d = data3d.transpose(1, 0, 2)
    data3d = data3d.reshape(batch * dilation, -1, channel)

    return data3d
Ejemplo n.º 4
0
def conv3d(x,
           outdim,
           kernel,
           stride=1,
           pad=0,
           padding='SAME',
           mode='CONSTANT',
           initializer=tf.he_uniform,
           bias=False,
           **kwargs):

    kernel = _kernel_shape(3, kernel, x.dims[-1], outdim)
    stride = _stride_shape(3, stride)  # stride 5-dim

    pads = None
    if padding == 'SAME' and mode != 'CONSTANT':
        # pad manually
        half = ((kernel[0] - 1) // 2, (kernel[1] - 1) // 2,
                (kernel[2] - 1) // 2)
        pads = [(0, 0), (pad + half[0], pad + kernel[0] - 1 - half[0]),
                (pad + half[1], pad + kernel[1] - 1 - half[1]),
                (pad + half[2], pad + kernel[2] - 1 - half[2]), (0, 0)]
        padding = 'VALID'  # change to valid because manually padded
    elif pad:
        pads = [(0, 0), (pad, pad), (pad, pad), (pad, pad), (0, 0)]
    if pads is not None:
        x = tf.pad(x, pads, mode=mode)

    W = tf.get_weight('W',
                      shape=kernel,
                      initializer=initializer(kernel),
                      **kwargs)
    out = tf.nn.conv3d(x, W, stride, padding)
    if bias:
        b = tf.get_bias('b',
                        shape=(outdim, ),
                        initializer=tf.zeros_initializer(),
                        **kwargs)
        out = tf.nn.bias_add(out, b)

    return out
Ejemplo n.º 5
0
def pad_if_need(image, size, offsets=None):
    """
    :param image: tensor3d[H,W,C]
    :param size: (int, int) targetsize (H,W)
    :param offsets: (0,0) for None
    :return:
    """
    assert image.ndim == 3
    imshape = tf.shape(image)

    # get target shape if possible
    tshape = image.dims
    for i in (0, 1):
        if tshape[i] is not None and size[i] > tshape[i]:
            tshape[i] = size[i]

    targetshape = tf.convert_to_tensor(size).append(imshape[-1])
    need = targetshape - imshape
    # padding need
    need = tf.where(need > 0, need, tf.zeros(tf.shape(need), dtype=tf.int32))
    if offsets is None:
        offsets = [0, 0, 0]
    else:
        offsets = list(offsets)
        offsets.append(0)

    # upper padding = need // 2

    padding_first = need // 2 + tf.convert_to_tensor(offsets)
    padding_left = need - padding_first
    padding = tf.concat(0, [[padding_first], [padding_left]]).T

    out = tf.pad(image, padding, 'CONSTANT')
    # rshape = tf.maximum(imshape, targetshape)

    # if known shape.. set
    out.set_shape(tshape)

    return out
Ejemplo n.º 6
0
def atrous(x,
           outdim,
           kernel,
           rate,
           pad=0,
           padding='SAME',
           initializer=tf.he_uniform,
           bias=None,
           **kwargs):
    # todo rate per axis?

    assert isinstance(pad, int)
    nd = x.ndim - 2
    if pad:
        pads = [(0, 0)] + [(pad, pad)] * nd + [(0, 0)]
        x = tf.pad(x, pads, mode='CONSTANT')

    kernel = _kernel_shape(nd, kernel, x.dims[-1], outdim)
    W = tf.get_weight('W',
                      shape=kernel,
                      initializer=initializer(kernel),
                      **kwargs)

    if nd == 1:
        out = _atrous1d(x, W, rate, padding=padding)
    elif nd == 2:
        out = tf.nn.atrous_conv2d(x, W, rate, padding)
    else:
        raise NotImplementedError('not implementd for ndim [{0}]'.format(nd))

    if bias is not None:
        b = tf.get_bias('b',
                        shape=(outdim, ),
                        initializer=tf.zeros_initializer(),
                        **kwargs)
        out = tf.nn.bias_add(out, b)

    return out