56 lines
1.6 KiB
Python
Executable File
56 lines
1.6 KiB
Python
Executable File
import numpy as np
|
|
from prml.nn.tensor.constant import Constant
|
|
from prml.nn.tensor.tensor import Tensor
|
|
from prml.nn.function import Function
|
|
|
|
|
|
class Product(Function):
|
|
|
|
def __init__(self, axis=None, keepdims=False):
|
|
if isinstance(axis, int):
|
|
axis = (axis,)
|
|
elif isinstance(axis, tuple):
|
|
axis = tuple(sorted(axis))
|
|
self.axis = axis
|
|
self.keepdims = keepdims
|
|
|
|
def forward(self, x):
|
|
x = self._convert2tensor(x)
|
|
self.x = x
|
|
self.output = np.prod(self.x.value, axis=self.axis, keepdims=True)
|
|
if not self.keepdims:
|
|
output = np.squeeze(self.output)
|
|
if output.size == 1:
|
|
output = output.item()
|
|
else:
|
|
output = self.output
|
|
if isinstance(self.x, Constant):
|
|
return Constant(output)
|
|
return Tensor(output, function=self)
|
|
|
|
def backward(self, delta):
|
|
if not self.keepdims and self.axis is not None:
|
|
for ax in self.axis:
|
|
delta = np.expand_dims(delta, ax)
|
|
dx = delta * self.output / self.x.value
|
|
self.x.backward(dx)
|
|
|
|
|
|
def prod(x, axis=None, keepdims=False):
|
|
"""
|
|
product of all element in the array
|
|
Parameters
|
|
----------
|
|
x : tensor_like
|
|
input array
|
|
axis : int, tuple of ints
|
|
axis or axes along which a product is performed
|
|
keepdims : bool
|
|
keep dimensionality or not
|
|
Returns
|
|
-------
|
|
product : tensor_like
|
|
product of all element
|
|
"""
|
|
return Product(axis=axis, keepdims=keepdims).forward(x)
|