Exemple #1
0
def conv_bn(inp, ker_shape, stride, padding, out_chl, isrelu, mode = None):
	global idx
	idx += 1
	print(inp.partial_shape, ker_shape, out_chl)
	if ker_shape == 1:
		W = ortho_group.rvs(out_chl)
		W = W[:, :inp.partial_shape[1]]
		W = W.reshape(W.shape[0], W.shape[1], 1, 1)
		W = ConstProvider(W)
		b = ConstProvider(np.zeros(out_chl))
	else:
		W = G(mean = 0, std = ((1 + int(isrelu)) / (ker_shape**2 * inp.partial_shape[1]))**0.5)
		b = C(0)
	l1 = Conv2D(
		"conv{}".format(idx), inp, kernel_shape = ker_shape, stride = stride, padding = padding,
		output_nr_channel = out_chl,
		group = mode,
		W = W,
		b = b,
		nonlinearity = Identity()
		)
	l2 = BN("bn{}".format(idx), l1, eps = 1e-9)
	l2 = ElementwiseAffine("bnaff{}".format(idx), l2, shared_in_channels = False, k = C(1), b = C(0))
	if isrelu:
		l2 = arith.ReLU(l2)
	return l2, l1
Exemple #2
0
def make_network(minibatch_size = 128):
	patch_size = 32
	inp = DataProvider("data", shape = (minibatch_size, 3, patch_size, patch_size))
	label = DataProvider("label", shape = (minibatch_size, ))

	#lay = bn_relu_conv(inp, 3, 1, 1, 16, False, False)
	lay, conv = conv_bn(inp, 3, 1, 1, 16, True)
	out = [conv]
	for chl in [32 * 3, 64 * 3, 128 * 3]:
		for i in range(10):
			lay, conv1, conv2 = xcep_layer(lay, chl)
			out.append(conv1)
			out.append(conv2)
		if chl != 128 * 3:
			lay = Pooling2D("pooling{}".format(chl), lay, window = 2, mode = "MAX")

	
	#global average pooling
	print(lay.partial_shape)
	feature = lay.mean(axis = 2).mean(axis = 2)
	#feature = Pooling2D("glbpoling", lay, window = 8, stride = 8, mode = "AVERAGE")
	W = ortho_group.rvs(feature.partial_shape[1])
	W = W[:, :10]
	W = ConstProvider(W)
	b = ConstProvider(np.zeros((10, )))
	pred = Softmax("pred", FullyConnected(
		"fc0", feature, output_dim = 10,
		W = W,
		b = b,
		nonlinearity = Identity()
		))
	
	network = Network(outputs = [pred] + out)
	network.loss_var = CrossEntropyLoss(pred, label)
	return network
Exemple #3
0
def make_network(minibatch_size = 64):
	patch_size = 32
	inp = DataProvider("data", shape = (minibatch_size, 3, patch_size, patch_size))
	label = DataProvider("label", shape = (minibatch_size, ))

	lay = bn_relu_conv(inp, 3, 1, 1, 16, False, False)

	k, l = 12, (40 - 4) // 3
	for i in range(3):
		lay = transition(dense_block(lay, k, l), i)
	
	#global average pooling
	print(lay.partial_shape)
	feature = lay.mean(axis = 2).mean(axis = 2)
	#feature = Pooling2D("glbpoling", lay, window = 8, stride = 8, mode = "AVERAGE")
	W = ortho_group.rvs(feature.partial_shape[1])
	W = W[:10, :].T
	W = ConstProvider(W)
	b = ConstProvider(np.zeros((10, )))
	pred = Softmax("pred", FullyConnected(
		"fc0", feature, output_dim = 10,
		#W = G(mean = 0, std = (1 / feature.partial_shape[1])**0.5),
		#b = C(0),
		W = W,
		b = b,
		nonlinearity = Identity()
		))
	
	network = Network(outputs = [pred])
	network.loss_var = CrossEntropyLoss(pred, label)
	return network
