MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
LtcUnitLayer.cs
1using System;
2using System.Collections.Generic;
3using System.Diagnostics;
4using System.Linq;
5using System.Runtime.InteropServices;
6using System.Text;
7using MyCaffe.basecode;
8using MyCaffe.common;
9using MyCaffe.fillers;
10using MyCaffe.param;
11using MyCaffe.param.lnn;
12
13namespace MyCaffe.layers.lnn
14{
24 public class LtcUnitLayer<T> : LnnUnitLayer<T>
25 {
26 Blob<T> m_blobInputs = null;
27 Blob<T> m_blobMues = null;
28 Blob<T> m_blobX = null;
29 Blob<T> m_blobSensorySigmoidW = null;
30 Blob<T> m_blobSensoryActivationW = null;
31 Blob<T> m_blobSensoryActivationW1 = null;
32 Blob<T> m_blobSensoryActivationRev = null;
33 Blob<T> m_blobSensoryNumeratorW = null;
34 Blob<T> m_blobSensoryDenominatorW = null;
35 Blob<T> m_blobSensoryNumeratorW1 = null;
36 Blob<T> m_blobSensoryDenominatorW1 = null;
37 Blob<T> m_blobTs = null;
38 Blob<T> m_blobCmt = null;
39 Blob<T> m_blobWork = null;
40 Blob<T> m_blobVPre = null;
41 BlobCollection<T> m_colWtsAccum = new BlobCollection<T>();
42 BlobCollection<T> m_colCmt = new BlobCollection<T>();
43 BlobCollection<T> m_colVPre = new BlobCollection<T>();
44 BlobCollection<T> m_colMues = new BlobCollection<T>();
45 BlobCollection<T> m_colSigmoidW = new BlobCollection<T>();
46 BlobCollection<T> m_colActivationW = new BlobCollection<T>();
47 BlobCollection<T> m_colActivationW1 = new BlobCollection<T>();
48 BlobCollection<T> m_colActivationRev = new BlobCollection<T>();
49 BlobCollection<T> m_colNumeratorW = new BlobCollection<T>();
50 BlobCollection<T> m_colDenominatorW = new BlobCollection<T>();
51 BlobCollection<T> m_colNumerator1 = new BlobCollection<T>();
52 BlobCollection<T> m_colNumerator2 = new BlobCollection<T>();
53 BlobCollection<T> m_colNumerator = new BlobCollection<T>();
54 BlobCollection<T> m_colDenominator = new BlobCollection<T>();
55 BlobCollection<T> m_colTop = new BlobCollection<T>();
56 BlobCollection<T> m_colBtm = new BlobCollection<T>();
57 Layer<T> m_sigmoid = null;
58 int[] m_rgShape = new int[] { 1, 1, 1, 1, };
59
63 public enum WEIGHT
64 {
68 GLEAK,
72 VLEAK,
76 CM,
80 SIGMA,
84 MU,
88 W,
92 EREV,
96 SENSORY_SIGMA,
100 SENSORY_MU,
104 SENSORY_W,
108 SENSORY_EREV,
112 INPUT_WT,
116 INPUT_BIAS
117 }
118
119
127 : base(cuda, log, p)
128 {
130
131 int nSensorySize = m_param.ltc_unit_param.input_size;
132 int nStateSize = m_param.ltc_unit_param.hidden_size;
133
134 List<int> rgShape = new List<int>() { nStateSize };
135 addWeight(blobs, m_colWtsAccum, "gleak", rgShape, m_param.ltc_unit_param.gleak_init_min, m_param.ltc_unit_param.gleak_init_max);
136 addWeight(blobs, m_colWtsAccum, "vleak", rgShape, m_param.ltc_unit_param.vleak_init_min, m_param.ltc_unit_param.vleak_init_max);
137 addWeight(blobs, m_colWtsAccum, "cm", rgShape, m_param.ltc_unit_param.cm_init_min, m_param.ltc_unit_param.cm_init_max);
138
139 rgShape.Add(nStateSize);
140 addWeight(blobs, m_colWtsAccum, "sigma", rgShape, m_param.ltc_unit_param.sigma_init_min, m_param.ltc_unit_param.sigma_init_max);
141 addWeight(blobs, m_colWtsAccum, "mu", rgShape, m_param.ltc_unit_param.mu_init_min, m_param.ltc_unit_param.mu_init_max);
142 addWeight(blobs, m_colWtsAccum, "w", rgShape, m_param.ltc_unit_param.w_init_min, m_param.ltc_unit_param.w_init_max);
143 addWeight(blobs, m_colWtsAccum, "erev", rgShape);
144
145 rgShape[0] = nSensorySize;
146 addWeight(blobs, m_colWtsAccum, "sensory_sigma", rgShape, m_param.ltc_unit_param.sensory_sigma_init_min, m_param.ltc_unit_param.sensory_sigma_init_max);
147 addWeight(blobs, m_colWtsAccum, "sensory_mu", rgShape, m_param.ltc_unit_param.sensory_mu_init_min, m_param.ltc_unit_param.sensory_mu_init_max);
148 addWeight(blobs, m_colWtsAccum, "sensory_w", rgShape, m_param.ltc_unit_param.sensory_w_init_min, m_param.ltc_unit_param.sensory_w_init_max);
149 addWeight(blobs, m_colWtsAccum, "sensory_erev", rgShape);
150
151 addWeight(blobs, m_colWtsAccum, "input_w", nSensorySize, 1.0);
152 addWeight(blobs, m_colWtsAccum, "input_b", nSensorySize, 0.0);
153
154 m_blobVPre = new Blob<T>(cuda, log);
155 m_blobVPre.Name = m_param.name + ".vpre";
156 m_blobWork = new Blob<T>(cuda, log);
157 m_blobWork.Name = m_param.name + ".work";
158 m_blobInputs = new Blob<T>(m_cuda, m_log);
159 m_blobInputs.Name = m_param.name + ".inputs";
160 m_blobMues = new Blob<T>(m_cuda, m_log);
161 m_blobMues.Name = m_param.name + ".mues";
162 m_blobX = new Blob<T>(m_cuda, m_log);
163 m_blobX.Name = m_param.name + ".x";
164 m_blobSensorySigmoidW = new Blob<T>(m_cuda, m_log);
165 m_blobSensorySigmoidW.Name = m_param.name + ".sensory_sigmoid_w";
166 m_blobSensoryActivationW = new Blob<T>(m_cuda, m_log);
167 m_blobSensoryActivationW.Name = m_param.name + ".sensory_activation_w";
168 m_blobSensoryActivationW1 = new Blob<T>(m_cuda, m_log);
169 m_blobSensoryActivationW1.Name = m_param.name + ".sensory_activation_w1";
170 m_blobSensoryActivationRev = new Blob<T>(m_cuda, m_log);
171 m_blobSensoryActivationRev.Name = m_param.name + ".sensory_activation_erev";
172 m_blobSensoryNumeratorW = new Blob<T>(m_cuda, m_log);
173 m_blobSensoryNumeratorW.Name = m_param.name + ".sensory_numerator_w";
174 m_blobSensoryDenominatorW = new Blob<T>(m_cuda, m_log);
175 m_blobSensoryDenominatorW.Name = m_param.name + ".sensory_denominator_w";
176 m_blobSensoryNumeratorW1 = new Blob<T>(m_cuda, m_log);
177 m_blobSensoryNumeratorW1.Name = m_param.name + ".sensory_numerator_w1";
178 m_blobSensoryDenominatorW1 = new Blob<T>(m_cuda, m_log);
179 m_blobSensoryDenominatorW1.Name = m_param.name + ".sensory_denominator_w1";
180 m_blobCmt = new Blob<T>(m_cuda, m_log);
181 m_blobCmt.Name = m_param.name + ".cm_t";
182 m_blobTs = new Blob<T>(m_cuda, m_log);
183 m_blobTs.Name = m_param.name + ".ts";
184
185 for (int i=0; i<m_param.ltc_unit_param.ode_unfolds; i++)
186 {
187 m_colVPre.Add(new Blob<T>(cuda, log));
188 m_colVPre[i].Name = m_param.name + ".vpre." + i.ToString();
189 m_colCmt.Add(new Blob<T>(cuda, log));
190 m_colCmt[i].Name = m_param.name + ".cmt." + i.ToString();
191
192 m_colMues.Add(new Blob<T>(cuda, log));
193 m_colMues[i].Name = m_param.name + ".mues." + i.ToString();
194 m_colSigmoidW.Add(new Blob<T>(cuda, log));
195 m_colSigmoidW[i].Name = m_param.name + ".sigmoid_w." + i.ToString();
196 m_colActivationW.Add(new Blob<T>(cuda, log));
197 m_colActivationW[i].Name = m_param.name + ".activation_w." + i.ToString();
198 m_colActivationW1.Add(new Blob<T>(cuda, log));
199 m_colActivationW1[i].Name = m_param.name + ".activation_w1." + i.ToString();
200 m_colActivationRev.Add(new Blob<T>(cuda, log));
201 m_colActivationRev[i].Name = m_param.name + ".activation_rev." + i.ToString();
202 m_colNumeratorW.Add(new Blob<T>(cuda, log));
203 m_colNumeratorW[i].Name = m_param.name + ".numerator_w." + i.ToString();
204 m_colDenominatorW.Add(new Blob<T>(cuda, log));
205 m_colDenominatorW[i].Name = m_param.name + ".denominator_w." + i.ToString();
206 m_colNumerator1.Add(new Blob<T>(cuda, log));
207 m_colNumerator1[i].Name = m_param.name + ".numerator1." + i.ToString();
208 m_colNumerator2.Add(new Blob<T>(cuda, log));
209 m_colNumerator2[i].Name = m_param.name + ".numerator2." + i.ToString();
210 m_colNumerator.Add(new Blob<T>(cuda, log));
211 m_colNumerator[i].Name = m_param.name + ".numerator." + i.ToString();
212 m_colDenominator.Add(new Blob<T>(cuda, log));
213 m_colDenominator[i].Name = m_param.name + ".denominator." + i.ToString();
214 }
215
216 LayerParameter sigmoid_param = new LayerParameter(LayerParameter.LayerType.SIGMOID);
217 sigmoid_param.name = m_param.name + ".sigmoid";
218 sigmoid_param.sigmoid_param.engine = EngineParameter.Engine.CAFFE;
219 m_sigmoid = Layer<T>.Create(cuda, log, sigmoid_param, null);
220 }
221
222 private void addWeight(BlobCollection<T> blobs1, BlobCollection<T> blobsAcc, string strName, List<int> rgShape, float fMin, float fMax)
223 {
224 Blob<T> blob = new Blob<T>(m_cuda, m_log, rgShape);
225 blob.Name = strName;
226
227 Blob<T> blobAcc = new Blob<T>(m_cuda, m_log, rgShape, false);
228 blobAcc.Name = strName + "_acc";
229
230 FillerParameter fp = new FillerParameter("uniform");
231 Filler<T> filler = Filler<T>.Create(m_cuda, m_log, fp);
232 fp.min = fMin;
233 fp.max = fMax;
234
235 filler.Fill(blob);
236
237 blobAcc.SetData(0);
238
239 blobs1.Add(blob);
240 blobsAcc.Add(blobAcc);
241 }
242
243 private void addWeight(BlobCollection<T> blobs1, BlobCollection<T> blobsAcc, string strName, List<int> rgShape)
244 {
245 Blob<T> blob = new Blob<T>(m_cuda, m_log, rgShape);
246 blob.Name = strName;
247
248 Blob<T> blobAcc = new Blob<T>(m_cuda, m_log, rgShape, false);
249 blobAcc.Name = strName + "_acc";
250
251 FillerParameter fp = new FillerParameter("uniform");
252 Filler<T> filler = Filler<T>.Create(m_cuda, m_log, fp);
253 fp.min = -1;
254 fp.max = 1;
255
256 filler.Fill(blob);
257
258 blobAcc.SetData(0);
259
260 blobs1.Add(blob);
261 blobsAcc.Add(blobAcc);
262 }
263
264 private void addWeight(BlobCollection<T> blobs1, BlobCollection<T> blobsAcc, string strName, int nSize, double dfVal)
265 {
266 List<int> rgShape = new List<int>() { nSize };
267
268 Blob<T> blob = new Blob<T>(m_cuda, m_log, rgShape);
269 blob.Name = strName;
270
271 Blob<T> blobAcc = new Blob<T>(m_cuda, m_log, rgShape, false);
272 blobAcc.Name = strName + "_acc";
273
274 FillerParameter fp = new FillerParameter("constant", dfVal);
275 Filler<T> filler = Filler<T>.Create(m_cuda, m_log, fp);
276
277 filler.Fill(blob);
278
279 blobAcc.SetData(0);
280
281 blobs1.Add(blob);
282 blobsAcc.Add(blobAcc);
283 }
284
286 protected override void dispose()
287 {
288 base.dispose();
289
291 dispose_internal_blobs();
292 else
293 clear_inernal_blobs();
294
295 dispose(ref m_colWtsAccum);
296 dispose(ref m_sigmoid);
297 }
298
299 private void dispose_internal_blobs(bool bSetToNull = true)
300 {
301 dispose(ref m_blobVPre);
302 dispose(ref m_blobInputs);
303 dispose(ref m_blobMues);
304 dispose(ref m_blobX);
305 dispose(ref m_blobSensorySigmoidW);
306 dispose(ref m_blobSensoryActivationW);
307 dispose(ref m_blobSensoryActivationW1);
308 dispose(ref m_blobSensoryActivationRev);
309 dispose(ref m_blobSensoryNumeratorW);
310 dispose(ref m_blobSensoryDenominatorW);
311 dispose(ref m_blobSensoryNumeratorW1);
312 dispose(ref m_blobSensoryDenominatorW1);
313 dispose(ref m_blobCmt);
314 dispose(ref m_blobTs);
315 dispose(ref m_blobWork);
316
317 dispose(ref m_colVPre, bSetToNull);
318 dispose(ref m_colCmt, bSetToNull);
319 dispose(ref m_colMues, bSetToNull);
320 dispose(ref m_colSigmoidW, bSetToNull);
321 dispose(ref m_colActivationW, bSetToNull);
322 dispose(ref m_colActivationW1, bSetToNull);
323 dispose(ref m_colActivationRev, bSetToNull);
324 dispose(ref m_colNumeratorW, bSetToNull);
325 dispose(ref m_colDenominatorW, bSetToNull);
326 dispose(ref m_colNumerator, bSetToNull);
327 dispose(ref m_colNumerator1, bSetToNull);
328 dispose(ref m_colNumerator2, bSetToNull);
329 dispose(ref m_colDenominator, bSetToNull);
330 }
331
332 private void clear_inernal_blobs()
333 {
334 m_colVPre.Clear();
335 m_colCmt.Clear();
336 m_colMues.Clear();
337 m_colSigmoidW.Clear();
338 m_colActivationW.Clear();
339 m_colActivationW1.Clear();
340 m_colActivationRev.Clear();
341 m_colNumeratorW.Clear();
342 m_colDenominatorW.Clear();
343 m_colNumerator.Clear();
344 m_colNumerator1.Clear();
345 m_colNumerator2.Clear();
346 m_colDenominator.Clear();
347 }
348
359 public override BlobCollection<T> CreateInternalSharedBlobs(int nIdx, CudaDnn<T> cuda, Log log)
360 {
362
363 dispose_internal_blobs(false);
364
365 Blob<T> blobVPre = new Blob<T>(cuda, log);
366 blobVPre.Name = m_param.name + ".vpre";
367 col.Add(blobVPre);
368
369 Blob<T> blobWork = new Blob<T>(cuda, log);
370 blobWork.Name = m_param.name + ".work";
371 col.Add(blobWork);
372
373 Blob<T> blobInputs = new Blob<T>(m_cuda, m_log);
374 blobInputs.Name = m_param.name + ".inputs";
375 col.Add(blobInputs);
376
377 Blob<T> blobMues = new Blob<T>(m_cuda, m_log);
378 blobMues.Name = m_param.name + ".mues";
379 col.Add(blobMues);
380
381 Blob<T> blobX = new Blob<T>(m_cuda, m_log);
382 blobX.Name = m_param.name + ".x";
383 col.Add(blobX);
384
385 Blob<T> blobSensorySigmoidW = new Blob<T>(m_cuda, m_log);
386 blobSensorySigmoidW.Name = m_param.name + ".sensory_sigmoid_w";
387 col.Add(blobSensorySigmoidW);
388
389 Blob<T> blobSensoryActivationW = new Blob<T>(m_cuda, m_log);
390 blobSensoryActivationW.Name = m_param.name + ".sensory_activation_w";
391 col.Add(blobSensoryActivationW);
392
393 Blob<T> blobSensoryActivationW1 = new Blob<T>(m_cuda, m_log);
394 blobSensoryActivationW1.Name = m_param.name + ".sensory_activation_w1";
395 col.Add(blobSensoryActivationW1);
396
397 Blob<T> blobSensoryActivationRev = new Blob<T>(m_cuda, m_log);
398 blobSensoryActivationRev.Name = m_param.name + ".sensory_activation_erev";
399 col.Add(blobSensoryActivationRev);
400
401 Blob<T> blobSensoryNumeratorW = new Blob<T>(m_cuda, m_log);
402 blobSensoryNumeratorW.Name = m_param.name + ".sensory_numerator_w";
403 col.Add(blobSensoryNumeratorW);
404
405 Blob<T> blobSensoryDenominatorW = new Blob<T>(m_cuda, m_log);
406 blobSensoryDenominatorW.Name = m_param.name + ".sensory_denominator_w";
407 col.Add(blobSensoryDenominatorW);
408
409 Blob<T> blobSensoryNumeratorW1 = new Blob<T>(m_cuda, m_log);
410 blobSensoryNumeratorW1.Name = m_param.name + ".sensory_numerator_w1";
411 col.Add(blobSensoryNumeratorW1);
412
413 Blob<T> blobSensoryDenominatorW1 = new Blob<T>(m_cuda, m_log);
414 blobSensoryDenominatorW1.Name = m_param.name + ".sensory_denominator_w1";
415 col.Add(blobSensoryDenominatorW1);
416
417 Blob<T> blobCmt = new Blob<T>(m_cuda, m_log);
418 blobCmt.Name = m_param.name + ".cm_t";
419 col.Add(blobCmt);
420
421 Blob<T> blobTs = new Blob<T>(m_cuda, m_log);
422 blobTs.Name = m_param.name + ".ts";
423 col.Add(blobTs);
424
425 for (int i = 0; i < m_param.ltc_unit_param.ode_unfolds; i++)
426 {
427 Blob<T> blobVPre_a = new Blob<T>(cuda, log);
428 blobVPre_a.Name = m_param.name + ".vpre." + i.ToString();
429 col.Add(blobVPre_a);
430
431 Blob<T> blobCmt_a = new Blob<T>(cuda, log);
432 blobCmt_a.Name = m_param.name + ".cmt." + i.ToString();
433 col.Add(blobCmt_a);
434
435 Blob<T> blobMues_a = new Blob<T>(cuda, log);
436 blobMues_a.Name = m_param.name + ".mues." + i.ToString();
437 col.Add(blobMues_a);
438
439 Blob<T> blobSigmoidW_a = new Blob<T>(cuda, log);
440 blobSigmoidW_a.Name = m_param.name + ".sigmoid_w." + i.ToString();
441 col.Add(blobSigmoidW_a);
442
443 Blob<T> blobActivationW_a = new Blob<T>(cuda, log);
444 blobActivationW_a.Name = m_param.name + ".activation_w." + i.ToString();
445 col.Add(blobActivationW_a);
446
447 Blob<T> blobActivationW1_a = new Blob<T>(cuda, log);
448 blobActivationW1_a.Name = m_param.name + ".activation_w1." + i.ToString();
449 col.Add(blobActivationW1_a);
450
451 Blob<T> blobActivationRev_a = new Blob<T>(cuda, log);
452 blobActivationRev_a.Name = m_param.name + ".activation_rev." + i.ToString();
453 col.Add(blobActivationRev_a);
454
455 Blob<T> blobNumeratorW_a = new Blob<T>(cuda, log);
456 blobNumeratorW_a.Name = m_param.name + ".numerator_w." + i.ToString();
457 col.Add(blobNumeratorW_a);
458
459 Blob<T> blobDenominatorW_a = new Blob<T>(cuda, log);
460 blobDenominatorW_a.Name = m_param.name + ".denominator_w." + i.ToString();
461 col.Add(blobDenominatorW_a);
462
463 Blob<T> blobNumerator1_a = new Blob<T>(cuda, log);
464 blobNumerator1_a.Name = m_param.name + ".numerator1." + i.ToString();
465 col.Add(blobNumerator1_a);
466
467 Blob<T> blobNumerator2_a = new Blob<T>(cuda, log);
468 blobNumerator2_a.Name = m_param.name + ".numerator2." + i.ToString();
469 col.Add(blobNumerator2_a);
470
471 Blob<T> blobNumerator_a = new Blob<T>(cuda, log);
472 blobNumerator_a.Name = m_param.name + ".numerator." + i.ToString();
473 col.Add(blobNumerator_a);
474
475 Blob<T> blobDenominator_a = new Blob<T>(cuda, log);
476 blobDenominator_a.Name = m_param.name + ".denominator." + i.ToString();
477 col.Add(blobDenominator_a);
478 }
479
480 return col;
481 }
482
488 {
489 int nIdx = 0;
490
491 m_bOwnInternalBlobs = false;
492
493 m_blobVPre = col[nIdx];
494 nIdx++;
495
496 m_blobWork = col[nIdx];
497 nIdx++;
498
499 m_blobInputs = col[nIdx];
500 nIdx++;
501
502 m_blobMues = col[nIdx];
503 nIdx++;
504
505 m_blobX = col[nIdx];
506 nIdx++;
507
508 m_blobSensorySigmoidW = col[nIdx];
509 nIdx++;
510
511 m_blobSensoryActivationW = col[nIdx];
512 nIdx++;
513
514 m_blobSensoryActivationW1 = col[nIdx];
515 nIdx++;
516
517 m_blobSensoryActivationRev = col[nIdx];
518 nIdx++;
519
520 m_blobSensoryNumeratorW = col[nIdx];
521 nIdx++;
522
523 m_blobSensoryDenominatorW = col[nIdx];
524 nIdx++;
525
526 m_blobSensoryNumeratorW1 = col[nIdx];
527 nIdx++;
528
529 m_blobSensoryDenominatorW1 = col[nIdx];
530 nIdx++;
531
532 m_blobCmt = col[nIdx];
533 nIdx++;
534
535 m_blobTs = col[nIdx];
536 nIdx++;
537
538 m_colVPre.Clear();
539 m_colCmt.Clear();
540 m_colMues.Clear();
541 m_colSigmoidW.Clear();
542 m_colActivationW.Clear();
543 m_colActivationW1.Clear();
544 m_colActivationRev.Clear();
545 m_colNumeratorW.Clear();
546 m_colDenominatorW.Clear();
547 m_colNumerator1.Clear();
548 m_colNumerator2.Clear();
549 m_colNumerator.Clear();
550 m_colDenominator.Clear();
551
552 for (int i = 0; i < m_param.ltc_unit_param.ode_unfolds; i++)
553 {
554 m_colVPre.Add(col[nIdx]);
555 nIdx++;
556
557 m_colCmt.Add(col[nIdx]);
558 nIdx++;
559
560 m_colMues.Add(col[nIdx]);
561 nIdx++;
562
563 m_colSigmoidW.Add(col[nIdx]);
564 nIdx++;
565
566 m_colActivationW.Add(col[nIdx]);
567 nIdx++;
568
569 m_colActivationW1.Add(col[nIdx]);
570 nIdx++;
571
572 m_colActivationRev.Add(col[nIdx]);
573 nIdx++;
574
575 m_colNumeratorW.Add(col[nIdx]);
576 nIdx++;
577
578 m_colDenominatorW.Add(col[nIdx]);
579 nIdx++;
580
581 m_colNumerator1.Add(col[nIdx]);
582 nIdx++;
583
584 m_colNumerator2.Add(col[nIdx]);
585 nIdx++;
586
587 m_colNumerator.Add(col[nIdx]);
588 nIdx++;
589
590 m_colDenominator.Add(col[nIdx]);
591 nIdx++;
592 }
593 }
594
595 private void addBtmTop(Blob<T> btm, Blob<T> top)
596 {
597 m_colBtm.Clear();
598 m_colBtm.Add(btm);
599 m_colTop.Clear();
600 m_colTop.Add(top);
601 }
602
604 protected override void setup_internal_blobs(BlobCollection<T> col)
605 {
606 if (col.Count > 0)
607 return;
608 }
609
613 public override int ExactNumBottomBlobs
614 {
615 get { return 3; }
616 }
617
621 public override int ExactNumTopBlobs
622 {
623 get { return 1; }
624 }
625
631 public override bool ReInitializeParameters(WEIGHT_TARGET target)
632 {
633 base.ReInitializeParameters(target);
634 return true;
635 }
636
642 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
643 {
644 addBtmTop(m_blobInputs, m_blobSensoryActivationW);
645 m_sigmoid.Setup(m_colBtm, m_colTop);
646 }
647
653 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
654 {
655 m_blobInputs.ReshapeLike(colBottom[0]);
656 m_blobMues.Reshape(colBottom[0].num, colBottom[0].channels, m_param.ltc_unit_param.hidden_size, 1);
657 m_colMues.Reshape(colBottom[0].num, colBottom[0].channels, m_param.ltc_unit_param.hidden_size, 1);
658 m_blobX.Reshape(colBottom[0].num, colBottom[0].channels, m_param.ltc_unit_param.hidden_size, 1);
659
660 m_blobVPre.ReshapeLike(colBottom[1]);
661
662 m_rgShape[0] = m_blobInputs.num;
663 m_rgShape[1] = m_blobInputs.channels;
664 m_rgShape[2] = m_param.ltc_unit_param.hidden_size;
665 m_blobSensorySigmoidW.Reshape(m_rgShape);
666 m_blobSensoryActivationW.Reshape(m_rgShape);
667 m_blobSensoryActivationW1.Reshape(m_rgShape);
668 m_blobSensoryActivationRev.Reshape(m_rgShape);
669
670 m_rgShape[0] = m_blobSensoryActivationW.num;
671 m_rgShape[1] = m_blobSensoryActivationW.height;
672 m_rgShape[2] = m_blobSensoryActivationW.width;
673 m_blobSensoryNumeratorW.Reshape(m_rgShape);
674 m_blobSensoryDenominatorW.Reshape(m_rgShape);
675 m_blobSensoryNumeratorW1.Reshape(m_rgShape);
676 m_blobSensoryDenominatorW1.Reshape(m_rgShape);
677 m_blobCmt.Reshape(m_rgShape);
678 m_blobTs.ReshapeLike(colBottom[2]);
679
680 m_rgShape[1] = m_param.ltc_unit_param.hidden_size;
681 m_rgShape[2] = m_param.ltc_unit_param.hidden_size;
682 m_colSigmoidW.Reshape(m_rgShape);
683 m_colActivationW.Reshape(m_rgShape);
684 m_colActivationW1.Reshape(m_rgShape);
685 m_colActivationRev.Reshape(m_rgShape);
686
687 m_rgShape[2] = 1;
688 m_colNumeratorW.Reshape(m_rgShape);
689 m_colDenominatorW.Reshape(m_rgShape);
690 m_colNumerator.Reshape(m_rgShape);
691 m_colNumerator1.Reshape(m_rgShape);
692 m_colDenominator.Reshape(m_rgShape);
693
694 m_rgShape[0] = m_param.ltc_unit_param.hidden_size;
695 m_rgShape[1] = 1;
696 m_colNumerator2.Reshape(m_rgShape);
697
698 m_colCmt.ReshapeLike(m_blobCmt);
699 m_colVPre.ReshapeLike(m_blobVPre);
700
701 colTop[0].ReshapeLike(m_blobVPre);
702 }
703
717 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
718 {
719 map_inputs_fwd(colBottom[0], m_blobInputs);
720
721 addBtmTop(m_blobInputs, colTop[0]);
722 m_colBtm.Add(colBottom[1]);
723 m_colBtm.Add(colBottom[2]);
724 ode_solver_fwd(m_colBtm, m_colTop);
725 }
726
743 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
744 {
745 addBtmTop(m_blobInputs, colTop[0]);
746 m_colBtm.Add(colBottom[1]);
747 m_colBtm.Add(colBottom[2]);
748 ode_solver_bwd(m_colBtm, m_colTop);
749
750 map_inputs_bwd(colBottom[0], m_blobInputs);
751 }
752
753 private void op_fwd(OP op, Blob<T> btm1, Blob<T> btm2, Blob<T> top, int nC = 0, int nN1 = 0, int nSD1 = 0, int nN2 = 0, int nSD2 = 0)
754 {
755 if (nC == 0)
756 nC = btm1.channels;
757
758 if (nN1 == 0)
759 nN1 = btm1.num;
760
761 if (nSD1 == 0)
762 nSD1 = (btm1.num_axes < 2) ? 1 : btm1.count(2);
763
764 if (nN2 == 0)
765 nN2 = (btm2.num_axes == 1) ? 1 : btm2.num;
766
767 if (nSD2 == 0)
768 nSD2 = (btm2.num_axes < 2) ? 1 : btm2.count(2);
769
770 int nN = Math.Max(nN1, nN2);
771 int nSD = Math.Max(nSD1, nSD2);
772 int nCount = nN * nC * nSD;
773
774 if (nCount != top.count())
775 top.Reshape(nN, nC, nSD, 1);
776
777 m_cuda.channel_op_fwd(op, top.count(), nC, nN1, nSD1, nN2, nSD2, btm1.gpu_data, btm2.gpu_data, top.mutable_gpu_data);
778 }
779
780 private void op_bwd_local(OP op, Blob<T> btm1, Blob<T> btm2, Blob<T> top, int nC = 0, int nN1 = 0, int nSD1 = 0, int nN2 = 0, int nSD2 = 0)
781 {
782 if (nC == 0)
783 nC = btm1.channels;
784
785 if (nN1 == 0)
786 nN1 = btm1.num;
787
788 if (nSD1 == 0)
789 nSD1 = (btm1.num_axes < 2) ? 1 : btm1.count(2);
790
791 if (nN2 == 0)
792 nN2 = (btm2.num_axes == 1) ? 1 : btm2.num;
793
794 if (nSD2 == 0)
795 nSD2 = (btm2.num_axes < 2) ? 1 : btm2.count(2);
796
797 int nN = Math.Max(nN1, nN2);
798 int nSD = Math.Max(nSD1, nSD2);
799 int nCount = nN * nC * nSD;
800
801 if (nCount != top.count())
802 top.Reshape(nN, nC, nSD, 1);
803
804 if (nCount != m_blobWork.count())
805 m_blobWork.ReshapeLike(top);
806
807 //m_cuda.channel_op_bwd(op, top.count(), nC, nN1, nSD1, nN2, nSD2, btm1.gpu_data, btm2.gpu_data, top.gpu_data, btm1.mutable_gpu_diff, btm2.mutable_gpu_diff, top.gpu_diff, m_blobWork.mutable_gpu_data);
808
809 // Gradient for btm1
810 if (top.gpu_diff != btm1.gpu_diff)
811 {
812 m_blobWork.SetDiff(0);
813 if (op == OP.MUL || op == OP.DIV)
814 {
815 if (top.count() == btm1.count())
816 m_cuda.channel_op_fwd(op, nCount, nC, nN1, nSD1, nN2, nSD2, top.gpu_diff, btm2.gpu_data, btm1.mutable_gpu_diff);
817 else
818 m_cuda.channel_op_fwd(op, nCount, nC, nN1, nSD1, nN2, nSD2, top.gpu_diff, btm2.gpu_data, m_blobWork.mutable_gpu_diff);
819 }
820 else
821 {
822 if (top.count() == btm1.count())
823 btm1.CopyFrom(top, true);
824 else
825 m_blobWork.CopyFrom(top, true);
826 }
827
828 if (nSD1 < nSD2)
829 {
830 int nNa = nN1 * nC * nSD1;
831 int nCa = nSD2 / nSD1;
832 int nSDa = 1;
833 m_cuda.channel_sum(nCount, nNa, nCa, nSDa, m_blobWork.gpu_diff, btm1.mutable_gpu_diff, true);
834 }
835 else if (nN1 < nN2)
836 {
837 int nNa = nN1;
838 int nCa = nN2 / nN1;
839 int nSDa = nC * nSD1;
840 m_cuda.channel_sum(nCount, nNa, nCa, nSDa, m_blobWork.gpu_diff, btm1.mutable_gpu_diff, true);
841 }
842 }
843
844 // Gradient for btm2
845 if (top.gpu_diff != btm2.gpu_diff)
846 {
847 m_blobWork.SetDiff(0);
848 if (op == OP.DIV)
849 {
850 m_cuda.powx(btm2.count(), btm2.gpu_data, 2.0, btm2.mutable_gpu_diff);
851 m_cuda.channel_op_fwd(op, nCount, nC, nN1, nSD1, nN2, nSD2, btm1.gpu_data, btm2.gpu_diff, m_blobWork.mutable_gpu_diff);
852 m_blobWork.scale_diff(-1);
853
854 int nCc = m_blobWork.channels;
855 int nNc = m_blobWork.num;
856 int nSDc = top.count(2);
857
858 if (top.count() == btm2.count())
859 m_cuda.channel_op_fwd(OP.MUL, nCount, nCc, nNc, nSDc, nNc, nSDc, m_blobWork.gpu_diff, top.gpu_diff, btm2.mutable_gpu_diff);
860 else
861 m_cuda.channel_op_fwd(OP.MUL, nCount, nCc, nNc, nSDc, nNc, nSDc, m_blobWork.gpu_diff, top.gpu_diff, m_blobWork.mutable_gpu_diff);
862 }
863 else if (op == OP.MUL)
864 {
865 if (top.count() == btm2.count())
866 m_cuda.channel_op_fwd(op, nCount, nC, nN1, nSD1, nN2, nSD2, top.gpu_diff, btm1.gpu_data, btm2.mutable_gpu_diff);
867 else
868 m_cuda.channel_op_fwd(op, nCount, nC, nN1, nSD1, nN1, nSD2, top.gpu_diff, btm1.gpu_data, m_blobWork.mutable_gpu_diff);
869 }
870 else if (op == OP.SUB)
871 {
872 if (top.count() == btm1.count())
873 m_cuda.scale(top.count(), -1, top.gpu_diff, btm2.mutable_gpu_diff);
874 else
875 m_cuda.scale(top.count(), -1, top.gpu_diff, m_blobWork.mutable_gpu_diff);
876 }
877 else
878 {
879 if (top.count() == btm2.count())
880 btm2.CopyFrom(top, true);
881 else
882 m_blobWork.CopyFrom(top, true);
883 }
884
885 if (nSD2 < nSD1)
886 {
887 int nNb = Math.Max(nN1, nN2);
888 int nCb = nSD1 / nSD2;
889 int nSDb = 1;
890 m_cuda.channel_sum(nCount, nNb, nCb, nSDb, m_blobWork.gpu_diff, btm2.mutable_gpu_diff, true);
891 }
892 else if (nN2 < nN1)
893 {
894 int nNb = nN2;
895 int nCb = nN1 / nN2;
896 int nSDb = nC * nSD2;
897 m_cuda.channel_sum(nCount, nNb, nCb, nSDb, m_blobWork.gpu_diff, btm2.mutable_gpu_diff, true);
898 }
899 }
900 }
901
902 private void op_bwd(OP op, Blob<T> btm1, Blob<T> btm2, Blob<T> top, int nC = 0, int nN1 = 0, int nSD1 = 0, int nN2 = 0, int nSD2 = 0, int nCy = 0, int nSDy = 0)
903 {
904 if (nC == 0)
905 nC = btm1.channels;
906
907 if (nN1 == 0)
908 nN1 = btm1.num;
909
910 if (nSD1 == 0)
911 nSD1 = (btm1.num_axes < 2) ? 1 : btm1.count(2);
912
913 if (nN2 == 0)
914 nN2 = (btm2.num_axes == 1) ? 1 : btm2.num;
915
916 if (nSD2 == 0)
917 nSD2 = (btm2.num_axes < 2) ? 1 : btm2.count(2);
918
919 if (nCy == 0)
920 nCy = top.channels;
921
922 if (nSDy == 0)
923 nSDy = top.count(2);
924
925 int nN = Math.Max(nN1, nN2);
926 int nSD = Math.Max(nSD1, nSD2);
927 int nCount = nN * nC * nSD;
928
929 if (nCount != top.count())
930 top.Reshape(nN, nC, nSD, 1);
931
932 if (nCount != m_blobWork.count())
933 m_blobWork.ReshapeLike(top);
934
935 m_cuda.channel_op_bwd(op, top.count(), nC, nN1, nSD1, nN2, nSD2, nCy, nSDy, btm1.gpu_data, btm2.gpu_data, top.gpu_data, btm1.mutable_gpu_diff, btm2.mutable_gpu_diff, top.gpu_diff, m_blobWork.mutable_gpu_data);
936 }
937
938 private void sigmoid_fwd(BlobCollection<T> colBtm, BlobCollection<T> colTop, int t = -1)
939 {
940 Blob<T> blobPre = colBtm[0];
941 Blob<T> blobMu = colBtm[1];
942 Blob<T> blobSigma = colBtm[2];
943 Blob<T> blobTop = colTop[0];
944 Blob<T> blobMues = m_blobMues;
945
946 if (t >= 0)
947 blobMues = m_colMues[t];
948
949 op_fwd(OP.SUB, blobPre, blobMu, blobMues, blobPre.channels, blobPre.num, blobPre.count(2), 1, blobMu.channels);
950 op_fwd(OP.MUL, blobMues, blobSigma, m_blobX, blobMues.channels, blobMues.num, blobMues.count(2), 1, blobSigma.channels);
951
952 addBtmTop(m_blobX, blobTop);
953 m_sigmoid.Forward(m_colBtm, m_colTop);
954 }
955
956 private void sigmoid_bwd(BlobCollection<T> colBtm, BlobCollection<T> colTop, int t = -1)
957 {
958 Blob<T> blobPre = colBtm[0];
959 Blob<T> blobMu = colBtm[1];
960 Blob<T> blobSigma = colBtm[2];
961 Blob<T> blobTop = colTop[0];
962 Blob<T> blobMues = m_blobMues;
963
964 if (t >= 0)
965 blobMues = m_colMues[t];
966
967 addBtmTop(m_blobX, blobTop);
968 m_sigmoid.Backward(m_colTop, new List<bool>() { true }, m_colBtm);
969
970 op_bwd_local(OP.MUL, blobMues, blobSigma, m_blobX, blobMues.channels, blobMues.num, blobMues.count(2), 1, blobSigma.channels);
971 op_bwd_local(OP.SUB, blobPre, blobMu, blobMues, blobPre.channels, blobPre.num, blobPre.count(2), 1, blobMu.channels);
972 }
973
974
975 private void map_inputs_fwd(Blob<T> btm, Blob<T> top)
976 {
977 op_fwd(OP.MUL, btm, blobs[(int)WEIGHT.INPUT_WT], top);
978 op_fwd(OP.ADD, top, blobs[(int)WEIGHT.INPUT_BIAS], top);
979 }
980
981 private void map_inputs_bwd(Blob<T> btm, Blob<T> top)
982 {
983 op_bwd(OP.ADD, top, blobs[(int)WEIGHT.INPUT_BIAS], top);
984 op_bwd(OP.MUL, btm, blobs[(int)WEIGHT.INPUT_WT], top);
985 }
986
987 private void ode_solver_fwd(BlobCollection<T> colBtm, BlobCollection<T> colTop)
988 {
989 Blob<T> blobInputs = colBtm[0];
990 Blob<T> blobVPre = colBtm[1];
991 Blob<T> blobTs = colBtm[2];
992 Blob<T> blobTop = colTop[0];
993 int nN = blobInputs.num;
994 int nC = blobInputs.channels;
996
997 int nCount = blobInputs.count();
998
999 m_blobVPre.CopyFrom(blobVPre);
1000
1001 // Pre-compute the effect of the sensory inputs.
1002 addBtmTop(blobInputs, m_blobSensorySigmoidW);
1003 m_colBtm.Add(blobs[(int)WEIGHT.SENSORY_MU]);
1004 m_colBtm.Add(blobs[(int)WEIGHT.SENSORY_SIGMA]);
1005 sigmoid_fwd(m_colBtm, m_colTop);
1006
1007 op_fwd(OP.MUL, m_blobSensorySigmoidW, blobs[(int)WEIGHT.SENSORY_W], m_blobSensoryActivationW, nC, nN, nSD, 1, nSD);
1008 op_fwd(OP.MUL, m_blobSensoryActivationW, blobs[(int)WEIGHT.SENSORY_EREV], m_blobSensoryActivationRev, nC, nN, nSD, 1, nSD);
1009
1010 // Reduce over dim=1 (source sensory neurons)
1011 m_cuda.channel_sum(nCount, m_blobSensoryActivationRev.num, m_blobSensoryActivationRev.channels, m_blobSensoryActivationRev.count(2), m_blobSensoryActivationRev.gpu_data, m_blobSensoryNumeratorW.mutable_gpu_data, true);
1012 m_cuda.channel_sum(nCount, m_blobSensoryActivationW.num, m_blobSensoryActivationW.channels, m_blobSensoryActivationW.count(2), m_blobSensoryActivationW.gpu_data, m_blobSensoryDenominatorW.mutable_gpu_data, true);
1013
1014 // cm/t is loop invariant, so we can compute it once here.
1015 m_blobTs.CopyFrom(blobTs);
1016 m_blobTs.add_scalar(1.0);
1018 op_fwd(OP.DIV, blobs[(int)WEIGHT.CM], m_blobTs, m_blobCmt, 1, 1, nSD, nN, 1);
1019
1020 // Unfold the multi-step ODE solver into one RNN step.
1021 for (int t = 0; t < m_param.ltc_unit_param.ode_unfolds; t++)
1022 {
1023 m_colVPre[t].CopyFrom(m_blobVPre);
1024 m_colCmt[t].CopyFrom(m_blobCmt);
1025
1026 // Compute the W activation
1027 addBtmTop(m_colVPre[t], m_colSigmoidW[t]);
1028 m_colBtm.Add(blobs[(int)WEIGHT.MU]);
1029 m_colBtm.Add(blobs[(int)WEIGHT.SIGMA]);
1030 sigmoid_fwd(m_colBtm, m_colTop, t);
1031 op_fwd(OP.MUL, m_colSigmoidW[t], blobs[(int)WEIGHT.W], m_colActivationW[t], nSD, nN, nSD, 1, nSD);
1032
1033 // Compute the Rev activation
1034 op_fwd(OP.MUL, m_colActivationW[t], blobs[(int)WEIGHT.EREV], m_colActivationRev[t], nSD, nN, nSD, 1, nSD);
1035
1036 // Reduce over dim=1 (source neurons)
1037 m_cuda.channel_sum(nCount, m_colActivationRev[t].num, m_colActivationRev[t].channels, m_colActivationRev[t].count(2), m_colActivationRev[t].gpu_data, m_colNumeratorW[t].mutable_gpu_data, true);
1038 m_cuda.channel_sum(nCount, m_colActivationW[t].num, m_colActivationW[t].channels, m_colActivationW[t].count(2), m_colActivationW[t].gpu_data, m_colDenominatorW[t].mutable_gpu_data, true);
1039 // Add sensory input
1040 op_fwd(OP.ADD, m_colNumeratorW[t], m_blobSensoryNumeratorW, m_colNumeratorW[t]);
1041 op_fwd(OP.ADD, m_colDenominatorW[t], m_blobSensoryDenominatorW, m_colDenominatorW[t]);
1042
1043 // Compute the numerator
1044 op_fwd(OP.MUL, m_colCmt[t], m_colVPre[t], m_colNumerator1[t]);
1045 op_fwd(OP.MUL, blobs[(int)WEIGHT.GLEAK], blobs[(int)WEIGHT.VLEAK], m_colNumerator2[t], nSD, 1, 1, 1, 1);
1046 op_fwd(OP.ADD, m_colNumerator1[t], m_colNumerator2[t], m_colNumerator[t], nSD, nN, 1, 1, 1);
1047 op_fwd(OP.ADD, m_colNumerator[t], m_colNumeratorW[t], m_colNumerator[t]);
1048
1049 // Compute the denominator
1050 op_fwd(OP.ADD, m_colCmt[t], blobs[(int)WEIGHT.GLEAK], m_colDenominator[t], nSD, nN, 1, 1, 1);
1051 op_fwd(OP.ADD, m_colDenominator[t], m_colDenominatorW[t], m_colDenominator[t]);
1052 m_colDenominator[t].add_scalar(m_param.ltc_unit_param.epsilon);
1053
1054 // Compute the output
1055 op_fwd(OP.DIV, m_colNumerator[t], m_colDenominator[t], m_blobVPre);
1056 }
1057
1058 blobTop.CopyFrom(m_blobVPre);
1059 }
1060
1061 private void accumulateGrad(BlobCollection<T> src, BlobCollection<T> dst, WEIGHT wt)
1062 {
1063 m_cuda.add(dst[(int)wt].count(), src[(int)wt].gpu_diff, dst[(int)wt].gpu_data, dst[(int)wt].mutable_gpu_data);
1064 }
1065
1066 private void copyGrad(BlobCollection<T> src, BlobCollection<T> dst, WEIGHT wt)
1067 {
1068 m_cuda.copy(dst[(int)wt].count(), src[(int)wt].gpu_data, dst[(int)wt].mutable_gpu_diff);
1069 }
1070
1071 private void ode_solver_bwd(BlobCollection<T> colBtm, BlobCollection<T> colTop)
1072 {
1073 Blob<T> blobInputs = colBtm[0];
1074 Blob<T> blobVPre = colBtm[1];
1075 Blob<T> blobTs = colBtm[2];
1076 Blob<T> blobTop = colTop[0];
1077 int nN = blobInputs.num;
1078 int nC = blobInputs.channels;
1080
1081 int nCount = blobInputs.count();
1082
1083 m_blobCmt.SetDiff(0);
1084
1085 foreach (Blob<T> blob in m_colWtsAccum)
1086 {
1087 blob.SetDiff(0);
1088 }
1089
1090 // Unfold the multi-step ODE solver into one RNN step.
1091 for (int t = m_param.ltc_unit_param.ode_unfolds-1; t >= 0; t--)
1092 {
1093 // Compute the output
1094 if (t == m_param.ltc_unit_param.ode_unfolds - 1)
1095 op_bwd_local(OP.DIV, m_colNumerator[t], m_colDenominator[t], colTop[0]);
1096 else
1097 op_bwd_local(OP.DIV, m_colNumerator[t], m_colDenominator[t], m_blobVPre);
1098
1099 m_blobVPre.SetDiff(0);
1100
1101 // Compute the denominator
1102 op_bwd(OP.ADD, m_colDenominator[t], m_colDenominatorW[t], m_colDenominator[t]);
1103 op_bwd(OP.ADD, m_colCmt[t], blobs[(int)WEIGHT.GLEAK], m_colDenominator[t], nSD, nN, 1, 1, 1);
1104 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.GLEAK);
1105 m_cuda.add(m_blobCmt.count(), m_colCmt[t].gpu_diff, m_blobCmt.gpu_diff, m_blobCmt.mutable_gpu_diff);
1106
1107 // Compute the numerator
1108 op_bwd(OP.ADD, m_colNumerator[t], m_colNumeratorW[t], m_colNumerator[t]);
1109 op_bwd(OP.ADD, m_colNumerator1[t], m_colNumerator2[t], m_colNumerator[t], nSD, nN, 1, 1, 1);
1110 op_bwd(OP.MUL, blobs[(int)WEIGHT.GLEAK], blobs[(int)WEIGHT.VLEAK], m_colNumerator2[t], nSD, 1, 1, 1, 1);
1111 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.GLEAK);
1112 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.VLEAK);
1113
1114 op_bwd(OP.MUL, m_colCmt[t], m_colVPre[t], m_colNumerator1[t]);
1115 m_cuda.add(m_blobCmt.count(), m_colCmt[t].gpu_diff, m_blobCmt.gpu_diff, m_blobCmt.mutable_gpu_diff);
1116 m_cuda.add(m_blobVPre.count(), m_colVPre[t].gpu_diff, m_blobVPre.gpu_diff, m_blobVPre.mutable_gpu_diff);
1117
1118 // Add sensory input
1119 op_bwd(OP.ADD, m_colDenominatorW[t], m_blobSensoryDenominatorW1, m_colDenominatorW[t]);
1120 m_cuda.add(m_blobSensoryDenominatorW.count(), m_blobSensoryDenominatorW1.gpu_diff, m_blobSensoryDenominatorW.gpu_diff, m_blobSensoryDenominatorW.mutable_gpu_diff);
1121 op_bwd(OP.ADD, m_colNumeratorW[t], m_blobSensoryNumeratorW1, m_colNumeratorW[t]);
1122 m_cuda.add(m_blobSensoryNumeratorW.count(), m_blobSensoryNumeratorW1.gpu_diff, m_blobSensoryNumeratorW.gpu_diff, m_blobSensoryNumeratorW.mutable_gpu_diff);
1123
1124 // Reduce over dim=1 (source neurons)
1125 m_cuda.channel_sum(m_colActivationRev[t].count(), m_colActivationRev[t].num, m_colActivationRev[t].channels, m_colActivationRev[t].count(2), m_colActivationRev[t].mutable_gpu_diff, m_colNumeratorW[t].gpu_diff, true, DIR.BWD);
1126 m_cuda.channel_sum(m_colActivationW1[t].count(), m_colActivationW1[t].num, m_colActivationW1[t].channels, m_colActivationW1[t].count(2), m_colActivationW1[t].mutable_gpu_diff, m_colDenominatorW[t].gpu_diff, true, DIR.BWD);
1127
1128 // Compute the Rev activation
1129 op_bwd_local(OP.MUL, m_colActivationW[t], blobs[(int)WEIGHT.EREV], m_colActivationRev[t], nSD, nN, nSD, 1, nSD);
1130 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.EREV);
1131 // Accumulate the gradient
1132 m_cuda.add(m_colActivationW[t].count(), m_colActivationW1[t].gpu_diff, m_colActivationW[t].gpu_diff, m_colActivationW1[t].mutable_gpu_diff);
1133
1134 // Compute the W activation
1135 op_bwd_local(OP.MUL, m_colSigmoidW[t], blobs[(int)WEIGHT.W], m_colActivationW1[t], nSD, nN, nSD, 1, nSD);
1136 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.W);
1137
1138 addBtmTop(m_colVPre[t], m_colSigmoidW[t]);
1139 m_colBtm.Add(blobs[(int)WEIGHT.MU]);
1140 m_colBtm.Add(blobs[(int)WEIGHT.SIGMA]);
1141 sigmoid_bwd(m_colBtm, m_colTop, t);
1142
1143 m_cuda.add(m_blobVPre.count(), m_colVPre[t].gpu_diff, m_blobVPre.gpu_diff, m_blobVPre.mutable_gpu_diff);
1144 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.MU);
1145 accumulateGrad(blobs, m_colWtsAccum, WEIGHT.SIGMA);
1146 }
1147
1148 copyGrad(m_colWtsAccum, blobs, WEIGHT.GLEAK);
1149 copyGrad(m_colWtsAccum, blobs, WEIGHT.VLEAK);
1150 copyGrad(m_colWtsAccum, blobs, WEIGHT.EREV);
1151 copyGrad(m_colWtsAccum, blobs, WEIGHT.W);
1152 copyGrad(m_colWtsAccum, blobs, WEIGHT.MU);
1153 copyGrad(m_colWtsAccum, blobs, WEIGHT.SIGMA);
1154
1155 m_cuda.debug();
1156 // cm/t is loop invariant, so we can compute it once here.
1157 op_bwd(OP.DIV, blobs[(int)WEIGHT.CM], m_blobTs, m_blobCmt, 1, 1, nSD, nN, 1, m_blobCmt.channels, m_blobCmt.count(2));
1159 blobTs.CopyFrom(m_blobTs, true);
1160
1161 // Reduce over dim=1 (source sensory neurons)
1162 m_cuda.channel_sum(m_blobSensoryActivationRev.count(), m_blobSensoryActivationRev.num, m_blobSensoryActivationRev.channels, m_blobSensoryActivationRev.count(2), m_blobSensoryActivationRev.gpu_diff, m_blobSensoryNumeratorW.mutable_gpu_diff, true, DIR.BWD, 1);
1163 m_cuda.channel_sum(m_blobSensoryActivationW1.count(), m_blobSensoryActivationW1.num, m_blobSensoryActivationW1.channels, m_blobSensoryActivationW1.count(2), m_blobSensoryActivationW1.gpu_diff, m_blobSensoryDenominatorW.mutable_gpu_diff, true, DIR.BWD, 1);
1164
1165 // Pre-compute the effect of the sensory inputs.
1166 op_bwd_local(OP.MUL, m_blobSensoryActivationW, blobs[(int)WEIGHT.SENSORY_EREV], m_blobSensoryActivationRev, nC, nN, nSD, 1, nSD);
1167 m_cuda.add(m_blobSensoryActivationW.count(), m_blobSensoryActivationW.gpu_diff, m_blobSensoryActivationW1.gpu_diff, m_blobSensoryActivationW.mutable_gpu_diff);
1168 op_bwd_local(OP.MUL, m_blobSensorySigmoidW, blobs[(int)WEIGHT.SENSORY_W], m_blobSensoryActivationW, nC, nN, nSD, 1, nSD);
1169
1170 addBtmTop(blobInputs, m_blobSensorySigmoidW);
1171 m_colBtm.Add(blobs[(int)WEIGHT.SENSORY_MU]);
1172 m_colBtm.Add(blobs[(int)WEIGHT.SENSORY_SIGMA]);
1173 sigmoid_bwd(m_colBtm, m_colTop);
1174
1175 blobVPre.CopyFrom(m_blobVPre, true);
1176 }
1177 }
1178}
The Log class provides general output in text form.
Definition: Log.cs:13
The BlobCollection contains a list of Blobs.
void Add(Blob< T > b)
Add a new Blob to the collection.
int Count
Returns the number of items in the collection.
void Clear(bool bDispose=false)
Remove all items from the collection.
void ReshapeLike(BlobCollection< T > src)
Reshapes all blobs in the collection to the sizes of the source.
void Reshape(int[] rgShape)
Reshapes all blobs in the collection to the given shape.
void CopyFrom(BlobCollection< T > bSrc, bool bCopyDiff=false)
Copy the data or diff from another BlobCollection into this one.
The Blob is the main holder of data that moves through the Layers of the Net.
Definition: Blob.cs:25
int channels
DEPRECIATED; legacy shape accessor channels: use shape(1) instead.
Definition: Blob.cs:800
void SetData(T[] rgData, int nCount=-1, bool bSetCount=true)
Sets a number of items within the Blob's data.
Definition: Blob.cs:1922
int height
DEPRECIATED; legacy shape accessor height: use shape(2) instead.
Definition: Blob.cs:808
int num_axes
Returns the number of axes in the Blob.
Definition: Blob.cs:705
long mutable_gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1555
long mutable_gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1487
void Reshape(int nNum, int nChannels, int nHeight, int nWidth, bool? bUseHalfSize=null)
DEPRECIATED; use
Definition: Blob.cs:442
void CopyFrom(Blob< T > src, int nSrcOffset, int nDstOffset, int nCount, bool bCopyData, bool bCopyDiff)
Copy from a source Blob.
Definition: Blob.cs:903
void scale_data(double df)
Scale the data by a scaling factor.
Definition: Blob.cs:1754
int width
DEPRECIATED; legacy shape accessor width: use shape(3) instead.
Definition: Blob.cs:816
void add_scalar(double dfVal)
Adds a scalar value to the Blob.
Definition: Blob.cs:2779
int count()
Returns the total number of items in the Blob.
Definition: Blob.cs:739
void ReshapeLike(Blob< T > b, bool? bUseHalfSize=null)
Reshape this Blob to have the same shape as another Blob.
Definition: Blob.cs:648
string Name
Get/set the name of the Blob.
Definition: Blob.cs:2184
long gpu_diff
Returns the diff GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1541
void scale_diff(double df)
Scale the diff by a scaling factor.
Definition: Blob.cs:1763
void SetDiff(double dfVal, int nIdx=-1)
Either sets all of the diff items in the Blob to a given value, or alternatively only sets a single i...
Definition: Blob.cs:1981
int num
DEPRECIATED; legacy shape accessor num: use shape(0) instead.
Definition: Blob.cs:792
long gpu_data
Returns the data GPU handle used by the CudaDnn connection.
Definition: Blob.cs:1479
The CudaDnn object is the main interface to the Low-Level Cuda C++ DLL.
Definition: CudaDnn.cs:969
Abstract Filler class used to fill blobs with values.
Definition: Filler.cs:19
void Fill(Blob< T > b)
Fill the blob with values based on the actual filler used.
Definition: Filler.cs:50
static Filler< T > Create(CudaDnn< T > cuda, Log log, FillerParameter p)
Create a new Filler instance.
Definition: Filler.cs:79
An interface for the units of computation which can be composed into a Net.
Definition: Layer.cs:31
Log m_log
Specifies the Log for output.
Definition: Layer.cs:43
LayerParameter m_param
Specifies the LayerParameter describing the Layer.
Definition: Layer.cs:47
void Backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Given the top Blob error gradients, compute the bottom Blob error gradients.
Definition: Layer.cs:815
double Forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Given the bottom (input) Blobs, this function computes the top (output) Blobs and the loss.
Definition: Layer.cs:728
CudaDnn< T > m_cuda
Specifies the CudaDnn connection to Cuda.
Definition: Layer.cs:39
void Setup(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Implements common Layer setup functionality.
Definition: Layer.cs:439
static Layer< T > Create(CudaDnn< T > cuda, Log log, LayerParameter p, CancelEvent evtCancel, IXDatabaseBase db=null, TransferInput trxinput=null)
Create a new Layer based on the LayerParameter.
Definition: Layer.cs:1468
LayerParameter.LayerType m_type
Specifies the Layer type.
Definition: Layer.cs:35
BlobCollection< T > blobs
Returns the collection of learnable parameter Blobs for the Layer.
Definition: Layer.cs:875
The LnnUnitLayer implements the base class to the Cfc and Ltc Unit layers.
Definition: LnnUnitLayer.cs:19
bool m_bOwnInternalBlobs
Specifies member variable used to track whether or not the internal blobs are owned by this layer.
Definition: LnnUnitLayer.cs:23
The LtcUnitLayer implements the liquid time constant with ODE solver (LTCCell) layer.
Definition: LtcUnitLayer.cs:25
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t. the LtcUnit value inputs.
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: attn
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Forward computation
override void dispose()
Releases all GPU and host resources used by the Layer.
override bool ReInitializeParameters(WEIGHT_TARGET target)
Re-initialize the parameters of the layer.
LtcUnitLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The LtcUnitLayer constructor.
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
override void SetInternalSharedBlobs(BlobCollection< T > col)
Set the internal shared blobs to a set of external blobs.
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
override BlobCollection< T > CreateInternalSharedBlobs(int nIdx, CudaDnn< T > cuda, Log log)
Create the internal shared blobs used by the layer for a given index.
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: input, hx, ts
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Specifies whether to use the NVIDIA cuDnn version or Caffe version of a given forward/backward operat...
Engine engine
Specifies the Engine in use.
Engine
Defines the type of engine to use.
Specifies the filler parameters used to create each Filler.
double min
Specifies the minimum value to use with the 'uniform' filler.
double max
Specifies the maximum value to use with the 'uniform' filler.
Specifies the base parameter for all layers.
string name
Specifies the name of this LayerParameter.
LtcUnitParameter ltc_unit_param
Returns the parameter set when initialized with LayerType.LTC_UNIT
SigmoidParameter sigmoid_param
Returns the parameter set when initialized with LayerType.SIGMOID
LayerType
Specifies the layer type.
float sensory_sigma_init_min
Specifies the initial sensory_sigma min value (default = 3.0f).
int hidden_size
Specifies the number of hidden units (default = 256).
float mu_init_max
Specifies the initial mu max value (default = 0.8f).
float w_init_max
Specifies the initial w max value (default = 1.0f).
float cm_init_min
Specifies the initial cm min value (default = 0.4f).
float sensory_mu_init_min
Specifies the initial sensory_mu min value (default = 0.3f).
float sigma_init_max
Specifies the initial sigma max value (default = 8.0f).
float sensory_w_init_min
Specifies the initial sensory_w min value (default = 0.001f).
float vleak_init_max
Specifies the initial vleak max value (default = 0.2f).
float sensory_sigma_init_max
Specifies the initial sensory_sigma max value (default = 8.0f).
float sigma_init_min
Specifies the initial sigma min value (default = 3.0f).
float sensory_mu_init_max
Specifies the initial sensory_mu max value (default = 0.8f).
float w_init_min
Specifies the initial w min value (default = 0.001f).
float gleak_init_min
Specifies the initial gleak min value (default = 0.001f).
float epsilon
Specifies the epsilon used to avoid divide by zero (default = 1e-08).
float cm_init_max
Specifies the initial cm max value (default = 0.6f).
float vleak_init_min
Specifies the initial vleak min value (default = -0.2f).
float mu_init_min
Specifies the initial mu min value (default = 0.3f).
int ode_unfolds
Specifies the number of unfolds run by the ode (default = 6).
float sensory_w_init_max
Specifies the initial sensory_w max value (default = 1.0f).
int input_size
Specifies the input size.
float gleak_init_max
Specifies the initial gleak max value (default = 1.0f).
The MyCaffe.basecode contains all generic types used throughout MyCaffe.
Definition: Annotation.cs:12
The MyCaffe.common namespace contains common MyCaffe classes.
Definition: BatchInput.cs:8
OP
Defines the operations performed by the channel_op function.
Definition: CudaDnn.cs:135
DIR
Defines the direction of data flow.
Definition: CudaDnn.cs:22
WEIGHT_TARGET
Defines the type of weight to target in re-initializations.
Definition: Interfaces.cs:38
The MyCaffe.fillers namespace contains all fillers including the Filler class.
The MyCaffe.layers.lnn namespace contains all Liquid Neural Network (LNN) related layers.
Definition: LayerFactory.cs:15
The MyCaffe.param namespace contains parameters used to create models.
The MyCaffe namespace contains the main body of MyCaffe code that closesly tracks the C++ Caffe open-...
Definition: Annotation.cs:12