Args: dy (CTensor): the gradient tensor from upper operations Returns: a tuple for (da, db), da is data for dL / da, db is data for dL / db.
(self, dy)
| 2528 | return res |
| 2529 | |
| 2530 | def backward(self, dy): |
| 2531 | """ |
| 2532 | Args: |
| 2533 | dy (CTensor): the gradient tensor from upper operations |
| 2534 | Returns: |
| 2535 | a tuple for (da, db), da is data for dL / da, db is data |
| 2536 | for dL / db. |
| 2537 | """ |
| 2538 | dx0 = singa.__mul__(dy, self.input[1]) |
| 2539 | dx1 = singa.__mul__(dy, self.input[0]) |
| 2540 | if (type(dy) == float) or self.shape0 == self.shape1: |
| 2541 | assert self.shape0 == self.shape1, ('should have same shape') |
| 2542 | return dx0, dx1 |
| 2543 | # handle broadcast |
| 2544 | dx0 = back_broadcast(self.shape3, self.shape0, dx0) |
| 2545 | dx1 = back_broadcast(self.shape3, self.shape1, dx1) |
| 2546 | return dx0, dx1 |
| 2547 | |
| 2548 | |
| 2549 | def mul(x, y): |
nothing calls this directly
no test coverage detected