Exemple #4
0
def make_network(minibatch_size=128, debug=False):
    patch_size = 32
    inp = DataProvider("data",
                       shape=(minibatch_size, 3, patch_size, patch_size),
                       dtype=np.float32)
    label = DataProvider("label", shape=(minibatch_size, ), dtype=np.int32)

    lay = conv_bn(inp, 3, 1, 1, 16, True)

    n = 18
    lis = [16, 32, 64]
    for i in lis:
        lay = res_block(lay, i, n)

    #global average pooling
    #feature = lay.mean(axis = 2).mean(axis = 2)
    feature = Pooling2D("pooling",
                        lay,
                        window=8,
                        stride=8,
                        padding=0,
                        mode="AVERAGE")
    W = ortho_group.rvs(feature.partial_shape[1])
    W = W[:10, :].T
    for i in range(1, 10):
        W[:, i] += W[:, i - 1]
    W = ConstProvider(W)
    b = ConstProvider(np.zeros((10, )))
    fc0 = FullyConnected("fc0",
                         feature,
                         output_dim=10,
                         W=W,
                         b=b,
                         nonlinearity=Identity())
    pred = Softmax("pred", fc0)

    network = Network(outputs=[pred])
    network.loss_var = CrossEntropyLoss(pred, label)

    if debug:
        visitor = NetworkVisitor(network.loss_var)
        """
		for i in visitor.all_oprs:
			print(i)
			print(i.partial_shape)
			print("input = ", i.inputs)
			print("output = ", i.outputs)
			print()
		"""

    return network
