Commit ac6e140f authored by Yuxin Wu's avatar Yuxin Wu

upsample layer

parent 67cfcdee
...@@ -11,6 +11,7 @@ import tqdm ...@@ -11,6 +11,7 @@ import tqdm
import os import os
from tensorpack.utils import logger from tensorpack.utils import logger
from tensorpack.utils.fs import mkdir_p from tensorpack.utils.fs import mkdir_p
from tensorpack.dataflow import *
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
...@@ -44,13 +45,13 @@ if args.output: ...@@ -44,13 +45,13 @@ if args.output:
NR_DP_TEST = args.number NR_DP_TEST = args.number
logger.info("Testing dataflow speed:") logger.info("Testing dataflow speed:")
ds = RepeatedData(config.dataset, -1)
with tqdm.tqdm(total=NR_DP_TEST, leave=True, unit='data points') as pbar: with tqdm.tqdm(total=NR_DP_TEST, leave=True, unit='data points') as pbar:
for idx, dp in enumerate(config.dataset.get_data()): for idx, dp in enumerate(ds.get_data()):
del dp del dp
if idx > NR_DP_TEST: if idx > NR_DP_TEST:
break break
pbar.update() pbar.update()
from IPython import embed; embed()
...@@ -10,8 +10,8 @@ from .base import DataFlow, ProxyDataFlow ...@@ -10,8 +10,8 @@ from .base import DataFlow, ProxyDataFlow
from ..utils import * from ..utils import *
__all__ = ['BatchData', 'FixedSizeData', 'FakeData', 'MapData', __all__ = ['BatchData', 'FixedSizeData', 'FakeData', 'MapData',
'MapDataComponent', 'RandomChooseData', 'RandomMixData', 'RepeatedData', 'MapDataComponent', 'RandomChooseData',
'JoinData', 'ConcatData', 'SelectComponent'] 'RandomMixData', 'JoinData', 'ConcatData', 'SelectComponent']
class BatchData(ProxyDataFlow): class BatchData(ProxyDataFlow):
def __init__(self, ds, batch_size, remainder=False): def __init__(self, ds, batch_size, remainder=False):
......
...@@ -24,7 +24,7 @@ class BSDS500(DataFlow): ...@@ -24,7 +24,7 @@ class BSDS500(DataFlow):
Produce (image, label) pair, where image has shape (321, 481, 3) and Produce (image, label) pair, where image has shape (321, 481, 3) and
ranges in [0,255]. Label is binary and has shape (321, 481). ranges in [0,255]. Label is binary and has shape (321, 481).
Those pixels annotated as boundaries by >= 3 out of 5 annotators are Those pixels annotated as boundaries by >= 3 annotators are
considered positive examples. This is used in `Holistically-Nested Edge Detection considered positive examples. This is used in `Holistically-Nested Edge Detection
<http://arxiv.org/abs/1504.06375>`_. <http://arxiv.org/abs/1504.06375>`_.
""" """
...@@ -71,7 +71,8 @@ class BSDS500(DataFlow): ...@@ -71,7 +71,8 @@ class BSDS500(DataFlow):
imgid = os.path.basename(f).split('.')[0] imgid = os.path.basename(f).split('.')[0]
gt_file = os.path.join(gt_dir, imgid) gt_file = os.path.join(gt_dir, imgid)
gt = loadmat(gt_file)['groundTruth'][0] gt = loadmat(gt_file)['groundTruth'][0]
gt = sum(gt[k]['Boundaries'][0][0] for k in range(5)) n_annot = gt.shape[0]
gt = sum(gt[k]['Boundaries'][0][0] for k in range(n_annot))
gt[gt < 3] = 0 gt[gt < 3] = 0
gt[gt != 0] = 1 gt[gt != 0] = 1
if gt.shape[0] > gt.shape[1]: if gt.shape[0] > gt.shape[1]:
......
...@@ -11,7 +11,7 @@ from six.moves import range ...@@ -11,7 +11,7 @@ from six.moves import range
try: try:
import h5py import h5py
except ImportError: except ImportError:
logger.error("Error in 'import h5py'. HDF5Data won't be available.") logger.warn("Error in 'import h5py'. HDF5Data won't be available.")
__all__ = [] __all__ = []
else: else:
__all__ = ['HDF5Data'] __all__ = ['HDF5Data']
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
from abc import abstractmethod, ABCMeta from abc import abstractmethod, ABCMeta
from ...utils import get_rng from ...utils import get_rng
from six.moves import zip
__all__ = ['ImageAugmentor', 'AugmentorList'] __all__ = ['ImageAugmentor', 'AugmentorList']
......
...@@ -17,7 +17,7 @@ from ..utils import logger ...@@ -17,7 +17,7 @@ from ..utils import logger
try: try:
import zmq import zmq
except ImportError: except ImportError:
logger.error("Error in 'import zmq'. PrefetchDataZMQ won't be available.") logger.warn("Error in 'import zmq'. PrefetchDataZMQ won't be available.")
__all__ = ['PrefetchData'] __all__ = ['PrefetchData']
else: else:
__all__ = ['PrefetchData', 'PrefetchDataZMQ'] __all__ = ['PrefetchData', 'PrefetchDataZMQ']
......
...@@ -69,7 +69,7 @@ def FixedUnPooling(x, shape, unpool_mat=None): ...@@ -69,7 +69,7 @@ def FixedUnPooling(x, shape, unpool_mat=None):
:param input: NHWC tensor :param input: NHWC tensor
:param shape: int or [h, w] :param shape: int or [h, w]
:param unpool_mat: a tf matrix with size=shape. If None, will use a mat :param unpool_mat: a tf/np matrix with size=shape. If None, will use a mat
with 1 at top-left corner. with 1 at top-left corner.
:returns: NHWC tensor :returns: NHWC tensor
""" """
...@@ -80,6 +80,8 @@ def FixedUnPooling(x, shape, unpool_mat=None): ...@@ -80,6 +80,8 @@ def FixedUnPooling(x, shape, unpool_mat=None):
mat = np.zeros(shape, dtype='float32') mat = np.zeros(shape, dtype='float32')
mat[0][0] = 1 mat[0][0] = 1
unpool_mat = tf.Variable(mat, trainable=False, name='unpool_mat') unpool_mat = tf.Variable(mat, trainable=False, name='unpool_mat')
elif isinstance(unpool_mat, np.ndarray):
unpool_mat = tf.Variable(unpool_mat, trainable=False, name='unpool_mat')
assert unpool_mat.get_shape().as_list() == list(shape) assert unpool_mat.get_shape().as_list() == list(shape)
# perform a tensor-matrix kronecker product # perform a tensor-matrix kronecker product
...@@ -96,6 +98,41 @@ def FixedUnPooling(x, shape, unpool_mat=None): ...@@ -96,6 +98,41 @@ def FixedUnPooling(x, shape, unpool_mat=None):
input_shape[3]]) input_shape[3]])
return prod return prod
@layer_register()
def BilinearUpSample(x, shape):
"""
Bilinear upsample the input images.
:param x: input NHWC tensor
:param shape: an integer
"""
def bilinear_conv_filler(s):
"""
s: width, height of the conv filter
See https://github.com/BVLC/caffe/blob/master/include%2Fcaffe%2Ffiller.hpp#L244
"""
f = np.ceil(float(s) / 2)
c = float(2 * f - 1 - f % 2) / (2 * f)
ret = np.zeros((s, s), dtype='float32')
for x in range(s):
for y in range(s):
ret[x,y] = (1 - abs(x / f - c)) * (1 - abs(y / f - c))
return ret
ch = x.get_shape().as_list()[3]
shape = int(shape)
filter_shape = 2 * shape
w = bilinear_conv_filler(filter_shape)
w = np.repeat(w, ch * ch).reshape((filter_shape, filter_shape, ch, ch))
weight_var = tf.constant(w,
tf.float32,
shape=(filter_shape, filter_shape, ch, ch))
unpool_mat = np.zeros((shape, shape), dtype='float32')
unpool_mat[-1,-1] = 1
x = FixedUnPooling('unpool', x, shape, unpool_mat)
output = tf.nn.conv2d(x, weight_var, [1,1,1,1], padding='SAME')
return output
from ._test import TestModel from ._test import TestModel
class TestPool(TestModel): class TestPool(TestModel):
def test_fixed_unpooling(self): def test_fixed_unpooling(self):
...@@ -113,3 +150,23 @@ class TestPool(TestModel): ...@@ -113,3 +150,23 @@ class TestPool(TestModel):
# the rest are zeros # the rest are zeros
res[0,::2,::2,0] = 0 res[0,::2,::2,0] = 0
self.assertTrue((res == 0).all()) self.assertTrue((res == 0).all())
def test_upsample(self):
h, w = 5, 5
scale = 2
mat = np.random.rand(h, w).astype('float32')
inp = self.make_variable(mat)
inp = tf.reshape(inp, [1, h, w, 1])
output = BilinearUpSample('upsample', inp, scale)
res = self.run_variable(output)
from skimage.transform import rescale
res2 = rescale(mat, scale)
diff = np.abs(res2 - res[0,:,:,0])
# not equivalent at corner
diff[0,0] = diff[-1,-1] = 0
self.assertTrue(diff.max() < 1e-4)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment