模型的双向GRU怎么转比较好
Created by: richlaji
复现的pytorch代码: import torch import torch.nn as nn rnn = nn.GRU(10,20, bidirectional=True) input = torch.randn(5, 3, 10) h0 = torch.randn(2, 3, 20) output, hn = rnn(input,h0) torch.onnx.export(rnn, input, 'test.onnx', verbose=True)
转onnx出的结果: graph(%input : Float(5, 3, 10), %weight_ih_l0 : Float(60, 10), %weight_hh_l0 : Float(60, 20), %bias_ih_l0 : Float(60), %bias_hh_l0 : Float(60), %weight_ih_l0_reverse : Float(60, 10), %weight_hh_l0_reverse : Float(60, 20), %bias_ih_l0_reverse : Float(60), %bias_hh_l0_reverse : Float(60)): %9 : Long() = onnx::Constantvalue={1}, scope: GRU %10 : Tensor = onnx::Shape(%input), scope: GRU %11 : Long() = onnx::Gatheraxis=0, scope: GRU %12 : Long() = onnx::Constantvalue={2}, scope: GRU %13 : Long() = onnx::Constantvalue={20}, scope: GRU %14 : Tensor = onnx::Unsqueezeaxes=[0] %15 : Tensor = onnx::Unsqueezeaxes=[0] %16 : Tensor = onnx::Unsqueezeaxes=[0] %17 : Tensor = onnx::Concataxis=0 %18 : Float(2, 3, 20) = onnx::ConstantOfShapevalue={0}, scope: GRU %19 : Tensor? = prim::Constant(), scope: GRU %20 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %21 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %22 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %23 : Tensor = onnx::Concataxis=0, scope: GRU %24 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %25 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %26 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %27 : Tensor = onnx::Concataxis=0, scope: GRU %28 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %29 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %30 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %31 : Tensor = onnx::Concataxis=0, scope: GRU %32 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %33 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %34 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %35 : Tensor = onnx::Concataxis=0, scope: GRU %36 : Tensor = onnx::Concataxis=0, scope: GRU %37 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %38 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %39 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %40 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %41 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %42 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %43 : Tensor = onnx::Concataxis=0, scope: GRU %44 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %45 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %46 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %47 : Tensor = onnx::Concataxis=0, scope: GRU %48 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %49 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %50 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %51 : Tensor = onnx::Concataxis=0, scope: GRU %52 : Tensor = onnx::Sliceaxes=[0], ends=[40], starts=[20], scope: GRU %53 : Tensor = onnx::Sliceaxes=[0], ends=[20], starts=[0], scope: GRU %54 : Tensor = onnx::Sliceaxes=[0], ends=[60], starts=[40], scope: GRU %55 : Tensor = onnx::Concataxis=0, scope: GRU %56 : Tensor = onnx::Concataxis=0, scope: GRU %57 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %58 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %59 : Tensor = onnx::Unsqueezeaxes=[0], scope: GRU %60 : Tensor = onnx::Concataxis=0, scope: GRU %61 : Tensor = onnx::Concataxis=0, scope: GRU %62 : Tensor = onnx::Concataxis=0, scope: GRU %63 : Tensor, %64 : Float(2, 3, 20) = onnx::GRUdirection="bidirectional", hidden_size=20, linear_before_reset=1, scope: GRU %65 : Tensor = onnx::Transposeperm=[0, 2, 1, 3], scope: GRU %66 : Tensor = onnx::Constantvalue= 0 0 -1 [ Variable[CPUType]{3} ], scope: GRU %67 : Float(5, 3, 40) = onnx::Reshape(%65, %66), scope: GRU return (%67, %64)
x2paddle --framework=onnx --model=test.onnx --save_dir=./转paddle模型,会找不到%19这个节点,报错如下: Traceback (most recent call last): File "/home/zhangzexin/anaconda3/envs/paddle/bin/x2paddle", line 10, in sys.exit(main()) File "/home/zhangzexin/anaconda3/envs/paddle/lib/python3.6/site-packages/x2paddle/convert.py", line 211, in main onnx2paddle(args.model, args.save_dir) File "/home/zhangzexin/anaconda3/envs/paddle/lib/python3.6/site-packages/x2paddle/convert.py", line 154, in onnx2paddle model = ONNXDecoder(model_path) File "/home/zhangzexin/anaconda3/envs/paddle/lib/python3.6/site-packages/x2paddle/decoder/onnx_decoder.py", line 334, in init self.standardize_variable_name(model.graph) File "/home/zhangzexin/anaconda3/envs/paddle/lib/python3.6/site-packages/x2paddle/decoder/onnx_decoder.py", line 501, in standardize_variable_name node.input[i] = self.make_variable_name(node.input[i]) File "/home/zhangzexin/anaconda3/envs/paddle/lib/python3.6/site-packages/x2paddle/decoder/onnx_decoder.py", line 478, in make_variable_name raise ValueError('name should not be empty') ValueError: name should not be empty
已看github上一个gru的issue,看到推荐是使用nn.GRUCell的方式,但由于使用了nn.GRU封装的bidirection等属性,想知道(1)现在nn.GRU是一定没有办法转成功嘛,(2)有没有办法在不重新训练模型的情况下转成paddle呢~非常期待回复,感谢!