Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
冰之2023
Mace
提交
25b125f0
Mace
项目概览
冰之2023
/
Mace
与 Fork 源项目一致
Fork自
Xiaomi / Mace
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Mace
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
25b125f0
编写于
11月 27, 2017
作者:
李
李寅
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into 'master'
Add maxpool test See merge request !115
上级
b1e92eae
f5613d76
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
253 addition
and
1 deletion
+253
-1
mace/dsp/BUILD
mace/dsp/BUILD
+1
-0
mace/dsp/test/quantized_maxpool_test.cc
mace/dsp/test/quantized_maxpool_test.cc
+231
-0
mace/dsp/util/quantize.cc
mace/dsp/util/quantize.cc
+16
-1
mace/dsp/util/quantize.h
mace/dsp/util/quantize.h
+5
-0
未找到文件。
mace/dsp/BUILD
浏览文件 @
25b125f0
...
...
@@ -28,6 +28,7 @@ cc_library(
deps
=
[
"//mace/proto:cc_proto"
,
"//mace/core:core"
,
"//mace/dsp/util:util"
,
],
)
...
...
mace/dsp/test/quantized_maxpool_test.cc
0 → 100644
浏览文件 @
25b125f0
//
// Copyright (c) 2017 XiaoMi All rights reserved.
//
#include "mace/dsp/hexagon_control_wrapper.h"
#include "mace/dsp/util/quantize.h"
#include "mace/kernels/conv_pool_2d_util.h"
#include "mace/kernels/pooling.h"
#include "gtest/gtest.h"
using
namespace
mace
;
static
NetDef
BuildNetDef
(
const
vector
<
index_t
>
&
input_shape
,
const
vector
<
index_t
>
&
output_shape
,
const
vector
<
index_t
>
&
filter_shape
,
const
vector
<
int
>
&
stride
,
Padding
padding
,
float
input_min
,
float
input_max
)
{
NetDef
net
;
net
.
set_name
(
"quantized_maxpool_test"
);
// input op
OperatorDef
*
input_op
=
net
.
add_op
();
input_op
->
set_name
(
"input_node"
);
input_op
->
set_type
(
"INPUT"
);
input_op
->
set_node_id
(
0
);
input_op
->
set_padding
(
0
);
input_op
->
add_out_max_byte_size
(
1000
);
// maxpool op
OperatorDef
*
maxpool_op
=
net
.
add_op
();
maxpool_op
->
set_name
(
"maxpool"
);
maxpool_op
->
set_type
(
"QuantizedMaxPool_8"
);
maxpool_op
->
set_node_id
(
1
);
if
(
padding
==
Padding
::
SAME
)
{
maxpool_op
->
set_padding
(
1
);
}
else
{
maxpool_op
->
set_padding
(
2
);
}
maxpool_op
->
add_input
(
"input_node"
);
maxpool_op
->
add_input
(
"input_min"
);
maxpool_op
->
add_input
(
"input_max"
);
maxpool_op
->
add_input
(
"ksize"
);
maxpool_op
->
add_input
(
"stride"
);
maxpool_op
->
add_output
(
"maxpool:0"
);
maxpool_op
->
add_output
(
"maxpool:1"
);
maxpool_op
->
add_output
(
"maxpool:2"
);
NodeInput
*
input_node_input
=
maxpool_op
->
add_node_input
();
input_node_input
->
set_node_id
(
0
);
input_node_input
->
set_output_port
(
0
);
input_node_input
=
maxpool_op
->
add_node_input
();
input_node_input
->
set_node_id
(
10
);
input_node_input
->
set_output_port
(
0
);
input_node_input
=
maxpool_op
->
add_node_input
();
input_node_input
->
set_node_id
(
11
);
input_node_input
=
maxpool_op
->
add_node_input
();
input_node_input
->
set_node_id
(
12
);
input_node_input
->
set_output_port
(
0
);
input_node_input
=
maxpool_op
->
add_node_input
();
input_node_input
->
set_node_id
(
13
);
input_node_input
->
set_output_port
(
0
);
maxpool_op
->
add_out_max_byte_size
(
1000
);
maxpool_op
->
add_out_max_byte_size
(
1000
);
maxpool_op
->
add_out_max_byte_size
(
1000
);
// output op
OperatorDef
*
output_op
=
net
.
add_op
();
output_op
->
set_name
(
"__output__"
);
output_op
->
set_type
(
"OUTPUT"
);
output_op
->
set_op_id
(
2
);
input_node_input
=
output_op
->
add_node_input
();
input_node_input
->
set_node_id
(
1
);
input_node_input
->
set_output_port
(
0
);
// tensor
TensorProto
*
input_min_tensor
=
net
.
add_tensors
();
input_min_tensor
->
set_name
(
"input_min"
);
input_min_tensor
->
add_dims
(
1
);
input_min_tensor
->
set_data_type
(
DataType
::
DT_FLOAT
);
input_min_tensor
->
set_node_id
(
10
);
input_min_tensor
->
add_float_data
(
input_min
);
TensorProto
*
input_max_tensor
=
net
.
add_tensors
();
input_max_tensor
->
set_name
(
"input_max"
);
input_max_tensor
->
add_dims
(
1
);
input_max_tensor
->
set_data_type
(
DataType
::
DT_FLOAT
);
input_max_tensor
->
set_node_id
(
11
);
input_max_tensor
->
add_float_data
(
input_max
);
TensorProto
*
ksize_tensor
=
net
.
add_tensors
();
ksize_tensor
->
set_name
(
"ksize"
);
ksize_tensor
->
add_dims
(
filter_shape
[
0
]);
ksize_tensor
->
add_dims
(
filter_shape
[
1
]);
ksize_tensor
->
add_dims
(
filter_shape
[
2
]);
ksize_tensor
->
add_dims
(
filter_shape
[
3
]);
ksize_tensor
->
set_data_type
(
DataType
::
DT_INT32
);
ksize_tensor
->
set_node_id
(
12
);
TensorProto
*
stride_tensor
=
net
.
add_tensors
();
stride_tensor
->
set_name
(
"stride"
);
stride_tensor
->
add_dims
(
stride
[
0
]);
stride_tensor
->
add_dims
(
stride
[
1
]);
stride_tensor
->
add_dims
(
stride
[
2
]);
stride_tensor
->
add_dims
(
stride
[
3
]);
stride_tensor
->
set_data_type
(
DataType
::
DT_INT32
);
stride_tensor
->
set_node_id
(
13
);
// input & output info
InputInfo
*
input_info
=
net
.
add_input_info
();
input_info
->
set_name
(
"input_node"
);
input_info
->
set_node_id
(
0
);
input_info
->
add_dims
(
input_shape
[
0
]);
input_info
->
add_dims
(
input_shape
[
1
]);
input_info
->
add_dims
(
input_shape
[
2
]);
input_info
->
add_dims
(
input_shape
[
3
]);
input_info
->
set_data_type
(
DataType
::
DT_UINT8
);
input_info
->
set_max_byte_size
(
1000
);
OutputInfo
*
output_info
=
net
.
add_output_info
();
output_info
->
set_name
(
"output_node"
);
output_info
->
set_node_id
(
1
);
output_info
->
add_dims
(
output_shape
[
0
]);
output_info
->
add_dims
(
output_shape
[
1
]);
output_info
->
add_dims
(
output_shape
[
2
]);
output_info
->
add_dims
(
output_shape
[
3
]);
output_info
->
set_data_type
(
DataType
::
DT_UINT8
);
output_info
->
set_max_byte_size
(
1000
);
return
net
;
}
static
void
TestQuantizedMaxPool
(
Padding
padding
,
int
kernel_size
,
int
stride_size
)
{
testing
::
internal
::
LogToStderr
();
HexagonControlWrapper
wrapper
;
wrapper
.
Init
();
wrapper
.
SetDebugLevel
(
3
);
wrapper
.
Config
();
vector
<
index_t
>
input_shape
{
1
,
10
,
10
,
3
};
vector
<
index_t
>
filter_shape
{
1
,
3
,
3
,
1
};
vector
<
int
>
stride
{
1
,
stride_size
,
stride_size
,
1
};
vector
<
int
>
dilation
{
1
,
1
,
1
,
1
};
vector
<
index_t
>
output_shape
{
input_shape
[
0
],
0
,
0
,
input_shape
[
3
]};
vector
<
int
>
padding_size
(
2
);
switch
(
padding
)
{
case
VALID
:
output_shape
[
1
]
=
(
input_shape
[
1
]
-
filter_shape
[
1
])
/
stride
[
1
]
+
1
;
output_shape
[
2
]
=
(
input_shape
[
2
]
-
filter_shape
[
2
])
/
stride
[
2
]
+
1
;
break
;
case
SAME
:
output_shape
[
1
]
=
(
input_shape
[
1
]
-
1
)
/
stride
[
1
]
+
1
;
output_shape
[
2
]
=
(
input_shape
[
2
]
-
1
)
/
stride
[
2
]
+
1
;
break
;
default:
ASSERT_TRUE
(
0
);
}
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
VLOG
(
0
)
<<
"! shape = "
<<
output_shape
[
i
];
}
NetDef
net
=
BuildNetDef
(
input_shape
,
output_shape
,
filter_shape
,
stride
,
padding
,
-
50
,
100
);
VLOG
(
0
)
<<
wrapper
.
SetupGraph
(
net
);
Allocator
*
cpu_allocator
=
GetDeviceAllocator
(
DeviceType
::
CPU
);
Tensor
original_tensor
(
cpu_allocator
,
DT_FLOAT
);
Tensor
input_tensor
(
cpu_allocator
,
DT_UINT8
);
Tensor
output_tensor
(
cpu_allocator
,
DT_UINT8
);
Tensor
dequantized_output_tensor
(
cpu_allocator
,
DT_FLOAT
);
original_tensor
.
Resize
(
input_shape
);
input_tensor
.
Resize
(
input_shape
);
output_tensor
.
Resize
(
output_shape
);
dequantized_output_tensor
.
Resize
(
output_shape
);
float
*
original_data
=
original_tensor
.
mutable_data
<
float
>
();
uint8_t
*
input_data
=
input_tensor
.
mutable_data
<
uint8_t
>
();
const
uint8_t
*
output_data
=
output_tensor
.
data
<
uint8_t
>
();
float
*
dequantized_output_data
=
dequantized_output_tensor
.
mutable_data
<
float
>
();
std
::
random_device
rd
;
std
::
mt19937
gen
(
rd
());
std
::
normal_distribution
<
float
>
nd
(
-
50
,
50
);
std
::
generate
(
original_data
,
original_data
+
original_tensor
.
size
(),
[
&
gen
,
&
nd
]
{
return
nd
(
gen
);
});
Quantizer
quantizer
;
float
min_in
,
min_out
;
quantizer
.
Quantize
(
original_tensor
,
&
input_tensor
,
&
min_in
,
&
min_out
);
VLOG
(
0
)
<<
wrapper
.
ExecuteGraph
(
input_tensor
,
&
output_tensor
);
quantizer
.
DeQuantize
(
output_tensor
,
min_in
,
min_out
,
&
dequantized_output_tensor
);
// debug original float input data
for
(
index_t
c
=
0
;
c
<
input_shape
[
3
];
++
c
)
{
for
(
index_t
i
=
0
;
i
<
input_shape
[
1
];
++
i
)
{
for
(
index_t
j
=
0
;
j
<
input_shape
[
2
];
++
j
)
{
std
::
cout
<<
original_data
[
i
*
input_shape
[
2
]
*
input_shape
[
3
]
+
j
*
input_shape
[
3
]
+
c
]
<<
" "
;
}
std
::
cout
<<
std
::
endl
;
}
std
::
cout
<<
std
::
endl
<<
std
::
endl
;
}
// debug dequantized float output data
for
(
index_t
c
=
0
;
c
<
output_shape
[
3
];
++
c
)
{
for
(
index_t
i
=
0
;
i
<
output_shape
[
1
];
++
i
)
{
for
(
index_t
j
=
0
;
j
<
output_shape
[
2
];
++
j
)
{
std
::
cout
<<
dequantized_output_data
[
i
*
output_shape
[
2
]
*
output_shape
[
3
]
+
j
*
output_shape
[
3
]
+
c
]
<<
" "
;
}
std
::
cout
<<
std
::
endl
;
}
std
::
cout
<<
std
::
endl
<<
std
::
endl
;
}
wrapper
.
PrintLog
();
VLOG
(
0
)
<<
wrapper
.
TeardownGraph
();
wrapper
.
Finalize
();
}
TEST
(
QuantizedMaxPoolTest
,
QuantizedMaxPoolValidStride1
)
{
TestQuantizedMaxPool
(
Padding
::
VALID
,
3
,
1
);
}
TEST
(
QuantizedMaxPoolTest
,
QuantizedMaxPoolValidStride2
)
{
TestQuantizedMaxPool
(
Padding
::
VALID
,
3
,
2
);
}
TEST
(
QuantizedMaxPoolTest
,
QuantizedMaxPoolSameStride1
)
{
TestQuantizedMaxPool
(
Padding
::
SAME
,
3
,
1
);
}
TEST
(
QuantizedMaxPoolTest
,
QuantizedMaxPoolSameStride2
)
{
TestQuantizedMaxPool
(
Padding
::
SAME
,
3
,
2
);
}
\ No newline at end of file
mace/dsp/util/quantize.cc
浏览文件 @
25b125f0
...
...
@@ -6,6 +6,21 @@
namespace
mace
{
void
Quantizer
::
Quantize
(
const
Tensor
&
in_tensor
,
Tensor
*
out_tensor
,
float
*
min_out
,
float
*
max_out
)
{
if
(
in_tensor
.
size
()
==
0
)
return
;
const
float
*
in_data
=
in_tensor
.
data
<
float
>
();
float
min_in
=
in_data
[
0
];
float
max_in
=
in_data
[
0
];
for
(
index_t
i
=
0
;
i
<
in_tensor
.
size
();
++
i
)
{
min_in
=
std
::
min
(
min_in
,
in_data
[
i
]);
max_in
=
std
::
max
(
max_in
,
in_data
[
i
]);
}
Quantize
(
in_tensor
,
min_in
,
max_in
,
out_tensor
,
min_out
,
max_out
);
}
void
Quantizer
::
Quantize
(
const
Tensor
&
in_tensor
,
const
float
min_in
,
const
float
max_in
,
...
...
@@ -61,7 +76,7 @@ void Quantizer::DeQuantize(const Tensor &in_tensor,
const
uint8_t
*
in
=
in_tensor
.
data
<
uint8_t
>
();
float
*
out
=
out_tensor
->
mutable_data
<
float
>
();
for
(
int
i
=
0
;
i
<
in_tensor
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
out_tensor
->
size
();
++
i
)
{
out
[
i
]
=
(
in
[
i
]
*
stepsize
)
+
min_in
;
}
}
...
...
mace/dsp/util/quantize.h
浏览文件 @
25b125f0
...
...
@@ -15,6 +15,9 @@ class Quantizer {
Quantizer
()
{}
~
Quantizer
()
{}
void
Quantize
(
const
Tensor
&
in_tensor
,
Tensor
*
out_tensor
,
float
*
min_out
,
float
*
max_out
);
void
Quantize
(
const
Tensor
&
in_tensor
,
const
float
min_in
,
const
float
max_in
,
Tensor
*
out_tensor
,
...
...
@@ -30,6 +33,8 @@ class Quantizer {
float
*
max_out
,
float
*
stepsize
,
float
*
recip_stepsize
);
DISABLE_COPY_AND_ASSIGN
(
Quantizer
);
};
}
// mace
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录