人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

python算法學習雙曲嵌入論文方法與代碼解析說明

發(fā)布日期:2021-12-14 07:41 | 文章來源:源碼中國

本篇接上一篇:python算法學習雙曲嵌入論文代碼實現(xiàn)數(shù)據(jù)集介紹

1. 方法說明

首先學習相關的論文中的一些知識,并結合進行代碼的編寫。文中主要使用Poincaré embedding。

對應的python代碼為:

def dist1(vec1, vec2): # eqn1 
 diff_vec = vec1 - vec2
 return 1 + 2 * norm(diff_vec) / ((1 - norm(vec1)) * (1 - norm(vec2)))

損失函數(shù)

我們想要尋找最優(yōu)的embedding,就需要構建一個損失函數(shù),目標是使得相似詞匯的embedding結果,盡可能接近,且層級越高(類別越大)的詞越靠近中心。我們需要最小化這個損失函數(shù),從而得到embedding的結果。

其實在傳統(tǒng)的詞嵌入中,我們也是用上述的損失函數(shù),但距離選用的是余弦距離。

梯度下降

后面將使用梯度下降方法進行求解迭代。

由于是將歐氏空間計算得到的梯度在黎曼空間中進行迭代,由上文的(1)式,我們有:

梯度求解

202111595310129

對應的更新函數(shù)在Python中設置如下:

# 范數(shù)計算
def norm(x):
 return np.dot(x, x)
# 距離函數(shù)對\theta求偏導
def compute_distance_gradients(theta, x, gamma):
 alpha = (1.0 - np.dot(theta, theta))
 norm_x = norm(x)
 beta = (1 - norm_x)
 c_ = 4.0 / (alpha * beta * sqrt(gamma ** 2 - 1))
 return c_ * ((norm_x - 2 * np.dot(theta, x) + 1) / alpha * theta - x)
# 更新公式
def update(emb, grad, lr): 
 c_ = (1 - norm(emb)) ** 2 / 4
 upd =  lr * c_ * grad
 emb = emb - upd
 if (norm(emb) >= 1):
  emb = emb / sqrt(norm(emb)) - eps
 return emb

至此,我們就可以開始寫一個完整的訓練過程了。在這之前,再補充一個繪圖函數(shù)(可以看embedding的實際訓練情況):

def plotall(ii):
 fig = plt.figure(figsize=(10, 10))
 # 繪制所有節(jié)點
 for a in emb:
  plt.plot(emb[a][0], emb[a][1], marker = 'o', color = [levelOfNode[a]/(last_level+1),levelOfNode[a]/(last_level+1),levelOfNode[a]/(last_level+1)])
 for a in network:
  for b in network[a]:
plt.plot([emb[a][0], emb[b][0]], [emb[a][1], emb[b][1]], color = [levelOfNode[a]/(last_level+1),levelOfNode[a]/(last_level+1),levelOfNode[a]/(last_level+1)])
circle = plt.Circle((0, 0), 1, color='y', fill=False)
plt.gcf().gca().add_artist(circle)
 plt.xlim(-1, 1)
 plt.ylim(-1, 1)
 fig.savefig('~/GitHub/hyperE/fig/' + str(last_level) + '_' + str(ii) + '.png', dpi = 200)

2. 代碼訓練過程

首先初始化embeddings,這里按照論文中寫的,用 ( − 0.001 , 0.001 ) (-0.001, 0.001) (−0.001,0.001)間的均勻分布進行隨機初始化:

emb = {}
for node in levelOfNode:
 emb[node] = np.random.uniform(low = -0.001, high = 0.001, size = (2, ))

下面設置學習率等參數(shù):

vocab = list(emb.keys())
eps = 1e-5 
lr = 0.1 # 學習率
num_negs = 10  # 負樣本個數(shù)

接下來開始正式迭代,具體每一行的含義均在注釋中有進行說明:

# 繪制初始化權重
plotall("init")
for epoch in range(1000):
 loss = []
 random.shuffle(vocab)
 
 # 下面需要抽取不同的樣本:pos2 與 pos1 相關;negs 不與 pos1 相關
 for pos1 in vocab:
  if not network[pos1]: # 葉子節(jié)點則不進行訓練