Exemple #5
0
def b_resize(name, inp, rate=0.8):
    #inp = ConstProvider([[[[1, 2], [3, 4]]]], dtype = np.float32)
    f_size = inp.partial_shape[2]
    l = int(f_size * rate)
    s = [[0, l], [f_size - l, f_size]]
    ar0 = Linspace(0, inp.shape[0], inp.shape[0], endpoint=False)
    ar0 = ar0.add_axis(1).add_axis(2).add_axis(3).broadcast(
        inp.shape).add_axis(4)
    ar1 = Linspace(0, inp.shape[1], inp.shape[1], endpoint=False)
    ar1 = ar1.add_axis(0).add_axis(2).add_axis(3).broadcast(
        inp.shape).add_axis(4)

    fmaps = [inp]
    for i in range(4):
        xx = s[i % 2]
        yy = s[i // 2]
        #x = Linspace(xx[0], xx[1], f_size, endpoint = False)
        #y = Linspace(yy[0], yy[1], f_size, endpoint = False)
        x = ConstProvider(np.linspace(xx[0], xx[1], f_size, endpoint=False))
        y = ConstProvider(np.linspace(yy[0], yy[1], f_size, endpoint=False))
        fx, fy = Floor(x), Floor(y)
        cx, cy = Ceil(x), Ceil(y)
        nfmaps = []
        for sx in range(2):
            for sy in range(2):
                ix = fx if sx == 0 else cx
                iy = fy if sy == 0 else cy
                bx = (cx - x + Equal(fx, cx) if sx == 0 else x - fx)
                by = (cy - y + Equal(fy, cy) if sy == 0 else y - fy)
                arx = ix.add_axis(0).add_axis(0).add_axis(3).broadcast(
                    inp.shape).add_axis(4)
                ary = iy.add_axis(0).add_axis(0).add_axis(0).broadcast(
                    inp.shape).add_axis(4)
                idxmap = Astype(Concat([ar0, ar1, arx, ary], axis=4), np.int32)
                sample = IndexingRemap(inp, idxmap)
                sample *= bx.dimshuffle('x', 'x', 0, 'x') * by.dimshuffle(
                    'x', 'x', 'x', 0)
                nfmaps.append(sample)
        fmap = nfmaps[0]
        for i in range(1, 4):
            fmap += nfmaps[i]
        fmaps.append(fmap)
    fmap = Concat(fmaps, axis=1)
    return fmap
Exemple #6
0
def dfconv(inp, chl, isrelu, ker_shape = 3, stride = 1, padding = 1, dx = [-1, 0, 1], dy = [-1, 0, 1]):
	inp = Conv2D(
		name + "conv", inp, kernel_shape = 3, stride = 1, padding = 1,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = ((1) / (ker_shape**2 * inp.partial_shape[1]))**0.5),
		nonlinearity = Identity()
		)
	inp = BN(name + "BN", inp, eps = 1e-9)

	global idx
	#idx += 1
	gamma = 0.001
	offsetx = inp.partial_shape[2] * Conv2D(
		"conv{}_offsetx".format(idx + 1), inp, kernel_shape = ker_shape, stride = stride, 
		padding = padding,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = gamma / (ker_shape**2 * inp.partial_shape[2])),
		nonlinearity = Identity()
		)
	offsety = inp.partial_shape[3] * Conv2D(
		"conv{}_offsety".format(idx + 1), inp, kernel_shape = ker_shape, stride = stride, 
		padding = padding,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = gamma / (ker_shape**2 * inp.partial_shape[3])),
		nonlinearity = Identity()
		)

	outputs = []
	for sx in range(2):
		for sy in range(2):
			if sx == 0:
				ofx = Floor(offsetx)
				bilx = offsetx - ofx
			else:
				ofx = Ceil(offsetx)
				bilx = ofx - offsetx
			if sy == 0:
				ofy = Floor(offsety)
				bily = offsety - ofy
			else:
				ofy = Ceil(offsety)
				bily = ofy - offsety

			"""
			No padding
			padding1 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], 1, inp.partial_shape[3])))
			padding2 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], inp.partial_shape[2] + 2, 1)))
			arg_fea = Concat([padding1, inp, padding1], axis = 2)
			arg_fea = Concat([padding2, arg_fea, padding2], axis = 3)
			"""
			arg_fea = inp

			#one_mat = ConstProvider(np.ones((inp.partial_shape[2], inp.partial_shape[3])), dtype = np.int32)
			one_mat = ConstProvider(1, dtype = np.int32).add_axis(0).broadcast((ofx.partial_shape[2], ofx.partial_shape[3]))
			affx = (Cumsum(one_mat, axis = 0) - 1) * stride
			affy = (Cumsum(one_mat, axis = 1) - 1) * stride

			ofx = ofx + affx.dimshuffle('x', 'x', 0, 1)
			ofy = ofy + affy.dimshuffle('x', 'x', 0, 1)
			one_mat = ConstProvider(np.ones((ker_shape, ofx.partial_shape[2], ofx.partial_shape[3])))
			#ofx[:, :ker_shape, :, :] -= 1
			#ofx[:, ker_shape*2:, :, :] += 1
			ofx += Concat([one_mat * i for i in dx], axis = 0).dimshuffle('x', 0, 1, 2)
			#ofy[:, ::3, :, :] -= 1
			#ofy[:, 2::3, :, :] += 1
			one_mat = ones((1, ofx.partial_shape[2], ofx.partial_shape[3]))
			one_mat = Concat([one_mat * i for i in dy], axis = 0)
			one_mat = Concat([one_mat] * ker_shape, axis = 0)
			ofy += one_mat.dimshuffle('x', 0, 1, 2)
			ofx = Max(Min(ofx, arg_fea.partial_shape[2] - 1), 0)
			ofy = Max(Min(ofy, arg_fea.partial_shape[3] - 1), 0)

			def DeformReshape(inp, ker_shape):
				inp = inp.reshape(inp.shape[0], ker_shape, ker_shape, inp.shape[2], inp.shape[3])
				inp = inp.dimshuffle(0, 3, 1, 4, 2)
				inp = inp.reshape(inp.shape[0], inp.shape[1] * inp.shape[2], inp.shape[3] * inp.shape[4])
				return inp

			ofx = DeformReshape(ofx, ker_shape)
			ofy = DeformReshape(ofy, ker_shape)
			bilx = DeformReshape(bilx, ker_shape)
			bily = DeformReshape(bily, ker_shape)

			of = ofx * arg_fea.shape[2] + ofy
			arg_fea = arg_fea.reshape(arg_fea.shape[0], arg_fea.shape[1], -1)
			of = of.reshape(ofx.shape[0], -1)
			of = of.dimshuffle(0, 'x', 1)
			#of = Concat([of] * arg_fea.partial_shape[1], axis = 1)
			of = of.broadcast((of.shape[0], arg_fea.shape[1], of.shape[2]))
			arx = Linspace(0, arg_fea.shape[0], arg_fea.shape[0], endpoint = False)
			arx = arx.add_axis(1).add_axis(2).broadcast(of.shape)
			ary = Linspace(0, arg_fea.shape[1], arg_fea.shape[1], endpoint = False)
			ary = ary.add_axis(0).add_axis(2).broadcast(of.shape)
			of = of.add_axis(3)
			arx = arx.add_axis(3)
			ary = ary.add_axis(3)
			idxmap = Astype(Concat([arx, ary, of], axis = 3), np.int32)
			"""
			sample = []
			for i in range(arg_fea.partial_shape[0]):
				for j in range(arg_fea.partial_shape[1]):
					sample.append(arg_fea[i][j].ai[of[i][j]].dimshuffle('x', 0))
			sample = Concat(sample, axis = 0)
			"""
			sample = IndexingRemap(arg_fea, idxmap).reshape(inp.shape[0], inp.shape[1], bilx.shape[1], -1)
			bilx = bilx.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
			bily = bily.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
			sample *= bilx * bily
			
			outputs.append(sample)
	
	output = outputs[0]
	for i in outputs[1:]:
		output += i
	
	return conv_bn(output, ker_shape, 3, 0, chl, isrelu)
