Я пытаюсь реализовать многочлену glm в tenorflow с помощью пакета tenorflow_probability glm. Я посмотрел на источник из Бернулли GLM и нашел следующий код, который прямо реализует Бернулли GLM, наследуя от класса ExponentialFamily
class Bernoulli(tfp.glm.ExponentialFamily):
"""`Bernoulli(probs=mean)` where `mean = sigmoid(matmul(X, weights))`."""
_is_canonical = True
def _call(self, r):
mean = tf.nn.sigmoid(r)
variance = grad_mean = mean * tf.nn.sigmoid(-r)
return mean, variance, grad_mean
def _log_prob(self, y, r):
return tfd.Bernoulli(logits=r).log_prob(y)
Моя попытка адаптации к полиномиальной настройке GLM ниже
class MtlGLM(tfp.glm.ExponentialFamily):
"""`Bernoulli(probs=mean)` where `mean = sigmoid(matmul(X, weights))`."""
_is_canonical = True
def _call(self, r):
mean = tf.nn.softmax(r)
variance = grad_mean = mean * (1-mean)
return mean, variance, grad_mean
def _log_prob(self, y, r):
#print(len(y))
return tfd.Multinomial(1,logits=r).log_prob(y)
однако, когда я пытаюсь уместиться на моделируемых данных (как показано ниже), мои коэффициенты начинают взрываться после двух итераций или около того. Что происходит?
#imports
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
#simulate data
n_classes = 5
nB = 3
ndat = 500
beta = np.random.normal(size=[n_classes,nB])
X = np.random.normal(size=[nB,ndat])
softmax = lambda b,x: np.exp(b.dot(x))/(np.sum(np.exp(b.dot(x)),axis=0))
pvals = softmax(beta,X)
y = np.zeros([n_classes,ndat])
for kk,i in enumerate(pvals.T):
y[:,kk] = np.random.multinomial(n=1,pvals=i)
#fit the model
coefs = np.zeros_like(beta)
glm = MtlGLM()
for _ in range(5):
coefs,_ = tfp.glm.fit_one_step(X.T,y,glm,model_coefficients_start=coefs)