Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
11d565ca
O
Opencv
项目概览
Greenplum
/
Opencv
10 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
11d565ca
编写于
3月 18, 2020
作者:
D
Dmitry Kurtaev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix LSTM from ONNX with batch==1
上级
8d69dbdf
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
69 addition
and
37 deletion
+69
-37
modules/dnn/src/layers/recurrent_layers.cpp
modules/dnn/src/layers/recurrent_layers.cpp
+5
-4
modules/dnn/src/onnx/onnx_importer.cpp
modules/dnn/src/onnx/onnx_importer.cpp
+64
-33
未找到文件。
modules/dnn/src/layers/recurrent_layers.cpp
浏览文件 @
11d565ca
...
...
@@ -110,10 +110,11 @@ public:
const
Mat
&
Wh
=
blobs
[
0
];
const
Mat
&
Wx
=
blobs
[
1
];
const
Mat
&
bias
=
blobs
[
2
];
CV_Assert
(
Wh
.
dims
==
2
&&
Wx
.
dims
==
2
);
CV_Assert
(
Wh
.
rows
==
Wx
.
rows
);
CV_Assert
(
Wh
.
rows
==
4
*
Wh
.
cols
);
CV_Assert
(
Wh
.
rows
==
(
int
)
bias
.
total
());
CV_CheckEQ
(
Wh
.
dims
,
2
,
""
);
CV_CheckEQ
(
Wx
.
dims
,
2
,
""
);
CV_CheckEQ
(
Wh
.
rows
,
Wx
.
rows
,
""
);
CV_CheckEQ
(
Wh
.
rows
,
4
*
Wh
.
cols
,
""
);
CV_CheckEQ
(
Wh
.
rows
,
(
int
)
bias
.
total
(),
""
);
CV_Assert
(
Wh
.
type
()
==
Wx
.
type
()
&&
Wx
.
type
()
==
bias
.
type
());
// Peephole weights.
...
...
modules/dnn/src/onnx/onnx_importer.cpp
浏览文件 @
11d565ca
...
...
@@ -49,6 +49,11 @@ class ONNXImporter
LayerParams
getLayerParams
(
const
opencv_onnx
::
NodeProto
&
node_proto
);
bool
isCeilMode
(
const
LayerParams
&
layerParams
);
void
addLayer
(
Net
&
dstNet
,
LayerParams
&
layerParams
,
const
opencv_onnx
::
NodeProto
&
node_proto
,
std
::
map
<
std
::
string
,
LayerInfo
>&
layer_id
,
std
::
map
<
std
::
string
,
MatShape
>&
outShapes
);
public:
ONNXImporter
(
const
char
*
onnxFile
)
...
...
@@ -259,6 +264,42 @@ Mat ONNXImporter::getBlob(const opencv_onnx::NodeProto& node_proto,
return
constBlob
->
second
;
}
void
ONNXImporter
::
addLayer
(
Net
&
dstNet
,
LayerParams
&
layerParams
,
const
opencv_onnx
::
NodeProto
&
node_proto
,
std
::
map
<
std
::
string
,
LayerInfo
>&
layer_id
,
std
::
map
<
std
::
string
,
MatShape
>&
outShapes
)
{
std
::
map
<
std
::
string
,
LayerInfo
>::
iterator
layerId
;
std
::
map
<
std
::
string
,
MatShape
>::
iterator
shapeIt
;
int
id
=
dstNet
.
addLayer
(
layerParams
.
name
,
layerParams
.
type
,
layerParams
);
for
(
int
i
=
0
;
i
<
node_proto
.
output_size
();
++
i
)
{
layer_id
.
insert
(
std
::
make_pair
(
node_proto
.
output
(
i
),
LayerInfo
(
id
,
i
)));
}
std
::
vector
<
MatShape
>
layerInpShapes
,
layerOutShapes
,
layerInternalShapes
;
int
inpNum
=
0
;
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
layerId
=
layer_id
.
find
(
node_proto
.
input
(
j
));
if
(
layerId
!=
layer_id
.
end
())
{
dstNet
.
connect
(
layerId
->
second
.
layerId
,
layerId
->
second
.
outputId
,
id
,
inpNum
);
++
inpNum
;
// Collect input shapes.
shapeIt
=
outShapes
.
find
(
node_proto
.
input
(
j
));
CV_Assert
(
shapeIt
!=
outShapes
.
end
());
layerInpShapes
.
push_back
(
shapeIt
->
second
);
}
}
// Compute shape of output blob for this layer.
Ptr
<
Layer
>
layer
=
dstNet
.
getLayer
(
id
);
layer
->
getMemoryShapes
(
layerInpShapes
,
0
,
layerOutShapes
,
layerInternalShapes
);
for
(
int
i
=
0
;
i
<
node_proto
.
output_size
()
&&
i
<
(
int
)
layerOutShapes
.
size
();
++
i
)
{
outShapes
[
node_proto
.
output
(
i
)]
=
layerOutShapes
[
i
];
}
}
void
ONNXImporter
::
populateNet
(
Net
dstNet
)
{
CV_Assert
(
model_proto
.
has_graph
());
...
...
@@ -581,13 +622,16 @@ void ONNXImporter::populateNet(Net dstNet)
}
else
if
(
layer_type
==
"LSTM"
)
{
LayerParams
lstmParams
=
layerParams
;
lstmParams
.
name
+=
"/lstm"
;
// https://pytorch.org/docs/stable/nn.html#lstm
CV_Assert
(
node_proto
.
input_size
()
==
7
);
Mat
Wx
=
getBlob
(
node_proto
,
constBlobs
,
1
);
Mat
Wh
=
getBlob
(
node_proto
,
constBlobs
,
2
);
Mat
b
=
getBlob
(
node_proto
,
constBlobs
,
3
);
const
int
numHidden
=
Wh
.
size
[
2
]
;
const
int
numHidden
=
lstmParams
.
get
<
int
>
(
"hidden_size"
)
;
Wx
=
Wx
.
reshape
(
1
,
Wx
.
size
[
1
]);
Wh
=
Wh
.
reshape
(
1
,
Wh
.
size
[
1
]);
...
...
@@ -612,10 +656,24 @@ void ONNXImporter::populateNet(Net dstNet)
}
std
::
swap
(
biasData
[
numHidden
+
j
],
biasData
[
numHidden
*
2
+
j
]);
}
layerParams
.
blobs
.
resize
(
3
);
layerParams
.
blobs
[
0
]
=
Wh
;
layerParams
.
blobs
[
1
]
=
Wx
;
layerParams
.
blobs
[
2
]
=
b
;
lstmParams
.
blobs
.
resize
(
3
);
lstmParams
.
blobs
[
0
]
=
Wh
;
lstmParams
.
blobs
[
1
]
=
Wx
;
lstmParams
.
blobs
[
2
]
=
b
;
node_proto
.
set_output
(
0
,
lstmParams
.
name
);
// set different name so output shapes will be registered on that name
addLayer
(
dstNet
,
lstmParams
,
node_proto
,
layer_id
,
outShapes
);
MatShape
lstmShape
=
outShapes
[
node_proto
.
output
(
0
)];
// Add fake 1 as it is done in ONNX
lstmShape
.
insert
(
lstmShape
.
begin
()
+
1
,
1
);
layerParams
.
type
=
"Reshape"
;
layerParams
.
set
(
"dim"
,
DictValue
::
arrayInt
(
&
lstmShape
[
0
],
lstmShape
.
size
()));
node_proto
.
set_input
(
0
,
lstmParams
.
name
);
// redirect input to LSTM
node_proto
.
set_output
(
0
,
layerParams
.
name
);
// keep origin LSTM's name
}
else
if
(
layer_type
==
"ImageScaler"
)
{
...
...
@@ -1228,34 +1286,7 @@ void ONNXImporter::populateNet(Net dstNet)
layerParams
.
blobs
.
push_back
(
getBlob
(
node_proto
,
constBlobs
,
j
));
}
}
int
id
=
dstNet
.
addLayer
(
layerParams
.
name
,
layerParams
.
type
,
layerParams
);
for
(
int
i
=
0
;
i
<
node_proto
.
output_size
();
++
i
)
{
layer_id
.
insert
(
std
::
make_pair
(
node_proto
.
output
(
i
),
LayerInfo
(
id
,
i
)));
}
std
::
vector
<
MatShape
>
layerInpShapes
,
layerOutShapes
,
layerInternalShapes
;
int
inpNum
=
0
;
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
layerId
=
layer_id
.
find
(
node_proto
.
input
(
j
));
if
(
layerId
!=
layer_id
.
end
())
{
dstNet
.
connect
(
layerId
->
second
.
layerId
,
layerId
->
second
.
outputId
,
id
,
inpNum
);
++
inpNum
;
// Collect input shapes.
shapeIt
=
outShapes
.
find
(
node_proto
.
input
(
j
));
CV_Assert
(
shapeIt
!=
outShapes
.
end
());
layerInpShapes
.
push_back
(
shapeIt
->
second
);
}
}
// Compute shape of output blob for this layer.
Ptr
<
Layer
>
layer
=
dstNet
.
getLayer
(
id
);
layer
->
getMemoryShapes
(
layerInpShapes
,
0
,
layerOutShapes
,
layerInternalShapes
);
for
(
int
i
=
0
;
i
<
node_proto
.
output_size
()
&&
i
<
(
int
)
layerOutShapes
.
size
();
++
i
)
{
outShapes
[
node_proto
.
output
(
i
)]
=
layerOutShapes
[
i
];
}
addLayer
(
dstNet
,
layerParams
,
node_proto
,
layer_id
,
outShapes
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录