邻接矩阵 to pyg需要的edge_index格式
scipy 1 2 3 import torchA = torch.rand([10 ,10 ]) A
tensor([[0.8253, 0.2458, 0.9340, 0.4631, 0.5114, 0.3248, 0.8528, 0.6354, 0.2988,
0.1087],
[0.0190, 0.5693, 0.4843, 0.9588, 0.6011, 0.5755, 0.4621, 0.7694, 0.0637,
0.9790],
[0.6978, 0.9686, 0.9701, 0.2234, 0.5633, 0.9978, 0.9766, 0.3365, 0.3512,
0.2396],
[0.3582, 0.9965, 0.7739, 0.5641, 0.7275, 0.3078, 0.1826, 0.5449, 0.6566,
0.1949],
[0.8194, 0.7996, 0.9177, 0.3419, 0.5239, 0.7048, 0.4503, 0.0758, 0.2244,
0.0659],
[0.6131, 0.3546, 0.0789, 0.2735, 0.0781, 0.8000, 0.0587, 0.6644, 0.2678,
0.6351],
[0.7244, 0.0463, 0.9280, 0.6456, 0.6837, 0.0763, 0.0759, 0.0440, 0.1849,
0.8942],
[0.3589, 0.6925, 0.2334, 0.3476, 0.6695, 0.1048, 0.1470, 0.5548, 0.4736,
0.6934],
[0.0356, 0.8016, 0.6176, 0.2867, 0.1340, 0.7196, 0.0562, 0.5548, 0.7376,
0.2841],
[0.9301, 0.1725, 0.4012, 0.3893, 0.8366, 0.1587, 0.3342, 0.7945, 0.8123,
0.8724]])
1 2 3 4 import scipy.sparse as spadj = sp.coo_matrix(A) values = adj.data values,adj.row,adj.col
(array([0.825252 , 0.24581629, 0.9340454 , 0.4631123 , 0.51142365,
0.32479858, 0.85282457, 0.63537604, 0.29877287, 0.10873711,
0.01895636, 0.5693259 , 0.48427123, 0.9587981 , 0.6010562 ,
0.57548887, 0.46208388, 0.7693816 , 0.06371653, 0.97895676,
0.6978117 , 0.9685761 , 0.97011906, 0.22341514, 0.56326205,
0.9978037 , 0.97661865, 0.33654213, 0.35123014, 0.23959029,
0.358207 , 0.99651885, 0.7739324 , 0.5641022 , 0.72754997,
0.3077591 , 0.18257308, 0.5449101 , 0.65663534, 0.1949212 ,
0.8193548 , 0.79964596, 0.9176568 , 0.34189552, 0.5239384 ,
0.70477635, 0.4503097 , 0.07584941, 0.22442049, 0.06589556,
0.6130815 , 0.35458 , 0.07890564, 0.27350843, 0.07805085,
0.79995 , 0.05868119, 0.66441715, 0.267847 , 0.6351336 ,
0.72437716, 0.04632962, 0.92803836, 0.645646 , 0.6836786 ,
0.07632524, 0.07594979, 0.04397732, 0.18492383, 0.89419115,
0.3588807 , 0.6925135 , 0.23337674, 0.34763372, 0.66951907,
0.10478634, 0.14702266, 0.55476344, 0.47362745, 0.69343317,
0.03562325, 0.80160064, 0.6175768 , 0.2867241 , 0.13401723,
0.719559 , 0.05618161, 0.55481714, 0.7375902 , 0.28414857,
0.9300911 , 0.17248052, 0.4012187 , 0.38931435, 0.83664143,
0.15867668, 0.3341686 , 0.7945494 , 0.81226593, 0.8724434 ],
dtype=float32),
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9], dtype=int32),
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32))
1 2 3 4 import numpy as npindices = np.vstack((adj.row,adj.col)) edge_index = torch.LongTensor(indices) edge_index,edge_index.shape
(tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9]]),
torch.Size([2, 100]))
1 2 3 edge_attr = adj.data edge_attr = torch.FloatTensor(edge_attr) edge_attr,edge_attr.shape
(tensor([0.8253, 0.2458, 0.9340, 0.4631, 0.5114, 0.3248, 0.8528, 0.6354, 0.2988,
0.1087, 0.0190, 0.5693, 0.4843, 0.9588, 0.6011, 0.5755, 0.4621, 0.7694,
0.0637, 0.9790, 0.6978, 0.9686, 0.9701, 0.2234, 0.5633, 0.9978, 0.9766,
0.3365, 0.3512, 0.2396, 0.3582, 0.9965, 0.7739, 0.5641, 0.7275, 0.3078,
0.1826, 0.5449, 0.6566, 0.1949, 0.8194, 0.7996, 0.9177, 0.3419, 0.5239,
0.7048, 0.4503, 0.0758, 0.2244, 0.0659, 0.6131, 0.3546, 0.0789, 0.2735,
0.0781, 0.8000, 0.0587, 0.6644, 0.2678, 0.6351, 0.7244, 0.0463, 0.9280,
0.6456, 0.6837, 0.0763, 0.0759, 0.0440, 0.1849, 0.8942, 0.3589, 0.6925,
0.2334, 0.3476, 0.6695, 0.1048, 0.1470, 0.5548, 0.4736, 0.6934, 0.0356,
0.8016, 0.6176, 0.2867, 0.1340, 0.7196, 0.0562, 0.5548, 0.7376, 0.2841,
0.9301, 0.1725, 0.4012, 0.3893, 0.8366, 0.1587, 0.3342, 0.7945, 0.8123,
0.8724]),
torch.Size([100]))
torch** 使用前面的方法,当传入cuda的输入然后进行转换时,前面的方法只能在cpu上执行,因为cuda不支持numpy(),需要进行cpu和cuda的转换。(一直以为是因为数据传输等方面可能的影响导致我的速度变慢,但是似乎影响更大的是因为后续模型加载非成batch))
torch的方法不需要
1 2 3 import torchA = torch.rand([10 ,10 ]) A
tensor([[0.8176, 0.2545, 0.6473, 0.2937, 0.9869, 0.0929, 0.6526, 0.6831, 0.0242,
0.3227],
[0.8430, 0.0125, 0.0166, 0.2306, 0.6767, 0.7800, 0.3947, 0.5706, 0.1307,
0.3265],
[0.8983, 0.5701, 0.0590, 0.0370, 0.1142, 0.9176, 0.0413, 0.7737, 0.8839,
0.9673],
[0.2120, 0.0877, 0.8496, 0.2748, 0.2316, 0.1640, 0.2160, 0.1306, 0.4602,
0.9815],
[0.8076, 0.4725, 0.8042, 0.3854, 0.4384, 0.9577, 0.5992, 0.5335, 0.9595,
0.1808],
[0.3166, 0.5219, 0.1348, 0.2726, 0.6527, 0.7875, 0.2952, 0.6067, 0.5722,
0.0738],
[0.2799, 0.3344, 0.2588, 0.3888, 0.6586, 0.3389, 0.3849, 0.0184, 0.8913,
0.5702],
[0.5489, 0.5952, 0.3463, 0.6634, 0.1480, 0.4949, 0.3449, 0.6737, 0.5059,
0.1255],
[0.3011, 0.6796, 0.9407, 0.1118, 0.2194, 0.9374, 0.2392, 0.1681, 0.4226,
0.9818],
[0.7948, 0.4114, 0.2621, 0.5588, 0.2609, 0.7126, 0.6315, 0.7893, 0.2553,
0.4072]])
1 2 adj = A.to_sparse() adj, adj.indices(),adj.values()
(tensor(indices=tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9]]),
values=tensor([0.8176, 0.2545, 0.6473, 0.2937, 0.9869, 0.0929, 0.6526,
0.6831, 0.0242, 0.3227, 0.8430, 0.0125, 0.0166, 0.2306,
0.6767, 0.7800, 0.3947, 0.5706, 0.1307, 0.3265, 0.8983,
0.5701, 0.0590, 0.0370, 0.1142, 0.9176, 0.0413, 0.7737,
0.8839, 0.9673, 0.2120, 0.0877, 0.8496, 0.2748, 0.2316,
0.1640, 0.2160, 0.1306, 0.4602, 0.9815, 0.8076, 0.4725,
0.8042, 0.3854, 0.4384, 0.9577, 0.5992, 0.5335, 0.9595,
0.1808, 0.3166, 0.5219, 0.1348, 0.2726, 0.6527, 0.7875,
0.2952, 0.6067, 0.5722, 0.0738, 0.2799, 0.3344, 0.2588,
0.3888, 0.6586, 0.3389, 0.3849, 0.0184, 0.8913, 0.5702,
0.5489, 0.5952, 0.3463, 0.6634, 0.1480, 0.4949, 0.3449,
0.6737, 0.5059, 0.1255, 0.3011, 0.6796, 0.9407, 0.1118,
0.2194, 0.9374, 0.2392, 0.1681, 0.4226, 0.9818, 0.7948,
0.4114, 0.2621, 0.5588, 0.2609, 0.7126, 0.6315, 0.7893,
0.2553, 0.4072]),
size=(10, 10), nnz=100, layout=torch.sparse_coo),
tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9]]),
tensor([0.8176, 0.2545, 0.6473, 0.2937, 0.9869, 0.0929, 0.6526, 0.6831, 0.0242,
0.3227, 0.8430, 0.0125, 0.0166, 0.2306, 0.6767, 0.7800, 0.3947, 0.5706,
0.1307, 0.3265, 0.8983, 0.5701, 0.0590, 0.0370, 0.1142, 0.9176, 0.0413,
0.7737, 0.8839, 0.9673, 0.2120, 0.0877, 0.8496, 0.2748, 0.2316, 0.1640,
0.2160, 0.1306, 0.4602, 0.9815, 0.8076, 0.4725, 0.8042, 0.3854, 0.4384,
0.9577, 0.5992, 0.5335, 0.9595, 0.1808, 0.3166, 0.5219, 0.1348, 0.2726,
0.6527, 0.7875, 0.2952, 0.6067, 0.5722, 0.0738, 0.2799, 0.3344, 0.2588,
0.3888, 0.6586, 0.3389, 0.3849, 0.0184, 0.8913, 0.5702, 0.5489, 0.5952,
0.3463, 0.6634, 0.1480, 0.4949, 0.3449, 0.6737, 0.5059, 0.1255, 0.3011,
0.6796, 0.9407, 0.1118, 0.2194, 0.9374, 0.2392, 0.1681, 0.4226, 0.9818,
0.7948, 0.4114, 0.2621, 0.5588, 0.2609, 0.7126, 0.6315, 0.7893, 0.2553,
0.4072]))
1 2 3 indices = adj.indices() edge_index = indices edge_index,edge_index.shape
(tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9],
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
6, 7, 8, 9]]),
torch.Size([2, 100]))
1 2 edge_attr = adj.values() edge_attr,edge_attr.shape
(tensor([0.8176, 0.2545, 0.6473, 0.2937, 0.9869, 0.0929, 0.6526, 0.6831, 0.0242,
0.3227, 0.8430, 0.0125, 0.0166, 0.2306, 0.6767, 0.7800, 0.3947, 0.5706,
0.1307, 0.3265, 0.8983, 0.5701, 0.0590, 0.0370, 0.1142, 0.9176, 0.0413,
0.7737, 0.8839, 0.9673, 0.2120, 0.0877, 0.8496, 0.2748, 0.2316, 0.1640,
0.2160, 0.1306, 0.4602, 0.9815, 0.8076, 0.4725, 0.8042, 0.3854, 0.4384,
0.9577, 0.5992, 0.5335, 0.9595, 0.1808, 0.3166, 0.5219, 0.1348, 0.2726,
0.6527, 0.7875, 0.2952, 0.6067, 0.5722, 0.0738, 0.2799, 0.3344, 0.2588,
0.3888, 0.6586, 0.3389, 0.3849, 0.0184, 0.8913, 0.5702, 0.5489, 0.5952,
0.3463, 0.6634, 0.1480, 0.4949, 0.3449, 0.6737, 0.5059, 0.1255, 0.3011,
0.6796, 0.9407, 0.1118, 0.2194, 0.9374, 0.2392, 0.1681, 0.4226, 0.9818,
0.7948, 0.4114, 0.2621, 0.5588, 0.2609, 0.7126, 0.6315, 0.7893, 0.2553,
0.4072]),
torch.Size([100]))
edge_index to 邻接矩阵 1 2 3 4 import scipy.sparse as spfrom torch import sparse_coo_tensoradj = sparse_coo_tensor(edge_index,edge_attr,[10 ,10 ]) adj.to_dense()
tensor([[4.5977e-01, 6.6455e-01, 4.3946e-01, 3.8642e-01, 1.2331e-01, 2.9945e-01,
2.5433e-01, 9.7476e-01, 4.5961e-04, 5.9594e-02],
[2.2455e-01, 9.7698e-01, 8.7531e-01, 2.8142e-01, 7.0980e-01, 6.2595e-01,
2.3625e-01, 5.7737e-01, 4.4227e-01, 6.5420e-01],
[5.4512e-01, 2.4614e-01, 6.9270e-01, 6.8005e-01, 1.3384e-01, 5.9974e-01,
9.2275e-01, 3.6578e-01, 3.5667e-01, 5.8081e-01],
[9.6142e-02, 8.5471e-01, 5.9899e-02, 3.0163e-01, 2.9641e-01, 2.8706e-01,
4.8757e-01, 8.8466e-01, 3.4357e-01, 9.9034e-01],
[4.5909e-01, 7.2475e-01, 2.4294e-01, 7.3560e-01, 3.2247e-01, 7.6749e-01,
3.6008e-01, 3.0816e-01, 7.4665e-01, 6.7713e-01],
[6.6836e-01, 8.9111e-01, 8.0428e-01, 7.9984e-01, 6.5296e-01, 8.1743e-01,
8.8702e-01, 3.6678e-01, 4.2774e-01, 2.3170e-02],
[8.1350e-01, 1.6834e-01, 7.7933e-02, 3.8021e-01, 9.7750e-01, 5.6143e-01,
7.9341e-01, 3.7514e-01, 9.3114e-01, 5.6821e-01],
[8.4002e-01, 9.2273e-01, 5.6649e-01, 7.5386e-01, 9.1587e-01, 3.9596e-02,
8.9435e-01, 5.6476e-01, 2.3289e-01, 1.9653e-01],
[2.1682e-01, 2.8950e-01, 7.5310e-01, 6.7648e-01, 5.1057e-02, 1.6519e-01,
5.8807e-01, 9.4542e-02, 6.3111e-01, 2.9049e-01],
[5.7742e-02, 3.1503e-01, 5.6936e-01, 2.2748e-01, 4.8668e-01, 6.4949e-01,
6.1752e-01, 3.9269e-01, 2.7897e-01, 5.5806e-01]])
1 2 adj = sp.coo_matrix((edge_attr,(edge_index[0 ],edge_index[1 ])),shape=[10 ,10 ]) adj.toarray()
array([[4.5977378e-01, 6.6455245e-01, 4.3945801e-01, 3.8642406e-01,
1.2331247e-01, 2.9944807e-01, 2.5433010e-01, 9.7475851e-01,
4.5961142e-04, 5.9593856e-02],
[2.2454953e-01, 9.7697508e-01, 8.7531334e-01, 2.8141612e-01,
7.0980257e-01, 6.2595367e-01, 2.3624879e-01, 5.7737088e-01,
4.4226754e-01, 6.5420014e-01],
[5.4512197e-01, 2.4613553e-01, 6.9269532e-01, 6.8004644e-01,
1.3383734e-01, 5.9973723e-01, 9.2274553e-01, 3.6578351e-01,
3.5666680e-01, 5.8080733e-01],
[9.6142113e-02, 8.5471165e-01, 5.9899449e-02, 3.0162632e-01,
2.9641372e-01, 2.8705674e-01, 4.8757398e-01, 8.8466209e-01,
3.4356719e-01, 9.9034435e-01],
[4.5909441e-01, 7.2474545e-01, 2.4293584e-01, 7.3560286e-01,
3.2246715e-01, 7.6749289e-01, 3.6007798e-01, 3.0815858e-01,
7.4665487e-01, 6.7713338e-01],
[6.6836429e-01, 8.9111018e-01, 8.0427557e-01, 7.9984426e-01,
6.5295666e-01, 8.1743485e-01, 8.8702154e-01, 3.6678237e-01,
4.2774427e-01, 2.3170471e-02],
[8.1350172e-01, 1.6834372e-01, 7.7932715e-02, 3.8021082e-01,
9.7749555e-01, 5.6143039e-01, 7.9341477e-01, 3.7514049e-01,
9.3114382e-01, 5.6820768e-01],
[8.4002483e-01, 9.2273450e-01, 5.6649190e-01, 7.5385606e-01,
9.1587120e-01, 3.9596200e-02, 8.9435184e-01, 5.6475997e-01,
2.3288828e-01, 1.9652534e-01],
[2.1682233e-01, 2.8950059e-01, 7.5310403e-01, 6.7648250e-01,
5.1056564e-02, 1.6518539e-01, 5.8806950e-01, 9.4541669e-02,
6.3110876e-01, 2.9048622e-01],
[5.7742238e-02, 3.1502587e-01, 5.6935811e-01, 2.2748303e-01,
4.8667991e-01, 6.4949030e-01, 6.1752105e-01, 3.9268762e-01,
2.7897447e-01, 5.5806071e-01]], dtype=float32)
构建自定义边权重的GNN 胡乱定值的 代码修改自:https://zhuanlan.zhihu.com/p/426907570
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from torch_geometric.nn import GATConvclass Net (torch.nn.Module): def __init__ (self ): super (Net, self).__init__() self.conv1 = GCNConv(data.num_features, 16 , cached=True , normalize=True ) self.conv2 = GCNConv(16 , 2 , cached=True , normalize=True ) def forward (self ): x, edge_index, edge_weight = data.x, data.edge_index, data.edge_attr x = F.relu(self.conv1(x, edge_index, edge_weight)) x = F.dropout(x, training=self.training) x = self.conv2(x, edge_index, edge_weight) return F.log_softmax(x, dim=1 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import torchimport torch.nn.functional as Ffrom torch_geometric.nn import GCNConv, ChebConv from torch_geometric.data import data as Dfrom torch_geometric.data import datasetx = torch.tensor([[1 ],[2 ],[3 ],[4 ],[5 ],[6 ],[7 ],[8 ],[9 ],[10 ]], dtype=torch.float ) print (x.shape)x = torch.ones(10 ,dtype=torch.float ).unsqueeze(-1 ) y = torch.randint(0 ,2 ,[10 ]) train_mask = torch.tensor([True , True , True ,True ,True ,True ,True ,True ,True ,True ], dtype=torch.bool ) val_mask=train_mask test_mask=train_mask data=D.Data() data.x,data.y,data.edge_index,data.edge_attr,data.train_mask,data.val_mask,data.test_mask \ = x,y,edge_index,edge_attr,train_mask,val_mask,test_mask
torch.Size([10, 1])
1 2 3 4 5 6 7 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu' ) model, data = Net().to(device), data.to(device) optimizer = torch.optim.Adam([ dict (params=model.conv1.parameters(), weight_decay=5e-4 ), dict (params=model.conv2.parameters(), weight_decay=0 ) ], lr=0.01 )
1 2 3 4 5 6 def train (): model.train() optimizer.zero_grad() F.nll_loss(model()[data.train_mask], data.y[data.train_mask]).backward() optimizer.step()
1 2 3 4 5 6 7 8 9 @torch.no_grad() def test (): model.eval () logits, accs = model(), [] for _, mask in data('train_mask' , 'val_mask' , 'test_mask' ): pred = logits[mask].max (1 )[1 ] acc = pred.eq(data.y[mask]).sum ().item() / mask.sum ().item() accs.append(acc) return accs
1 2 3 4 5 6 7 8 9 best_val_acc = test_acc = 0 for epoch in range (1 , 10 ): train() train_acc, val_acc, tmp_test_acc = test() if val_acc > best_val_acc: best_val_acc = val_acc test_acc = tmp_test_acc log = 'Epoch: {:03d}, Train: {:.4f}, Val: {:.4f}, Test: {:.4f}' print (log.format (epoch, train_acc, best_val_acc, test_acc))
Epoch: 001, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 002, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 003, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 004, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 005, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 006, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 007, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 008, Train: 0.5000, Val: 0.5000, Test: 0.5000
Epoch: 009, Train: 0.5000, Val: 0.5000, Test: 0.5000
批量 单独传入,stack结果 1 2 3 4 5 6 7 8 9 10 11 12 13 class Net (torch.nn.Module): def __init__ (self ): super (Net, self).__init__() self.layer = GATConv(in_channels=16 , out_channels=16 ) self.layer2 = GATConv(in_channels=16 , out_channels=1 ) def forward (self,x,edg_index ): output = torch.stack([self.layer(graph, edge_index=edge_indexi) for graph,edge_indexi in zip (x,edg_index)], dim=0 ) output = torch.stack([self.layer2(graph, edge_index=edge_indexi) for graph,edge_indexi in zip (output,edg_index)], dim=0 ) return output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from torch_geometric.nn import GATConvx = torch.randn((8 , 207 , 16 )) y = torch.rand([8 ,207 ,1 ]).float () edge_index = torch.randint(high=206 , size=(2 , 1200 )) edge_index = edge_index.repeat(8 ,1 ,1 ) model = Net() optimizer = torch.optim.Adam(params=model.parameters(),lr=0.01 ) model.train() import times = time.time() for e in range (3 ): optimizer.zero_grad() out = model(x,edge_index) loss = F.mse_loss(out, y) loss.backward() optimizer.step() print (loss.item()) print ("time:" ,time.time()-s)
0.7729121446609497
0.41821303963661194
0.384408563375473
time: 0.09303927421569824
Batch+Data 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from torch_geometric.nn import GATConvfrom torch import nnclass Net (torch.nn.Module): def __init__ (self ): super (Net, self).__init__() self.layer = GATConv(in_channels=16 , out_channels=16 ) self.layer2 = GATConv(in_channels=16 ,out_channels=1 ) self.dropout = nn.Dropout(0.2 ) def forward (self,x,edge_index ): data_list = [Data(x=x_, edge_index=edge_indexi) for x_ , edge_indexi in zip (x,edge_index)] batch = Batch.from_data_list(data_list) output = self.layer(batch.x, edge_index=batch.edge_index) output = self.dropout(output) data_list = [Data(x=x_, edge_index=edge_indexi) for x_ , edge_indexi in zip (torch.split(output,x.shape[1 ]),edge_index)] batch = Batch.from_data_list(data_list) output = self.layer2(batch.x,batch.edge_index) output = self.dropout(output) return output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 from torch_geometric.data import Data,Batchfrom torch_geometric.nn import GATConvimport torch.nn.functional as Fimport timex = torch.randn((8 , 207 , 16 )) y = torch.rand([8 ,207 ,1 ]).float () edge_index = torch.randint(high=206 , size=(2 , 1200 )) print (edge_index.shape)edge_index = edge_index.repeat(8 ,1 ,1 ) print (edge_index.shape)model = Net() optimizer = torch.optim.Adam(params=model.parameters(),lr=0.01 ) model.train() s = time.time() for e in range (3 ): optimizer.zero_grad() result = model(x,edge_index) result = torch.stack(torch.split(result,x.shape[1 ])) print ("reshape the output:" ,result.shape) loss = F.mse_loss(result, y) loss.backward() optimizer.step() print (loss.item()) print ("time:" ,time.time()-s)
torch.Size([2, 1200])
torch.Size([8, 2, 1200])
reshape the output: torch.Size([8, 207, 1])
2.3954498767852783
reshape the output: torch.Size([8, 207, 1])
1.1830278635025024
reshape the output: torch.Size([8, 207, 1])
0.9167585372924805
time: 0.05799269676208496
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from torch_geometric.data import Data,Batchfrom torch_geometric.nn import GATConvimport torch.nn.functional as Fx = torch.randn((8 , 207 , 16 )) y = torch.rand([8 ,207 ,1 ]).float () edge_index = torch.randint(high=206 , size=(2 , 1200 )) print (edge_index.shape)edge_index = edge_index.repeat(8 ,1 ,1 ) print (edge_index.shape)data_list = [Data(x=x_, edge_index=edge_indexi) for x_ , edge_indexi in zip (x,edge_index)] batch = Batch.from_data_list(data_list) layer = GATConv(in_channels=16 , out_channels=2 ) result = layer(batch.x, edge_index=batch.edge_index) print (result.shape)
torch.Size([2, 1200])
torch.Size([8, 2, 1200])
torch.Size([1656, 2])
1 2 3 x = torch.rand([2 , 2 , 40000 ]) for i in x: print (i.shape)
torch.Size([2, 40000])
torch.Size([2, 40000])
批量邻接矩阵转换 转换实现 转换完stack 1 2 3 4 5 6 7 8 9 10 11 def adj2coo (self,Ab ): import scipy.sparse as sp import numpy as np adj = sp.coo_matrix(Ab) edge_attr = adj.data indices = np.vstack((adj.row, adj.col)) edge_index = torch.LongTensor(indices) edge_attr = torch.FloatTensor(edge_attr) print (edge_index.shape,edge_attr.shape) return edge_index,edge_attr
1 2 edg_indexH, edge_attrH = torch.stack([self.adj2coo(i)[0 ] for i in scoadj], dim=0 ), torch.stack( [self.adj2coo(i)[1 ] for i in adj], dim=0 )
一次性解决 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def adj2edge_index (self,A ): import scipy.sparse as sp import numpy as np edg_indexAll = torch.zeros(0 ,dtype=torch.int64) edg_attrAll = torch.zeros(0 ,dtype=torch.float32) for b in A: adj = sp.coo_matrix(b) edge_attr = adj.data indices = np.vstack((adj.row, adj.col)) edge_index = torch.LongTensor(indices) edge_attr = torch.FloatTensor(edge_attr) edg_indexAll = torch.cat((edg_indexAll, edge_index)) edg_attrAll = torch.cat((edg_attrAll, edge_attr)) return edg_indexAll.view(A.shape[0 ],2 ,-1 ),edg_attrAll.view(A.shape[0 ],-1 )
应用到模型 模型中传参 1 2 3 4 5 x3 = self.relu( torch.stack( [self.gc6(graph, edge_index=self.adj2coo(edge)[0 ], edge_attr=self.adj2coo(edge)[1 ]) for graph, edge in zip (x3_h,A)], dim=0 ))
Batch+Data 效率更高,如一个epoch前面是280s,后面是90s
1 2 3 4 5 6 from torch_geometric.data import Data,Batchdata_list = [Data(x = x_,edge_ index=self.adj2coo(edge)[0 ] ,edge_attr=self.adj2coo(edge)[1 ]) for x_ ,edge in zip (x, A) ] batchH = Batch.from_data_list(data_listata_list) x1_h = self. relu(self. gc1(batchH.x, edge_index=batchH. edge_indexedge_attr=batchH.edge_attr ))