Args: dy (CTensor): the gradient tensor from upper operations Returns: a CTensor tuple for (da, db), da is data for dL / da, db is data for dL / db.
(self, dy)
| 3324 | return res |
| 3325 | |
| 3326 | def backward(self, dy): |
| 3327 | """ |
| 3328 | Args: |
| 3329 | dy (CTensor): the gradient tensor from upper operations |
| 3330 | Returns: |
| 3331 | a CTensor tuple for (da, db), da is data for dL / da, db is data |
| 3332 | for dL / db. |
| 3333 | """ |
| 3334 | #dy/dx_0 = b^(-1) |
| 3335 | #dy/dx_1 = (-a)*b^(-2) |
| 3336 | dx0 = singa.__mul__(dy, self.input[1]) |
| 3337 | dx1 = singa.__mul__(self.input[0], singa.PowFloat(self.input[1], 2.0)) |
| 3338 | dx1 = singa.__mul__(dy, dx1) |
| 3339 | if (type(dy) == float) or self.shape0 == self.shape1: |
| 3340 | assert self.shape0 == self.shape1, ('should have same shape') |
| 3341 | return dx0, dx1 |
| 3342 | # handle broadcast |
| 3343 | dx0 = back_broadcast(self.shape3, self.shape0, dx0) |
| 3344 | dx1 = back_broadcast(self.shape3, self.shape1, dx1) |
| 3345 | return dx0, dx1 |
| 3346 | |
| 3347 | |
| 3348 | def div(a, b): |
nothing calls this directly
no test coverage detected