Code Review) DyRep : Learning Representations over Dynamic Graphs
Paper Review :
https://velog.io/@rlawlsgus117/Paper-Review-DyRep-Learning-Representations-over-Dynamic-Graphs
Original Source Code (not official)
https://github.com/code-ball/dynamic-embedding
Modified Source Code (for me)
https://github.com/KimJinHyeon0/dynamic-embedding
소스코드가 Official이 아니여서 애초에 코드가 돌지 않았고, 포함되어있던 Dataset도 불러오지 못 해서 전체적인 코드 검증이 필요했다.
Code
1. data_processing.py
기존 dataset인 Calls.csv / Proximity.csv / RElationshipsFromSurveys.csv / SMS.csv 대신에
web-Google Dataset을 수정해서 사용하기로 했다.
Google Web Graph Source:
https://www.kaggle.com/pappukrjha/google-web-graph
작업 내용
- Edge random shuffle
- 메인 코드에서 필요한 k(1) 추가 (전부 Communication으로 가정)
- Train : Test = 8 : 2
- 메인 코드에서 train data와 test data를 다른 파일로 불러오기 때문에 train / test 개별 저장
import numpy as np
import random
data_path = './data/web-Google.txt'
with open(data_path, 'r') as f:
data = f.read().replace("\n", ",").split(",")
del data[:5]
# add random k (0,1)
for i in range(len(data)):
# random_k = random.randint(0, 1)
# data[i] += '\t'+str(random_k)
data[i] += '\t1'
#split into train/test
dataset = np.array(data)
dataset = np.random.permutation(dataset)
test_size = int(len(data)*0.2)
train_size = test_size * 4
test_data = dataset[:test_size]
train_data = dataset[test_size:]
#save files
f = open('./data/web-Google_dyrep_train.txt', 'w')
f.write('\n'.join(train_data))
f.close()
f = open('./data/web-Google_dyrep_test.txt', 'w')
f.write('\n'.join(test_data))
f.close()
2. data_loader.py 데이터 읽기 오류
1번에서 수정한 dataset을 읽는것도 중간에서 오류 발생했다.
400만개 정도 되는 Edge들 중에서 몇 개가 읽히지 않았다.
-> 일일히 범위 좁혀가면서 찾음
3471570번 데이터에 FromNode랑 ToNode가 없었다.
-> raw data는 빵꾸 없는데 왜 생긴지 모름 (?)
data_loader에서 3471570번 데이터만 삭제
(수정) data_processing 다시 돌리니 문제 해결 (일시적 오류였던 것 같다.)
3. torch.narrow
torch.narrow 언제 쓰는지 정확히 몰랐는데 짤짤이 털 때(?) 쓰는 듯하다.
...
train_data = [[float(i) for i in train_data[p].split("\t")] for p in range(len(train_data)-1)]
train_data = torch.from_numpy(np.array(train_data, dtype=float))
print('original train_data : ', train_data.shape)
train_batch_num = train_data.size(0) // batch
train_data = train_data.narrow(0, 0, train_batch_num * batch) #짤 털기
print('\nnarrowed train_data : ', train_data.shape)
...
그림으로 보면 이해가 빠르다 (짤짤이 30 삭제)
4. .cuda() 추가
cuda 설정이 안 되어있어서 .cuda() 추가
cuda = torch.device('cuda')
5. model.py - AttributeError: 'int' object has no attribute 'data'
111~112행에서 latest_embeddings.data를 int의 data로 불러오고 있었다. (수정)
v1.data -> v1
v2.data -> v2
6. main.py - IndexError: index 361554 is out of bounds for dimension 0 with size 100
web-Google.txt 문제인데 얘네는 node가 510000개면서 nodeid는 910000번대까지 있다.
그래서 IndexError 터진 듯.
-> opt.nodes (number of nodes in graph, default=100)를 여유있게 100만으로 줬다.
...
dynemb = dynemb(1000000, opt.emsize, opt.ndyn, opt.eval_batch_size)
...
7. main.py - TypeError: 'builtin_function_or_method' object is not subscriptable
batch마다 잘 돌길래 됐나보다 했더니 100 batch마다 돌아가는 구문에서 오류가 나왔다.
original code:
if i % opt.log_interval == 0 and i > 0:
cur_loss = total_loss.item[0] / opt.log_interval
epoch_loss += cur_loss
elapsed = time.time() - start_time
print('| Epoch {:3d} | {:3d}/{:3d} batches | lr {:2.4f} | Training Time {:5.2f} s/batch | '
'Current Training Loss {:5.2f}'.format(
epoch + 1, i, batch_num, lr,
elapsed / opt.log_interval, cur_loss))
total_loss = 0
start_time = time.time()
main.py의 88행, 위 코드의 2행에서 오류가 떴다.
출력해보니 total_loss가 죄다 nan이였다.
거슬러 올라가보니 model.py에서 임베딩 칠 때가 문제였다.
8. model.py
def forward(self, input, node_list, N, eval_phase=0):
outputv1_intent = []
outputv1_surv = []
for i in range(input.size(0)):
inp_tuple = input[i]
v1 = int(inp_tuple.data[0])
v2 = int(inp_tuple.data[1])
l = int(inp_tuple.data[3])
k = int(inp_tuple.data[4])
if self.embed_available.data[int(inp_tuple.data[0])]:
v1_emb = self.latest_embeddings[int(inp_tuple.data[0])].view(1, 1, self.em_size)
else:
emb_inp = Variable(torch.LongTensor([[int(inp_tuple.data[0])]]))
v1_emb = self.initial_embeddings(emb_inp)
self.embed_available.data[int(inp_tuple.data[0])] = 1
if self.embed_available.data[int(inp_tuple.data[1])]:
v2_emb = self.latest_embeddings[int(inp_tuple.data[1])].view(1, 1, self.em_size)
else:
emb_inp = Variable(torch.LongTensor([[int(inp_tuple.data[1])]]))
v2_emb = self.initial_embeddings(emb_inp)
self.embed_available.data[int(inp_tuple.data[1])] = 1
model.py의 82~83행과 89~90행, 위 코드의 11~12행과 18~19행 if문이 문제였다.
latest_embeddings 통과하고 나온 임베딩 값이 안 예쁘게(?) 나왔다.
latest_embeddings :
self.latest_embeddings = Variable(torch.zeros(nsize, em_size)).cuda()
(수정)
계속 보다보니 lastest_embeddings 자체는 문제가 없는 것으로 결론내렸다.
오히려 임베딩 거치고 나온 데이터들이 서로 같은 값인 것에 의문을 가지다가
문제 5번에서 v1.data -> v1로 고친 것이 잘못 되었음을 깨달았다.
원본 코드에서는 v1.data였는데, v1으로 고치는 것이 아닌, v1_emb로 고쳐야했다.
self.latest_embeddings.data[int(inp_tuple.data[0])] = v1_emb.data # origin = v1.data
self.latest_embeddings.data[int(inp_tuple.data[1])] = v2_emb.data # origin = v2.data
9. 시간 문제
연구실 서버가 있긴 하지만 지금 쓸 수 있는 상황이 아니라서 우선 급한대로 노트북으로 코드를 돌리고 있다.
배치 당 대략 4초 정도 걸리는데, 1 epoch당 13613 배치가 있으니 단순 계산만 잡아도
13613batch * 4sec = 54,452sec. 약 15시간이 걸린다. 1 에폭당 15시간인데 3에폭을 줬으니 45시간이 걸릴텐데 우선 두고봐야겠다.
10. IndexError
11. 새로운 데이터셋에서 작업 시작.
Author And Source
이 문제에 관하여(Code Review) DyRep : Learning Representations over Dynamic Graphs), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rlawlsgus117/Code-Review-DyRep-Learning-Representations-over-Dynamic-Graphs저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)