Exemple #7
0
def dfpooling(name, inp, window = 2, padding = 0, dx = [0, 1], dy = [0, 1]):
	#inp = ConstProvider([[[[1, 2], [3, 4]]]], dtype = np.float32)
	"""
	Add a new conv&bn to insure that the scale of the feature map is variance 1.
	"""
	ker_shape = window
	stride = window	
	offsetlay = Conv2D(
		name + "conv", inp, kernel_shape = 3, stride = 1, padding = 1,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = ((1) / (3**2 * inp.partial_shape[1]))**0.5),
		nonlinearity = Identity()
		)
	#offsetlay = BN(name + "BN", offsetlay, eps = 1e-9)

	offsetx = Conv2D(
		name + "conv1x", offsetlay, kernel_shape = ker_shape, stride = stride, 
		padding = padding,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = (1 / (ker_shape**2 * inp.partial_shape[2]))**0.5),
		nonlinearity = Identity()
		)
	offsety = Conv2D(
		name + "conv1y", offsetlay, kernel_shape = ker_shape, stride = stride, 
		padding = padding,
		output_nr_channel = ker_shape**2,
		W = G(mean = 0, std = (1 / (ker_shape**2 * inp.partial_shape[3]))**0.5),
		nonlinearity = Identity()
		)
	offset = Concat([offsetx, offsety], axis = 1)

	ndim = ker_shape**2 * offsetx.partial_shape[2] * offsetx.partial_shape[3] * 2
	offset = FullyConnected(
		name + "offset", offsetx, output_dim = ndim,
		W = G(mean = 0, std = (1 / ndim)**2),
		#W = C(0),
		b = C(0),
		nonlinearity = Identity()
		)
	offsetx = offset[:, :ndim // 2].reshape(offsetx.shape)
	offsety = offset[:, ndim // 2:].reshape(offsety.shape)
	"""
	offsetx = FullyConnected(
		name + "offsetx", offsetx, output_dim = ndim,
		W = G(mean = 0, std = gamma / ndim),
		b = C(0),
		nonlinearity = Identity()
		)
	offsetx = offsetx.reshape(offsety.shape)
	offsety = FullyConnected(
		name + "offsety", offsety, output_dim = ndim,
		W = G(mean = 0, std = gamma / ndim),
		b = C(0),
		nonlinearity = Identity()
		)
	offsety = offsety.reshape(offsetx.shape)
	print(offsety.partial_shape)
	"""

	#offsetx = ZeroGrad(offsetx)
	#offsety = ZeroGrad(offsety)
	outputs = []
	for sx in range(2):
		for sy in range(2):
			if sx == 0:
				ofx = Floor(offsetx)
				bilx = 1 - (offsetx - ofx)
			else:
				ofx = Ceil(offsetx)
				bilx = 1 - (ofx - offsetx)
			if sy == 0:
				ofy = Floor(offsety)
				bily = 1 - (offsety - ofy)
			else:
				ofy = Ceil(offsety)
				bily = 1 - (ofy - offsety)
			"""
			No padding
			padding1 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], 1, inp.partial_shape[3])))
			padding2 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], inp.partial_shape[2] + 2, 1)))
			arg_fea = Concat([padding1, inp, padding1], axis = 2)
			arg_fea = Concat([padding2, arg_fea, padding2], axis = 3)
			"""
			arg_fea = inp

			#one_mat = ConstProvider(np.ones((inp.partial_shape[2], inp.partial_shape[3])), dtype = np.int32)
			one_mat = ConstProvider(1, dtype = np.int32).add_axis(0).broadcast((ofx.shape[2], ofx.shape[3]))
			affx = (Cumsum(one_mat, axis = 0) - 1) * stride
			affy = (Cumsum(one_mat, axis = 1) - 1) * stride

			ofx = ofx + affx.dimshuffle('x', 'x', 0, 1)
			ofy = ofy + affy.dimshuffle('x', 'x', 0, 1)
			one_mat = ConstProvider(np.ones((ker_shape, ofx.partial_shape[2], ofx.partial_shape[3])))
			#ofx[:, :ker_shape, :, :] -= 1
			#ofx[:, ker_shape*2:, :, :] += 1
			ofx += Concat([one_mat * i for i in dx], axis = 0).dimshuffle('x', 0, 1, 2)
			#ofy[:, ::3, :, :] -= 1
			#ofy[:, 2::3, :, :] += 1
			one_mat = ones((1, ofx.partial_shape[2], ofx.partial_shape[3]))
			one_mat = Concat([one_mat * i for i in dy], axis = 0)
			one_mat = Concat([one_mat] * ker_shape, axis = 0)
			ofy += one_mat.dimshuffle('x', 0, 1, 2)
			ofx = Max(Min(ofx, arg_fea.partial_shape[2] - 1), 0)
			ofy = Max(Min(ofy, arg_fea.partial_shape[3] - 1), 0)

			def DeformReshape(inp, ker_shape):
				inp = inp.reshape(inp.shape[0], ker_shape, ker_shape, inp.shape[2], inp.partial_shape[3])
				inp = inp.dimshuffle(0, 3, 1, 4, 2)
				inp = inp.reshape(inp.shape[0], inp.shape[1] * inp.shape[2], inp.shape[3] * inp.shape[4])
				return inp

			ofx = DeformReshape(ofx, ker_shape)
			ofy = DeformReshape(ofy, ker_shape)
			bilx = DeformReshape(bilx, ker_shape)
			bily = DeformReshape(bily, ker_shape)

			of = ofx * arg_fea.partial_shape[2] + ofy
			arg_fea = arg_fea.reshape(arg_fea.shape[0], arg_fea.shape[1], -1)
			of = of.reshape(ofx.shape[0], -1)
			of = of.dimshuffle(0, 'x', 1)
			#of = Concat([of] * arg_fea.partial_shape[1], axis = 1)
			of = of.broadcast((of.shape[0], arg_fea.shape[1], of.shape[2]))
			arx = Linspace(0, arg_fea.shape[0], arg_fea.shape[0], endpoint = False)
			arx = arx.add_axis(1).add_axis(2).broadcast(of.shape)
			ary = Linspace(0, arg_fea.shape[1], arg_fea.shape[1], endpoint = False)
			ary = ary.add_axis(0).add_axis(2).broadcast(of.shape)
			of = of.add_axis(3)
			arx = arx.add_axis(3)
			ary = ary.add_axis(3)
			idxmap = Astype(Concat([arx, ary, of], axis = 3), np.int32)
			"""
			sample = []
			for i in range(arg_fea.partial_shape[0]):
				for j in range(arg_fea.partial_shape[1]):
					sample.append(arg_fea[i][j].ai[of[i][j]].dimshuffle('x', 0))
			sample = Concat(sample, axis = 0)
			"""
			sample = IndexingRemap(arg_fea, idxmap).reshape(inp.shape[0], inp.shape[1], bilx.shape[1], -1)
			bilx = bilx.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
			bily = bily.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
			sample *= bilx * bily
			
			outputs.append(sample)
	
	output = outputs[0]
	for i in outputs[1:]:
		output += i
	
	return Pooling2D(name, output, window = 2, mode = "AVERAGE")
Exemple #8
0
def dfpooling(name, inp, window=2, padding=0, dx=[0, 1], dy=[0, 1]):
    #inp = ConstProvider([[[[1, 2], [3, 4]]]], dtype = np.float32)

    ker_shape = window
    stride = window
    gamma = 0.1
    offsetx = gamma * inp.partial_shape[2] * Conv2D(name + "offsetx",
                                                    inp,
                                                    kernel_shape=ker_shape,
                                                    stride=stride,
                                                    padding=padding,
                                                    output_nr_channel=ker_shape
                                                    **2,
                                                    W=C(0),
                                                    nonlinearity=Identity())
    offsety = gamma * inp.partial_shape[3] * Conv2D(name + "offsety",
                                                    inp,
                                                    kernel_shape=ker_shape,
                                                    stride=stride,
                                                    padding=padding,
                                                    output_nr_channel=ker_shape
                                                    **2,
                                                    W=C(0),
                                                    nonlinearity=Identity())
    outputs = []
    for sx in range(2):
        for sy in range(2):
            if sx == 0:
                ofx = Floor(offsetx)
                bilx = offsetx - ofx + Equal(Floor(offsetx), Ceil(offsetx))
            else:
                ofx = Ceil(offsetx)
                bilx = ofx - offsetx
            if sy == 0:
                ofy = Floor(offsety)
                bily = offsety - ofy + Equal(Floor(offsety), Ceil(offsety))
            else:
                ofy = Ceil(offsety)
                bily = ofy - offsety
            """
			No padding
			padding1 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], 1, inp.partial_shape[3])))
			padding2 = ConstProvider(np.zeros((inp.partial_shape[0], inp.partial_shape[1], inp.partial_shape[2] + 2, 1)))
			arg_fea = Concat([padding1, inp, padding1], axis = 2)
			arg_fea = Concat([padding2, arg_fea, padding2], axis = 3)
			"""
            arg_fea = inp

            #one_mat = ConstProvider(np.ones((inp.partial_shape[2], inp.partial_shape[3])), dtype = np.int32)
            one_mat = ConstProvider(1, dtype=np.int32).add_axis(0).broadcast(
                (ofx.partial_shape[2], ofx.partial_shape[3]))
            affx = (Cumsum(one_mat, axis=0) - 1) * stride
            affy = (Cumsum(one_mat, axis=1) - 1) * stride

            ofx = ofx + affx.dimshuffle('x', 'x', 0, 1)
            ofy = ofy + affy.dimshuffle('x', 'x', 0, 1)
            one_mat = ConstProvider(
                np.ones(
                    (ker_shape, ofx.partial_shape[2], ofx.partial_shape[3])))
            #ofx[:, :ker_shape, :, :] -= 1
            #ofx[:, ker_shape*2:, :, :] += 1
            ofx += Concat([one_mat * i for i in dx],
                          axis=0).dimshuffle('x', 0, 1, 2)
            #ofy[:, ::3, :, :] -= 1
            #ofy[:, 2::3, :, :] += 1
            one_mat = ones((1, ofx.partial_shape[2], ofx.partial_shape[3]))
            one_mat = Concat([one_mat * i for i in dy], axis=0)
            one_mat = Concat([one_mat] * ker_shape, axis=0)
            ofy += one_mat.dimshuffle('x', 0, 1, 2)
            ofx = Max(Min(ofx, arg_fea.partial_shape[2] - 1), 0)
            ofy = Max(Min(ofy, arg_fea.partial_shape[3] - 1), 0)

            def DeformReshape(inp, ker_shape):
                inp = inp.reshape(inp.partial_shape[0], ker_shape, ker_shape,
                                  inp.partial_shape[2], inp.partial_shape[3])
                inp = inp.dimshuffle(0, 3, 1, 4, 2)
                inp = inp.reshape(inp.partial_shape[0],
                                  inp.partial_shape[1] * inp.partial_shape[2],
                                  inp.partial_shape[3] * inp.partial_shape[4])
                return inp

            ofx = DeformReshape(ofx, ker_shape)
            ofy = DeformReshape(ofy, ker_shape)
            bilx = DeformReshape(bilx, ker_shape)
            bily = DeformReshape(bily, ker_shape)

            of = ofx * arg_fea.partial_shape[2] + ofy
            arg_fea = arg_fea.reshape(arg_fea.partial_shape[0],
                                      arg_fea.partial_shape[1], -1)
            of = of.reshape(ofx.partial_shape[0], -1)
            of = of.dimshuffle(0, 'x', 1)
            #of = Concat([of] * arg_fea.partial_shape[1], axis = 1)
            of = of.broadcast((of.partial_shape[0], arg_fea.partial_shape[1],
                               of.partial_shape[2]))
            arx = Linspace(0,
                           arg_fea.partial_shape[0],
                           arg_fea.partial_shape[0],
                           endpoint=False)
            arx = arx.add_axis(1).add_axis(2).broadcast(of.shape)
            ary = Linspace(0,
                           arg_fea.partial_shape[1],
                           arg_fea.partial_shape[1],
                           endpoint=False)
            ary = ary.add_axis(0).add_axis(2).broadcast(of.shape)
            of = of.add_axis(3)
            arx = arx.add_axis(3)
            ary = ary.add_axis(3)
            idxmap = Astype(Concat([arx, ary, of], axis=3), np.int32)
            """
			sample = []
			for i in range(arg_fea.partial_shape[0]):
				for j in range(arg_fea.partial_shape[1]):
					sample.append(arg_fea[i][j].ai[of[i][j]].dimshuffle('x', 0))
			sample = Concat(sample, axis = 0)
			"""
            sample = IndexingRemap(arg_fea,
                                   idxmap).reshape(inp.partial_shape[0],
                                                   inp.partial_shape[1],
                                                   bilx.partial_shape[1], -1)
            bilx = bilx.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
            bily = bily.dimshuffle(0, 'x', 1, 2).broadcast(sample.shape)
            sample *= bilx * bily

            outputs.append(sample)

    output = outputs[0]
    for i in outputs[1:]:
        output += i

    return Pooling2D(name, output, window=2, mode="AVERAGE")