1. 程式人生 > >【隨感】在Keras中如何按最大似然(Max Likewood)訓練模型

【隨感】在Keras中如何按最大似然(Max Likewood)訓練模型

在Keras中如何按最大似然(Max Likewood)訓練模型

按照生成模型的思路,模型的引數是和資料分佈無關的,利用極大似然準則就可以訓練模型。但是在類似Keras這種神經網路庫中,如何訓練類似如下的目標函式:

Eo[t],l[logπθ(a[t]o[t],h[t1],l))+ηvθ(o[t],h[t1],l)]-\mathbb{E}_{{o}^{[t]},{l}} [ { \log\pi_{\theta}(a^{[t]}|{o}^{[t]},{h}^{[t-1]},{l})) } + { \eta v_{\theta}({o}^{[t]},{h}^{[t-1]},{l})} ]

其中類似πθ(a[t]o[t],h[t1],l))\pi_{\theta}(a^{[t]}|{o}^{[t]},{h}^{[t-1]},{l}))這樣的對映的取樣是困難的(你不能將一次/多次前向傳播的結果就當做是取樣的結果),必須以極大量的前向傳播結果才能逼近這個分佈(大數定律)。下面將介紹一種替代方案,也就是將證明可以用KL散度 (Kullback–Leibler divergence)代替最大似然模型。

最大似然的損失函式: L

(θ,x)=log(Pθ(x))\mathcal{L}(\theta,x) = -log(\mathcal{P}_{\theta}(x))

優化目標即為θ=minθlog(Pθ(x))\theta=\min_{\theta} -log(\mathcal{P}_{\theta}(x)),假設真實資料分佈服從xQ(x)x \sim \mathcal{Q}(x),那麼引數θ\theta的風險期望為:

Ex[L(θ,x)]=xQ(x)log(Pθ(x))=xQ(x)log(Q(x)/Pθ(x))DK

L(QP)+xQ(x)log(1/Q(x)H(Q))\mathbb{E}_{x}[\mathcal{L}(\theta,x)]=-\sum_{x}\mathcal{Q}(x) log(\mathcal{P}_{\theta}(x)) \\ = \underbrace{\sum_{x}\mathcal{Q}(x) log( { \mathcal{Q}(x) }/{ \mathcal{P}_{\theta}(x) })}_{D_{KL}(\mathcal{Q}||\mathcal{P}) } + \underbrace{\sum_{x}\mathcal{Q}(x) log( {1}/{ \mathcal{Q}(x) }}_{H(\mathcal{Q})} )

由於真實資料分佈是Q(x)\mathcal{Q}(x),那麼H(Q)H(\mathcal{Q})是給定的,那麼Ex[L(θ,x)]\mathbb{E}_{x}[\mathcal{L}(\theta,x)]Q=Pθ\mathcal{Q}=\mathcal{P_{\theta}}時是最小的且為00.

因此我們在訓練時採用Keras自帶的crossentropy即可:

from keras.layers import Input,Embedding,LSTM,Dense
from keras.models import Model
from keras import backend as K

word_size = 128
dim_hidden = 100
dim_action = 10
dim_value  = 10
encode_size = 64

input          = Input(shape=(None,))
embedded       = Embedding(dim_hidden,word_size)(input)
encoder        = LSTM(encode_size)(embedded)
predict_action = Dense(dim_action)(encoder)
predict_value  = Dense(dim_value)(encoder)

def object1(y_true, y_pred, eta=0.2):
    loss1 = K.categorical_crossentropy(y_true, y_pred)
    return K.log(loss1)

def object2(y_true, y_pred, eta=0.2):
    loss2 = K.categorical_crossentropy(y_true, y_pred)
    return eta*loss2

model = Model(inputs=input, outputs=[predict_action,predict_value])
model.compile(optimizer='adam', loss=[object1,object2])