MyCaffe  1.12.2.41
Deep learning software for Windows C# programmers.
CfcLayer.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.param;
10using MyCaffe.param.lnn;
11
12namespace MyCaffe.layers.lnn
13{
23 public class CfcLayer<T> : Layer<T>
24 {
25 int m_nBatchSize;
26 int m_nSeqLen;
27 int m_nTrueInFeatures;
28 int m_nReshapeCount = 0;
29 int m_nMaskCount;
30 BlobCollection<T> m_colTop = new BlobCollection<T>();
31 BlobCollection<T> m_colBtm = new BlobCollection<T>();
32 Layer<T> m_rnn_cell = null;
33 Layer<T> m_cat = null;
34 Layer<T> m_fc = null;
35 Blob<T> m_blobInputs1 = null;
36 Blob<T> m_blobInputs = null;
37 Blob<T> m_blobHState1 = null;
38 Blob<T> m_blobHState = null;
39 BlobCollection<T> m_rgBlobHState = new BlobCollection<T>();
40
41 List<BlobCollection<T>> m_rgrgInternalBlobs = new List<BlobCollection<T>>();
42
43 Blob<T> m_blobTs = null;
44 Blob<T> m_blobTsFull = null;
45 Blob<T> m_blobForwardInput = null;
46 Blob<T> m_blobForwardInput1 = null;
47 Blob<T> m_blobForwardInput2 = null;
48 Blob<T> m_blobForwardOutput = null;
49 Blob<T> m_blobForwardOutput1 = null;
50 Blob<T> m_blobForwardOutput2 = null;
51 Blob<T> m_blobTimeSinceUpdate = null;
52 Blob<T> m_blobTimeSinceUpdate1 = null;
53 Blob<T> m_blobMask = null;
54 Blob<T> m_blobMaskInv = null;
55 Blob<T> m_blobCurrentMask = null;
56 Blob<T> m_blobCurrentMaskFull = null;
57 Blob<T> m_blobCurrentOutput = null;
58 Blob<T> m_blobOutputSequence = null;
59 int[] m_rgShape = new int[] { 1, 1, 1, 1 };
60 bool m_bSetup = false;
61 int m_nHiddenSize = 0;
62
70 : base(cuda, log, p)
71 {
73
75 m_nHiddenSize = p.ltc_unit_param.hidden_size;
76 else
77 m_nHiddenSize = p.cfc_unit_param.hidden_size;
78
79 m_blobHState1 = new Blob<T>(m_cuda, m_log);
80 m_blobHState = new Blob<T>(m_cuda, m_log);
81
82 m_blobTs = new Blob<T>(m_cuda, m_log);
83
84 m_blobInputs = new Blob<T>(m_cuda, m_log);
85 m_blobInputs1 = new Blob<T>(m_cuda, m_log);
86 m_blobMask = new Blob<T>(m_cuda, m_log);
87 m_blobMaskInv = new Blob<T>(m_cuda, m_log);
88
89 m_blobCurrentMask = new Blob<T>(m_cuda, m_log);
90 m_blobCurrentOutput = new Blob<T>(m_cuda, m_log);
91 m_blobCurrentMaskFull = new Blob<T>(m_cuda, m_log);
92
93 m_blobForwardInput = new Blob<T>(m_cuda, m_log);
94 m_blobForwardInput1 = new Blob<T>(m_cuda, m_log);
95 m_blobForwardInput2 = new Blob<T>(m_cuda, m_log);
96 m_blobTimeSinceUpdate = new Blob<T>(m_cuda, m_log);
97 m_blobTimeSinceUpdate1 = new Blob<T>(m_cuda, m_log);
98 m_blobTsFull = new Blob<T>(m_cuda, m_log);
99
100 m_blobForwardOutput = new Blob<T>(m_cuda, m_log);
101 m_blobForwardOutput1 = new Blob<T>(m_cuda, m_log);
102 m_blobForwardOutput2 = new Blob<T>(m_cuda, m_log);
103
104 m_blobOutputSequence = new Blob<T>(m_cuda, m_log);
105
107 cat.concat_param.axis = 1;
108 m_cat = Layer<T>.Create(m_cuda, m_log, convertLayerParam(cat, p), null);
109
110 LayerParameter rnn = null;
111
113 {
114 rnn = new LayerParameter(LayerParameter.LayerType.LTC_UNIT);
116 }
117 else
118 {
119 rnn = new LayerParameter(LayerParameter.LayerType.CFC_UNIT);
121 }
122
123 m_rnn_cell = Layer<T>.Create(m_cuda, m_log, convertLayerParam(rnn, p), null);
124
125 LayerParameter fc = new LayerParameter(LayerParameter.LayerType.INNERPRODUCT, "fc");
129 fc.inner_product_param.bias_filler = new FillerParameter("constant", 0.1);
131 m_fc = Layer<T>.Create(m_cuda, m_log, convertLayerParam(fc, p), null);
132 }
133
134 private void dispose(ref List<BlobCollection<T>> rg)
135 {
136 if (rg == null)
137 return;
138
139 for (int i = 0; i < rg.Count; i++)
140 {
141 for (int j = 0; j < rg[i].Count; j++)
142 {
143 if (rg[i][j] != null)
144 rg[i][j].Dispose();
145 }
146 }
147 rg.Clear();
148 rg = null;
149 }
150
152 protected override void dispose()
153 {
154 base.dispose();
155
156 dispose(ref m_rgBlobHState);
157
158 dispose(ref m_rgrgInternalBlobs);
159
160 dispose(ref m_blobHState1);
161 dispose(ref m_blobHState);
162 dispose(ref m_blobInputs1);
163 dispose(ref m_blobInputs);
164 dispose(ref m_blobTs);
165 dispose(ref m_blobTsFull);
166 dispose(ref m_blobForwardInput);
167 dispose(ref m_blobForwardInput1);
168 dispose(ref m_blobForwardInput2);
169 dispose(ref m_blobForwardOutput);
170 dispose(ref m_blobForwardOutput1);
171 dispose(ref m_blobForwardOutput2);
172 dispose(ref m_blobTimeSinceUpdate);
173 dispose(ref m_blobTimeSinceUpdate1);
174 dispose(ref m_blobMask);
175 dispose(ref m_blobMaskInv);
176 dispose(ref m_blobCurrentMask);
177 dispose(ref m_blobCurrentMaskFull);
178 dispose(ref m_blobCurrentOutput);
179 dispose(ref m_blobOutputSequence);
180
181 dispose(ref m_rnn_cell);
182 dispose(ref m_cat);
183 dispose(ref m_fc);
184 }
185
186 private void addBtmTop(Blob<T> btm, Blob<T> top)
187 {
188 m_colBtm.Clear();
189 m_colBtm.Add(btm);
190 m_colTop.Clear();
191 m_colTop.Add(top);
192 }
193
195 protected override void setup_internal_blobs(BlobCollection<T> col)
196 {
197 if (col.Count > 0)
198 return;
199 }
200
204 public override int ExactNumBottomBlobs
205 {
206 get { return 3; }
207 }
208
212 public override int ExactNumTopBlobs
213 {
214 get { return 1; }
215 }
216
222 public override bool ReInitializeParameters(WEIGHT_TARGET target)
223 {
224 base.ReInitializeParameters(target);
225 return true;
226 }
227
233 public override void LayerSetUp(BlobCollection<T> colBottom, BlobCollection<T> colTop)
234 {
235 if (m_bSetup)
236 return;
237
238 m_nBatchSize = colBottom[0].num;
239 m_nSeqLen = colBottom[0].channels;
240 m_nTrueInFeatures = colBottom[0].count(2);
241 m_nReshapeCount = 0;
242
243 m_rgShape[0] = m_nBatchSize;
244 m_rgShape[1] = m_nHiddenSize;
245 m_blobHState1.Reshape(m_rgShape);
246 m_blobHState.Reshape(m_rgShape);
247
248 for (int i = 0; i < m_nSeqLen; i++)
249 {
250 Blob<T> blobHStateT = new Blob<T>(m_cuda, m_log, m_rgShape);
251 blobHStateT.Name = "h_state_" + i.ToString();
252 m_rgBlobHState.Add(blobHStateT);
253
254 BlobCollection<T> col = ((LnnUnitLayer<T>)m_rnn_cell).CreateInternalSharedBlobs(i, m_cuda, m_log);
255 m_rgrgInternalBlobs.Add(col);
256 }
257
258 m_rgShape[1] = 1;
259 m_blobTs.Reshape(m_rgShape);
260
261 m_rgShape[1] = m_nTrueInFeatures;
262 m_blobInputs.Reshape(m_rgShape);
263 m_blobMask.ReshapeLike(m_blobInputs);
264 m_blobMaskInv.ReshapeLike(m_blobInputs);
265 m_nMaskCount = m_blobMask.count(2);
266
267 m_rgShape[1] = 1;
268 m_blobCurrentMask.Reshape(m_rgShape);
269
270 m_rgShape[1] = m_nTrueInFeatures;
271 m_blobForwardInput.Reshape(m_rgShape);
272 m_blobForwardInput1.Reshape(m_rgShape);
273 m_blobForwardInput2.Reshape(m_rgShape);
274 m_blobTimeSinceUpdate.Reshape(m_rgShape);
275 m_blobTimeSinceUpdate1.Reshape(m_rgShape);
276 m_blobTsFull.Reshape(m_rgShape);
277
278 m_rgShape[1] = m_param.cfc_param.output_features;
279 m_blobForwardOutput.Reshape(m_rgShape);
280 m_blobForwardOutput1.Reshape(m_rgShape);
281 m_blobForwardOutput2.Reshape(m_rgShape);
282
283 addBtmTop(m_blobForwardInput, m_blobInputs1);
284 if (m_nTrueInFeatures * 2 < m_param.cfc_param.input_features && m_nMaskCount == m_nTrueInFeatures)
285 m_colBtm.Add(m_blobTimeSinceUpdate);
286 m_colBtm.Add(m_blobMask);
287 m_cat.Setup(m_colBtm, m_colTop);
288
289 ((LnnUnitLayer<T>)m_rnn_cell).SetInternalSharedBlobs(m_rgrgInternalBlobs[0]);
290
291 addBtmTop(m_blobInputs1, m_blobHState);
292 m_colBtm.Add(m_blobHState1);
293 m_colBtm.Add(m_blobTs);
294 m_rnn_cell.Setup(m_colBtm, m_colTop);
295 blobs.Add(m_rnn_cell.blobs);
296
297 m_blobHState.Unsqueeze(4);
298
299 addBtmTop(m_blobHState, m_blobCurrentOutput);
300 m_fc.Setup(m_colBtm, m_colTop);
301 blobs.Add(m_fc.blobs);
302
303 m_blobCurrentMaskFull.ReshapeLike(m_blobCurrentOutput);
304
305 addBtmTop(m_blobHState, colTop[0]);
306 m_fc.Reshape(m_colBtm, m_colTop);
307
308 m_bSetup = true;
309 }
310
316 public override void Reshape(BlobCollection<T> colBottom, BlobCollection<T> colTop)
317 {
318 int nTrueInFeatures = (int)colBottom[0].count(2);
319
320 // Only reshape when needed.
321 if (m_nReshapeCount > 0 &&
322 m_nBatchSize > 0 && m_nBatchSize == colBottom[0].num &&
323 m_nSeqLen > 0 && m_nSeqLen == colBottom[0].channels &&
324 m_nTrueInFeatures > 0 && m_nTrueInFeatures == nTrueInFeatures)
325 return;
326
327 m_nReshapeCount++;
328 m_nBatchSize = colBottom[0].num;
329 m_nSeqLen = colBottom[0].channels;
330 m_nTrueInFeatures = nTrueInFeatures;
331
332 m_rgShape[0] = m_nBatchSize;
333 m_rgShape[1] = m_nHiddenSize;
334
335 m_blobHState1.Reshape(m_rgShape);
336 m_blobHState.Reshape(m_rgShape);
337
338 for (int i=0; i<m_nSeqLen; i++)
339 {
340 m_rgBlobHState[i].Reshape(m_rgShape);
341 }
342
343 m_rgShape[1] = 1;
344 m_blobTs.Reshape(m_rgShape);
345
346 m_rgShape[1] = m_nTrueInFeatures;
347 m_blobInputs.Reshape(m_rgShape);
348 m_blobMask.ReshapeLike(m_blobInputs);
349 m_blobMaskInv.ReshapeLike(m_blobInputs);
350 m_blobMaskInv.SetDiff(1.0);
351 m_nMaskCount = m_blobMask.count(2);
352
353 m_rgShape[1] = 1;
354 m_blobCurrentMask.Reshape(m_rgShape);
355
356 m_rgShape[1] = m_nTrueInFeatures;
357 m_blobForwardInput.Reshape(m_rgShape);
358 m_blobForwardInput1.Reshape(m_rgShape);
359 m_blobForwardInput2.Reshape(m_rgShape);
360 m_blobTimeSinceUpdate.Reshape(m_rgShape);
361 m_blobTimeSinceUpdate1.Reshape(m_rgShape);
362 m_blobTsFull.ReshapeLike(m_blobTimeSinceUpdate1);
363
364 m_rgShape[1] = m_param.cfc_param.output_features;
365 m_blobForwardOutput.Reshape(m_rgShape);
366 m_blobForwardOutput1.Reshape(m_rgShape);
367 m_blobForwardOutput2.Reshape(m_rgShape);
368
369 addBtmTop(m_blobForwardInput, m_blobInputs1);
370 if (m_nTrueInFeatures * 2 < m_param.cfc_param.input_features && m_nMaskCount == m_nTrueInFeatures)
371 m_colBtm.Add(m_blobTimeSinceUpdate);
372 m_colBtm.Add(m_blobMask);
373 m_cat.Reshape(m_colBtm, m_colTop);
374
375 for (int i = 0; i < m_nSeqLen; i++)
376 {
377 addBtmTop(m_blobInputs1, m_blobHState);
378 m_colBtm.Add(m_blobHState1);
379 m_colBtm.Add(m_blobTs);
380
381 ((LnnUnitLayer<T>)m_rnn_cell).SetInternalSharedBlobs(m_rgrgInternalBlobs[i]);
382
383 m_rnn_cell.Reshape(m_colBtm, m_colTop);
384 }
385
386 m_blobHState.Unsqueeze(4);
387
388 addBtmTop(m_blobHState, m_blobCurrentOutput);
389 m_fc.Reshape(m_colBtm, m_colTop);
390
391 m_blobCurrentMaskFull.ReshapeLike(m_blobCurrentOutput);
392
393 addBtmTop(m_blobHState, colTop[0]);
394 m_fc.Reshape(m_colBtm, m_colTop);
395 }
396
410 protected override void forward(BlobCollection<T> colBottom, BlobCollection<T> colTop)
411 {
412 m_blobForwardInput.SetData(0);
413 m_blobForwardOutput.SetData(0);
414 m_blobTimeSinceUpdate.SetData(0);
415 m_blobHState.SetData(0);
416
417 for (int t = 0; t < m_nSeqLen; t++)
418 {
419 // Copy the t'th time step of the input to the input blob.
420 m_cuda.channel_copy(m_blobInputs.count(), m_blobInputs.num, 1, m_nSeqLen, m_nTrueInFeatures, t, colBottom[0].gpu_data, m_blobInputs.mutable_gpu_data, DIR.FWD);
421 // Copy the t'th timestep of the time since update to the ts blob.
422 m_cuda.channel_copy(m_blobTs.count(), m_blobTs.num, 1, m_nSeqLen, 1, t, colBottom[1].gpu_data, m_blobTs.mutable_gpu_data, DIR.FWD);
423 m_cuda.channel_fillfrom(m_blobTsFull.count(), 1, m_blobTs.num, m_blobTsFull.channels, m_blobTs.gpu_data, m_blobTsFull.mutable_gpu_data, DIR.FWD);
424
425 // Apply masking
426 if (colBottom.Count() > 2)
427 {
428 int nMaskCount = colBottom[2].count(2);
429 if (nMaskCount == m_nTrueInFeatures)
430 {
431 // Copy the t'th mask of the full mask to the mask blob.
432 m_cuda.channel_copy(m_blobMask.count(), m_blobMask.num, 1, m_nSeqLen, nMaskCount, t, colBottom[2].gpu_data, m_blobMask.mutable_gpu_data, DIR.FWD);
433 // Create the mask inverse
434 m_cuda.sub(m_blobMask.count(), m_blobMaskInv.gpu_diff, m_blobMask.gpu_data, m_blobMaskInv.mutable_gpu_data);
435
436 // Update the forwarded input.
437 m_cuda.mul(m_blobMask.count(), m_blobInputs.gpu_data, m_blobMask.gpu_data, m_blobForwardInput1.mutable_gpu_data);
438 m_cuda.mul(m_blobMask.count(), m_blobForwardInput.gpu_data, m_blobMaskInv.gpu_data, m_blobForwardInput2.mutable_gpu_data);
439 m_cuda.add(m_blobMask.count(), m_blobForwardInput1.gpu_data, m_blobForwardInput2.gpu_data, m_blobForwardInput.mutable_gpu_data);
440
441 // Update the time since update.
442 m_cuda.add(m_blobTimeSinceUpdate.count(), m_blobTimeSinceUpdate.gpu_data, m_blobTsFull.gpu_data, m_blobTimeSinceUpdate1.mutable_gpu_data);
443 m_cuda.mul(m_blobTimeSinceUpdate1.count(), m_blobTimeSinceUpdate1.gpu_data, m_blobMaskInv.gpu_data, m_blobTimeSinceUpdate.mutable_gpu_data);
444 }
445 else
446 {
447 m_cuda.copy(m_blobForwardInput.count(), m_blobInputs.gpu_data, m_blobForwardInput.mutable_gpu_data);
448 }
449
450 // Update a 3x in-features mask.
451 if (m_nTrueInFeatures * 2 < m_param.cfc_param.input_features && m_nMaskCount == m_nTrueInFeatures)
452 {
453 addBtmTop(m_blobForwardInput, m_blobInputs1);
454 m_colBtm.Add(m_blobTimeSinceUpdate);
455 m_colBtm.Add(m_blobMask);
456 m_cat.Forward(m_colBtm, m_colTop);
457 }
458 // Update a 2x in-features mask.
459 else
460 {
461 addBtmTop(m_blobForwardInput, m_blobInputs1);
462 m_colBtm.Add(m_blobMask);
463 m_cat.Forward(m_colBtm, m_colTop);
464 }
465 }
466 else
467 {
468 m_blobInputs1.CopyFrom(m_blobInputs);
469 }
470
471 // Run the CfcCell forward pass.
472 addBtmTop(m_blobInputs1, m_blobHState1);
473 m_colBtm.Add(m_blobHState);
474 m_colBtm.Add(m_blobTs);
475
476 ((LnnUnitLayer<T>)m_rnn_cell).SetInternalSharedBlobs(m_rgrgInternalBlobs[t]);
477
478 m_rnn_cell.Forward(m_colBtm, m_colTop);
479
480 m_blobHState1.Unsqueeze(4);
481 m_rgBlobHState[t].CopyFrom(m_blobHState1);
482
483 // Apply masking
484 if (colBottom.Count > 2)
485 {
486 m_cuda.channel_max(m_blobMask.count(), m_blobMask.num, m_blobMask.channels, 1, m_blobMask.gpu_data, m_blobCurrentMask.mutable_gpu_data);
487
488 // Create mask inverse
489 m_blobCurrentMask.SetDiff(1.0);
490 m_cuda.sub(m_blobCurrentMask.count(), m_blobCurrentMask.gpu_diff, m_blobCurrentMask.gpu_data, m_blobCurrentMask.mutable_gpu_diff);
491
492 m_cuda.channel_fillfrom(m_blobCurrentMaskFull.count(), m_blobCurrentMask.num, m_blobCurrentMask.channels, m_blobCurrentMaskFull.channels, m_blobCurrentMask.gpu_data, m_blobCurrentMaskFull.mutable_gpu_data, DIR.FWD);
493 m_cuda.channel_fillfrom(m_blobCurrentMaskFull.count(), m_blobCurrentMask.num, m_blobCurrentMask.channels, m_blobCurrentMaskFull.channels, m_blobCurrentMask.gpu_diff, m_blobCurrentMaskFull.mutable_gpu_diff, DIR.FWD);
494
495 addBtmTop(m_blobHState1, m_blobCurrentOutput);
496 m_fc.Forward(m_colBtm, m_colTop);
497
498 // Update the forwarded output.
499 m_cuda.mul(m_blobCurrentMaskFull.count(), m_blobCurrentOutput.gpu_data, m_blobCurrentMaskFull.gpu_data, m_blobForwardOutput1.mutable_gpu_data);
500 m_cuda.mul(m_blobCurrentMaskFull.count(), m_blobForwardOutput.gpu_data, m_blobCurrentMaskFull.gpu_diff, m_blobForwardOutput2.mutable_gpu_data);
501 m_cuda.add(m_blobCurrentMaskFull.count(), m_blobForwardOutput1.gpu_data, m_blobForwardOutput2.gpu_data, m_blobForwardOutput.mutable_gpu_data);
502 }
503
504 m_blobHState.CopyFrom(m_blobHState1);
505 }
506
508 {
509 throw new NotImplementedException("return sequences is not implemented yet.");
510 }
511 else if (colBottom.Count > 2)
512 {
513 colTop[0].CopyFrom(m_blobForwardOutput);
514 }
515 else
516 {
517 addBtmTop(m_blobHState, colTop[0]);
518 m_fc.Forward(m_colBtm, m_colTop);
519 }
520 }
521
538 protected override void backward(BlobCollection<T> colTop, List<bool> rgbPropagateDown, BlobCollection<T> colBottom)
539 {
540 m_blobHState.SetDiff(0);
541 m_blobInputs.SetDiff(0);
542 m_blobForwardInput.SetDiff(0);
543
545 {
546 throw new NotImplementedException("return sequences is not implemented yet.");
547 }
548 else if (colBottom.Count > 2)
549 {
550 m_blobForwardOutput.CopyFrom(colTop[0], true);
551 }
552 else
553 {
554 addBtmTop(m_blobHState, colTop[0]);
555 m_fc.Backward(m_colTop, rgbPropagateDown, m_colBtm);
556 }
557
558 int nMaskCount = colBottom[2].count(2);
559 for (int t = m_nSeqLen - 1; t >= 0; t--)
560 {
561 m_blobHState1.CopyFrom(m_rgBlobHState[t]);
562
563 if (colBottom.Count > 2)
564 {
565 // Copy the t'th mask of the full mask to the mask blob.
566 m_cuda.channel_copy(m_blobMask.count(), m_blobMask.num, 1, m_nSeqLen, nMaskCount, t, colBottom[2].gpu_data, m_blobMask.mutable_gpu_data, DIR.FWD);
567 // Create the mask inverse
568 m_cuda.sub(m_blobMask.count(), m_blobMaskInv.gpu_diff, m_blobMask.gpu_data, m_blobMaskInv.mutable_gpu_data);
569
570 m_cuda.channel_max(m_blobMask.count(), m_blobMask.num, m_blobMask.channels, 1, m_blobMask.gpu_data, m_blobCurrentMask.mutable_gpu_data);
571
572 // Create mask inverse
573 m_blobCurrentMask.SetDiff(1.0);
574 m_cuda.sub(m_blobCurrentMask.count(), m_blobCurrentMask.gpu_diff, m_blobCurrentMask.gpu_data, m_blobCurrentMask.mutable_gpu_diff);
575
576 m_cuda.channel_fillfrom(m_blobCurrentMaskFull.count(), m_blobCurrentMask.num, m_blobCurrentMask.channels, m_blobCurrentMaskFull.channels, m_blobCurrentMask.gpu_data, m_blobCurrentMaskFull.mutable_gpu_data, DIR.FWD);
577 m_cuda.channel_fillfrom(m_blobCurrentMaskFull.count(), m_blobCurrentMask.num, m_blobCurrentMask.channels, m_blobCurrentMaskFull.channels, m_blobCurrentMask.gpu_diff, m_blobCurrentMaskFull.mutable_gpu_diff, DIR.FWD);
578
579 m_blobForwardOutput1.CopyFrom(m_blobForwardOutput, true);
580 m_blobForwardOutput2.CopyFrom(m_blobForwardOutput, true);
581
582 // Update the forwarded output.
583 m_cuda.mul(m_blobCurrentMaskFull.count(), m_blobForwardOutput1.gpu_diff, m_blobCurrentMaskFull.gpu_data, m_blobCurrentOutput.mutable_gpu_diff);
584 m_cuda.mul(m_blobCurrentMaskFull.count(), m_blobForwardOutput2.gpu_diff, m_blobCurrentMaskFull.gpu_diff, m_blobForwardOutput.mutable_gpu_diff);
585
586 addBtmTop(m_blobHState1, m_blobCurrentOutput);
587 m_fc.Backward(m_colTop, rgbPropagateDown, m_colBtm);
588 }
589
590 if (t < m_nSeqLen - 1)
591 m_cuda.add(m_blobHState1.count(), m_blobHState1.gpu_diff, m_rgBlobHState[t + 1].gpu_diff, m_blobHState1.mutable_gpu_diff);
592
593 // Run the CfcCell backward pass.
594 addBtmTop(m_blobInputs1, m_blobHState1);
595 m_colBtm.Add(m_blobHState);
596 m_colBtm.Add(m_blobTs);
597
598 ((LnnUnitLayer<T>)m_rnn_cell).SetInternalSharedBlobs(m_rgrgInternalBlobs[t]);
599
600 m_rnn_cell.Backward(m_colTop, new List<bool>() { true, true, true }, m_colBtm);
601 m_rgBlobHState[t].CopyFrom(m_blobHState, true);
602
603 // Apply masking
604 if (colBottom.Count() > 2)
605 {
606 if (m_nTrueInFeatures * 2 < m_param.cfc_param.input_features && m_nMaskCount == m_nTrueInFeatures)
607 {
608 addBtmTop(m_blobForwardInput1, m_blobInputs1);
609 m_colBtm.Add(m_blobTimeSinceUpdate);
610 m_colBtm.Add(m_blobMask);
611 m_cat.Backward(m_colTop, new List<bool>() { true, true, true }, m_colBtm);
612 }
613 else
614 {
615 addBtmTop(m_blobForwardInput1, m_blobInputs1);
616 m_colBtm.Add(m_blobMask);
617 m_cat.Backward(m_colTop, new List<bool>() { true, true }, m_colBtm);
618 }
619
620 // Accumulate grad with previous masked forward input.
621 m_cuda.mul(m_blobForwardInput.count(), m_blobForwardInput.gpu_diff, m_blobForwardInput2.gpu_diff, m_blobForwardInput.mutable_gpu_diff);
622 m_cuda.add(m_blobForwardInput.count(), m_blobForwardInput.gpu_diff, m_blobForwardInput1.gpu_diff, m_blobForwardInput.mutable_gpu_diff);
623
624 if (nMaskCount == m_nTrueInFeatures)
625 {
626 // Input grad = mask * Inputs1
627 m_cuda.mul(m_blobForwardInput.count(), m_blobForwardInput.gpu_diff, m_blobMask.gpu_data, m_blobInputs.mutable_gpu_diff);
628 // Forwarded input grad = mask_inv * Forwarded input grad
629 //m_cuda.mul(m_blobForwardInput.count(), m_blobForwardInput.gpu_diff, m_blobMaskInv.gpu_data, m_blobForwardInput.mutable_gpu_diff);
630 }
631 else
632 {
633 m_cuda.copy(m_blobForwardInput.count(), m_blobForwardInput.gpu_diff, m_blobInputs.mutable_gpu_diff);
634 }
635 }
636 else
637 {
638 m_blobInputs.CopyFrom(m_blobInputs1, true);
639 }
640
641 // Copy the t'th timestep of the time since update to the ts blob.
642 //m_cuda.channel_fillfrom(m_blobTsFull.count(), 1, m_blobTs.num, m_blobTsFull.channels, m_blobTs.gpu_diff, m_blobTsFull.mutable_gpu_diff, DIR.BWD);
643
644 //m_cuda.channel_copy(m_blobTs.count(), m_blobTs.num, 1, m_nSeqLen, 1, t, colBottom[1].gpu_diff, m_blobTs.mutable_gpu_diff, DIR.BWD);
645 // Copy the t'th time step of the input to the input blob.
646 m_cuda.channel_copy(m_blobInputs.count(), m_blobInputs.num, 1, m_nSeqLen, m_nTrueInFeatures, t, colBottom[0].gpu_diff, m_blobInputs.mutable_gpu_diff, DIR.BWD);
647
648 // Save previous mask.
649 m_cuda.copy(m_blobForwardInput2.count(), m_blobMaskInv.gpu_data, m_blobForwardInput2.mutable_gpu_diff);
650 }
651 }
652 }
653}
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 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
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 Unsqueeze(int nNumAxes)
Unsqueeze the shape by adding shape=1 on each axis until the 'nNumAxes' is reached.
Definition: Blob.cs:201
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
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 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
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
abstract void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Adjust the shapes of top blobs and internal buffers to accomodate the shapes of the bottom blobs.
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
LayerParameter convertLayerParam(LayerParameter pChild, LayerParameter pParent)
Called to convert a parent LayerParameterEx, used in blob sharing, with a child layer parameter.
Definition: Layer.cs:1134
The CfcLayer implements the Closed form Continuous layer.
Definition: CfcLayer.cs:24
override int ExactNumTopBlobs
Returns the exact number of required top (output) Blobs: attn
Definition: CfcLayer.cs:213
CfcLayer(CudaDnn< T > cuda, Log log, LayerParameter p)
The CfcLayer constructor.
Definition: CfcLayer.cs:69
override void LayerSetUp(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Setup the layer.
Definition: CfcLayer.cs:233
override void forward(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Forward computation
Definition: CfcLayer.cs:410
override int ExactNumBottomBlobs
Returns the exact number of required bottom (input) Blobs: input, hx, ts
Definition: CfcLayer.cs:205
override void backward(BlobCollection< T > colTop, List< bool > rgbPropagateDown, BlobCollection< T > colBottom)
Computes the error gradient w.r.t. the Cfc value inputs.
Definition: CfcLayer.cs:538
override void dispose()
Releases all GPU and host resources used by the Layer.
Definition: CfcLayer.cs:152
override bool ReInitializeParameters(WEIGHT_TARGET target)
Re-initialize the parameters of the layer.
Definition: CfcLayer.cs:222
override void setup_internal_blobs(BlobCollection< T > col)
Derivative layers should add all internal blobws to the 'col' provided.
Definition: CfcLayer.cs:195
override void Reshape(BlobCollection< T > colBottom, BlobCollection< T > colTop)
Reshape the bottom (input) and top (output) blobs.
Definition: CfcLayer.cs:316
The LnnUnitLayer implements the base class to the Cfc and Ltc Unit layers.
Definition: LnnUnitLayer.cs:19
int axis
The axis along which to concatenate – may be negative to index from the end (e.g.,...
Specifies the filler parameters used to create each Filler.
FillerParameter weight_filler
The filler for the weights.
int axis
Specifies the first axis to be lumped into a single inner product computation; all preceding axes are...
FillerParameter bias_filler
The filler for the bias.
uint num_output
The number of outputs for the layer.
bool bias_term
Whether to have bias terms or not.
Specifies the base parameter for all layers.
CfcParameter cfc_param
Returns the parameter set when initialized with LayerType.CFC
LtcUnitParameter ltc_unit_param
Returns the parameter set when initialized with LayerType.LTC_UNIT
InnerProductParameter inner_product_param
Returns the parameter set when initialized with LayerType.INNERPRODUCT
ConcatParameter concat_param
Returns the parameter set when initialized with LayerType.CONCAT
CfcUnitParameter cfc_unit_param
Returns the parameter set when initialized with LayerType.CFC_UNIT
LayerType
Specifies the layer type.
Specifies the parameters used by the CfcLayer. Note, you must also fill out the CfcUnitParameter.
Definition: CfcParameter.cs:21
CELL_TYPE cell_type
Specifies the cell type to use (default = CFC).
Definition: CfcParameter.cs:53
CELL_TYPE
Defines the cell type.
Definition: CfcParameter.cs:32
int input_features
Specifies the number of input features.
Definition: CfcParameter.cs:63
int output_features
Specifies the number of output features
Definition: CfcParameter.cs:83
bool return_sequences
Specifies whether or not to return the sequence.
Definition: CfcParameter.cs:93
int hidden_size
Specifies the hidden size used to size the backbone units and other internal layers.
override void Copy(LayerParameterBase src)
Copy on parameter to another.
int hidden_size
Specifies the number of hidden units (default = 256).
override void Copy(LayerParameterBase src)
Copy on parameter to another.
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
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.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