Deterministic bilinearly-upsample the input images. It is implemented by deconvolution with "BilinearFiller" in Caffe. It is aimed to mimic caffe behavior. Args: x (tf.Tensor): a NCHW tensor shape (int): the upsample factor Returns: tf.Tensor: a NCHW te
(x, shape)
| 45 | |
| 46 | @layer_register(log_shape=True) |
| 47 | def CaffeBilinearUpSample(x, shape): |
| 48 | """ |
| 49 | Deterministic bilinearly-upsample the input images. |
| 50 | It is implemented by deconvolution with "BilinearFiller" in Caffe. |
| 51 | It is aimed to mimic caffe behavior. |
| 52 | |
| 53 | Args: |
| 54 | x (tf.Tensor): a NCHW tensor |
| 55 | shape (int): the upsample factor |
| 56 | |
| 57 | Returns: |
| 58 | tf.Tensor: a NCHW tensor. |
| 59 | """ |
| 60 | inp_shape = x.shape.as_list() |
| 61 | ch = inp_shape[1] |
| 62 | assert ch == 1, "This layer only works for channel=1" |
| 63 | # for a version that supports >1 channels, see: |
| 64 | # https://github.com/tensorpack/tensorpack/issues/1040#issuecomment-452798180 |
| 65 | |
| 66 | shape = int(shape) |
| 67 | filter_shape = 2 * shape |
| 68 | |
| 69 | def bilinear_conv_filler(s): |
| 70 | """ |
| 71 | s: width, height of the conv filter |
| 72 | https://github.com/BVLC/caffe/blob/99bd99795dcdf0b1d3086a8d67ab1782a8a08383/include/caffe/filler.hpp#L219-L268 |
| 73 | """ |
| 74 | f = np.ceil(float(s) / 2) |
| 75 | c = float(2 * f - 1 - f % 2) / (2 * f) |
| 76 | ret = np.zeros((s, s), dtype='float32') |
| 77 | for x in range(s): |
| 78 | for y in range(s): |
| 79 | ret[x, y] = (1 - abs(x / f - c)) * (1 - abs(y / f - c)) |
| 80 | return ret |
| 81 | |
| 82 | w = bilinear_conv_filler(filter_shape) |
| 83 | w = np.repeat(w, ch * ch).reshape((filter_shape, filter_shape, ch, ch)) |
| 84 | |
| 85 | weight_var = tf.constant(w, tf.float32, |
| 86 | shape=(filter_shape, filter_shape, ch, ch), |
| 87 | name='bilinear_upsample_filter') |
| 88 | x = tf.pad(x, [[0, 0], [0, 0], [shape - 1, shape - 1], [shape - 1, shape - 1]], mode='SYMMETRIC') |
| 89 | out_shape = tf.shape(x) * tf.constant([1, 1, shape, shape], tf.int32) |
| 90 | deconv = tf.nn.conv2d_transpose(x, weight_var, out_shape, |
| 91 | [1, 1, shape, shape], 'SAME', data_format='NCHW') |
| 92 | edge = shape * (shape - 1) |
| 93 | deconv = deconv[:, :, edge:-edge, edge:-edge] |
| 94 | |
| 95 | if inp_shape[2]: |
| 96 | inp_shape[2] *= shape |
| 97 | if inp_shape[3]: |
| 98 | inp_shape[3] *= shape |
| 99 | deconv.set_shape(inp_shape) |
| 100 | return deconv |
| 101 | |
| 102 | |
| 103 | class Model(ModelDesc): |
no test coverage detected