提交 3f29e88b 编写于 作者: C channingss

support transformer

...@@ -6,7 +6,7 @@ python: ...@@ -6,7 +6,7 @@ python:
- '3.6' - '3.6'
script: script:
- if [[ $TRAVIS_PYTHON_VERSION != 2.7 ]]; then /bin/bash ./scripts/check_code_style.sh; fi - if [[ $TRAVIS_PYTHON_VERSION != 2.7 ]]; then /bin/bash ./tools/check_code_style.sh; fi
notifications: notifications:
email: email:
......
...@@ -9,7 +9,7 @@ X2Paddle在多个主流的CV模型上,测试过TensorFlow/Caffe/ONNX模型的 ...@@ -9,7 +9,7 @@ X2Paddle在多个主流的CV模型上,测试过TensorFlow/Caffe/ONNX模型的
## 环境依赖 ## 环境依赖
python >= 3.5 python == 2.7 | python >= 3.5
paddlepaddle >= 1.5.0 paddlepaddle >= 1.5.0
**按需安装以下依赖** **按需安装以下依赖**
......
import urllib from six.moves import urllib
import sys import sys
from paddle.fluid.framework import Program from paddle.fluid.framework import Program
......
__version__ = "0.4.5" __version__ = "0.5.0"
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
# limitations under the License. # limitations under the License.
from x2paddle.core.graph import GraphNode from x2paddle.core.graph import GraphNode
import collections
from x2paddle.core.util import * from x2paddle.core.util import *
import collections
import six
class Layer(object): class Layer(object):
...@@ -28,7 +29,7 @@ class Layer(object): ...@@ -28,7 +29,7 @@ class Layer(object):
def get_code(self): def get_code(self):
layer_code = "" layer_code = ""
if self.output is not None: if self.output is not None:
if isinstance(self.output, str): if isinstance(self.output, six.string_types):
layer_code = self.output + " = " layer_code = self.output + " = "
else: else:
layer_code = self.output.layer_name + " = " layer_code = self.output.layer_name + " = "
...@@ -47,7 +48,7 @@ class Layer(object): ...@@ -47,7 +48,7 @@ class Layer(object):
"[{}]".format(input.index) + ", ") "[{}]".format(input.index) + ", ")
else: else:
in_list += (input.layer_name + ", ") in_list += (input.layer_name + ", ")
elif isinstance(input, str): elif isinstance(input, six.string_types):
in_list += (input + ", ") in_list += (input + ", ")
else: else:
raise Exception( raise Exception(
...@@ -72,7 +73,7 @@ class Layer(object): ...@@ -72,7 +73,7 @@ class Layer(object):
"[{}]".format(self.inputs.index) + ", ") "[{}]".format(self.inputs.index) + ", ")
else: else:
layer_code += (self.inputs.layer_name + ", ") layer_code += (self.inputs.layer_name + ", ")
elif isinstance(self.inputs, str): elif isinstance(self.inputs, six.string_types):
layer_code += (self.inputs + ", ") layer_code += (self.inputs + ", ")
else: else:
raise Exception("Unknown type of inputs.") raise Exception("Unknown type of inputs.")
...@@ -119,6 +120,6 @@ class FluidCode(object): ...@@ -119,6 +120,6 @@ class FluidCode(object):
for layer in self.layers: for layer in self.layers:
if isinstance(layer, Layer): if isinstance(layer, Layer):
codes.append(layer.get_code()) codes.append(layer.get_code())
elif isinstance(layer, str): elif isinstance(layer, six.string_types):
codes.append(layer) codes.append(layer)
return codes return codes
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from __future__ import print_function
from __future__ import division
import collections import collections
import copy as cp import copy as cp
...@@ -98,8 +100,3 @@ class Graph(object): ...@@ -98,8 +100,3 @@ class Graph(object):
raise Exception("node[{}] not in graph".format(dst)) raise Exception("node[{}] not in graph".format(dst))
self.node_map[dst].inputs.append(src) self.node_map[dst].inputs.append(src)
self.node_map[src].outputs.append(dst) self.node_map[src].outputs.append(dst)
def print(self):
for i, tmp in enumerate(self.topo_sort):
print(tmp, self.node_map[tmp].layer_type, self.node_map[tmp].inputs,
self.node_map[tmp].outputs)
...@@ -236,11 +236,7 @@ class CaffeDecoder(object): ...@@ -236,11 +236,7 @@ class CaffeDecoder(object):
data.MergeFromString(open(self.model_path, 'rb').read()) data.MergeFromString(open(self.model_path, 'rb').read())
pair = lambda layer: (layer.name, self.normalize_pb_data(layer)) pair = lambda layer: (layer.name, self.normalize_pb_data(layer))
layers = data.layers or data.layer layers = data.layers or data.layer
import time
start = time.time()
self.params = [pair(layer) for layer in layers if layer.blobs] self.params = [pair(layer) for layer in layers if layer.blobs]
end = time.time()
print('cost:', str(end - start))
def normalize_pb_data(self, layer): def normalize_pb_data(self, layer):
transformed = [] transformed = []
......
...@@ -954,6 +954,13 @@ class CaffeOpMapper(OpMapper): ...@@ -954,6 +954,13 @@ class CaffeOpMapper(OpMapper):
inputs_node = [] inputs_node = []
for i in range(len(node.inputs)): for i in range(len(node.inputs)):
input = self.graph.get_bottom_node(node, idx=i, copy=True) input = self.graph.get_bottom_node(node, idx=i, copy=True)
if i == 1 and op == 'DetectionOutput':
input = self.graph.get_bottom_node(node, idx=i, copy=True)
print(input.layer_type)
while input is not None and input.layer_type != 'Softmax':
input = self.graph.get_bottom_node(input, idx=0, copy=True)
assert input is not None, 'This kind of DetectionOutput is not supported!'
input = self.graph.get_bottom_node(input, idx=0, copy=True)
inputs_node.append(input) inputs_node.append(input)
node.fluid_code.add_layer(func.__code__.co_name, node.fluid_code.add_layer(func.__code__.co_name,
inputs=inputs_node, inputs=inputs_node,
......
...@@ -24,6 +24,8 @@ import sys ...@@ -24,6 +24,8 @@ import sys
def get_same_padding(in_size, kernel_size, stride): def get_same_padding(in_size, kernel_size, stride):
new_size = int(math.ceil(in_size * 1.0 / stride)) new_size = int(math.ceil(in_size * 1.0 / stride))
pad_size = (new_size - 1) * stride + kernel_size - in_size pad_size = (new_size - 1) * stride + kernel_size - in_size
if pad_size < 0:
pad_size = 0
pad0 = int(pad_size / 2) pad0 = int(pad_size / 2)
pad1 = pad_size - pad0 pad1 = pad_size - pad0
return [pad0, pad1] return [pad0, pad1]
...@@ -369,12 +371,13 @@ class TFOpMapper(OpMapper): ...@@ -369,12 +371,13 @@ class TFOpMapper(OpMapper):
pad_w = get_same_padding(in_shape[3], k_size[3], strides[3]) pad_w = get_same_padding(in_shape[3], k_size[3], strides[3])
pad_h = pad_h[0] + pad_h[1] pad_h = pad_h[0] + pad_h[1]
pad_w = pad_w[0] + pad_w[1] pad_w = pad_w[0] + pad_w[1]
attr = {"paddings": [0, pad_h, 0, pad_w], "pad_value": -10000.0} if pad_h != 0 or pad_w != 0:
node.fluid_code.add_layer("pad2d", attr = {"paddings": [0, pad_h, 0, pad_w], "pad_value": -10000.0}
inputs=input, node.fluid_code.add_layer("pad2d",
output=node, inputs=input,
param_attr=attr) output=node,
input = 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"),
...@@ -551,6 +554,7 @@ class TFOpMapper(OpMapper): ...@@ -551,6 +554,7 @@ class TFOpMapper(OpMapper):
def Reshape(self, node): def Reshape(self, node):
input = self.graph.get_node(node.layer.input[0], copy=True) input = self.graph.get_node(node.layer.input[0], copy=True)
param = self.graph.get_node(node.layer.input[1], copy=True) param = self.graph.get_node(node.layer.input[1], copy=True)
is_variable = False
if param.layer_type == "Const": if param.layer_type == "Const":
attr = {"shape": param.value.tolist()} attr = {"shape": param.value.tolist()}
self.add_omit_nodes(param.layer_name, node.layer_name) self.add_omit_nodes(param.layer_name, node.layer_name)
...@@ -582,6 +586,24 @@ class TFOpMapper(OpMapper): ...@@ -582,6 +586,24 @@ class TFOpMapper(OpMapper):
new_param += (node.layer_name + "[{}]".format(i) + ", ") new_param += (node.layer_name + "[{}]".format(i) + ", ")
new_param = new_param.strip(", ") + "]" new_param = new_param.strip(", ") + "]"
attr = {"shape": new_param} attr = {"shape": new_param}
is_variable = True
# to change [192, -1]->[-1, 192], allways put -1 in the first dimension
# optimization for Paddle-Lite
in_shape = input.out_shapes[0]
if is_variable and in_shape.count(-1) < 1:
total_size = 1
for i in range(len(in_shape)):
total_size *= in_shape[i]
for i in range(len(attr["shape"])):
if attr["shape"][i] == 0:
attr["shape"][i] = in_shape[i]
if attr["shape"][i] != -1:
total_size /= attr["shape"][i]
if attr["shape"].count(-1) > 0:
index = attr["shape"].index(-1)
attr["shape"][index] = int(total_size)
attr["shape"][0] = -1
if len(input.out_shapes[0]) == 4 and node.tf_data_format == "NHWC": if len(input.out_shapes[0]) == 4 and node.tf_data_format == "NHWC":
if len(attr["shape"]) < 3: if len(attr["shape"]) < 3:
...@@ -763,6 +785,9 @@ class TFOpMapper(OpMapper): ...@@ -763,6 +785,9 @@ class TFOpMapper(OpMapper):
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)
delta = self.graph.get_node(node.layer.input[2], copy=True) delta = self.graph.get_node(node.layer.input[2], copy=True)
self.add_omit_nodes(start.layer_name, node.layer_name)
self.add_omit_nodes(limit.layer_name, node.layer_name)
self.add_omit_nodes(delta.layer_name, node.layer_name)
if start.layer_type == "Const": if start.layer_type == "Const":
start = start.value start = start.value
else: else:
...@@ -775,9 +800,6 @@ class TFOpMapper(OpMapper): ...@@ -775,9 +800,6 @@ class TFOpMapper(OpMapper):
delta = delta.value delta = delta.value
else: else:
delta = self.decoder.infer_tensor(delta) delta = self.decoder.infer_tensor(delta)
self.add_omit_nodes(start.layer_name, node.layer_name)
self.add_omit_nodes(limit.layer_name, node.layer_name)
self.add_omit_nodes(delta.layer_name, node.layer_name)
inputs = {"start": start, "end": limit, "step": delta} inputs = {"start": start, "end": limit, "step": delta}
attr = {"dtype": string(node.dtype)} attr = {"dtype": string(node.dtype)}
......
...@@ -24,6 +24,8 @@ import sys ...@@ -24,6 +24,8 @@ import sys
def get_same_padding(in_size, kernel_size, stride): def get_same_padding(in_size, kernel_size, stride):
new_size = int(math.ceil(in_size * 1.0 / stride)) new_size = int(math.ceil(in_size * 1.0 / stride))
pad_size = (new_size - 1) * stride + kernel_size - in_size pad_size = (new_size - 1) * stride + kernel_size - in_size
if pad_size < 0:
pad_size = 0
pad0 = int(pad_size / 2) pad0 = int(pad_size / 2)
pad1 = pad_size - pad0 pad1 = pad_size - pad0
return [pad0, pad1] return [pad0, pad1]
...@@ -500,6 +502,7 @@ class TFOpMapperNHWC(OpMapper): ...@@ -500,6 +502,7 @@ class TFOpMapperNHWC(OpMapper):
def Reshape(self, node): def Reshape(self, node):
input = self.graph.get_node(node.layer.input[0], copy=True) input = self.graph.get_node(node.layer.input[0], copy=True)
param = self.graph.get_node(node.layer.input[1], copy=True) param = self.graph.get_node(node.layer.input[1], copy=True)
is_variable = False
if param.layer_type == "Const": if param.layer_type == "Const":
attr = {"shape": param.value.tolist()} attr = {"shape": param.value.tolist()}
self.add_omit_nodes(param.layer_name, node.layer_name) self.add_omit_nodes(param.layer_name, node.layer_name)
...@@ -527,6 +530,24 @@ class TFOpMapperNHWC(OpMapper): ...@@ -527,6 +530,24 @@ class TFOpMapperNHWC(OpMapper):
new_param += (node.layer_name + "[{}]".format(i) + ", ") new_param += (node.layer_name + "[{}]".format(i) + ", ")
new_param = new_param.strip(", ") + "]" new_param = new_param.strip(", ") + "]"
attr = {"shape": new_param} attr = {"shape": new_param}
is_variable = True
# to change [192, -1]->[-1, 192], allways put -1 in the first dimension
# optimization for Paddle-Lite
in_shape = input.out_shapes[0]
if not is_variable and in_shape.count(-1) < 1:
total_size = 1
for i in range(len(in_shape)):
total_size *= in_shape[i]
for i in range(len(attr["shape"])):
if attr["shape"][i] == 0:
attr["shape"][i] = in_shape[i]
if attr["shape"][i] != -1:
total_size /= attr["shape"][i]
if attr["shape"].count(-1) > 0:
index = attr["shape"].index(-1)
attr["shape"][index] = int(total_size)
attr["shape"][0] = -1
node.fluid_code.add_layer("reshape", node.fluid_code.add_layer("reshape",
inputs=input, inputs=input,
output=node, output=node,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册