Skip to content

Commit baffe3c

Browse files
committed
Modified cost function.
1 parent 846b709 commit baffe3c

File tree

7 files changed

+90
-26
lines changed

7 files changed

+90
-26
lines changed

KRMLP.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "KRMLP"
3-
s.version = "2.2.2"
3+
s.version = "2.2.3"
44
s.summary = "Deep Learning for multi-layer perceptrons neural network (MLP)."
55
s.description = <<-DESC
66
Machine Learning (マシンラーニング) in this project, it implemented multi-layer perceptrons neural network (ニューラルネットワーク) and Back Propagation Neural Network (BPN). It designed unlimited hidden layers to do the training tasks. This network can be used in products recommendation (おすすめの商品), user behavior analysis (ユーザーの行動分析), data mining (データマイニング) and data analysis (データ分析).

ML/KRMLP.m

100644100755
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ - (void)setupNetworkActivation
4343

4444
- (void)setupCostFunction
4545
{
46-
KRMLPCost *cost = self.cost;
47-
cost.patternsCount = self.patternsCount;
48-
cost.outputsCount = self.outputNetsCount;
46+
KRMLPCost *cost = self.cost;
47+
[cost removeRecords];
4948
}
5049

5150
- (void)initializeSettings
@@ -95,8 +94,8 @@ - (void)trainingWithInputs:(NSArray <NSNumber *> *)inputs targets:(NSArray <NSNu
9594

9695
// 多分類的 output layer to hidden layer 跟 hidden layer to hidden layer / input layer 的 delta value (誤差值) 算法都一樣。
9796
// Recording cost value, btw, the delta-values of output-layer-nets are recorded in the output-nets self (net.deltaValue).
98-
KRMLPCost *cost = self.cost;
99-
cost.costValue = [outputLayer calculateCostAndDeltaWithTargets:targets];
97+
[outputLayer calculateDeltasWithTargets:targets];
98+
[self.cost addOutputs:outputLayer.outputs targets:targets];
10099

101100
// Reversing and looping hiddenLayers to start in calculating the delta values from output-layer to hidden layers (that includes hidden layer to hidden layer).
102101
// lastDeltas the initial value is delta-values of output-nets, the delta-value comes from net.deltaValue.
@@ -132,6 +131,7 @@ - (void)trainingWithInputs:(NSArray <NSNumber *> *)inputs targets:(NSArray <NSNu
132131

133132
- (void)iterationTraining
134133
{
134+
[self.cost removeRecords];
135135
self.currentIteration += 1;
136136

137137
// The self.patterns is getter of inputLayer.nets.

ML/Layers/KRMLPOutputLayer/KRMLPCost.h

100644100755
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010

1111
@interface KRMLPCost : NSObject
1212

13-
@property (nonatomic, assign) double costValue; // The (targetValue - outputValue)^2.
14-
@property (nonatomic, assign) NSInteger patternsCount; // Patterns counting number.
15-
@property (nonatomic, assign) NSInteger outputsCount; // Output nets counting number.
16-
@property (nonatomic, readonly) double mse; // The costValue / (patternsCount * outputsCount) / 2.0f
17-
@property (nonatomic, readonly) double rmse; // The costValue / (patternsCount * outputsCount)
13+
@property (nonatomic, readonly) NSInteger patternsCount; // Patterns counting number.
14+
@property (nonatomic, readonly) NSInteger outputsCount; // Output nets counting number.
15+
@property (nonatomic, readonly) double mse; // The costValue / (patternsCount * outputsCount) / 2.0f
16+
@property (nonatomic, readonly) double rmse; // The costValue / (patternsCount * outputsCount)
17+
@property (nonatomic, readonly) double crossEntropy; // Not all situations can use Cross-Entropy to optimize, in some cases the MSE better than it.
1818

1919
- (instancetype)init;
2020

21+
- (void)addOutputs:(NSArray <NSNumber *> *)outputs targets:(NSArray <NSNumber *> *)targets;
22+
- (void)removeRecords;
23+
2124
@end

ML/Layers/KRMLPOutputLayer/KRMLPCost.m

100644100755
Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,19 @@
88

99
#import "KRMLPCost.h"
1010

11+
@interface KRMLPCost ()
12+
13+
@property (nonatomic, readonly) double costValue; // The (targetValue - outputValue)^2.
14+
@property (nonatomic) NSMutableArray <NSArray <NSNumber *> *> *outputs; // The outputs of patterns in this iteration.
15+
@property (nonatomic) NSMutableArray <NSArray <NSNumber *> *> *targets; // The targets of patterns in this iteration.
16+
17+
@end
18+
1119
@implementation KRMLPCost (Checks)
1220

1321
- (BOOL)canCalculate
1422
{
15-
return ( self.patternsCount != 0.0f && self.outputsCount != 0.0f );
23+
return (self.patternsCount != 0 && self.outputsCount != 0);
1624
}
1725

1826
@end
@@ -24,25 +32,82 @@ - (instancetype)init
2432
self = [super init];
2533
if( self )
2634
{
27-
_costValue = 0.0f;
28-
_patternsCount = 0.0f;
29-
_outputsCount = 0.0f;
35+
_outputs = [[NSMutableArray alloc] init];
36+
_targets = [[NSMutableArray alloc] init];
3037
}
3138
return self;
3239
}
3340

41+
- (void)addOutputs:(NSArray<NSNumber *> *)outputs targets:(NSArray<NSNumber *> *)targets
42+
{
43+
[_outputs addObject:[outputs copy]];
44+
[_targets addObject:[targets copy]];
45+
}
46+
47+
- (void)removeRecords
48+
{
49+
[_outputs removeAllObjects];
50+
[_targets removeAllObjects];
51+
}
52+
3453
#pragma mark - Getters
54+
- (double)costValue
55+
{
56+
__block NSArray <NSArray <NSNumber *> *> *targets = _targets;
57+
__block double costValue = 0.0f;
58+
[_outputs enumerateObjectsUsingBlock:^(NSArray<NSNumber *> * _Nonnull patternOutputs, NSUInteger idx, BOOL * _Nonnull stop) {
59+
__block NSArray <NSNumber *> *patternTargets = [targets objectAtIndex:idx];
60+
[patternOutputs enumerateObjectsUsingBlock:^(NSNumber * _Nonnull netOutput, NSUInteger idx, BOOL * _Nonnull stop) {
61+
double outputValue = [netOutput doubleValue];
62+
double targetValue = [[patternTargets objectAtIndex:idx] doubleValue];
63+
double outputError = targetValue - outputValue;
64+
// 計算 MSE, RMSE 共同使用的總和誤差值 : SUM(error^2)
65+
costValue += (outputError * outputError);
66+
}];
67+
}];
68+
return costValue;
69+
}
70+
71+
- (NSInteger)patternsCount
72+
{
73+
return [_outputs count];
74+
}
75+
76+
- (NSInteger)outputsCount
77+
{
78+
return [[_outputs firstObject] count];
79+
}
80+
3581
// e.g. Cost Value = SUM( ( d(j) - y(j) ) ^ 2 ) / ( [patterns count] * [outputNets count] ) * 0.5f
3682
// MSE (均方誤差) = Cost Value / (訓練範例數目 x 數出層神經元數目) / 2
37-
// RMSE (均方根誤差) = sqrt(Cost Value / (訓練範例數目 x 數出層神經元數目) / 2)
83+
// RMSE (均方根誤差) = sqrt(Cost Value / (訓練範例數目 x 數出層神經元數目))
3884
- (double)mse
3985
{
40-
return [self canCalculate] ? _costValue / (_patternsCount * _outputsCount) * 0.5f : NSNotFound;
86+
return [self canCalculate] ? self.costValue / (self.patternsCount * self.outputsCount) * 0.5f : NSNotFound;
4187
}
4288

4389
- (double)rmse
4490
{
45-
return [self canCalculate] ? sqrt(_costValue / (_patternsCount * _outputsCount) * 0.5f) : NSNotFound;
91+
return [self canCalculate] ? sqrt(self.costValue / (self.patternsCount * self.outputsCount)) : NSNotFound;
92+
}
93+
94+
- (double)crossEntropy
95+
{
96+
__block NSArray <NSArray <NSNumber *> *> *targets = _targets;
97+
__block double iterationEntropy = 0.0f;
98+
__block NSInteger outputCount = self.outputsCount;
99+
[_outputs enumerateObjectsUsingBlock:^(NSArray<NSNumber *> * _Nonnull patternOutputs, NSUInteger idx, BOOL * _Nonnull stop) {
100+
__block NSArray <NSNumber *> *patternTargets = [targets objectAtIndex:idx];
101+
__block double patternEntropy = 0.0f;
102+
[patternOutputs enumerateObjectsUsingBlock:^(NSNumber * _Nonnull netOutput, NSUInteger idx, BOOL * _Nonnull stop) {
103+
double outputValue = [netOutput doubleValue];
104+
double targetValue = [[patternTargets objectAtIndex:idx] doubleValue];
105+
double entropy = (targetValue * log(outputValue)) + ((1.0f - targetValue) * log(1.0f - outputValue));
106+
patternEntropy += entropy;
107+
}];
108+
iterationEntropy += -(patternEntropy / outputCount);
109+
}];
110+
return (iterationEntropy / self.patternsCount);
46111
}
47112

48113
@end

ML/Layers/KRMLPOutputLayer/KRMLPOutputLayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
- (void)addNetsFromArray:(NSArray <KRMLPOutputNet *> *)layerNets;
2020
- (NSArray <NSNumber *> *)directOutputsWithInputs:(NSArray <NSNumber *> *)inputs;
2121
- (NSArray <NSNumber *> *)layerOutputsWithInputs:(NSArray <NSNumber *> *)inputs;
22-
- (double)calculateCostAndDeltaWithTargets:(NSArray <NSNumber *> *)targets;
22+
- (void)calculateDeltasWithTargets:(NSArray <NSNumber *> *)targets;
2323
- (void)updateWithHiddenLayerOutputs:(NSArray <NSNumber *> *)layerOutputs learningRate:(double)learningRate;
2424

2525
@end

ML/Layers/KRMLPOutputLayer/KRMLPOutputLayer.m

100644100755
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,23 +71,19 @@ - (void)addNetsFromArray:(NSArray<KRMLPOutputNet *> *)layerNets
7171

7272
// 計算修正 Weights 與 Biases 用的 Delta Values 和當前 Pattern 的 Cost Value (網路輸出誤差值) for Cost Function.
7373
// Returns the cost function value of this pattern.
74-
- (double)calculateCostAndDeltaWithTargets:(NSArray <NSNumber *> *)targets
74+
- (void)calculateDeltasWithTargets:(NSArray <NSNumber *> *)targets
7575
{
7676
__weak typeof(self) weakSelf = self;
77-
__block double costValue = 0.0f;
7877
[_nets enumerateObjectsUsingBlock:^(KRMLPOutputNet * _Nonnull outputNet, NSUInteger idx, BOOL * _Nonnull stop) {
7978
__strong typeof(weakSelf) strongSelf = weakSelf;
8079
double targetValue = [[targets objectAtIndex:idx] doubleValue];
8180
double outputValue = [[strongSelf.outputs objectAtIndex:idx] doubleValue];
8281
double outputError = targetValue - outputValue; // d(j) - y(j) = d(j) - f(net(j))
83-
// 計算 MSE, RMSE 共同使用的總和誤差值 : SUM(error^2)
84-
costValue += ( outputError * outputError );
8582
// a is Partial Derivative simple.
8683
// Delta Value 是由 a(E)/a(wij) = ( d(j) - f(net(j)) ) * -f'(net(j)) = ( d(j) - y(j) ) * -f'( y(j) )
8784
// Output Net(j) 的 Delta 輸出誤差由於後續修正權重公式的關係, 會將負號消去, 故這裡先直接將負號消去: ( d(j) - y(j) ) * f'( y(j) )
8885
outputNet.deltaValue = ( outputError * outputNet.outputPartialDerivative );
8986
}];
90-
return costValue;
9187
}
9288

9389
// Updating the weights and biases with last hidden layer outputs.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Machine Learning (マシンラーニング) in this project, it implemented mult
77

88
```ruby
99
platform :ios, '9.0'
10-
pod "KRMLP", "~> 2.2.2"
10+
pod "KRMLP", "~> 2.2.3"
1111
```
1212

1313
## How to use
@@ -274,7 +274,7 @@ QuickProp:
274274

275275
## Version
276276

277-
V2.2.2
277+
V2.2.3
278278

279279
## License
280280

0 commit comments

Comments
 (0)