实现CBOW模型类
初始化:初始化方法的參數包括詞匯個數 vocab_size 和中間層的神經元個數 hidden_size。首先生成兩個權重(W_in 和 W_out),并用一些小的隨機值初始化這兩個權重。設置astype(‘f’),初始化將使用 32 位的浮點數。
生成層:生成兩個輸入側的 MatMul 層、一個輸出側的 MatMul 層,以及一個 Softmax with Loss 層。
保存權重和梯度:將該神經網絡中使用的權重參數和梯度分別保存在列表類型的成員變量 params 和 grads 中。
正向傳播 forward() 函數:該函數接收參數 contexts 和 target,并返回損失(loss)。這兩個參數結構如下。
contexts 是一個三維 NumPy 數組,第 0 維的元素個數是 mini-batch 的數量,第 1 維的元素個數是上下文的窗口大小,第 2 維表示 one-hot 向量。下面這個代碼取出來的是什么?
h0 = self.in_layer0.forward(contexts[:, 0])h1 = self.in_layer1.forward(contexts[:, 1])jym做了一個測試:
import sys sys.path.append('..') from common.util import preprocess #, create_co_matrix, most_similar from common.util import create_contexts_target, convert_one_hottext = 'You say goodbye and I say hello.' corpus, word_to_id, id_to_word = preprocess(text) contexts, target = create_contexts_target(corpus, window_size=1) #print(contexts) #print(target) vocab_size = len(word_to_id) target = convert_one_hot(target, vocab_size) contexts = convert_one_hot(contexts, vocab_size) print(contexts[:, 0])輸出:然后從輸出就知道了,取的是不同target的左邊的單詞。
[[1 0 0 0 0 0 0][0 1 0 0 0 0 0][0 0 1 0 0 0 0][0 0 0 1 0 0 0][0 0 0 0 1 0 0][0 1 0 0 0 0 0]]反向傳播 backward():神經網絡的反向傳播在與正向傳播相反的方向上傳播梯度。這個反向傳播從 1 出發,并將其傳向 Softmax with Loss 層。然后,將 Softmax with Loss 層的反向傳播的輸出 ds 傳到輸出側的 MatMul 層。“×”的反向傳播將正向傳播時的輸入值“交換”后乘以梯度。“+”的反向傳播將梯度“原樣”傳播。
這個backward函數里面調用的是之前寫好的層的反向傳播函數,比如loss_layer.backward(dout),因此backward函數用完之后,各個權重參數的梯度就保存在了成員變量 grads 中(這是之前寫的層里面的反向傳播函數來實現的)。先調用 forward() 函數,再調用 backward() 函數,grads 列表中的梯度被更新。
import sys sys.path.append('..') import numpy as np from common.layers import MatMul, SoftmaxWithLossclass 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總結
- 上一篇: 按120分计算成绩 mysql_Mysq
- 下一篇: LSTM的结构