1
- /* Copyright © 2017-2020 ABBYY Production LLC
1
+ /* Copyright © 2017-2024 ABBYY
2
2
3
3
Licensed under the Apache License, Version 2.0 (the "License");
4
4
you may not use this file except in compliance with the License.
@@ -22,31 +22,23 @@ limitations under the License.
22
22
23
23
namespace NeoML {
24
24
25
- CCrossEntropyLossLayer::CCrossEntropyLossLayer ( IMathEngine& mathEngine ) :
26
- CLossLayer ( mathEngine, " CCnnCrossEntropyLossLayer" ),
27
- isSoftmaxApplied ( true )
28
- {
29
- }
30
-
31
25
void CCrossEntropyLossLayer::BatchCalculateLossAndGradient ( int batchSize, CConstFloatHandle data, int vectorSize,
32
26
CConstFloatHandle label, int labelSize, CFloatHandle lossValue, CFloatHandle lossGradient )
33
27
{
34
28
BatchCalculateLossAndGradient ( batchSize, data, vectorSize, label, labelSize,
35
- lossValue, lossGradient, CFloatHandle () );
29
+ lossValue, lossGradient, CFloatHandle{} );
36
30
}
37
31
38
32
void CCrossEntropyLossLayer::BatchCalculateLossAndGradient ( int batchSize, CConstFloatHandle data, int vectorSize,
39
33
CConstFloatHandle label, int labelSize, CFloatHandle lossValue, CFloatHandle lossGradient, CFloatHandle labelLossGradient )
40
34
{
41
35
CheckLayerArchitecture ( labelSize == vectorSize,
42
36
" for float labels the dimensions should be equal to the first input dimensions" );
43
-
44
- int totalSize = batchSize * vectorSize;
45
-
46
37
CheckLayerArchitecture ( vectorSize >= 2 , " CrossEntropyLoss layer works only with multi-class classification" );
47
38
39
+ const int totalSize = batchSize * vectorSize;
48
40
CFloatHandleStackVar activation ( MathEngine (), totalSize );
49
- CFloatHandleStackVar activationEltwiseMul ( MathEngine (), totalSize ) ;
41
+ CFloatHandle activationEltwiseMul = lossGradient. IsNull () ? lossValue : lossGradient ;
50
42
51
43
if ( isSoftmaxApplied ) {
52
44
MathEngine ().MatrixSoftmaxByRows ( data, batchSize, vectorSize, activation );
@@ -83,7 +75,7 @@ void CCrossEntropyLossLayer::BatchCalculateLossAndGradient( int batchSize, CCons
83
75
}
84
76
85
77
// Put 0 for those elements for which the label sum is 0
86
- CFloatHandleStackVar& labelSum = activation;
78
+ CFloatHandle labelSum = activation;
87
79
MathEngine ().SumMatrixColumns ( labelSum, label, batchSize, vectorSize );
88
80
MathEngine ().MultiplyDiagMatrixByMatrix ( labelSum, batchSize, activationEltwiseMul, vectorSize,
89
81
lossGradient, totalSize );
@@ -94,13 +86,11 @@ void CCrossEntropyLossLayer::BatchCalculateLossAndGradient( int batchSize, CCons
94
86
{
95
87
CheckLayerArchitecture ( labelSize == 1 ,
96
88
" for int labels each object in the blob should contain the number of the class" );
97
-
98
- int totalSize = batchSize * vectorSize;
99
-
100
89
CheckLayerArchitecture ( vectorSize >= 2 , " CrossEntropyLoss layer works only with multi-class classification" );
101
90
102
- CFloatHandleStackVar activationMul ( MathEngine (), batchSize ) ;
91
+ const int totalSize = batchSize * vectorSize ;
103
92
CFloatHandleStackVar activation ( MathEngine (), totalSize );
93
+ CFloatHandle activationMul = lossGradient.IsNull () ? lossValue : lossGradient;
104
94
105
95
if ( isSoftmaxApplied ) {
106
96
MathEngine ().MatrixSoftmaxByRows ( data, batchSize, vectorSize, activation );
@@ -115,7 +105,6 @@ void CCrossEntropyLossLayer::BatchCalculateLossAndGradient( int batchSize, CCons
115
105
116
106
MathEngine ().VectorFill ( activationMul, 0 , batchSize );
117
107
MathEngine ().AddMatrixElementsToVector ( activation, batchSize, vectorSize, label, activationMul, batchSize );
118
-
119
108
MathEngine ().VectorNegLog ( activationMul, lossValue, batchSize );
120
109
121
110
if ( lossGradient.IsNull () ) {
@@ -141,18 +130,17 @@ void CCrossEntropyLossLayer::BatchCalculateLossAndGradient( int batchSize, CCons
141
130
MathEngine ().MultiplyDiagMatrixByMatrix ( activationMul, batchSize, activation, vectorSize, lossGradient, totalSize );
142
131
}
143
132
144
- static const int CrossEntropyLossLayerVersion = 2000 ;
133
+ constexpr int crossEntropyLossLayerVersion = 2000 ;
145
134
146
135
void CCrossEntropyLossLayer::Serialize ( CArchive& archive )
147
136
{
148
- archive.SerializeVersion ( CrossEntropyLossLayerVersion , CDnn::ArchiveMinSupportedVersion );
137
+ archive.SerializeVersion ( crossEntropyLossLayerVersion , CDnn::ArchiveMinSupportedVersion );
149
138
CLossLayer::Serialize ( archive );
150
139
151
140
archive.Serialize ( isSoftmaxApplied );
152
141
}
153
142
154
- CLayerWrapper<CCrossEntropyLossLayer> CrossEntropyLoss (
155
- bool isSoftmaxApplied, float lossWeight )
143
+ CLayerWrapper<CCrossEntropyLossLayer> CrossEntropyLoss ( bool isSoftmaxApplied, float lossWeight )
156
144
{
157
145
return CLayerWrapper<CCrossEntropyLossLayer>( " CrossEntropyLoss" , [=]( CCrossEntropyLossLayer* result ) {
158
146
result->SetApplySoftmax ( isSoftmaxApplied );
0 commit comments