CBOW模型的学习、Trainer类的实现
CBOW 模型的學習的實現:給神經網絡準備好學習數據。然后求梯度,并逐步更新權重參數。
Trainer類:學習的類。
初始化:類的初始化程序接收神經網絡(模型)和優化器(SGD、Momentum、AdaGrad、Adam)
學習:調用 fit() 方法開始學習。參數:x,輸入數據;t,監督標簽;max_epoch,進行學習的 epoch 數;batch_size,mini-batch 的大小;eval_interval,輸出結果(平均損失等)的間隔。 例如設置 eval_interval=20,則每 20 次迭代計算 1 次平均損失, 并將結果輸出到界面上;max_grad,梯度的最大范數。 當梯度的范數超過這個值時,縮小梯度。
def fit(self, x, t, max_epoch=10, batch_size=32, max_grad=None, eval_interval=20):plot方法:畫出 fit() 方法記錄的損失(按照 eval_interval 評價的平均損失)。
class Trainer:def __init__(self, model, optimizer):self.model = modelself.optimizer = optimizerself.loss_list = []self.eval_interval = Noneself.current_epoch = 0def fit(self, x, t, max_epoch=10, batch_size=32, max_grad=None, eval_interval=20):data_size = len(x)max_iters = data_size // batch_sizeself.eval_interval = eval_intervalmodel, optimizer = self.model, self.optimizertotal_loss = 0loss_count = 0start_time = time.time()for epoch in range(max_epoch):# 打亂idx = numpy.random.permutation(numpy.arange(data_size))x = x[idx]t = t[idx]for iters in range(max_iters):batch_x = x[iters*batch_size:(iters+1)*batch_size]batch_t = t[iters*batch_size:(iters+1)*batch_size]# 計算梯度,更新參數loss = model.forward(batch_x, batch_t)model.backward()params, grads = remove_duplicate(model.params, model.grads) # 將共享的權重整合為1個if max_grad is not None:clip_grads(grads, max_grad)optimizer.update(params, grads)total_loss += lossloss_count += 1# 評價if (eval_interval is not None) and (iters % eval_interval) == 0:avg_loss = total_loss / loss_countelapsed_time = time.time() - start_timeprint('| epoch %d | iter %d / %d | time %d[s] | loss %.2f'% (self.current_epoch + 1, iters + 1, max_iters, elapsed_time, avg_loss))self.loss_list.append(float(avg_loss))total_loss, loss_count = 0, 0self.current_epoch += 1def plot(self, ylim=None):x = numpy.arange(len(self.loss_list))if ylim is not None:plt.ylim(*ylim)plt.plot(x, self.loss_list, label='train')plt.xlabel('iterations (x' + str(self.eval_interval) + ')')plt.ylabel('loss')plt.show()這里面使用Trainer 類來執行CBOW 模型的學習。
這個model其實存的就是SimpleCBOW的成員變量。
model = SimpleCBOW(vocab_size, hidden_size)下面是調用Trainer 類:
trainer = Trainer(model, optimizer) trainer.fit(contexts, target, max_epoch, batch_size) trainer.plot() # coding: utf-8 import sys sys.path.append('..') # 為了引入父目錄的文件而進行的設定 from common.trainer import Trainer from common.optimizer import Adam from simple_cbow import SimpleCBOW from common.util import preprocess, create_contexts_target, convert_one_hotwindow_size = 1 hidden_size = 5 batch_size = 3 max_epoch = 1000text = 'You say goodbye and I say hello.' corpus, word_to_id, id_to_word = preprocess(text)vocab_size = len(word_to_id) contexts, target = create_contexts_target(corpus, window_size) target = convert_one_hot(target, vocab_size) contexts = convert_one_hot(contexts, vocab_size)model = SimpleCBOW(vocab_size, hidden_size) optimizer = Adam() trainer = Trainer(model, optimizer)trainer.fit(contexts, target, max_epoch, batch_size) trainer.plot()word_vecs = model.word_vecs for word_id, word in id_to_word.items():print(word, word_vecs[word_id])結果:
SimpleCBOW類里面成員變量有下面這個:權重矩陣W_in就是單詞的分布式表示。
# 將單詞的分布式表示設置為成員變量 self.word_vecs = W_in那就可以看看單詞的分布式表示。
word_vecs = model.word_vecs for word_id, word in id_to_word.items():print(word, word_vecs[word_id])結果如下:可見,單詞表示為了密集向量
you [-0.9987413 1.0136298 -1.4921554 0.97300434 1.0181936 ] say [ 1.161595 -1.1513934 -0.25779223 -1.1773298 -1.1531342 ] goodbye [-0.88470864 0.9155085 -0.30859873 0.9318609 0.9092796 ] and [ 0.7929211 -0.8148116 -1.8787507 -0.7845257 -0.8028278] i [-0.8925459 0.95505357 -0.29667985 0.90895575 0.90703803] hello [-1.0259517 0.97562104 -1.5057516 0.96239203 1.0297285 ] . [ 1.2134467 -1.1766206 1.6439314 -1.1993438 -1.1676227]這里面為啥是5個數,其實還是在于權重矩陣W。在SimpleCBOW類里面W_in大小是跟單詞數目和hidden_size有關的。
V, H = vocab_size, hidden_size# 初始化權重 W_in = 0.01 * np.random.randn(V, H).astype('f')在使用Trainer 類來執行CBOW 模型的學習時,設置的hidden_size = 5,所以最后單詞就表示成包含五個數的向量了。
CBOW模型的學習:調整權重,以使預測準確。也就是說,上下文是 you 和 goodbye,正確解標簽應該是 say,那么如果網絡具有良好的權重,對應正確解的神經元(say)的得分應該更高。
對神經網絡進行學習,其實是用了Softmax 函數和交叉熵誤差。使用 Softmax 函數將得分轉化為概率,再求這些概率和監督標簽之間的交叉熵誤差,并將其作為損失進行學習。推理的 CBOW 模型加上 Softmax 層和 Cross Entropy Error 層,就可以得到損失。
輸入側和輸出側的權重都可以被視為單詞的分布式表示,這里面只使用輸入側的權重作為單詞的分布式表示。
最后把之前寫的CBOW模型類放上來:
class SimpleCBOW:def __init__(self, vocab_size, hidden_size):V, H = vocab_size, hidden_size# 初始化權重W_in = 0.01 * np.random.randn(V, H).astype('f')W_out = 0.01 * np.random.randn(H, V).astype('f')# 生成層self.in_layer0 = MatMul(W_in)self.in_layer1 = MatMul(W_in)self.out_layer = MatMul(W_out)self.loss_layer = SoftmaxWithLoss()# 將所有的權重和梯度整理到列表中layers = [self.in_layer0, self.in_layer1, self.out_layer]self.params, self.grads = [], []for layer in layers:self.params += layer.paramsself.grads += layer.grads# 將單詞的分布式表示設置為成員變量self.word_vecs = W_indef forward(self, contexts, target):h0 = self.in_layer0.forward(contexts[:, 0])h1 = self.in_layer1.forward(contexts[:, 1])h = (h0 + h1) * 0.5score = self.out_layer.forward(h)loss = self.loss_layer.forward(score, target)return lossdef backward(self, dout=1):ds = self.loss_layer.backward(dout)da = self.out_layer.backward(ds)da *= 0.5self.in_layer1.backward(da)self.in_layer0.backward(da)return None總結
以上是生活随笔為你收集整理的CBOW模型的学习、Trainer类的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微变等效电路法分析放大电路
- 下一篇: 文件隐藏服务器版本信息,如何隐藏Apac