TaxoRec部署與程式碼閱讀

Exungsh💫發表於2024-03-10

部署環境

  1. Pytorch 1.8.1
  2. Python 3.7.3
conda create -n pytorch-taxorec python=3.7.3
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torch==1.8.1
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple geoopt==0.2.0
::根據geoot文件,geoot0.2.0以上版本安裝時會安裝torch1.9.0,故使用0.2.0版本
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scikit-learn

遇到的問題

匯入模組報錯

發生異常: ModuleNotFoundError
No module named 'utils'
  File "C:\Users\13666\Desktop\tan\TaxoRec-master\models\model.py", line 6, in <module>
    from utils.helper import default_device
ModuleNotFoundError: No module named 'utils'

解決:
當匯入模組時,Python直譯器會搜尋 sys.path 中的所有路徑,如果找不到模組所在的路徑就會報錯,所以自定義模組要處於 sys.path 裡才能被匯入。
除錯的時候的model.py位於\TaxoRec-master\models\目錄下,所以sys.path包含當前執行的檔案目錄,而不包含utils資料夾目錄,故找不到utils模組。

import sys
sys.path.append('C:\\Users\\13666\\Desktop\\tan\\TaxoRec-master')

tensor型別不匹配

Traceback (most recent call last):
  File "C:\Users\13666\Desktop\tan\TaxoRec-master\models\model.py", line 86, in decode
    emb_in = h[idx[:, 0]]
IndexError: tensors used as indices must be long, byte or bool tensors

解決:
idx轉化為long型別,修改所有類似的程式碼

emb_in = h[idx[:, 0].long()]

UnboundLocalError

Traceback (most recent call last):
  File "C:\Users\13666\Desktop\tan\TaxoRec-master\models\model.py", line 169, in cluster_loss
    scores = scores / scores.max()
UnboundLocalError: local variable 'scores' referenced before assignment

出錯程式碼:

if len(node) == 0 or len(node) == 1:
	continue
try:
	scores = node_list[i].scores.cuda(default_device())
except Exception as e:
	print(node_list[i].term_ids, k, i)
scores = scores / scores.max()

一個不太明白的報錯,這裡scores在try中已經有了定義,UnboundLocalError通常是區域性變數未定義就使用導致的。

解決:

if len(node) == 0 or len(node) == 1:
	continue
try:
	scores = node_list[i].scores.cuda(default_device())
except Exception as e:
	print(node_list[i].term_ids, k, i)
	continue #test
scores = scores / scores.max()

不知道這樣修改有沒有隱式的風險。

程式碼執行

Epoch: 0799 6.710 time: 2.0359s 
0.0356  0.0588  0.0968  0.1589
0.042   0.0482  0.0605  0.0784
best_eval [0.06039383853310364, 0.09928730412048004, 0.04828638527394727, 0.0614728631325225]
best_eval [0.06039383853310364, 0.09928730412048004, 0.04828638527394727, 0.0614728631325225]

輸出解讀與程式碼思路

第一行輸出程式碼

print(" ".join(['Epoch: {:04d}'.format(epoch),
                        '{:.3f}'.format(avg_loss),
                        'time: {:.4f}s'.format(time.time() - t)]), end=' ')

799為輪數,6.710為平均損失,2.0359s為第799輪訓練時間

第二到五行輸出程式碼

results = eval_rec(pred_matrix, data)
...
print('\t'.join([str(round(x, 4)) for x in results[0]]))
print('\t'.join([str(round(x, 4)) for x in results[-1]]))
print('best_eval', best_metric)
if unchange == 200:
	print('best_eval', best_metric)
	break

這裡的eval_rec函式返回了recallndcg兩個列表,分別代表了
Recall@5, Recall@10, Recall@20, Recall@50
以及
NDCG@5, NDCG@10, NDCG@20, NDCG@50的數值,即

0.0356  0.0588  0.0968  0.1589
0.042   0.0482  0.0605  0.0784

best_eval指的是整個系統的最佳效能,根據前面

recalls = results[0]
if recalls[1] > best_metric[0]:
    best_metric[0] = recalls[1]
    best_metric[2] = results[1][1]
    torch.save(model.state_dict(), save_path)
    unchange = 0
if recalls[2] > best_metric[1]:
    best_metric[1] = recalls[2]
    best_metric[3] = results[1][2]
    torch.save(model.state_dict(), save_path)
    unchange = 0
else:
    unchange += args.eval_freq

可以得出best_metric中儲存的分別為[Recall@10,Recall@20,NDCG@10,NDCG@20]的最大值,和資料基本吻合。

image

參考資料:

Melinda315/TaxoRec (github.com)

Releases · geoopt/geoopt (github.com)

解決Python匯入自定義模組時ModuleNotFoundError問題

相關文章