Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Crayon鑫
Paddle
提交
eb43d93a
P
Paddle
项目概览
Crayon鑫
/
Paddle
与 Fork 源项目一致
Fork自
PaddlePaddle / Paddle
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Paddle
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
eb43d93a
编写于
3月 20, 2017
作者:
G
gaoyuan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Change Normalize layer to CrossChannelNorm layer
上级
eea0097d
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
115 addition
and
96 deletion
+115
-96
paddle/gserver/layers/CrossChannelNormLayer.cpp
paddle/gserver/layers/CrossChannelNormLayer.cpp
+13
-68
paddle/gserver/layers/NormLayer.cpp
paddle/gserver/layers/NormLayer.cpp
+12
-0
paddle/gserver/layers/NormLayer.h
paddle/gserver/layers/NormLayer.h
+31
-0
paddle/gserver/tests/test_LayerGrad.cpp
paddle/gserver/tests/test_LayerGrad.cpp
+11
-6
paddle/math/BaseMatrix.cu
paddle/math/BaseMatrix.cu
+18
-0
paddle/math/BaseMatrix.h
paddle/math/BaseMatrix.h
+3
-0
paddle/math/tests/test_BaseMatrix.cpp
paddle/math/tests/test_BaseMatrix.cpp
+2
-0
python/paddle/trainer/config_parser.py
python/paddle/trainer/config_parser.py
+8
-13
python/paddle/trainer_config_helpers/layers.py
python/paddle/trainer_config_helpers/layers.py
+17
-9
未找到文件。
paddle/gserver/layers/
Normalize
Layer.cpp
→
paddle/gserver/layers/
CrossChannelNorm
Layer.cpp
浏览文件 @
eb43d93a
...
...
@@ -13,53 +13,13 @@ See the License for the specific language governing permissions and
limitations under the License. */
#include "Layer.h"
#include "NormLayer.h"
#include "paddle/math/BaseMatrix.h"
#include "paddle/math/Matrix.h"
namespace
paddle
{
/**
* This layer applys normalize across the channels of each sample to a
* conv layer's output and scale the output by a group of trainable factors
* which dimensions equal to the channel's number.
* - Input: One and only one input layer are accepted. The input layer must be
* be a data output layer.
* - Output: The normalized data of the input data.
* Reference:
* Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed,
* Cheng-Yang Fu, Alexander C. Berg. SSD: Single Shot MultiBox Detector
*/
class
NormalizeLayer
:
public
Layer
{
public:
explicit
NormalizeLayer
(
const
LayerConfig
&
config
)
:
Layer
(
config
)
{}
bool
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
);
void
forward
(
PassType
passType
);
void
backward
(
const
UpdateCallback
&
callback
);
protected:
size_t
channels_
;
std
::
unique_ptr
<
Weight
>
scale_
;
MatrixPtr
scaleDiff_
;
MatrixPtr
normBuffer_
;
MatrixPtr
dataBuffer_
;
MatrixPtr
channelBuffer_
;
MatrixPtr
spatialBuffer_
;
MatrixPtr
sampleBuffer_
;
};
REGISTER_LAYER
(
normalize
,
NormalizeLayer
);
bool
NormalizeLayer
::
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
{
Layer
::
init
(
layerMap
,
parameterMap
);
CHECK
(
parameters_
[
0
]);
channels_
=
config_
.
num_filters
();
scale_
.
reset
(
new
Weight
(
channels_
,
1
,
parameters_
[
0
]));
return
true
;
}
void
NormalizeLayer
::
forward
(
PassType
passType
)
{
void
CrossChannelNormLayer
::
forward
(
PassType
passType
)
{
Layer
::
forward
(
passType
);
auto
in
=
getInput
(
0
);
MatrixPtr
inV
=
getInputValue
(
0
);
...
...
@@ -74,16 +34,12 @@ void NormalizeLayer::forward(PassType passType) {
Matrix
::
resizeOrCreate
(
dataBuffer_
,
batchSize
,
dataDim
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
spatialBuffer_
,
1
,
spatialDim
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
channelBuffer_
,
channels_
,
1
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
sampleBuffer_
,
channels_
,
spatialDim
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
normBuffer_
,
batchSize
,
spatialDim
,
false
,
useGpu_
);
normBuffer_
->
zeroMem
();
spatialBuffer_
->
zeroMem
();
sampleBuffer_
->
zeroMem
();
dataBuffer_
->
zeroMem
();
// add eps to avoid overflow
normBuffer_
->
addScalar
(
*
normBuffer_
,
1e-6
);
channelBuffer_
->
resetOne
();
inV
->
square2
(
*
dataBuffer_
);
for
(
size_t
i
=
0
;
i
<
batchSize
;
i
++
)
{
spatialBuffer_
->
zeroMem
();
...
...
@@ -102,18 +58,14 @@ void NormalizeLayer::forward(PassType passType) {
spatialBuffer_
->
sumCols
(
*
dataTmp
,
1
,
1
);
spatialBuffer_
->
sqrt2
(
*
spatialBuffer_
);
normTmp
->
copyFrom
(
*
spatialBuffer_
);
sampleBuffer_
->
mul
(
*
channelBuffer_
,
*
spatialBuffer_
,
1.
,
0.
);
sampleBuffer_
->
dotDiv
(
*
inTmp
,
*
sampleBuffer_
);
outTmp
->
copyFrom
(
*
sampleBuffer_
);
outTmp
->
copyFrom
(
*
inTmp
);
outTmp
->
divRowVector
(
*
spatialBuffer_
);
// scale the layer.
spatialBuffer_
->
resetOne
();
sampleBuffer_
->
mul
(
*
scale_
->
getW
(),
*
spatialBuffer_
,
1.
,
0.
);
outTmp
->
dotMul
(
*
outTmp
,
*
sampleBuffer_
);
outTmp
->
mulColVector
(
*
scale_
->
getW
());
}
}
void
Normalize
Layer
::
backward
(
const
UpdateCallback
&
callback
)
{
void
CrossChannelNorm
Layer
::
backward
(
const
UpdateCallback
&
callback
)
{
MatrixPtr
inG
=
getInputGrad
(
0
);
MatrixPtr
inV
=
getInputValue
(
0
);
MatrixPtr
outG
=
getOutputGrad
();
...
...
@@ -124,9 +76,10 @@ void NormalizeLayer::backward(const UpdateCallback& callback) {
size_t
dataDim
=
inG
->
getWidth
();
size_t
spatialDim
=
dataDim
/
channels_
;
bool
syncFlag
=
hl_get_sync_flag
();
dataBuffer_
->
dotMul
(
*
outG
,
*
outV
);
Matrix
::
resizeOrCreate
(
scaleDiff_
,
channels_
,
1
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
channelBuffer_
,
channels_
,
1
,
false
,
useGpu_
);
Matrix
::
resizeOrCreate
(
sampleBuffer_
,
channels_
,
spatialDim
,
false
,
useGpu_
);
scaleDiff_
->
zeroMem
();
for
(
size_t
i
=
0
;
i
<
batchSize
;
i
++
)
{
spatialBuffer_
->
zeroMem
();
...
...
@@ -154,28 +107,20 @@ void NormalizeLayer::backward(const UpdateCallback& callback) {
sampleBuffer_
->
dotMul
(
*
inValueTmp
,
*
outGradTmp
);
spatialBuffer_
->
sumCols
(
*
sampleBuffer_
,
1.
,
1.
);
// scale the grad
channelBuffer_
->
resetOne
();
sampleBuffer_
->
mul
(
*
channelBuffer_
,
*
spatialBuffer_
,
1.
,
0.
);
inGradTmp
->
dotMul
(
*
inValueTmp
,
*
sampleBuffer_
);
inGradTmp
->
copyFrom
(
*
inValueTmp
);
inGradTmp
->
mulRowVector
(
*
spatialBuffer_
);
// divide by square of norm
spatialBuffer_
->
dotMul
(
*
normTmp
,
*
normTmp
);
sampleBuffer_
->
mul
(
*
channelBuffer_
,
*
spatialBuffer_
,
1.
,
0.
);
inGradTmp
->
dotDiv
(
*
inGradTmp
,
*
sampleBuffer_
);
inGradTmp
->
divRowVector
(
*
spatialBuffer_
);
// subtract
inGradTmp
->
add
(
*
outGradTmp
,
-
1
,
1
);
// divide by norm
sampleBuffer_
->
mul
(
*
channelBuffer_
,
*
normTmp
,
1.
,
0.
);
inGradTmp
->
dotDiv
(
*
inGradTmp
,
*
sampleBuffer_
);
inGradTmp
->
divRowVector
(
*
normTmp
);
// scale the diff
spatialBuffer_
->
resetOne
();
sampleBuffer_
->
mul
(
*
scale_
->
getW
(),
*
spatialBuffer_
,
1.
,
0.
);
inGradTmp
->
dotMul
(
*
inGradTmp
,
*
sampleBuffer_
);
inGradTmp
->
mulColVector
(
*
scale_
->
getW
());
}
// updata scale
if
(
scale_
->
getWGrad
())
scale_
->
getWGrad
()
->
copyFrom
(
*
scaleDiff_
);
hl_set_sync_flag
(
false
);
hl_set_sync_flag
(
syncFlag
);
scale_
->
getParameterPtr
()
->
incUpdate
(
callback
);
}
...
...
paddle/gserver/layers/NormLayer.cpp
浏览文件 @
eb43d93a
...
...
@@ -26,6 +26,8 @@ Layer* NormLayer::create(const LayerConfig& config) {
return
new
ResponseNormLayer
(
config
);
}
else
if
(
norm
==
"cmrnorm-projection"
)
{
return
new
CMRProjectionNormLayer
(
config
);
}
else
if
(
norm
==
"cross-channel-norm"
)
{
return
new
CrossChannelNormLayer
(
config
);
}
else
{
LOG
(
FATAL
)
<<
"Unknown norm type: "
<<
norm
;
return
nullptr
;
...
...
@@ -54,4 +56,14 @@ bool ResponseNormLayer::init(const LayerMap& layerMap,
return
true
;
}
bool
CrossChannelNormLayer
::
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
{
Layer
::
init
(
layerMap
,
parameterMap
);
CHECK
(
parameters_
[
0
]);
const
NormConfig
&
conf
=
config_
.
inputs
(
0
).
norm_conf
();
channels_
=
conf
.
channels
();
scale_
.
reset
(
new
Weight
(
channels_
,
1
,
parameters_
[
0
]));
return
true
;
}
}
// namespace paddle
paddle/gserver/layers/NormLayer.h
浏览文件 @
eb43d93a
...
...
@@ -65,4 +65,35 @@ public:
}
};
/**
* This layer applys normalize across the channels of each sample to a
* conv layer's output and scale the output by a group of trainable factors
* which dimensions equal to the channel's number.
* - Input: One and only one input layer are accepted. The input layer must be
* be a data output layer.
* - Output: The normalized data of the input data.
* Reference:
* Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed,
* Cheng-Yang Fu, Alexander C. Berg. SSD: Single Shot MultiBox Detector
*/
class
CrossChannelNormLayer
:
public
NormLayer
{
public:
explicit
CrossChannelNormLayer
(
const
LayerConfig
&
config
)
:
NormLayer
(
config
)
{}
bool
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
);
void
forward
(
PassType
passType
);
void
backward
(
const
UpdateCallback
&
callback
);
protected:
size_t
channels_
;
std
::
unique_ptr
<
Weight
>
scale_
;
MatrixPtr
scaleDiff_
;
MatrixPtr
normBuffer_
;
MatrixPtr
dataBuffer_
;
MatrixPtr
channelBuffer_
;
MatrixPtr
spatialBuffer_
;
MatrixPtr
sampleBuffer_
;
};
}
// namespace paddle
paddle/gserver/tests/test_LayerGrad.cpp
浏览文件 @
eb43d93a
...
...
@@ -1623,17 +1623,22 @@ TEST(Layer, PadLayer) {
}
}
TEST
(
Layer
,
Normalize
Layer
)
{
TEST
(
Layer
,
CrossChannelNorm
Layer
)
{
TestConfig
config
;
config
.
layerConfig
.
set_type
(
"norm
alize
"
);
config
.
layerConfig
.
set_type
(
"norm"
);
config
.
layerConfig
.
set_size
(
100
);
config
.
layerConfig
.
set_num_filters
(
10
);
LayerInputConfig
*
input
=
config
.
layerConfig
.
add_inputs
();
NormConfig
*
norm
=
input
->
mutable_norm_conf
();
norm
->
set_norm_type
(
"cross-channel-norm"
);
norm
->
set_channels
(
10
);
norm
->
set_size
(
100
);
norm
->
set_scale
(
0
);
norm
->
set_pow
(
0
);
norm
->
set_blocked
(
0
);
config
.
inputDefs
.
push_back
({
INPUT_DATA
,
"layer_0"
,
100
,
10
});
config
.
layerConfig
.
add_inputs
();
for
(
auto
useGpu
:
{
false
,
true
})
{
testLayerGrad
(
config
,
"
normalize
"
,
10
,
false
,
useGpu
,
false
,
5
);
testLayerGrad
(
config
,
"
cross-channel-norm
"
,
10
,
false
,
useGpu
,
false
,
5
);
}
}
...
...
paddle/math/BaseMatrix.cu
浏览文件 @
eb43d93a
...
...
@@ -1453,6 +1453,24 @@ void BaseMatrixT<T>::divRowVector(BaseMatrixT& b) {
true_type
()
/* bAsRowVector */
,
false_type
());
}
template
<
class
T
>
void
BaseMatrixT
<
T
>::
mulColVector
(
BaseMatrixT
&
b
)
{
MatrixOffset
offset
(
0
,
0
,
0
,
0
);
int
numRows
=
height_
;
int
numCols
=
width_
;
applyBinary
(
binary
::
DotMul
<
T
>
(),
b
,
numRows
,
numCols
,
offset
,
false_type
(),
true_type
()
/* bAsColVector */
);
}
template
<
class
T
>
void
BaseMatrixT
<
T
>::
divColVector
(
BaseMatrixT
&
b
)
{
MatrixOffset
offset
(
0
,
0
,
0
,
0
);
int
numRows
=
height_
;
int
numCols
=
width_
;
applyBinary
(
binary
::
DotDiv
<
T
>
(),
b
,
numRows
,
numCols
,
offset
,
false_type
(),
true_type
()
/* bAsColVector */
);
}
template
<
>
template
<
class
Agg
>
int
BaseMatrixT
<
real
>::
applyRow
(
Agg
agg
,
BaseMatrixT
&
b
)
{
...
...
paddle/math/BaseMatrix.h
浏览文件 @
eb43d93a
...
...
@@ -545,6 +545,9 @@ public:
void
mulRowVector
(
BaseMatrixT
&
b
);
void
divRowVector
(
BaseMatrixT
&
b
);
void
mulColVector
(
BaseMatrixT
&
b
);
void
divColVector
(
BaseMatrixT
&
b
);
void
addP2P
(
BaseMatrixT
&
b
);
/**
...
...
paddle/math/tests/test_BaseMatrix.cpp
浏览文件 @
eb43d93a
...
...
@@ -110,6 +110,8 @@ TEST(BaseMatrix, BaseMatrix) {
compare
(
&
BaseMatrix
::
addRowVector
);
compare
(
&
BaseMatrix
::
mulRowVector
);
compare
(
&
BaseMatrix
::
divRowVector
);
compare
(
&
BaseMatrix
::
mulColVector
);
compare
(
&
BaseMatrix
::
divColVector
);
compare
(
&
BaseMatrix
::
addP2P
);
compare
(
&
BaseMatrix
::
invSqrt
);
}
...
...
python/paddle/trainer/config_parser.py
浏览文件 @
eb43d93a
...
...
@@ -1156,9 +1156,11 @@ def parse_image(image, input_layer_name, image_conf):
def
parse_norm
(
norm
,
input_layer_name
,
norm_conf
):
norm_conf
.
norm_type
=
norm
.
norm_type
config_assert
(
norm
.
norm_type
in
[
'rnorm'
,
'cmrnorm-projection'
],
"norm-type %s is not in [rnorm, 'cmrnorm-projection']"
%
norm
.
norm_type
)
config_assert
(
norm
.
norm_type
in
[
'rnorm'
,
'cmrnorm-projection'
,
'cross-channel-norm'
],
"norm-type %s is not in [rnorm, cmrnorm-projection, cross-channel-norm]"
%
norm
.
norm_type
)
norm_conf
.
channels
=
norm
.
channels
norm_conf
.
size
=
norm
.
size
norm_conf
.
scale
=
norm
.
scale
...
...
@@ -1619,16 +1621,6 @@ class PriorBoxLayer(LayerBase):
self
.
config
.
size
=
size
@
config_layer
(
'normalize'
)
class
NormalizeLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
inputs
,
size
,
num_filters
,
**
xargs
):
super
(
NormalizeLayer
,
self
).
__init__
(
name
,
'normalize'
,
0
,
inputs
,
**
xargs
)
self
.
config
.
size
=
size
self
.
config
.
num_filters
=
num_filters
self
.
create_input_parameter
(
0
,
num_filters
,
[
num_filters
,
1
])
@
config_layer
(
'data'
)
class
DataLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
size
,
height
=
None
,
width
=
None
,
device
=
None
):
...
...
@@ -1831,6 +1823,9 @@ class NormLayer(LayerBase):
norm_conf
)
self
.
set_cnn_layer
(
name
,
norm_conf
.
output_y
,
norm_conf
.
output_x
,
norm_conf
.
channels
,
False
)
if
norm_conf
.
norm_type
==
"cross-channel-norm"
:
self
.
create_input_parameter
(
0
,
norm_conf
.
channels
,
[
norm_conf
.
channels
,
1
])
@
config_layer
(
'pool'
)
...
...
python/paddle/trainer_config_helpers/layers.py
浏览文件 @
eb43d93a
...
...
@@ -111,7 +111,7 @@ __all__ = [
'out_prod_layer'
,
'print_layer'
,
'priorbox_layer'
,
'
normalize
_layer'
,
'
cross_channel_norm
_layer'
,
'spp_layer'
,
'pad_layer'
,
'eos_layer'
,
...
...
@@ -185,7 +185,6 @@ class LayerType(object):
PRINT_LAYER
=
"print"
PRIORBOX_LAYER
=
"priorbox"
NORMALIZE_LAYER
=
"normalize"
CTC_LAYER
=
"ctc"
WARP_CTC_LAYER
=
"warp_ctc"
...
...
@@ -1000,8 +999,8 @@ def priorbox_layer(input,
size
=
size
)
@
wrap_name_default
(
"
normalize
"
)
def
normalize
_layer
(
input
,
name
=
None
,
param_attr
=
None
):
@
wrap_name_default
(
"
cross_channel_norm
"
)
def
cross_channel_norm
_layer
(
input
,
name
=
None
,
param_attr
=
None
):
"""
Normalize a layer's output. This layer is necessary for ssd.
This layer applys normalize across the channels of each sample to
...
...
@@ -1017,13 +1016,22 @@ def normalize_layer(input, name=None, param_attr=None):
"""
Layer
(
name
=
name
,
type
=
LayerType
.
NORMALIZE_LAYER
,
inputs
=
[
Input
(
input
.
name
,
**
param_attr
.
attr
)],
size
=
input
.
size
,
num_filters
=
input
.
num_filters
)
type
=
LayerType
.
NORM_LAYER
,
inputs
=
[
Input
(
input
.
name
,
norm
=
Norm
(
norm_type
=
"cross-channel-norm"
,
channels
=
input
.
num_filters
,
size
=
input
.
size
,
scale
=
0
,
pow
=
0
,
blocked
=
0
),
**
param_attr
.
attr
)
])
return
LayerOutput
(
name
,
LayerType
.
NORM
ALIZE
_LAYER
,
LayerType
.
NORM_LAYER
,
parents
=
input
,
num_filters
=
input
.
num_filters
,
size
=
input
.
size
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录