continue
  pos2 = random.choice(network[pos1]) # 隨機選取與pos1相關的節(jié)點pos2
  dist_pos_ = dist1(emb[pos1], emb[pos2]) # 保留中間變量gamma,加速計算
  dist_pos = np.arccosh(dist_pos_) # 計算pos1與pos2之間的距離
  
  # 下面抽取負樣本組(不與pos1相關的樣本組)
  negs = [[pos1, pos1]]
  dist_negs_ = [1] 
  dist_negs = [0]
  
  while (len(negs) < num_negs):
neg = random.choice(vocab)

# 保證負樣本neg與pos1沒有邊相連接
if not (neg in network[pos1] or pos1 in network[neg] or neg == pos1): 
 dist_neg_ = dist1(emb[pos1], emb[neg])
 dist_neg = np.arccosh(dist_neg_)
 negs.append([pos1, neg])
 dist_negs_.append(dist_neg_) # 保存中間變量gamma,加速計算
 dist_negs.append(dist_neg)
  
  # 針對一個樣本的損失
  loss_neg = 0.0
  for dist_neg in dist_negs:
loss_neg += exp(-1 * dist_neg)
  loss.append(dist_pos + log(loss_neg))
  
  # 損失函數(shù) 對 正樣本對 距離 d(u, v) 的導數(shù)
  grad_L_pos = -1
  
  # 損失函數(shù) 對 負樣本對 距離 d(u, v') 的導數(shù)
  grad_L_negs = []
  for dist_neg in dist_negs:
grad_L_negs.append(exp(-dist_neg) / loss_neg)

  # 計算正樣本對中兩個樣本的embedding的更新方向
  grad_pos1 = grad_L_pos * compute_distance_gradients(emb[pos1], emb[pos2], dist_pos_)
  grad_pos2 = grad_L_pos * compute_distance_gradients(emb[pos2], emb[pos1], dist_pos_)
  
  # 計算負樣本對中所有樣本的embedding的更新方向
  grad_negs_final = []
  for (grad_L_neg, neg, dist_neg_) in zip(grad_L_negs[1:], negs[1:], dist_negs_[1:]):
grad_neg0 = grad_L_neg * compute_distance_gradients(emb[neg[0]], emb[neg[1]], dist_neg_)
grad_neg1 = grad_L_neg * compute_distance_gradients(emb[neg[1]], emb[neg[0]], dist_neg_)
grad_negs_final.append([grad_neg0, grad_neg1])

  # 更新embeddings
  emb[pos1] = update(emb[pos1], -grad_pos1, lr)
  emb[pos2] = update(emb[pos2], -grad_pos2, lr)
  for (neg, grad_neg) in zip(negs, grad_negs_final):
emb[neg[0]] = update(emb[neg[0]], -grad_neg[0], lr)
emb[neg[1]] = update(emb[neg[1]], -grad_neg[1], lr)
 
 # 輸出損失
 if ((epoch) % 10 == 0):
  print(epoch + 1, "---Loss: ", sum(loss))
  
 # 繪制二維embeddings
 if ((epoch) % 100 == 0):
  plotall(epoch + 1)

3. 結果表現(xiàn)

結果如下所示(與論文有些不一致):

實際上應該還是有效的,有些團都能聚合在一起,下面是一個隨機訓練的結果(可以看出非?;靵y):

其他參考資料

Poincaré Embeddings for Learning Hierarchical Representations

Implementing Poincaré Embeddings

models.poincare – Train and use Poincare embeddings

How to make a graph on Python describing WordNet's synsets (NLTK)

networkx.drawing.nx_pylab.draw_networkx

以上就是python算法學習雙曲嵌入論文方法與代碼解析說明的詳細內(nèi)容,更多關于python雙曲嵌入論文方法與代碼的資料請關注本站其它相關文章!

版權聲明:本站文章來源標注為YINGSOO的內(nèi)容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。

相關文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務

7x24全年不間斷在線

專屬顧問服務

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務熱線

關注
微信

關注官方微信
頂部