Files
2026-07-13 13:30:25 +08:00

91 lines
2.6 KiB
Python
Executable File

from prml.nn.random.random import RandomVariable
from prml.nn.tensor.parameter import Parameter
class Network(object):
"""
a base class for network building
Parameters
----------
kwargs : tensor_like
parameters to be optimized
Attributes
----------
parameter : dict
dictionary of parameters to be optimized
random_variable : dict
dictionary of random varibles
"""
def __init__(self, **kwargs):
self.random_variable = {}
self.parameter = {}
for key, value in kwargs.items():
if isinstance(value, Parameter):
self.parameter[key] = value
else:
try:
value = Parameter(value)
except TypeError:
raise TypeError(f"invalid type argument: {type(value)}")
self.parameter[key] = value
object.__setattr__(self, key, value)
def __setattr__(self, key, value):
if isinstance(value, RandomVariable):
self.random_variable[key] = value
object.__setattr__(self, key, value)
def clear(self):
"""
clear gradient and constructed bayesian network
"""
for p in self.parameter.values():
p.cleargrad()
self.random_variable = {}
def log_pdf(self, coef=1.):
"""
compute logarithm of probabilty density function
Parameters
----------
coef : float
coefficient to balance likelihood and prior
assuming mini-batch size / whole data size for mini-batch training
Returns
-------
logp : tensor_like
logarithm of probability density function
"""
logp = 0
for rv in self.random_variable.values():
if rv.observed:
logp += rv.log_pdf().sum()
else:
logp += coef * rv.log_pdf().sum()
return logp
def elbo(self, coef=1.):
"""
compute evidence lower bound of this model
ln p(output) >= elbo
Parameters
----------
coef : float
coefficient to balance likelihood and prior
assuming mini-batch size / whole data size for mini-batch training
Returns
-------
evidence : tensor_like
evidence lower bound
"""
evidence = 0
for rv in self.random_variable.values():
if rv.observed:
evidence += rv.log_pdf().sum()
else:
evidence += -coef * rv.KLqp().sum()
return evidence