未验证 提交 85e63593 编写于 作者: C channings 提交者: GitHub

Merge pull request #6 from PaddlePaddle/develop

merge master
...@@ -10,7 +10,7 @@ X2Paddle在多个主流的CV模型上,测试过TensorFlow/Caffe/ONNX模型的 ...@@ -10,7 +10,7 @@ X2Paddle在多个主流的CV模型上,测试过TensorFlow/Caffe/ONNX模型的
## 环境依赖 ## 环境依赖
python == 2.7 | python >= 3.5 python == 2.7 | python >= 3.5
paddlepaddle >= 1.5.0 paddlepaddle >= 1.6.0
**按需安装以下依赖** **按需安装以下依赖**
tensorflow : tensorflow == 1.14.0 tensorflow : tensorflow == 1.14.0
...@@ -55,6 +55,7 @@ x2paddle --framework=onnx --model=onnx_model.onnx --save_dir=pd_model ...@@ -55,6 +55,7 @@ x2paddle --framework=onnx --model=onnx_model.onnx --save_dir=pd_model
|--caffe_proto | **[可选]** 由caffe.proto编译成caffe_pb2.py文件的存放路径,当存在自定义Layer时使用,默认为None | |--caffe_proto | **[可选]** 由caffe.proto编译成caffe_pb2.py文件的存放路径,当存在自定义Layer时使用,默认为None |
|--without_data_format_optimization | **[可选]** For TensorFlow, 当指定该参数时,关闭NHWC->NCHW的优化,见[文档Q2](FAQ.md) | |--without_data_format_optimization | **[可选]** For TensorFlow, 当指定该参数时,关闭NHWC->NCHW的优化,见[文档Q2](FAQ.md) |
|--define_input_shape | **[可选]** For TensorFlow, 当指定该参数时,强制用户输入每个Placeholder的shape,见[文档Q2](FAQ.md) | |--define_input_shape | **[可选]** For TensorFlow, 当指定该参数时,强制用户输入每个Placeholder的shape,见[文档Q2](FAQ.md) |
|--params_merge | **[可选]** 当指定该参数时,转换完成后,inference_model中的所有模型参数将合并保存为一个文件__params__ |
## 使用转换后的模型 ## 使用转换后的模型
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
| 33 | Mean | 34 | MatMul | 35 | ArgMax | 36 | StridedSlice | | 33 | Mean | 34 | MatMul | 35 | ArgMax | 36 | StridedSlice |
| 37 | Slice | 38 | Sum | 39 | Max | 40 | Conv2DBackpropInput | | 37 | Slice | 38 | Sum | 39 | Max | 40 | Conv2DBackpropInput |
| 41 | Cast | 42 | Split | 43 | Squeeze | 44 | ResizeNearestNeighbor | | 41 | Cast | 42 | Split | 43 | Squeeze | 44 | ResizeNearestNeighbor |
| 45 | Softmax | 46 | Range | 47 | ConcatV2 | | 45 | Softmax | 46 | Range | 47 | ConcatV2 | 48 | MirrorPad |
## Caffe ## Caffe
......
__version__ = "0.5.0" __version__ = "0.6.0"
...@@ -68,6 +68,11 @@ def arg_parser(): ...@@ -68,6 +68,11 @@ def arg_parser():
action="store_true", action="store_true",
default=False, default=False,
help="define input shape for tf model") help="define input shape for tf model")
parser.add_argument("--params_merge",
"-pm",
action="store_true",
default=False,
help="define whether merge the params")
return parser return parser
...@@ -75,7 +80,8 @@ def arg_parser(): ...@@ -75,7 +80,8 @@ def arg_parser():
def tf2paddle(model_path, def tf2paddle(model_path,
save_dir, save_dir,
without_data_format_optimization=False, without_data_format_optimization=False,
define_input_shape=False): define_input_shape=False,
params_merge=False):
# check tensorflow installation and version # check tensorflow installation and version
try: try:
import os import os
...@@ -121,10 +127,10 @@ def tf2paddle(model_path, ...@@ -121,10 +127,10 @@ def tf2paddle(model_path,
optimizer.merge_bias() optimizer.merge_bias()
optimizer.make_nchw_input_output() optimizer.make_nchw_input_output()
optimizer.remove_transpose() optimizer.remove_transpose()
mapper.save_inference_model(save_dir) mapper.save_inference_model(save_dir, params_merge)
def caffe2paddle(proto, weight, save_dir, caffe_proto): def caffe2paddle(proto, weight, save_dir, caffe_proto, params_merge=False):
from x2paddle.decoder.caffe_decoder import CaffeDecoder from x2paddle.decoder.caffe_decoder import CaffeDecoder
from x2paddle.op_mapper.caffe_op_mapper import CaffeOpMapper from x2paddle.op_mapper.caffe_op_mapper import CaffeOpMapper
from x2paddle.optimizer.caffe_optimizer import CaffeOptimizer from x2paddle.optimizer.caffe_optimizer import CaffeOptimizer
...@@ -141,10 +147,10 @@ def caffe2paddle(proto, weight, save_dir, caffe_proto): ...@@ -141,10 +147,10 @@ def caffe2paddle(proto, weight, save_dir, caffe_proto):
optimizer = CaffeOptimizer(mapper) optimizer = CaffeOptimizer(mapper)
optimizer.merge_bn_scale() optimizer.merge_bn_scale()
optimizer.merge_op_activation() optimizer.merge_op_activation()
mapper.save_inference_model(save_dir) mapper.save_inference_model(save_dir, params_merge)
def onnx2paddle(model_path, save_dir): def onnx2paddle(model_path, save_dir, params_merge=False):
# check onnx installation and version # check onnx installation and version
try: try:
import onnx import onnx
...@@ -167,7 +173,7 @@ def onnx2paddle(model_path, save_dir): ...@@ -167,7 +173,7 @@ def onnx2paddle(model_path, save_dir):
optimizer = ONNXOptimizer(mapper) optimizer = ONNXOptimizer(mapper)
optimizer.delete_redundance_code() optimizer.delete_redundance_code()
mapper.save_inference_model(save_dir) mapper.save_inference_model(save_dir, params_merge)
def main(): def main():
...@@ -182,7 +188,7 @@ def main(): ...@@ -182,7 +188,7 @@ def main():
if args.version: if args.version:
import x2paddle import x2paddle
print("x2paddle-{} with python>=3.5, paddlepaddle>=1.5.0\n".format( print("x2paddle-{} with python>=3.5, paddlepaddle>=1.6.0\n".format(
x2paddle.__version__)) x2paddle.__version__))
return return
...@@ -192,8 +198,8 @@ def main(): ...@@ -192,8 +198,8 @@ def main():
try: try:
import paddle import paddle
v0, v1, v2 = paddle.__version__.split('.') v0, v1, v2 = paddle.__version__.split('.')
if int(v0) != 1 or int(v1) < 5: if int(v0) != 1 or int(v1) < 6:
print("paddlepaddle>=1.5.0 is required") print("paddlepaddle>=1.6.0 is required")
return return
except: except:
print("paddlepaddle not installed, use \"pip install paddlepaddle\"") print("paddlepaddle not installed, use \"pip install paddlepaddle\"")
...@@ -202,20 +208,29 @@ def main(): ...@@ -202,20 +208,29 @@ def main():
assert args.model is not None, "--model should be defined while translating tensorflow model" assert args.model is not None, "--model should be defined while translating tensorflow model"
without_data_format_optimization = False without_data_format_optimization = False
define_input_shape = False define_input_shape = False
params_merge = False
if args.without_data_format_optimization: if args.without_data_format_optimization:
without_data_format_optimization = True without_data_format_optimization = True
if args.define_input_shape: if args.define_input_shape:
define_input_shape = True define_input_shape = True
if args.params_merge:
params_merge = True
tf2paddle(args.model, args.save_dir, without_data_format_optimization, tf2paddle(args.model, args.save_dir, without_data_format_optimization,
define_input_shape) define_input_shape, params_merge)
elif args.framework == "caffe": elif args.framework == "caffe":
assert args.prototxt is not None and args.weight is not None, "--prototxt and --weight should be defined while translating caffe model" assert args.prototxt is not None and args.weight is not None, "--prototxt and --weight should be defined while translating caffe model"
params_merge = False
if args.params_merge:
params_merge = True
caffe2paddle(args.prototxt, args.weight, args.save_dir, caffe2paddle(args.prototxt, args.weight, args.save_dir,
args.caffe_proto) args.caffe_proto, params_merge)
elif args.framework == "onnx": elif args.framework == "onnx":
assert args.model is not None, "--model should be defined while translating onnx model" assert args.model is not None, "--model should be defined while translating onnx model"
onnx2paddle(args.model, args.save_dir) params_merge = False
if args.params_merge:
params_merge = True
onnx2paddle(args.model, args.save_dir, params_merge)
else: else:
raise Exception("--framework only support tensorflow/caffe/onnx now") raise Exception("--framework only support tensorflow/caffe/onnx now")
......
...@@ -110,7 +110,7 @@ class OpMapper(object): ...@@ -110,7 +110,7 @@ class OpMapper(object):
self.add_codes("import paddle.fluid as fluid") self.add_codes("import paddle.fluid as fluid")
self.add_codes("") self.add_codes("")
def save_inference_model(self, save_dir): def save_inference_model(self, save_dir, params_merge):
self.save_python_model(save_dir) self.save_python_model(save_dir)
import sys import sys
...@@ -138,13 +138,20 @@ class OpMapper(object): ...@@ -138,13 +138,20 @@ class OpMapper(object):
py_code_dir, py_code_dir,
fluid.default_main_program(), fluid.default_main_program(),
predicate=if_exist) predicate=if_exist)
if params_merge:
fluid.io.save_inference_model(dirname=os.path.join( fluid.io.save_inference_model(dirname=os.path.join(
save_dir, "inference_model"), save_dir, "inference_model"),
feeded_var_names=input_names, feeded_var_names=input_names,
target_vars=outputs, target_vars=outputs,
executor=exe, executor=exe,
params_filename=None) params_filename="__params__")
else:
fluid.io.save_inference_model(dirname=os.path.join(
save_dir, "inference_model"),
feeded_var_names=input_names,
target_vars=outputs,
executor=exe,
params_filename=None)
except: except:
raise Exception( raise Exception(
"Paddle code was saved in {}/model.py, but seems there's wrong exist, please check model.py manually." "Paddle code was saved in {}/model.py, but seems there's wrong exist, please check model.py manually."
......
...@@ -243,7 +243,17 @@ class CaffeDecoder(object): ...@@ -243,7 +243,17 @@ class CaffeDecoder(object):
for blob in layer.blobs: for blob in layer.blobs:
if len(blob.shape.dim): if len(blob.shape.dim):
dims = blob.shape.dim dims = blob.shape.dim
c_o, c_i, h, w = map(int, [1] * (4 - len(dims)) + list(dims)) if layer.type == 'PReLU':
c_o, c_i, h, w = map(int, [1] + \
list(dims) + [1]* (3 - len(dims)))
elif layer.type == 'Normalize':
data = np.asarray(list(blob.data), dtype=np.float32)
transformed.append(data)
continue
else:
c_o, c_i, h, w = map(int, [1] * (4 - len(dims)) \
+ list(dims))
else: else:
c_o = blob.num c_o = blob.num
c_i = blob.channels c_i = blob.channels
......
...@@ -278,6 +278,7 @@ class TFOpMapper(OpMapper): ...@@ -278,6 +278,7 @@ class TFOpMapper(OpMapper):
'name': string(node.layer_name), 'name': string(node.layer_name),
'append_batch_size': False 'append_batch_size': False
} }
if shape[0] < 0: if shape[0] < 0:
self.batch_node = node self.batch_node = node
...@@ -382,7 +383,6 @@ class TFOpMapper(OpMapper): ...@@ -382,7 +383,6 @@ class TFOpMapper(OpMapper):
data_format = node.get_attr("data_format").decode() data_format = node.get_attr("data_format").decode()
pad_mode = node.get_attr("padding").decode() pad_mode = node.get_attr("padding").decode()
channel_first = data_format == "NCHW" channel_first = data_format == "NCHW"
padding = 0
if not channel_first: if not channel_first:
in_shape = [in_shape[i] for i in [0, 3, 1, 2]] in_shape = [in_shape[i] for i in [0, 3, 1, 2]]
...@@ -391,22 +391,10 @@ class TFOpMapper(OpMapper): ...@@ -391,22 +391,10 @@ class TFOpMapper(OpMapper):
else: else:
self.graph.data_format_propagation(node) self.graph.data_format_propagation(node)
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[2], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[3], strides[3])
pad_h = pad_h[0] + pad_h[1]
pad_w = pad_w[0] + pad_w[1]
if pad_h != 0 or pad_w != 0:
attr = {"paddings": [0, pad_h, 0, pad_w], "pad_value": -10000.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"pool_size": k_size[2:4], "pool_size": k_size[2:4],
"pool_type": string("max"), "pool_type": string("max"),
"pool_padding": padding, "pool_padding": string(pad_mode),
"pool_stride": strides[2:4] "pool_stride": strides[2:4]
} }
node.fluid_code.add_layer("pool2d", node.fluid_code.add_layer("pool2d",
...@@ -432,7 +420,6 @@ class TFOpMapper(OpMapper): ...@@ -432,7 +420,6 @@ class TFOpMapper(OpMapper):
data_format = node.get_attr("data_format").decode() data_format = node.get_attr("data_format").decode()
pad_mode = node.get_attr("padding").decode() pad_mode = node.get_attr("padding").decode()
channel_first = data_format == "NCHW" channel_first = data_format == "NCHW"
padding = 0
self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose( self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose(
kernel.value, (3, 2, 0, 1)) kernel.value, (3, 2, 0, 1))
...@@ -444,18 +431,6 @@ class TFOpMapper(OpMapper): ...@@ -444,18 +431,6 @@ class TFOpMapper(OpMapper):
else: else:
self.graph.data_format_propagation(node) self.graph.data_format_propagation(node)
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -463,7 +438,7 @@ class TFOpMapper(OpMapper): ...@@ -463,7 +438,7 @@ class TFOpMapper(OpMapper):
"filter_size": k_size[0:2], "filter_size": k_size[0:2],
"stride": strides[2:4], "stride": strides[2:4],
"dilation": dilations[2:4], "dilation": dilations[2:4],
"padding": padding "padding": string(pad_mode)
} }
node.fluid_code.add_layer("conv2d", node.fluid_code.add_layer("conv2d",
inputs=input, inputs=input,
...@@ -535,7 +510,6 @@ class TFOpMapper(OpMapper): ...@@ -535,7 +510,6 @@ class TFOpMapper(OpMapper):
data_format = node.get_attr("data_format").decode() data_format = node.get_attr("data_format").decode()
pad_mode = node.get_attr("padding").decode() pad_mode = node.get_attr("padding").decode()
channel_first = data_format == "NCHW" channel_first = data_format == "NCHW"
padding = 0
self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose( self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose(
kernel.value, (2, 3, 0, 1)) kernel.value, (2, 3, 0, 1))
...@@ -547,19 +521,6 @@ class TFOpMapper(OpMapper): ...@@ -547,19 +521,6 @@ class TFOpMapper(OpMapper):
else: else:
self.data_format_propagation(node) self.data_format_propagation(node)
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -569,7 +530,7 @@ class TFOpMapper(OpMapper): ...@@ -569,7 +530,7 @@ class TFOpMapper(OpMapper):
"dilation": dilations[2:4], "dilation": dilations[2:4],
"groups": k_size[3] * in_shape[1], "groups": k_size[3] * in_shape[1],
"use_cudnn": False, "use_cudnn": False,
"padding": padding "padding": string(pad_mode)
} }
node.fluid_code.add_layer("conv2d", node.fluid_code.add_layer("conv2d",
inputs=input, inputs=input,
...@@ -691,14 +652,9 @@ class TFOpMapper(OpMapper): ...@@ -691,14 +652,9 @@ class TFOpMapper(OpMapper):
attr = { attr = {
"pool_size": k_size[2:4], "pool_size": k_size[2:4],
"pool_type": string("avg"), "pool_type": string("avg"),
"pool_stride": strides[2:4] "pool_stride": strides[2:4],
"pool_padding": string(pad_mode)
} }
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[2], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[3], strides[3])
assert pad_h[0] == pad_h[1] and pad_w[0] == pad_w[
1], "Cannot map AvgPool"
attr["pool_padding"] = [pad_h[0], pad_w[0]]
node.fluid_code.add_layer("pool2d", node.fluid_code.add_layer("pool2d",
inputs=input, inputs=input,
output=node, output=node,
...@@ -806,6 +762,28 @@ class TFOpMapper(OpMapper): ...@@ -806,6 +762,28 @@ class TFOpMapper(OpMapper):
output=node, output=node,
param_attr=attr) param_attr=attr)
def MirrorPad(self, node):
input = self.graph.get_node(node.layer.input[0], copy=True)
paddings = self.graph.get_node(node.layer.input[1], copy=True)
assert paddings.layer_type == "Const", "Padding should be Const"
self.add_omit_nodes(paddings.layer_name, node.layer_name)
paddings = paddings.value.flatten().tolist()
mode = node.get_attr("mode").decode()
assert mode == "REFLECT", "Only support 'REFLECT` mode in MirrorPad"
if input.tf_data_format == "NHWC" and len(input.out_shapes[0]) == 4:
paddings = [paddings[i] for i in [0, 1, 6, 7, 2, 3, 4, 5]]
pad_op = "pad"
if len(input.out_shapes[0]) == 4:
if paddings[0] + paddings[1] + paddings[2] + paddings[3] == 0:
paddings = paddings[4:]
pad_op = "pad2d"
attr = {"paddings": paddings, "mode": string("reflect")}
node.fluid_code.add_layer(pad_op,
inputs=input,
output=node,
param_attr=attr)
def Range(self, node): def Range(self, node):
start = self.graph.get_node(node.layer.input[0], copy=True) start = self.graph.get_node(node.layer.input[0], copy=True)
limit = self.graph.get_node(node.layer.input[1], copy=True) limit = self.graph.get_node(node.layer.input[1], copy=True)
...@@ -993,20 +971,6 @@ class TFOpMapper(OpMapper): ...@@ -993,20 +971,6 @@ class TFOpMapper(OpMapper):
else: else:
self.data_format_propagation(node) self.data_format_propagation(node)
padding = 0
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -1014,29 +978,14 @@ class TFOpMapper(OpMapper): ...@@ -1014,29 +978,14 @@ class TFOpMapper(OpMapper):
"filter_size": k_size[0:2], "filter_size": k_size[0:2],
"stride": strides[2:4], "stride": strides[2:4],
"dilation": dilations[2:4], "dilation": dilations[2:4],
"padding": padding "padding": string(pad_mode),
"output_size": out_shape[1:3]
} }
node.fluid_code.add_layer("conv2d_transpose", node.fluid_code.add_layer("conv2d_transpose",
inputs=input, inputs=input,
output=node, output=node,
param_attr=attr) param_attr=attr)
if pad_mode == "SAME":
if node.tf_data_format == "NHWC":
out_shape = [out_shape[i] for i in [0, 3, 1, 2]]
for i in range(4):
if out_shape[i] < 0:
out_shape[i] = 999999
attr = {
"axes": [0, 1, 2, 3],
"starts": [0, 0, 0, 0],
"ends": out_shape
}
node.fluid_code.add_layer("slice",
inputs=node,
output=node,
param_attr=attr)
def Max(self, node): def Max(self, node):
input = self.graph.get_node(node.layer.input[0], copy=True) input = self.graph.get_node(node.layer.input[0], copy=True)
reduce_idx = self.graph.get_node(node.layer.input[1], copy=True) reduce_idx = self.graph.get_node(node.layer.input[1], copy=True)
......
...@@ -321,22 +321,11 @@ class TFOpMapperNHWC(OpMapper): ...@@ -321,22 +321,11 @@ class TFOpMapperNHWC(OpMapper):
k_size = [k_size[i] for i in [0, 3, 1, 2]] k_size = [k_size[i] for i in [0, 3, 1, 2]]
input = node input = node
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[2], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[3], strides[3])
pad_h = pad_h[0] + pad_h[1]
pad_w = pad_w[0] + pad_w[1]
attr = {"paddings": [0, pad_h, 0, pad_w], "pad_value": -10000.0}
if pad_h + pad_w != 0:
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"pool_size": k_size[2:4], "pool_size": k_size[2:4],
"pool_type": string("max"), "pool_type": string("max"),
"pool_stride": strides[2:4] "pool_stride": strides[2:4],
"pool_padding": string(pad_mode)
} }
node.fluid_code.add_layer("pool2d", node.fluid_code.add_layer("pool2d",
inputs=input, inputs=input,
...@@ -368,7 +357,6 @@ class TFOpMapperNHWC(OpMapper): ...@@ -368,7 +357,6 @@ class TFOpMapperNHWC(OpMapper):
data_format = node.get_attr("data_format").decode() data_format = node.get_attr("data_format").decode()
pad_mode = node.get_attr("padding").decode() pad_mode = node.get_attr("padding").decode()
channel_first = data_format == "NCHW" channel_first = data_format == "NCHW"
padding = 0
self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose( self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose(
kernel.value, (3, 2, 0, 1)) kernel.value, (3, 2, 0, 1))
...@@ -384,18 +372,6 @@ class TFOpMapperNHWC(OpMapper): ...@@ -384,18 +372,6 @@ class TFOpMapperNHWC(OpMapper):
param_attr=attr) param_attr=attr)
input = node input = node
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -403,7 +379,7 @@ class TFOpMapperNHWC(OpMapper): ...@@ -403,7 +379,7 @@ class TFOpMapperNHWC(OpMapper):
"filter_size": k_size[0:2], "filter_size": k_size[0:2],
"stride": strides[2:4], "stride": strides[2:4],
"dilation": dilations[2:4], "dilation": dilations[2:4],
"padding": padding "padding": string(pad_mode)
} }
node.fluid_code.add_layer("conv2d", node.fluid_code.add_layer("conv2d",
inputs=input, inputs=input,
...@@ -490,7 +466,6 @@ class TFOpMapperNHWC(OpMapper): ...@@ -490,7 +466,6 @@ class TFOpMapperNHWC(OpMapper):
data_format = node.get_attr("data_format").decode() data_format = node.get_attr("data_format").decode()
pad_mode = node.get_attr("padding").decode() pad_mode = node.get_attr("padding").decode()
channel_first = data_format == "NCHW" channel_first = data_format == "NCHW"
padding = 0
self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose( self.weights[kernel.layer_name.replace('/', '_')] = numpy.transpose(
kernel.value, (2, 3, 0, 1)) kernel.value, (2, 3, 0, 1))
...@@ -506,19 +481,6 @@ class TFOpMapperNHWC(OpMapper): ...@@ -506,19 +481,6 @@ class TFOpMapperNHWC(OpMapper):
param_attr=attr) param_attr=attr)
input = node input = node
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -528,7 +490,7 @@ class TFOpMapperNHWC(OpMapper): ...@@ -528,7 +490,7 @@ class TFOpMapperNHWC(OpMapper):
"dilation": dilations[2:4], "dilation": dilations[2:4],
"groups": k_size[3] * in_shape[1], "groups": k_size[3] * in_shape[1],
"use_cudnn": False, "use_cudnn": False,
"padding": padding "padding": string(pad_mode)
} }
node.fluid_code.add_layer("conv2d", node.fluid_code.add_layer("conv2d",
inputs=input, inputs=input,
...@@ -623,14 +585,9 @@ class TFOpMapperNHWC(OpMapper): ...@@ -623,14 +585,9 @@ class TFOpMapperNHWC(OpMapper):
attr = { attr = {
"pool_size": k_size[2:4], "pool_size": k_size[2:4],
"pool_type": string("avg"), "pool_type": string("avg"),
"pool_stride": strides[2:4] "pool_stride": strides[2:4],
"pool_padding": string(pad_mode)
} }
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[2], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[3], strides[3])
assert pad_h[0] == pad_h[1] and pad_w[0] == pad_w[
1], "Cannot map AvgPool"
attr["pool_padding"] = [pad_h[0], pad_w[0]]
node.fluid_code.add_layer("pool2d", node.fluid_code.add_layer("pool2d",
inputs=input, inputs=input,
output=node, output=node,
...@@ -990,20 +947,6 @@ class TFOpMapperNHWC(OpMapper): ...@@ -990,20 +947,6 @@ class TFOpMapperNHWC(OpMapper):
else: else:
self.data_format_propagation(node) self.data_format_propagation(node)
padding = 0
if pad_mode == "SAME":
pad_h = get_same_padding(in_shape[2], k_size[0], strides[2])
pad_w = get_same_padding(in_shape[3], k_size[1], strides[3])
if pad_h[0] == pad_h[1] and pad_w[0] == pad_w[1]:
padding = [pad_h[0], pad_w[0]]
else:
attr = {"paddings": pad_h + pad_w, "pad_value": 0.0}
node.fluid_code.add_layer("pad2d",
inputs=input,
output=node,
param_attr=attr)
input = node
attr = { attr = {
"bias_attr": False, "bias_attr": False,
"param_attr": string(kernel.layer_name), "param_attr": string(kernel.layer_name),
...@@ -1011,29 +954,14 @@ class TFOpMapperNHWC(OpMapper): ...@@ -1011,29 +954,14 @@ class TFOpMapperNHWC(OpMapper):
"filter_size": k_size[0:2], "filter_size": k_size[0:2],
"stride": strides[2:4], "stride": strides[2:4],
"dilation": dilations[2:4], "dilation": dilations[2:4],
"padding": padding "padding": string(pad_mode),
"output_size": out_shape[1:3]
} }
node.fluid_code.add_layer("conv2d_transpose", node.fluid_code.add_layer("conv2d_transpose",
inputs=input, inputs=input,
output=node, output=node,
param_attr=attr) param_attr=attr)
if pad_mode == "SAME":
if node.tf_data_format == "NHWC":
out_shape = [out_shape[i] for i in [0, 3, 1, 2]]
for i in range(4):
if out_shape[i] < 0:
out_shape[i] = 999999
attr = {
"axes": [0, 1, 2, 3],
"starts": [0, 0, 0, 0],
"ends": out_shape
}
node.fluid_code.add_layer("slice",
inputs=node,
output=node,
param_attr=attr)
if not channel_first: if not channel_first:
attr = {"perm": [0, 2, 3, 1]} attr = {"perm": [0, 2, 3, 1]}
node.fluid_code.add_layer("transpose", node.fluid_code.add_layer("transpose",
...@@ -1181,6 +1109,7 @@ class TFOpMapperNHWC(OpMapper): ...@@ -1181,6 +1109,7 @@ class TFOpMapperNHWC(OpMapper):
else: else:
shape = self.decoder.infer_shape_tensor(shape) shape = self.decoder.infer_shape_tensor(shape)
attr = {"shape": shape, "min": 0.0, "max": 0.9999} attr = {"shape": shape, "min": 0.0, "max": 0.9999}
if shape[0] < 0: if shape[0] < 0:
input = self.batch_node input = self.batch_node
node.fluid_code.add_layer("uniform_random_batch_size_like", node.fluid_code.add_layer("uniform_random_batch_size_like",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册