1. 程式人生 > 實用技巧 >圖遊走類模型

圖遊走類模型

圖神經網路七日打卡營

1、圖與圖學習

1)圖的兩個基本元素是點和邊,是一種統一描述複雜事務的語言,常見的圖有社交網路、推薦系統、化學分子結構。

2)圖學習: Graph Learning。深度學習中的一個子領域,強調處理的資料物件為圖;與一般深度學習的區別:能夠方便地處理不規則資料(樹、圖),同時也可以處理規則資料(如影象)。

3)圖學習的應用:

  • 節點級別任務:金融詐騙檢測(典型的節點分類)、自動駕駛中的3D點雲目標檢測
  • 邊級別任務:推薦系統(典型的邊預測)
  • 圖級別任務:氣味識別(典型的圖分類)、發現“宇宙”

4)圖學習是怎麼做的:

  • 圖遊走類演算法:通過在圖上的遊走,獲得多個節點序列,再利用 Skip Gram 模型訓練得到節點表示(下節課內容)
  • 圖神經網路演算法:端到端模型,利用訊息傳遞機制實現。
  • 知識圖譜嵌入演算法:專門用於知識圖譜的相關演算法。

2、圖遊走類模型(得到節點表示(Node Embedding)用於下游任務)

1)DeepWalk取樣演算法

class UserDefGraph(Graph):
    def random_walk(self, nodes, walk_len):
        """
        輸入:nodes - 當前節點id list (batch_size,)
             walk_len - 最大路徑長度 int
        輸出:以當前節點為起點得到的路徑 list (batch_size, walk_len)

        用到的函式
        1. self.successor(nodes)
           描述:獲取當前節點的下一個相鄰節點id列表
           輸入:nodes - list (batch_size,)
           輸出:succ_nodes - list of list ((num_successors_i,) for i in range(batch_size))
        2. self.outdegree(nodes)
           描述:獲取當前節點的出度
           輸入:nodes - list (batch_size,)
           輸出:out_degrees - list (batch_size,)
        
""" walks = [[node] for node in nodes] # 儲存遊走路徑? walks_ids = np.arange(0, len(nodes)) # 有多少起始節點 cur_nodes = np.array(nodes) # 所有的起始節點 for l in range(walk_len): """選取有下一個節點的路徑繼續取樣,否則結束""" outdegree = self.outdegree(cur_nodes) # 當前節點出度 walk_mask = (outdegree != 0)
if not np.any(walk_mask): break cur_nodes = cur_nodes[walk_mask] walks_ids = walks_ids[walk_mask] outdegree = outdegree[walk_mask] ###################################### # 請在此補充程式碼取樣出下一個節點 succ_nodes = self.successor(cur_nodes) sample_index = np.floor( np.random.rand(outdegree.shape[0]) * outdegree).astype("int64") next_nodes = [] for s, ind, walk_id in zip(succ_nodes, sample_index, walks_ids): walks[walk_id].append(s[ind]) next_nodes.append(s[ind]) ###################################### cur_nodes = np.array(next_nodes) return walks

2)Node2vec取樣演算法(DeepWalk的改進)

def node2vec_sample(succ, prev_succ, prev_node, p, q):
    """
    輸入:succ - 當前節點的下一個相鄰節點id列表 list (num_neighbors,)
         prev_succ - 前一個節點的下一個相鄰節點id列表 list (num_neighbors,)
         prev_node - 前一個節點id int
         p - 控制回到上一節點的概率 float
         q - 控制偏向DFS還是BFS float
    輸出:下一個節點id int
    """
    ##################################
    # 請在此實現node2vec的節點取樣函式
    succ_len = len(succ)
    prev_succ_len = len(prev_succ)
    
    probs=[]
    prob_sum = 0
    prob = 0

    prev_succ_set = np.asarray([])
    for i in range(prev_succ_len):
        prev_succ_set= np.append(prev_succ_set, prev_succ[i])

    for i in range(succ_len):
        if succ[i] == prev_node:
            prob = 1. / p
        elif np.where(prev_succ_set==succ[i]):
            prob = 1.
        elif np.where(prev_succ_set!=succ[i]):
            prob = 1. / q
        else:
             prob=0

        probs.append(prob)
        prob_sum += prob

    RAND_MAX = 65535
    rand_num = float(np.random.randint(0, RAND_MAX+1))/RAND_MAX*prob_sum

    sample_succ = 0
    for i in range(succ_len):
        rand_num -= probs[i]
        if rand_num <= 0:
            sample_succ = succ[i]
            return sample_succ
    ################################## 

    return sampled_succ