10
10
11
11
@interface KRHebbian ()
12
12
13
- // 轉置後的權重矩陣
14
- @property (nonatomic , strong ) NSMutableArray *_transposedWeights;
13
+ @property (nonatomic , assign ) NSInteger iteration;
15
14
16
15
@end
17
16
18
- @interface KRHebbian (fixPrivate)
19
-
20
- -(void )_initWithVars ;
21
-
22
- @end
23
-
24
- @implementation KRHebbian (fixPrivate)
25
-
26
- -(void )_initWithVars
27
- {
28
- self.theta = 0 .0f ;
29
- self.weights = nil ;
30
- self.params = nil ;
31
- deltaWeights = [[NSMutableArray alloc ] initWithCapacity: 0 ];
32
- self._transposedWeights = [NSMutableArray arrayWithCapacity: 0 ];
33
- }
34
-
35
- @end
36
-
37
- @interface KRHebbian (fixMatrixes)
38
-
39
- -(double )sumTransposedMatrix : (NSArray *)_transposedMatrix multiplyMatrix : (NSArray *)_multiplicandMatrix ;
40
- -(NSMutableArray *)weightMatrix : (NSArray *)_weightMatrix plusMatrix : (NSArray *)_plusMatrix theMark : (double )_mark ;
41
- -(NSInteger )sgn : (double )_sgnValue ;
42
-
43
- @end
44
-
45
- @implementation KRHebbian (fixMatrixes)
46
- /*
47
- * @ 累加( 轉置後的矩陣乘以另一個未轉置矩陣 ) ( 直 1 維 x 橫 1 維 )
48
- *
49
- * - 赫賓是 1 維 x 1 維 ( 不需考慮 N 維 )
50
- *
51
- * - 兩個矩陣必須滿足 A 矩陣的行數等於 B 矩陣的列數才可以相乘
52
- *
53
- * - _multiplierMatrix 乘數 ( 轉置後的矩陣 )
54
- *
55
- * @[ @[1], @[2], @[3] ]
56
- *
57
- * - _multiplicandMatrix 被乘數
58
- *
59
- * @[4, 5, 6]
60
- *
61
- */
62
- -(double )sumTransposedMatrix : (NSArray *)_transposedMatrix multiplyMatrix : (NSArray *)_multiplicandMatrix
63
- {
64
- NSUInteger _transposedCount = 1 ; // [_transposedMatrix count];
65
- if ( [[_transposedMatrix objectAtIndex: 0 ] isKindOfClass: [NSArray class ]] )
66
- {
67
- _transposedCount = [[_transposedMatrix objectAtIndex: 0 ] count ];
68
- }
69
- NSUInteger _multiplicandCount = [_multiplicandMatrix count ];
70
- double _sum = 0 .0f ;
71
- // 轉置矩陣的長度
72
- for ( int i=0 ; i<_transposedCount; i++ )
73
- {
74
- // 被乘矩陣的長度
75
- for ( int j=0 ; j<_multiplicandCount; j++ )
76
- {
77
- // NSLog(@"i = %i, j = %i", i, j);
78
- // 避免 Exception for Crash
79
- if ( j > _transposedCount )
80
- {
81
- break ;
82
- }
83
- double _transposedValue = [[[_transposedMatrix objectAtIndex: j] objectAtIndex: i] doubleValue ];
84
- double _multiplicandValue = [[_multiplicandMatrix objectAtIndex: j] doubleValue ];
85
- // NSLog(@"_transposedValue : %f", _transposedValue);
86
- // NSLog(@"_multiplicandValue : %f\n\n", _multiplicandValue);
87
- _sum += _transposedValue * _multiplicandValue;
88
- }
89
- }
90
- return _sum;
91
- }
92
-
93
- /*
94
- * @ 權重矩陣相加(矩陣一, 矩陣二, 標記)
95
- */
96
- -(NSMutableArray *)weightMatrix : (NSArray *)_weightMatrix plusMatrix : (NSArray *)_plusMatrix theMark : (double )_mark
97
- {
98
- NSMutableArray *_sums = [NSMutableArray arrayWithCapacity: 0 ];
99
- NSUInteger _weightCount = [_weightMatrix count ];
100
- if ( _weightCount < [_plusMatrix count ] )
101
- {
102
- // 代表 _weightMatrix 為多維陣列
103
- _weightCount = [[_weightMatrix objectAtIndex: 0 ] count ];
104
- }
105
-
106
- if ( _mark > 0 )
107
- {
108
- for ( int i=0 ; i<_weightCount; i++ )
109
- {
110
- double _weightValue = [[[_weightMatrix objectAtIndex: 0 ] objectAtIndex: i] doubleValue ];
111
- double _matrixValue = [[_plusMatrix objectAtIndex: i] doubleValue ];
112
- [_sums addObject: [NSString stringWithFormat: @" %lf " , ( _weightValue + _matrixValue )]];
113
- }
114
- }
115
-
116
- if ( _mark < 0 )
117
- {
118
- for ( int i=0 ; i<_weightCount; i++ )
119
- {
120
- double _weightValue = [[[_weightMatrix objectAtIndex: 0 ] objectAtIndex: i] doubleValue ];
121
- double _matrixValue = [[_plusMatrix objectAtIndex: i] doubleValue ];
122
- [_sums addObject: [NSString stringWithFormat: @" %lf " , ( _weightValue - _matrixValue )]];
123
- }
124
- }
125
-
126
- return _sums;
127
- }
128
-
17
+ @implementation KRHebbian (fixNets)
129
18
/*
130
19
* @ 求 SGN()
131
20
*/
132
- -(NSInteger )sgn : (double )_sgnValue
21
+ -(NSInteger )_sgn : (double )_sgnValue
133
22
{
134
- return ( _sgnValue >= 0 ) ? 1 : -1 ;
23
+ return ( _sgnValue >= 0 . 0f ) ? 1 : -1 ;
135
24
}
136
25
137
- @end
138
-
139
- @interface KRHebbian (fixNets)
140
-
141
- -(NSInteger )_findFOfNet ;
142
- -(NSMutableArray *)_findNextDeltaWeightsWithFOfNet : (NSInteger )_fOfNet ;
143
-
144
- @end
145
-
146
- @implementation KRHebbian (fixNets)
147
26
/*
148
27
* @ Step 1. 求出 Net
149
28
* @ Step 2. 求出 sgn()
150
29
*
151
30
* @ 回傳 sgn()
152
31
*
153
32
*/
154
- -(NSInteger )_findFOfNet
33
+ -(NSInteger )_fOfNetWithInputs : ( NSArray *) _inputs
155
34
{
156
- // W1 & X1
157
- double _net = [self sumTransposedMatrix: self ._transposedWeights multiplyMatrix: self .params];
158
- // 回傳 sgn() 判定值
159
- return [self sgn: _net];
35
+ double _sum = 0 .0f ;
36
+ NSInteger _index = 0 ;
37
+ for ( NSNumber *_xValue in _inputs )
38
+ {
39
+ _sum += [_xValue floatValue ] * [[self .weights objectAtIndex: _index] floatValue ];
40
+ ++_index;
41
+ }
42
+ return [self _sgn: _sum];
160
43
}
161
44
162
45
/*
163
46
* @ Step 3. 求 delta W (下一節點之權重值)
164
47
*/
165
- -(NSMutableArray *) _findNextDeltaWeightsWithFOfNet : ( NSInteger ) _fOfNet
48
+ -(void ) _turningWeightsByInputs : ( NSArray *) _inputs
166
49
{
167
- double _mark = self.theta * _fOfNet;
168
- // 這裡要用初始的權重矩陣
169
- return [self weightMatrix: self .weights
170
- plusMatrix: self .params
171
- theMark: _mark];
50
+ NSArray *_weights = self.weights ;
51
+ float _learningRate = self.learningRate ;
52
+ float _netOutput = [self _fOfNetWithInputs: _inputs];
53
+ NSMutableArray *_newWeights = [NSMutableArray new ];
54
+ NSInteger _index = 0 ;
55
+ for ( NSNumber *_weightValue in _weights )
56
+ {
57
+ float _deltaWeight = ( _learningRate * _netOutput * [[_inputs objectAtIndex: _index] floatValue ] );
58
+ float _newWeight = [_weightValue floatValue ] + _deltaWeight;
59
+ [_newWeights addObject: [NSNumber numberWithFloat: _newWeight]];
60
+ ++_index;
61
+ }
62
+ [self .weights removeAllObjects ];
63
+ [self .weights addObjectsFromArray: _newWeights];
172
64
}
173
65
174
66
@end
175
67
176
68
@implementation KRHebbian
177
69
178
- @synthesize theta = _theta;
179
- @synthesize weights = _weights;
180
- @synthesize params = _params;
181
- @synthesize deltaWeights = _deltaWeights;
182
-
183
70
+(instancetype )sharedAlgorithm
184
71
{
185
72
static dispatch_once_t pred;
@@ -190,90 +77,76 @@ +(instancetype)sharedAlgorithm
190
77
return _object;
191
78
}
192
79
193
- -(id )init
80
+ -(instancetype )init
194
81
{
195
82
self = [super init ];
196
83
if ( self )
197
84
{
198
- [self _initWithVars ];
85
+ _learningRate = 0 .5f ;
86
+ _weights = [NSMutableArray new ];
87
+ _patterns = [NSMutableArray new ];
88
+
89
+ _iteration = 0 ;
90
+ _maxIteration = 1 ;
199
91
}
200
92
return self;
201
93
}
202
94
203
- #pragma --mark Public Matrix Methods
204
- /*
205
- * @ 轉置矩陣
206
- * - 1. 傳入 1 維陣列
207
- * - 2. 傳入 2 維陣列
208
- * - 3. 傳入 N 維陣列
209
- */
210
- -(NSMutableArray *)transposeMatrix : (NSArray *)_matrix
95
+ #pragma --mark Public Hebbian Algorithm
96
+ -(void )addPatterns : (NSArray *)_inputs
97
+ {
98
+ [_patterns addObject: _inputs];
99
+ }
100
+
101
+ -(void )initializeWeights : (NSArray *)_initWeights
102
+ {
103
+ if ( [_weights count ] > 0 )
104
+ {
105
+ [_weights removeAllObjects ];
106
+ }
107
+ [_weights addObjectsFromArray: _initWeights];
108
+ }
109
+
110
+ -(void )training
211
111
{
212
- /*
213
- * @ 多維陣列要用多個 Array 互包來完成
214
- */
215
- if ( !_matrix ) return nil ;
216
- NSMutableArray *_transposedMatrix = [[NSMutableArray alloc ] initWithCapacity: 0 ];
217
- NSInteger _xCount = [_matrix count ];
218
- NSInteger _yCount = 0 ;
219
- // 如果第 1 個值為陣列
220
- if ( [[_matrix objectAtIndex: 0 ] isKindOfClass: [NSArray class ]] )
112
+ ++_iteration;
113
+ for ( NSArray *_inputs in _patterns )
221
114
{
222
- // 即為 N 維陣列
223
- _xCount = [[_matrix objectAtIndex: 0 ] count ];
224
- _yCount = [_matrix count ];
115
+ [self _turningWeightsByInputs: _inputs];
225
116
}
226
117
227
- // 1 維陣列
228
- if ( _yCount == 0 )
118
+ if ( _iteration >= _maxIteration )
229
119
{
230
- for ( int x= 0 ; x<_xCount; x++ )
120
+ if ( nil != _trainingCompletion )
231
121
{
232
- [_transposedMatrix addObject: [ NSArray arrayWithObject: [_matrix objectAtIndex: x]]] ;
122
+ _trainingCompletion ( YES , _weights, _iteration) ;
233
123
}
234
124
}
235
125
else
236
126
{
237
- for ( int x= 0 ; x<_xCount; x++ )
127
+ if ( nil != _trainingIteraion )
238
128
{
239
- // 轉置,所以 x 總長度為 _yCount
240
- NSMutableArray *_newRows = [NSMutableArray arrayWithCapacity: _yCount];
241
- for ( int y=0 ; y<_yCount; y++ )
242
- {
243
- // NSLog(@"x = %i, y = %i", x, y);
244
- if ( [[_matrix objectAtIndex: y] isKindOfClass: [NSArray class ]] )
245
- {
246
- [_newRows addObject: [[_matrix objectAtIndex: y] objectAtIndex: x]];
247
- }
248
- else
249
- {
250
- [_newRows addObject: [_matrix objectAtIndex: y]];
251
- }
252
- }
253
- [_transposedMatrix addObject: _newRows];
129
+ _trainingIteraion (_iteration, _weights);
254
130
}
131
+ [self training ];
255
132
}
256
- return _transposedMatrix;
257
133
}
258
134
259
- #pragma --mark Public Hebbian Algorithm
260
- /*
261
- * @ 先轉置原始權重矩陣
262
- */
263
- -(void )transposeWeights
135
+ -(void )trainingWithCompletion : (KRHebbianCompletion)_completion
264
136
{
265
- self._transposedWeights = [self transposeMatrix: self .weights];
137
+ _trainingCompletion = _completion;
138
+ [self training ];
266
139
}
267
140
268
- /*
269
- * @ 再執行 Hebbian
270
- * - 求出 f(net) 並轉換成 sgn
271
- */
272
- -(NSMutableArray *)training
141
+ #pragma --mark Block Setters
142
+ -(void )setTrainingCompletion : (KRHebbianCompletion)_block
143
+ {
144
+ _trainingCompletion = _block;
145
+ }
146
+
147
+ -(void )setTrainingIteraion : (KRHebbianIteration)_block
273
148
{
274
- [self transposeWeights ];
275
- self.deltaWeights = [self _findNextDeltaWeightsWithFOfNet: [self _findFOfNet ]];
276
- return _deltaWeights;
149
+ _trainingIteraion = _block;
277
150
}
278
151
279
152
@end
0 commit comments