提交 87876389 编写于 作者: S SunAhong1993

add gru

上级 90a29f43
...@@ -64,5 +64,5 @@ class TraceDecoder(Decoder): ...@@ -64,5 +64,5 @@ class TraceDecoder(Decoder):
print(e) print(e)
exit(0) exit(0)
self.graph = self._optimize_graph(self.script.inlined_graph) self.graph = self._optimize_graph(self.script.inlined_graph)
self.input_examples = input_examples self.input_examples = input_examples
...@@ -927,10 +927,13 @@ def aten_constant_pad_nd(mapper, graph, node): ...@@ -927,10 +927,13 @@ def aten_constant_pad_nd(mapper, graph, node):
if_layer.inputs["input-1"] = inputs_name[0] + "_len" if_layer.inputs["input-1"] = inputs_name[0] + "_len"
if len(layer_attrs["padding"]) == 2: if len(layer_attrs["padding"]) == 2:
layer_outputs[0] = layer_outputs[0].raplace("pad", "pad1d")
add_pad_layers("paddle.nn.Pad1D", 3) add_pad_layers("paddle.nn.Pad1D", 3)
elif len(layer_attrs["padding"]) == 4: elif len(layer_attrs["padding"]) == 4:
layer_outputs[0] = layer_outputs[0].raplace("pad", "pad2d")
add_pad_layers("paddle.nn.Pad2D", 4) add_pad_layers("paddle.nn.Pad2D", 4)
elif len(layer_attrs["padding"]) == 6: elif len(layer_attrs["padding"]) == 6:
layer_outputs[0] = layer_outputs[0].raplace("pad", "pad3d")
add_pad_layers("paddle.nn.Pad3D", 5) add_pad_layers("paddle.nn.Pad3D", 5)
else: else:
raise Exception("The lenght of padding list must be 2, 4 or 6!") raise Exception("The lenght of padding list must be 2, 4 or 6!")
...@@ -2144,6 +2147,88 @@ def aten_gt(mapper, graph, node): ...@@ -2144,6 +2147,88 @@ def aten_gt(mapper, graph, node):
return current_inputs, current_outputs return current_inputs, current_outputs
def aten_gru(mapper, graph, node):
""" 构造门控循环单元网络(GRU)的PaddleLayer。
TorchScript示例:
%21, %22 = aten::gru(%input, %hx, %20, %11, %10, %9, %11, %8, %11)
参数含义:
%21 (Tensor): 输出,由前向和后向cell的输出拼接得到。
%22 (Tensor): 输出,最终状态。
%input (Tensor): 网络输入。
%hx (Tensor): 网络的初始状态。
%20 (list): 所有权重组合成的list。
%11 (bool): 是否使用bias。
%10 (int): 网络层数。
%9 (float): dropout概率。
%11 (bool): 是否为训练阶段。
%8 (bool): 是否使用双向LSTM。
%11 (bool): 第一个维度是否为batch size。
"""
scope_name = mapper.normalize_scope_name(node)
op_name = name_generator("gru", mapper.nn_name2id)
output_names = mapper._get_outputs_name(node)
layer_outputs = [op_name]
layer_outputs.extend(output_names)
layer_inputs = {}
layer_attrs = {}
inputs_name, inputs_node = mapper._get_inputs_name(node)
# 获取当前节点输出的list
current_outputs = output_names
# 处理输入0,即%input.95
mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs, scope_name)
layer_inputs["input0"] = inputs_name[0]
# 处理输入1,即%734
mapper._check_input(graph, inputs_node[1], inputs_name[1], current_outputs, scope_name)
layer_inputs["input1"] = inputs_name[1]
# 获取当前节点输入、输出的list
current_inputs = list(layer_inputs.values())
# 处理输入2,即%734
mapper._check_input(graph, inputs_node[2], inputs_name[2], current_outputs, scope_name)
graph.layers.pop(mapper.output2id[inputs_name[2]])
param_inputs_name, _ = mapper._get_inputs_name(inputs_node[2])
new_param_inputs_name = list()
for i, param_name in enumerate(param_inputs_name):
if i == 0:
layer_attrs["hidden_size"] = int(mapper.paddle_params[param_name].shape[0] / 3)
layer_attrs["input_size"] = int(mapper.paddle_params[param_name].shape[1])
if len(mapper.paddle_params[param_name].shape) > 1:
part_name = param_name.split("_weight_")[-1]
mapper.paddle_params["{}.weight_{}".format(op_name, part_name)] = mapper.paddle_params[param_name]
new_param_inputs_name.append("{}.weight_{}".format(op_name, part_name))
else:
part_name = param_name.split("_bias_")[-1]
mapper.paddle_params["{}.bias_{}".format(op_name, part_name)] = mapper.paddle_params[param_name]
mapper.paddle_params.pop(param_name)
# 处理输入3,即%526
is_bias = mapper.attrs[inputs_name[3]]
if not is_bias:
for param_name in new_param_inputs_name:
bias_name = param_name.replace("weight", "bias")
bias_shape= mapper.paddle_params[param_name].shape[:1]
mapper.paddle_params[bias_name] = np.zeros(bias_shape).astype("float32")
# 处理输入4,即%525
layer_attrs["num_layers"] = mapper.attrs[inputs_name[4]]
# 处理输入5,即%524
layer_attrs["dropout"] = mapper.attrs[inputs_name[5]]
# 处理输入7,即%526
is_bidirectional = mapper.attrs[inputs_name[7]]
if is_bidirectional:
layer_attrs["direction"] = string("bidirectional")
# 处理输入8,即%526
batch_first = mapper.attrs[inputs_name[8]]
if not batch_first:
layer_attrs["time_major"] = True
graph.add_layer(
"paddle.nn.GRU",
inputs=layer_inputs,
outputs=layer_outputs,
scope_name=scope_name,
**layer_attrs)
return current_inputs, current_outputs
def aten_hardtanh_(mapper, graph, node): def aten_hardtanh_(mapper, graph, node):
""" 构造hardtanh激活的PaddleLayer。 """ 构造hardtanh激活的PaddleLayer。
...@@ -2232,6 +2317,68 @@ def aten_index_select(mapper, graph, node): ...@@ -2232,6 +2317,68 @@ def aten_index_select(mapper, graph, node):
return current_inputs, current_outputs return current_inputs, current_outputs
def aten_instance_norm(mapper, graph, node):
"""构造InstanceNorm的PaddleLayer
TorchScript示例:
%res.7 : Tensor = aten::instance_norm(%res.5, %88, %85, %84, %83, %87, %91, %92, %87)
参数含义:
%res.7 (Tensor): 输出,InstanceNorm的结果。
%res.5 (Tensor): 需要进行InstanceNorm的特征层。
%88 (Tensor): weights。
%85 (Tensor): bias。
%84 (Tensor): 全局均值。
%83 (Tensor): 全局方差。
%87 (bool): 是否使用输入的统计。
%91 (float): momentum。
%92 (float): eps。
%87 (bool): 是否启用cudnn。
"""
scope_name = mapper.normalize_scope_name(node)
op_name = name_generator("instance_norm", mapper.nn_name2id)
output_name = mapper._get_outputs_name(node)[0]
layer_outputs = [op_name, output_name]
layer_inputs = {}
layer_attrs = {}
inputs_name, inputs_node = mapper._get_inputs_name(node)
# 获取当前节点输出的list
current_outputs = [output_name]
# 处理输入0,即%input.80
mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs, scope_name)
layer_inputs["input"] = inputs_name[0]
# 获取当前节点输入、输出的list
current_inputs = list(layer_inputs.values())
# 处理输入1,即%88
if inputs_name[1] in mapper.pytorch_params:
weights = mapper.pytorch_params[inputs_name[1]]
mapper.paddle_params[op_name + ".weight"] = weights
layer_attrs['num_features'] = weights.shape[0]
# 处理输入2,即%85
if inputs_name[2] in mapper.pytorch_params:
bias = mapper.pytorch_params[inputs_name[2]]
mapper.paddle_params[op_name + ".bias"] = bias
# 处理输入3,即%84
if inputs_name[3] in mapper.pytorch_params:
mean = mapper.pytorch_params[inputs_name[3]]
mapper.paddle_params[op_name + "._mean"] = mean
# 处理输入4,即%83
if inputs_name[4] in mapper.pytorch_params:
var = mapper.pytorch_params[inputs_name[4]]
mapper.paddle_params[op_name + "._variance"] = var
# 处理输入6,即%91
layer_attrs["momentum"] = 1 - mapper.attrs[inputs_name[6]]
# 处理输入7,即%92
layer_attrs["epsilon"] = mapper.attrs[inputs_name[7]]
graph.add_layer(
"custom_layer:InstanceNorm",
inputs=layer_inputs,
outputs=layer_outputs,
scope_name=scope_name,
**layer_attrs)
return current_inputs, current_outputs
def aten_Int(mapper, graph, node): def aten_Int(mapper, graph, node):
""" 构造强转为int的PaddleLayer。 """ 构造强转为int的PaddleLayer。
...@@ -3393,6 +3540,98 @@ def aten_prelu(mapper, graph, node): ...@@ -3393,6 +3540,98 @@ def aten_prelu(mapper, graph, node):
return current_inputs, current_outputs return current_inputs, current_outputs
def aten_reflection_pad1d(mapper, graph, node):
""" 构造1维映射填充的PaddleLayer。
TorchScript示例:
%6 = aten::reflection_pad1d(%input, %7)
参数含义:
%6 (Tensor): 输出,填充后的Tensor。
%input (Tensor): 需要填充的Tensor。
%7 (list|Tensor): 填充大小。
"""
scope_name = mapper.normalize_scope_name(node)
op_name = name_generator("pad1d", mapper.nn_name2id)
output_name = mapper._get_outputs_name(node)[0]
layer_outputs = [op_name, output_name]
layer_inputs = {}
layer_attrs = {}
inputs_name, inputs_node = mapper._get_inputs_name(node)
# 获取当前节点输出的list
current_outputs = [output_name]
# 处理输入0,即%input
mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs, scope_name)
layer_inputs["input"] = inputs_name[0]
# 获取当前节点输入的list
current_inputs = list(layer_inputs.values())
# 处理输入1,即%7
if inputs_name[1] in mapper.attrs:
layer_attrs["padding"] = mapper.attrs[inputs_name[1]]
else:
mapper._check_input(graph, inputs_node[1], inputs_name[1],
current_outputs, scope_name)
ipt_node = inputs_node[1]
while ipt_node.kind() != "prim::GetAttr":
inputs_name, inputs_node = mapper._get_inputs_name(ipt_node)
ipt_node = inputs_node[0]
layer_attrs["padding"] = list(mapper.pytorch_params[inputs_name[0]])
layer_attrs["mode"] = string("reflect")
graph.add_layer(
"paddle.nn.Pad1D",
inputs=layer_inputs,
outputs=layer_outputs,
scope_name=scope_name,
**layer_attrs)
return current_inputs, current_outputs
def aten_reflection_pad2d(mapper, graph, node):
""" 构造2维映射填充的PaddleLayer。
TorchScript示例:
%6 = aten::reflection_pad2d(%input, %7)
参数含义:
%6 (Tensor): 输出,填充后的Tensor。
%input (Tensor): 需要填充的Tensor。
%7 (list|Tensor): 填充大小。
"""
scope_name = mapper.normalize_scope_name(node)
op_name = name_generator("pad2d", mapper.nn_name2id)
output_name = mapper._get_outputs_name(node)[0]
layer_outputs = [op_name, output_name]
layer_inputs = {}
layer_attrs = {}
inputs_name, inputs_node = mapper._get_inputs_name(node)
# 获取当前节点输出的list
current_outputs = [output_name]
# 处理输入0,即%input
mapper._check_input(graph, inputs_node[0], inputs_name[0], current_outputs, scope_name)
layer_inputs["input"] = inputs_name[0]
# 获取当前节点输入的list
current_inputs = list(layer_inputs.values())
# 处理输入1,即%7
if inputs_name[1] in mapper.attrs:
layer_attrs["padding"] = mapper.attrs[inputs_name[1]]
else:
mapper._check_input(graph, inputs_node[1], inputs_name[1],
current_outputs, scope_name)
ipt_node = inputs_node[1]
while ipt_node.kind() != "prim::GetAttr":
inputs_name, inputs_node = mapper._get_inputs_name(ipt_node)
ipt_node = inputs_node[0]
layer_attrs["padding"] = list(mapper.pytorch_params[inputs_name[0]])
layer_attrs["mode"] = string("reflect")
graph.add_layer(
"paddle.nn.Pad2D",
inputs=layer_inputs,
outputs=layer_outputs,
scope_name=scope_name,
**layer_attrs)
return current_inputs, current_outputs
def aten_relu(mapper, graph, node): def aten_relu(mapper, graph, node):
""" 构造ReLU激活的PaddleLayer。 """ 构造ReLU激活的PaddleLayer。
......
...@@ -569,15 +569,19 @@ def prim_TupleUnpack(mapper, graph, node): ...@@ -569,15 +569,19 @@ def prim_TupleUnpack(mapper, graph, node):
outputs_name = mapper._get_outputs_name(node) outputs_name = mapper._get_outputs_name(node)
layer_outputs = outputs_name layer_outputs = outputs_name
layer_inputs = {} layer_inputs = {}
layer_attrs = {}
inputs_name, inputs_node = mapper._get_inputs_name(node) inputs_name, inputs_node = mapper._get_inputs_name(node)
if inputs_node[0].kind() == "prim::GetAttr":
layer_attrs["input"] = list(mapper.pytorch_params[inputs_name[0]])
else:
layer_inputs["input"] = inputs_name[0]
# 获取当前节点输出的list # 获取当前节点输出的list
current_outputs = outputs_name current_outputs = outputs_name
layer_inputs["input"] = inputs_name[0]
# 获取当前节点输入的list # 获取当前节点输入的list
current_inputs = list(layer_inputs.values()) current_inputs = list(layer_inputs.values())
graph.add_layer( graph.add_layer(
"prim.tuple_unpack", inputs=layer_inputs, outputs=layer_outputs, scope_name=scope_name) "prim.tuple_unpack", inputs=layer_inputs, outputs=layer_outputs, scope_name=scope_name, **layer_attrs)
return current_inputs, current_outputs return current_inputs, current_outputs
......
...@@ -13,4 +13,5 @@ ...@@ -13,4 +13,5 @@
# limitations under the License. # limitations under the License.
from .gather import Gather from .gather import Gather
\ No newline at end of file from .instance_norm import InstanceNorm
\ No newline at end of file
...@@ -27,6 +27,8 @@ NN_KERNEL_NAME = {"paddle.nn.BatchNorm": "bn", ...@@ -27,6 +27,8 @@ NN_KERNEL_NAME = {"paddle.nn.BatchNorm": "bn",
"paddle.nn.Linear": "linear", "paddle.nn.Linear": "linear",
"paddle.nn.Conv2DTranspose": "conv", "paddle.nn.Conv2DTranspose": "conv",
"paddle.nn.LSTM": "lstm", "paddle.nn.LSTM": "lstm",
"paddle.nn.GRU": "gru",
"custom_layer:InstanceNorm": "instance_norm",
"paddle.nn.PReLU": "prelu", "paddle.nn.PReLU": "prelu",
"paddle.nn.ReLU": "relu", "paddle.nn.ReLU": "relu",
"paddle.nn.ReLU6": "relu", "paddle.nn.ReLU6": "relu",
...@@ -35,14 +37,14 @@ NN_KERNEL_NAME = {"paddle.nn.BatchNorm": "bn", ...@@ -35,14 +37,14 @@ NN_KERNEL_NAME = {"paddle.nn.BatchNorm": "bn",
"paddle.nn.Tanh": "tanh", "paddle.nn.Tanh": "tanh",
"paddle.nn.AvgPool2D": "avgpool", "paddle.nn.AvgPool2D": "avgpool",
"paddle.nn.MaxPool2D": "maxpool", "paddle.nn.MaxPool2D": "maxpool",
"paddle.nn.Pad1D": "pad", "paddle.nn.Pad1D": "pad1d",
"paddle.nn.Pad2D": "pad", "paddle.nn.Pad2D": "pad2d",
"paddle.nn.Pad3D": "pad", "paddle.nn.Pad3D": "pad3d",
"paddle.nn.Dropout": "dropout", "paddle.nn.Dropout": "dropout",
"paddle.nn.GELU": "gelu", "paddle.nn.GELU": "gelu",
"paddle.nn.Hardtanh": "tanh", "paddle.nn.Hardtanh": "tanh",
"paddle.nn.LeakyReLU": "leakly_relu"} "paddle.nn.LeakyReLU": "leakly_relu"}
NN_KERNEL_WITH_PARAMS = list(NN_KERNEL_NAME.keys())[:8] NN_KERNEL_WITH_PARAMS = list(NN_KERNEL_NAME.keys())[:10]
def rename_layers(layers, param_tree=None, is_rename_module=False): def rename_layers(layers, param_tree=None, is_rename_module=False):
""" 对子模块的输入输出等进行重命名。 """ 对子模块的输入输出等进行重命名。
...@@ -143,7 +145,10 @@ def _update_attrs(layer, different_attrs): ...@@ -143,7 +145,10 @@ def _update_attrs(layer, different_attrs):
if key_name in different_attrs: if key_name in different_attrs:
common_attrs.pop(k) common_attrs.pop(k)
special_attrs[k] = v special_attrs[k] = v
remove_default_attrs(layer.kernel, common_attrs) remove_kernel = layer.kernel
if remove_kernel == "custom_layer:InstanceNorm":
remove_kernel = "paddle.nn.InstanceNorm2D"
remove_default_attrs(remove_kernel, common_attrs)
common_attrs.update(special_attrs) common_attrs.update(special_attrs)
layer.attrs = common_attrs layer.attrs = common_attrs
......
...@@ -212,6 +212,8 @@ class ModuleGraph(object): ...@@ -212,6 +212,8 @@ class ModuleGraph(object):
layer_id_list2 = list(sub_layers2.keys()) layer_id_list2 = list(sub_layers2.keys())
for i, layer_id1 in enumerate(layer_id_list1): for i, layer_id1 in enumerate(layer_id_list1):
layer_id2 = layer_id_list2[i] layer_id2 = layer_id_list2[i]
if layer_id2 not in self.pd_graph.edges_in:
return False
if len(self.pd_graph.edges_in[layer_id1]) != len(self.pd_graph.edges_in[layer_id2]): if len(self.pd_graph.edges_in[layer_id1]) != len(self.pd_graph.edges_in[layer_id2]):
return False return False
for j, ipt_layer_id1 in enumerate(self.pd_graph.edges_in[layer_id1]): for j, ipt_layer_id1 in enumerate(self.pd_graph.edges_in[layer_id1]):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册