Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
机器未来
Paddle
提交
c6ec26df
P
Paddle
项目概览
机器未来
/
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看板
未验证
提交
c6ec26df
编写于
11月 19, 2017
作者:
C
Cao Ying
提交者:
GitHub
11月 19, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5736 from lcy-seso/l2_distance
Add the L2 distance layer.
上级
569f7c47
37190b7c
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
295 addition
and
17 deletion
+295
-17
doc/api/v2/config/layer.rst
doc/api/v2/config/layer.rst
+5
-0
paddle/gserver/layers/L2DistanceLayer.cpp
paddle/gserver/layers/L2DistanceLayer.cpp
+91
-0
paddle/gserver/layers/L2DistanceLayer.h
paddle/gserver/layers/L2DistanceLayer.h
+52
-0
paddle/gserver/tests/test_LayerGrad.cpp
paddle/gserver/tests/test_LayerGrad.cpp
+20
-0
python/paddle/trainer/config_parser.py
python/paddle/trainer/config_parser.py
+30
-14
python/paddle/trainer_config_helpers/layers.py
python/paddle/trainer_config_helpers/layers.py
+48
-1
python/paddle/trainer_config_helpers/tests/configs/file_list.sh
.../paddle/trainer_config_helpers/tests/configs/file_list.sh
+3
-2
python/paddle/trainer_config_helpers/tests/configs/protostr/test_l2_distance_layer.protostr
...rs/tests/configs/protostr/test_l2_distance_layer.protostr
+39
-0
python/paddle/trainer_config_helpers/tests/configs/test_l2_distance_layer.py
...er_config_helpers/tests/configs/test_l2_distance_layer.py
+7
-0
未找到文件。
doc/api/v2/config/layer.rst
浏览文件 @
c6ec26df
...
@@ -382,6 +382,11 @@ cos_sim
...
@@ -382,6 +382,11 @@ cos_sim
.. autoclass:: paddle.v2.layer.cos_sim
.. autoclass:: paddle.v2.layer.cos_sim
:noindex:
:noindex:
l2_distance
-----------
.. autoclass:: paddle.v2.layer.l2_distance
:noindex:
trans
trans
-----
-----
.. autoclass:: paddle.v2.layer.trans
.. autoclass:: paddle.v2.layer.trans
...
...
paddle/gserver/layers/L2DistanceLayer.cpp
0 → 100644
浏览文件 @
c6ec26df
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "L2DistanceLayer.h"
#include "paddle/utils/Logging.h"
#include "paddle/utils/Stat.h"
namespace
paddle
{
REGISTER_LAYER
(
l2_distance
,
L2DistanceLayer
);
bool
L2DistanceLayer
::
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
{
/* Initialize the basic parent class */
Layer
::
init
(
layerMap
,
parameterMap
);
CHECK_EQ
(
inputLayers_
.
size
(),
2UL
)
<<
"The L2DistanceLayer accepts two and "
<<
"only two inputs."
;
CHECK_EQ
(
getSize
(),
1UL
)
<<
"The output dimensionality of L2DistanceLayer "
<<
"is fixed to be 1."
;
return
true
;
}
void
L2DistanceLayer
::
forward
(
PassType
passType
)
{
Layer
::
forward
(
passType
);
const
auto
inV1
=
getInputValue
(
0
);
const
auto
inV2
=
getInputValue
(
1
);
CHECK
(
inV1
&&
inV2
);
CHECK_EQ
(
inV1
->
getHeight
(),
inV2
->
getHeight
())
<<
"The height of two inputs of this layer must be the same."
;
CHECK_EQ
(
inV1
->
getWidth
(),
inV2
->
getWidth
())
<<
"The width of two inputs of this layer must be the same."
;
int
batchSize
=
inV1
->
getHeight
();
int
output_dim
=
getSize
();
{
REGISTER_TIMER_INFO
(
"L2DistanceBpAtvTimer"
,
getName
().
c_str
());
reserveOutput
(
batchSize
,
output_dim
);
auto
outV
=
getOutputValue
();
CHECK
(
outV
)
<<
"The output matrix should not be null."
;
Matrix
::
resizeOrCreate
(
inputSub_
,
inV1
->
getHeight
(),
inV1
->
getWidth
(),
false
,
useGpu_
);
inputSub_
->
assign
(
*
inV1
);
inputSub_
->
sub
(
*
inV2
);
outV
->
sumOfProducts
(
*
inputSub_
,
*
inputSub_
,
1
,
0
);
outV
->
sqrt2
(
*
outV
);
}
}
void
L2DistanceLayer
::
backward
(
const
UpdateCallback
&
callback
)
{
const
auto
outG
=
getOutputGrad
();
const
auto
outV
=
getOutputValue
();
CHECK
(
outG
&&
outV
);
auto
inGrad1
=
getInputGrad
(
0
);
auto
inGrad2
=
getInputGrad
(
1
);
{
REGISTER_TIMER_INFO
(
"L2DistanceBpAtvTimer"
,
getName
().
c_str
());
if
(
inGrad1
||
inGrad2
)
{
outV
->
scalarDiv
(
*
outV
,
1.
);
outV
->
dotMul
(
*
outG
,
*
outV
);
}
if
(
inGrad1
)
inGrad1
->
addRowScale
(
0
,
*
inputSub_
,
*
outV
);
if
(
inGrad2
)
{
inputSub_
->
mulScalar
(
-
1.
);
inGrad2
->
addRowScale
(
0
,
*
inputSub_
,
*
outV
);
}
}
}
}
// namespace paddle
paddle/gserver/layers/L2DistanceLayer.h
0 → 100644
浏览文件 @
c6ec26df
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include "Layer.h"
#include "paddle/math/Matrix.h"
namespace
paddle
{
/**
* @brief The layer calculates the l2 distance between two input vectors.
* \f[
* f(\bf{x}, \bf{y}) = \sqrt{\sum_{i=1}^D(x_i - y_i)}
* \f]
*
* - Input1: A vector (batchSize * dataDim)
* - Input2: A vector (batchSize * dataDim)
* - Output: A vector (batchSize * 1)
*
* The configuration api is: l2_distance_layer.
*/
class
L2DistanceLayer
:
public
Layer
{
public:
explicit
L2DistanceLayer
(
const
LayerConfig
&
config
)
:
Layer
(
config
)
{}
~
L2DistanceLayer
()
{}
bool
init
(
const
LayerMap
&
layerMap
,
const
ParameterMap
&
parameterMap
)
override
;
void
forward
(
PassType
passType
)
override
;
void
backward
(
const
UpdateCallback
&
callback
=
nullptr
)
override
;
private:
// Store the result of subtracting Input2 from Input1 in forward computation,
// which will be reused in backward computation.
MatrixPtr
inputSub_
;
};
}
// namespace paddle
paddle/gserver/tests/test_LayerGrad.cpp
浏览文件 @
c6ec26df
...
@@ -583,6 +583,7 @@ TEST(Layer, maxoutLayer) {
...
@@ -583,6 +583,7 @@ TEST(Layer, maxoutLayer) {
testLayerGrad
(
config
,
"maxout"
,
10
,
false
,
useGpu
);
testLayerGrad
(
config
,
"maxout"
,
10
,
false
,
useGpu
);
}
}
}
}
void
testFcLayer
(
string
format
,
size_t
nnz
)
{
void
testFcLayer
(
string
format
,
size_t
nnz
)
{
TestConfig
config
;
TestConfig
config
;
config
.
biasSize
=
1024
;
config
.
biasSize
=
1024
;
...
@@ -2444,6 +2445,25 @@ TEST(Layer, ScaleSubRegionLayer) {
...
@@ -2444,6 +2445,25 @@ TEST(Layer, ScaleSubRegionLayer) {
}
}
}
}
TEST
(
Layer
,
L2DistanceLayer
)
{
TestConfig
config
;
config
.
layerConfig
.
set_type
(
"l2_distance"
);
config
.
layerConfig
.
set_size
(
1
);
config
.
biasSize
=
0
;
const
size_t
input_dim
=
27
;
const
size_t
batch_size
=
11
;
config
.
inputDefs
.
push_back
({
INPUT_DATA
,
"layer_0"
,
input_dim
,
0
});
config
.
inputDefs
.
push_back
({
INPUT_DATA
,
"layer_1"
,
input_dim
,
0
});
config
.
layerConfig
.
add_inputs
();
config
.
layerConfig
.
add_inputs
();
for
(
auto
useGpu
:
{
false
,
true
})
{
testLayerGrad
(
config
,
"l2_distance"
,
batch_size
,
false
,
useGpu
);
}
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
testing
::
InitGoogleTest
(
&
argc
,
argv
);
initMain
(
argc
,
argv
);
initMain
(
argc
,
argv
);
...
...
python/paddle/trainer/config_parser.py
浏览文件 @
c6ec26df
...
@@ -3342,6 +3342,20 @@ class RowL2NormLayer(LayerBase):
...
@@ -3342,6 +3342,20 @@ class RowL2NormLayer(LayerBase):
self
.
set_layer_size
(
input_layer
.
size
)
self
.
set_layer_size
(
input_layer
.
size
)
@
config_layer
(
'cos'
)
class
CosSimLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
inputs
,
cos_scale
=
1
,
device
=
None
):
super
(
CosSimLayer
,
self
).
__init__
(
name
,
'cos'
,
1
,
inputs
=
inputs
,
device
=
device
)
config_assert
(
len
(
self
.
inputs
)
==
2
,
'The CosSimLayer expects two and only two inputs.'
)
config_assert
(
self
.
get_input_layer
(
0
).
size
==
self
.
get_input_layer
(
1
).
size
,
'The two inputs of CosSimLayer must have the same dimensionality.'
)
self
.
config
.
cos_scale
=
cos_scale
@
config_layer
(
'cos_vm'
)
@
config_layer
(
'cos_vm'
)
class
CosSimVecMatLayer
(
LayerBase
):
class
CosSimVecMatLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
size
,
inputs
,
cos_scale
=
1.0
,
device
=
None
):
def
__init__
(
self
,
name
,
size
,
inputs
,
cos_scale
=
1.0
,
device
=
None
):
...
@@ -3349,10 +3363,24 @@ class CosSimVecMatLayer(LayerBase):
...
@@ -3349,10 +3363,24 @@ class CosSimVecMatLayer(LayerBase):
name
,
'cos_vm'
,
size
,
inputs
=
inputs
,
device
=
device
)
name
,
'cos_vm'
,
size
,
inputs
=
inputs
,
device
=
device
)
self
.
config
.
cos_scale
=
cos_scale
self
.
config
.
cos_scale
=
cos_scale
config_assert
(
config_assert
(
len
(
self
.
inputs
)
==
2
,
'
CosSimVecMatLayer must have 2 inputs
'
)
len
(
self
.
inputs
)
==
2
,
'
The CosSimVecMatLayer must have 2 inputs.
'
)
config_assert
(
config_assert
(
size
*
self
.
get_input_layer
(
0
).
size
==
self
.
get_input_layer
(
1
).
size
,
size
*
self
.
get_input_layer
(
0
).
size
==
self
.
get_input_layer
(
1
).
size
,
'Wrong input size for CosSimVecMatLayer'
)
'Wrong input size for CosSimVecMatLayer.'
)
@
config_layer
(
'l2_distance'
)
class
L2DistanceLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
inputs
,
device
=
None
):
super
(
L2DistanceLayer
,
self
).
__init__
(
name
,
'l2_distance'
,
1
,
inputs
=
inputs
,
device
=
device
)
config_assert
(
len
(
self
.
inputs
)
==
2
,
(
'The L2DistanceLayer must have '
'and only have 2 inputs.'
))
config_assert
(
self
.
get_input_layer
(
0
).
size
==
self
.
get_input_layer
(
1
).
size
,
(
'Two inputs of the L2DistanceLayer must have '
'the same dimensionality.'
))
@
config_layer
(
'sampling_id'
)
@
config_layer
(
'sampling_id'
)
...
@@ -3396,18 +3424,6 @@ class AverageLayer(LayerBase):
...
@@ -3396,18 +3424,6 @@ class AverageLayer(LayerBase):
self
.
create_bias_parameter
(
bias
,
self
.
config
.
size
)
self
.
create_bias_parameter
(
bias
,
self
.
config
.
size
)
@
config_layer
(
'cos'
)
class
CosSimLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
inputs
,
cos_scale
=
1
,
device
=
None
):
super
(
CosSimLayer
,
self
).
__init__
(
name
,
'cos'
,
1
,
inputs
=
inputs
,
device
=
device
)
config_assert
(
len
(
self
.
inputs
)
==
2
,
'CosSimLayer must have 2 inputs'
)
config_assert
(
self
.
get_input_layer
(
0
).
size
==
self
.
get_input_layer
(
1
).
size
,
'inputs of CosSimLayer must have same dim'
)
self
.
config
.
cos_scale
=
cos_scale
@
config_layer
(
'tensor'
)
@
config_layer
(
'tensor'
)
class
TensorLayer
(
LayerBase
):
class
TensorLayer
(
LayerBase
):
def
__init__
(
self
,
name
,
size
,
inputs
,
bias
=
True
,
**
xargs
):
def
__init__
(
self
,
name
,
size
,
inputs
,
bias
=
True
,
**
xargs
):
...
...
python/paddle/trainer_config_helpers/layers.py
浏览文件 @
c6ec26df
...
@@ -51,6 +51,7 @@ __all__ = [
...
@@ -51,6 +51,7 @@ __all__ = [
'last_seq'
,
'last_seq'
,
'first_seq'
,
'first_seq'
,
'cos_sim'
,
'cos_sim'
,
'l2_distance_layer'
,
'hsigmoid'
,
'hsigmoid'
,
'conv_projection'
,
'conv_projection'
,
'square_error_cost'
,
'square_error_cost'
,
...
@@ -168,6 +169,7 @@ class LayerType(object):
...
@@ -168,6 +169,7 @@ class LayerType(object):
COST
=
'cost'
COST
=
'cost'
COSINE_SIM_VEC
=
'cos_vm'
COSINE_SIM_VEC
=
'cos_vm'
COSINE_SIM
=
'cos'
COSINE_SIM
=
'cos'
L2_DISTANCE
=
'l2_distance'
HSIGMOID
=
'hsigmoid'
HSIGMOID
=
'hsigmoid'
CONV_LAYER
=
'conv'
CONV_LAYER
=
'conv'
CONVTRANS_LAYER
=
'convt'
CONVTRANS_LAYER
=
'convt'
...
@@ -2334,6 +2336,51 @@ def cos_sim(a, b, scale=1, size=1, name=None, layer_attr=None):
...
@@ -2334,6 +2336,51 @@ def cos_sim(a, b, scale=1, size=1, name=None, layer_attr=None):
return
LayerOutput
(
name
,
LayerType
.
COSINE_SIM
,
parents
=
[
a
,
b
],
size
=
size
)
return
LayerOutput
(
name
,
LayerType
.
COSINE_SIM
,
parents
=
[
a
,
b
],
size
=
size
)
@
wrap_name_default
()
@
layer_support
()
def
l2_distance_layer
(
x
,
y
,
name
=
None
,
layer_attr
=
None
):
"""
This layer calculates and returns the Euclidean distance between two input
vectors x and y. The equation is as follows:
.. math::
l2_distance(
\\
mathbf{x},
\\
mathbf{y}) =
\\
sqrt{
\\
sum_{i=1}^D(x_i - y_i)}
The output size of this layer is fixed to be 1. Note that the above
computation is for one sample. Multiple samples are processed in one batch.
The example usage is:
.. code-block:: python
l2_sim = l2_distance(x=layer1, y=layer2)
:param name: The name of this layer. It is optional.
:type name: basestring
:param x: The first input x for this layer, whose output is a matrix with
dimensionality N x D. N is the sample number in a mini-batch.
D is the dimensionality of x's output.
:type x: LayerOutput
:param y: The second input y for this layer, whose output is a matrix with
dimensionality N x D. N is the sample number in a mini-batch.
D is the dimensionality of y's output.
:type y: LayerOutput
:param layer_attr: The extra layer attributes, for example, drop rate.
See ExtraLayerAttribute for more details.
:type layer_attr: ExtraLayerAttribute
:return: The returned LayerOutput object.
:rtype: LayerOutput
"""
assert
isinstance
(
x
,
LayerOutput
)
and
isinstance
(
y
,
LayerOutput
)
Layer
(
name
=
name
,
type
=
LayerType
.
L2_DISTANCE
,
inputs
=
[
x
.
name
,
y
.
name
],
**
ExtraLayerAttribute
.
to_kwargs
(
layer_attr
))
return
LayerOutput
(
name
,
LayerType
.
L2_DISTANCE
,
parents
=
[
x
,
y
],
size
=
1
)
@
wrap_name_default
()
@
wrap_name_default
()
@
wrap_bias_attr_default
(
has_bias
=
True
)
@
wrap_bias_attr_default
(
has_bias
=
True
)
@
wrap_param_attr_default
()
@
wrap_param_attr_default
()
...
@@ -3873,7 +3920,7 @@ def recurrent_layer(input,
...
@@ -3873,7 +3920,7 @@ def recurrent_layer(input,
:type input: LayerOutput
:type input: LayerOutput
:param act: Activation type. TanhActivation is the default activation.
:param act: Activation type. TanhActivation is the default activation.
:type act: BaseActivation
:type act: BaseActivation
:param bias_attr: The parameter attribute for bias. If this parameter is set to
:param bias_attr: The parameter attribute for bias. If this parameter is set to
False or an object whose type is not ParameterAttribute,
False or an object whose type is not ParameterAttribute,
no bias is defined. If the parameter is set to True,
no bias is defined. If the parameter is set to True,
the bias is initialized to zero.
the bias is initialized to zero.
...
...
python/paddle/trainer_config_helpers/tests/configs/file_list.sh
浏览文件 @
c6ec26df
...
@@ -10,7 +10,8 @@ test_prelu_layer test_row_conv test_detection_output_layer test_multibox_loss_la
...
@@ -10,7 +10,8 @@ test_prelu_layer test_row_conv test_detection_output_layer test_multibox_loss_la
test_recursive_topology test_gated_unit_layer test_clip_layer test_row_l2_norm_layer
test_recursive_topology test_gated_unit_layer test_clip_layer test_row_l2_norm_layer
test_kmax_seq_socre_layer test_sub_nested_seq_select_layer test_scale_shift_layer
test_kmax_seq_socre_layer test_sub_nested_seq_select_layer test_scale_shift_layer
test_seq_slice_layer test_cross_entropy_over_beam test_roi_pool_layer test_pooling3D_layer
test_seq_slice_layer test_cross_entropy_over_beam test_roi_pool_layer test_pooling3D_layer
test_conv3d_layer test_deconv3d_layer test_BatchNorm3D test_resize_layer test_scale_sub_region_layer
test_conv3d_layer test_deconv3d_layer test_BatchNorm3D test_resize_layer
test_dot_prod_layer
)
test_conv3d_layer test_deconv3d_layer test_BatchNorm3D test_resize_layer
test_scale_sub_region_layer test_dot_prod_layer test_l2_distance_layer
)
export
whole_configs
=(
test_split_datasource
)
export
whole_configs
=(
test_split_datasource
)
python/paddle/trainer_config_helpers/tests/configs/protostr/test_l2_distance_layer.protostr
0 → 100644
浏览文件 @
c6ec26df
type: "nn"
layers {
name: "x"
type: "data"
size: 128
active_type: ""
}
layers {
name: "y"
type: "data"
size: 128
active_type: ""
}
layers {
name: "__l2_distance_layer_0__"
type: "l2_distance"
size: 1
active_type: ""
inputs {
input_layer_name: "x"
}
inputs {
input_layer_name: "y"
}
}
input_layer_names: "x"
input_layer_names: "y"
output_layer_names: "__l2_distance_layer_0__"
sub_models {
name: "root"
layer_names: "x"
layer_names: "y"
layer_names: "__l2_distance_layer_0__"
input_layer_names: "x"
input_layer_names: "y"
output_layer_names: "__l2_distance_layer_0__"
is_recurrent_layer_group: false
}
python/paddle/trainer_config_helpers/tests/configs/test_l2_distance_layer.py
0 → 100644
浏览文件 @
c6ec26df
from
paddle.trainer_config_helpers
import
*
outputs
(
l2_distance_layer
(
x
=
data_layer
(
name
=
'x'
,
size
=
128
),
y
=
data_layer
(
name
=
'y'
,
size
=
128
)))
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录