Skip to content

Commit eb3bf9e

Browse files
authored
Merge pull request #360 from emailweixu/sum_cost
Add SumCost
2 parents a276684 + 38764bf commit eb3bf9e

File tree

9 files changed

+122
-20
lines changed

9 files changed

+122
-20
lines changed

doc/source/gserver/layers/layer.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@ SumOfSquaresCostLayer
465465
.. doxygenclass:: paddle::SumOfSquaresCostLayer
466466
:members:
467467

468+
SumCostLayer
469+
`````````````````````
470+
.. doxygenclass:: paddle::SumCostLayer
471+
:members:
472+
468473
CosSimLayer
469474
-----------
470475
.. doxygenclass:: paddle::CosSimLayer

doc/ui/api/trainer_config_helpers/layers.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,12 @@ hsigmoid
407407
:members: hsigmoid
408408
:noindex:
409409

410+
sum_cost
411+
---------
412+
.. automodule:: paddle.trainer_config_helpers.layers
413+
:members: sum_cost
414+
:noindex:
415+
410416
Check Layer
411417
============
412418

paddle/gserver/layers/CostLayer.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,39 @@ void HuberTwoClass::backwardImpIn(
562562
}
563563
}
564564

565+
/**
566+
* This cost layer compute the sum of its input as loss.
567+
* \f[
568+
* o(i) = \sum_{j=1}^D y_{ij}
569+
* \f]
570+
*/
571+
class SumCostLayer : public Layer {
572+
public:
573+
explicit SumCostLayer(const LayerConfig& config) : Layer(config) {}
574+
575+
bool init(const LayerMap& layerMap, const ParameterMap& parameterMap) {
576+
bool ret = Layer::init(layerMap, parameterMap);
577+
if (!ret) return ret;
578+
CHECK_EQ(inputLayers_.size(), 1UL);
579+
return true;
580+
}
581+
582+
virtual void forward(PassType passType) {
583+
Layer::forward(passType);
584+
const MatrixPtr& input = getInputValue(0);
585+
586+
/* malloc memory for the output_ if necessary */
587+
int batchSize = input->getHeight();
588+
int size = 1;
589+
resizeOutput(batchSize, size);
590+
output_.value->sumRows(*input);
591+
}
592+
593+
virtual void backward(const UpdateCallback& callback = nullptr) {
594+
getInputGrad(0)->add((real)1);
595+
}
596+
};
597+
598+
REGISTER_LAYER(sum_cost, SumCostLayer);
599+
565600
} // namespace paddle

paddle/gserver/layers/CostLayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class SoftBinaryClassCrossEntropy : public CostLayer {
129129
* This cost layer compute Euclidean (L2) loss for real-valued regression
130130
* tasks.
131131
* \f[
132-
* L = \frac{1}{2N} \sum_{i=1}^N {|| \hat{y}_i - y_i||_2^2}
132+
* L = \sum_{i=1}^N {|| \hat{y}_i - y_i||_2^2}
133133
* \f]
134134
*/
135135
class SumOfSquaresCostLayer : public CostLayer {

paddle/gserver/tests/test_LayerGrad.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,19 @@ TEST(Layer, rankCostLayer) {
998998
}
999999
}
10001000

1001+
TEST(Layer, sumCostLayer) {
1002+
TestConfig config;
1003+
config.layerConfig.set_type("sum_cost");
1004+
config.biasSize = 0;
1005+
1006+
config.inputDefs.push_back({INPUT_DATA, "layer_0", 1, 0});
1007+
config.layerConfig.add_inputs();
1008+
1009+
for (auto useGpu : {false, true}) {
1010+
testLayerGrad(config, "sum_cost", 100, false, useGpu);
1011+
}
1012+
}
1013+
10011014
TEST(Layer, weightedRankCostLayer) {
10021015
TestConfig config;
10031016
config.layerConfig.set_type("rank-cost");

python/paddle/trainer/config_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,6 +1903,7 @@ def init(cls, name, inputs, device=None, coeff=1.):
19031903
define_cost('MultiBinaryLabelCrossEntropy', 'multi_binary_label_cross_entropy')
19041904
define_cost('SoftBinaryClassCrossEntropy', 'soft_binary_class_cross_entropy')
19051905
define_cost('HuberTwoClass', 'huber')
1906+
define_cost('SumCost', 'sum_cost')
19061907

19071908
@config_layer('hsigmoid')
19081909
class HierarchicalSigmoidLayer(LayerBase):

python/paddle/trainer_config_helpers/layers.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
'convex_comb_layer', 'ctc_layer', 'crf_layer', 'crf_decoding_layer',
5454
'nce_layer',
5555
'cross_entropy_with_selfnorm', 'cross_entropy',
56-
'multi_binary_label_cross_entropy',
56+
'multi_binary_label_cross_entropy', 'sum_cost',
5757
'rank_cost', 'lambda_cost', 'huber_cost',
5858
'block_expand_layer',
5959
'maxout_layer', 'out_prod_layer', 'print_layer'
@@ -130,6 +130,7 @@ class LayerType(object):
130130
CROSS_ENTROPY_WITH_SELFNORM = "multi_class_cross_entropy_with_selfnorm"
131131
SOFT_BIN_CLASS_CROSS_ENTROPY = "soft_binary_class_cross_entropy"
132132
MULTI_BIN_LABEL_CROSS_ENTROPY = "multi_binary_label_cross_entropy"
133+
SUM_COST = "sum_cost"
133134

134135
@staticmethod
135136
def is_layer_type(type_name):
@@ -4053,8 +4054,6 @@ def cross_entropy(input, label, name=None, coeff=1.0, layer_attr=None):
40534054
:type input: LayerOutput.
40544055
:param label: The input label.
40554056
:type input: LayerOutput.
4056-
:param type: The type of cost.
4057-
:type type: basestring.
40584057
:param name: The name of this layers. It is not necessary.
40594058
:type name: None|basestring.
40604059
:param coeff: The coefficient affects the gradient in the backward.
@@ -4091,8 +4090,6 @@ def cross_entropy_with_selfnorm(input, label, name=None, coeff=1.0,
40914090
:type input: LayerOutput.
40924091
:param label: The input label.
40934092
:type input: LayerOutput.
4094-
:param type: The type of cost.
4095-
:type type: basestring.
40964093
:param name: The name of this layers. It is not necessary.
40974094
:type name: None|basestring.
40984095
:param coeff: The coefficient affects the gradient in the backward.
@@ -4117,6 +4114,36 @@ def cross_entropy_with_selfnorm(input, label, name=None, coeff=1.0,
41174114
parents=[input, label], size=1)
41184115

41194116

4117+
@wrap_name_default()
4118+
@layer_support()
4119+
def sum_cost(input, name=None, layer_attr=None):
4120+
"""
4121+
A loss layer which calculate the sum of the input as loss
4122+
4123+
.. code-block:: python
4124+
4125+
cost = sum_cost(input)
4126+
4127+
:param input: The first input layer.
4128+
:type input: LayerOutput.
4129+
:param name: The name of this layers. It is not necessary.
4130+
:type name: None|basestring.
4131+
:param layer_attr: Extra Layer Attribute.
4132+
:type layer_attr: ExtraLayerAttribute
4133+
:return: LayerOutput object.
4134+
:rtype: LayerOutput.
4135+
"""
4136+
Layer(name=name,
4137+
type=LayerType.SUM_COST,
4138+
inputs=[input.name],
4139+
**ExtraLayerAttribute.to_kwargs(layer_attr)
4140+
)
4141+
4142+
return LayerOutput(name,
4143+
LayerType.SUM_COST,
4144+
parents=[input])
4145+
4146+
41204147
@wrap_name_default()
41214148
@layer_support()
41224149
def huber_cost(input, label, name=None, coeff=1.0, layer_attr=None):

python/paddle/trainer_config_helpers/tests/configs/protostr/test_cost_layers.protostr

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ layers {
2323
size: 10
2424
active_type: ""
2525
}
26+
layers {
27+
name: "__fc_layer_0__"
28+
type: "fc"
29+
size: 4
30+
active_type: "tanh"
31+
inputs {
32+
input_layer_name: "input"
33+
input_parameter_name: "___fc_layer_0__.w0"
34+
}
35+
bias_parameter_name: "___fc_layer_0__.wbias"
36+
}
2637
layers {
2738
name: "__ctc_layer_0__"
2839
type: "ctc"
@@ -36,17 +47,6 @@ layers {
3647
}
3748
norm_by_times: false
3849
}
39-
layers {
40-
name: "__fc_layer_0__"
41-
type: "fc"
42-
size: 4
43-
active_type: "tanh"
44-
inputs {
45-
input_layer_name: "input"
46-
input_parameter_name: "___fc_layer_0__.w0"
47-
}
48-
bias_parameter_name: "___fc_layer_0__.wbias"
49-
}
5050
layers {
5151
name: "crf_label"
5252
type: "data"
@@ -191,6 +191,16 @@ layers {
191191
}
192192
coeff: 1.0
193193
}
194+
layers {
195+
name: "__sum_cost_0__"
196+
type: "sum_cost"
197+
size: 1
198+
active_type: ""
199+
inputs {
200+
input_layer_name: "__fc_layer_0__"
201+
}
202+
coeff: 1.0
203+
}
194204
parameters {
195205
name: "___fc_layer_0__.w0"
196206
size: 800
@@ -241,14 +251,15 @@ output_layer_names: "__cross_entropy_0__"
241251
output_layer_names: "__cross_entropy_with_selfnorm_0__"
242252
output_layer_names: "__huber_cost_0__"
243253
output_layer_names: "__multi_binary_label_cross_entropy_0__"
254+
output_layer_names: "__sum_cost_0__"
244255
sub_models {
245256
name: "root"
246257
layer_names: "input"
247258
layer_names: "labels"
248259
layer_names: "probs"
249260
layer_names: "xe-label"
250-
layer_names: "__ctc_layer_0__"
251261
layer_names: "__fc_layer_0__"
262+
layer_names: "__ctc_layer_0__"
252263
layer_names: "crf_label"
253264
layer_names: "__crf_layer_0__"
254265
layer_names: "left"
@@ -264,6 +275,7 @@ sub_models {
264275
layer_names: "huber_label"
265276
layer_names: "__huber_cost_0__"
266277
layer_names: "__multi_binary_label_cross_entropy_0__"
278+
layer_names: "__sum_cost_0__"
267279
input_layer_names: "input"
268280
input_layer_names: "labels"
269281
input_layer_names: "crf_label"
@@ -284,6 +296,7 @@ sub_models {
284296
output_layer_names: "__cross_entropy_with_selfnorm_0__"
285297
output_layer_names: "__huber_cost_0__"
286298
output_layer_names: "__multi_binary_label_cross_entropy_0__"
299+
output_layer_names: "__sum_cost_0__"
287300
is_recurrent_layer_group: false
288301
}
289302

python/paddle/trainer_config_helpers/tests/configs/test_cost_layers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
probs = data_layer(name='probs', size=10)
1212
xe_label = data_layer(name='xe-label', size=10)
1313

14+
hidden = fc_layer(input=seq_in, size=4)
1415
outputs(ctc_layer(input=seq_in, label=labels),
15-
crf_layer(input=fc_layer(input=seq_in, size=4),
16+
crf_layer(input=hidden,
1617
label=data_layer(name='crf_label', size=4)),
1718
rank_cost(left=data_layer(name='left', size=1),
1819
right=data_layer(name='right', size=1),
@@ -23,4 +24,5 @@
2324
cross_entropy_with_selfnorm(input=probs, label=xe_label),
2425
huber_cost(input=data_layer(name='huber_probs', size=1),
2526
label=data_layer(name='huber_label', size=1)),
26-
multi_binary_label_cross_entropy(input=probs, label=xe_label))
27+
multi_binary_label_cross_entropy(input=probs, label=xe_label),
28+
sum_cost(hidden))

0 commit comments

Comments
 (0)