IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
8.7KB

  1. import decagon_pytorch.convolve
  2. import decagon.deep.layers
  3. import torch
  4. import tensorflow as tf
  5. import numpy as np
  6. def prepare_data():
  7. np.random.seed(0)
  8. latent = np.random.random((5, 10)).astype(np.float32)
  9. latent[latent < .5] = 0
  10. latent = np.ceil(latent)
  11. adjacency_matrices = []
  12. for _ in range(5):
  13. adj_mat = np.random.random((len(latent),) * 2).astype(np.float32)
  14. adj_mat[adj_mat < .5] = 0
  15. adj_mat = np.ceil(adj_mat)
  16. adjacency_matrices.append(adj_mat)
  17. print('latent:', latent)
  18. print('adjacency_matrices[0]:', adjacency_matrices[0])
  19. return latent, adjacency_matrices
  20. def dense_to_sparse_tf(x):
  21. a, b = np.where(x)
  22. indices = np.array([a, b]).T
  23. values = x[a, b]
  24. return tf.sparse.SparseTensor(indices, values, x.shape)
  25. def dropout_sparse_tf(x, keep_prob, num_nonzero_elems):
  26. """Dropout for sparse tensors. Currently fails for very large sparse tensors (>1M elements)
  27. """
  28. noise_shape = [num_nonzero_elems]
  29. random_tensor = keep_prob
  30. random_tensor += tf.convert_to_tensor(torch.rand(noise_shape).detach().numpy())
  31. # tf.convert_to_tensor(np.random.random(noise_shape))
  32. # tf.random_uniform(noise_shape)
  33. dropout_mask = tf.cast(tf.floor(random_tensor), dtype=tf.bool)
  34. pre_out = tf.sparse_retain(x, dropout_mask)
  35. return pre_out * (1./keep_prob)
  36. def graph_conv_torch():
  37. torch.random.manual_seed(0)
  38. latent, adjacency_matrices = prepare_data()
  39. latent = torch.tensor(latent)
  40. adj_mat = adjacency_matrices[0]
  41. adj_mat = torch.tensor(adj_mat)
  42. conv = decagon_pytorch.convolve.GraphConv(10, 10,
  43. adj_mat)
  44. latent = conv(latent)
  45. return latent
  46. def dropout_graph_conv_activation_torch(keep_prob=1.):
  47. torch.random.manual_seed(0)
  48. latent, adjacency_matrices = prepare_data()
  49. latent = torch.tensor(latent)
  50. adj_mat = adjacency_matrices[0]
  51. adj_mat = torch.tensor(adj_mat)
  52. conv = decagon_pytorch.convolve.DropoutGraphConvActivation(10, 10,
  53. adj_mat, keep_prob=keep_prob)
  54. latent = conv(latent)
  55. return latent
  56. def sparse_graph_conv_torch():
  57. torch.random.manual_seed(0)
  58. latent, adjacency_matrices = prepare_data()
  59. print('latent.dtype:', latent.dtype)
  60. latent = torch.tensor(latent).to_sparse()
  61. adj_mat = adjacency_matrices[0]
  62. adj_mat = torch.tensor(adj_mat).to_sparse()
  63. print('adj_mat.dtype:', adj_mat.dtype,
  64. 'latent.dtype:', latent.dtype)
  65. conv = decagon_pytorch.convolve.SparseGraphConv(10, 10,
  66. adj_mat)
  67. latent = conv(latent)
  68. return latent
  69. def sparse_graph_conv_tf():
  70. torch.random.manual_seed(0)
  71. latent, adjacency_matrices = prepare_data()
  72. conv_torch = decagon_pytorch.convolve.SparseGraphConv(10, 10,
  73. torch.tensor(adjacency_matrices[0]).to_sparse())
  74. weight = tf.constant(conv_torch.weight.detach().numpy())
  75. latent = dense_to_sparse_tf(latent)
  76. adj_mat = dense_to_sparse_tf(adjacency_matrices[0])
  77. latent = tf.sparse_tensor_dense_matmul(latent, weight)
  78. latent = tf.sparse_tensor_dense_matmul(adj_mat, latent)
  79. return latent
  80. def sparse_dropout_graph_conv_activation_torch(keep_prob=1.):
  81. torch.random.manual_seed(0)
  82. latent, adjacency_matrices = prepare_data()
  83. latent = torch.tensor(latent).to_sparse()
  84. adj_mat = adjacency_matrices[0]
  85. adj_mat = torch.tensor(adj_mat).to_sparse()
  86. conv = decagon_pytorch.convolve.SparseDropoutGraphConvActivation(10, 10,
  87. adj_mat, keep_prob=keep_prob)
  88. latent = conv(latent)
  89. return latent
  90. def sparse_dropout_graph_conv_activation_tf(keep_prob=1.):
  91. torch.random.manual_seed(0)
  92. latent, adjacency_matrices = prepare_data()
  93. conv_torch = decagon_pytorch.convolve.SparseGraphConv(10, 10,
  94. torch.tensor(adjacency_matrices[0]).to_sparse())
  95. weight = tf.constant(conv_torch.weight.detach().numpy())
  96. nonzero_feat = np.sum(latent > 0)
  97. latent = dense_to_sparse_tf(latent)
  98. latent = dropout_sparse_tf(latent, keep_prob,
  99. nonzero_feat)
  100. adj_mat = dense_to_sparse_tf(adjacency_matrices[0])
  101. latent = tf.sparse_tensor_dense_matmul(latent, weight)
  102. latent = tf.sparse_tensor_dense_matmul(adj_mat, latent)
  103. latent = tf.nn.relu(latent)
  104. return latent
  105. def test_sparse_graph_conv():
  106. latent_torch = sparse_graph_conv_torch()
  107. latent_tf = sparse_graph_conv_tf()
  108. assert np.all(latent_torch.detach().numpy() == latent_tf.eval(session = tf.Session()))
  109. def test_sparse_dropout_graph_conv_activation():
  110. for i in range(11):
  111. keep_prob = i/10. + np.finfo(np.float32).eps
  112. latent_torch = sparse_dropout_graph_conv_activation_torch(keep_prob)
  113. latent_tf = sparse_dropout_graph_conv_activation_tf(keep_prob)
  114. latent_torch = latent_torch.detach().numpy()
  115. latent_tf = latent_tf.eval(session = tf.Session())
  116. print('latent_torch:', latent_torch)
  117. print('latent_tf:', latent_tf)
  118. assert np.all(latent_torch - latent_tf < .000001)
  119. def test_sparse_multi_dgca():
  120. latent_torch = None
  121. latent_tf = []
  122. for i in range(11):
  123. keep_prob = i/10. + np.finfo(np.float32).eps
  124. latent_torch = sparse_dropout_graph_conv_activation_torch(keep_prob) \
  125. if latent_torch is None \
  126. else latent_torch + sparse_dropout_graph_conv_activation_torch(keep_prob)
  127. latent_tf.append(sparse_dropout_graph_conv_activation_tf(keep_prob))
  128. latent_torch = torch.nn.functional.normalize(latent_torch, p=2, dim=1)
  129. latent_tf = tf.add_n(latent_tf)
  130. latent_tf = tf.nn.l2_normalize(latent_tf, dim=1)
  131. latent_torch = latent_torch.detach().numpy()
  132. latent_tf = latent_tf.eval(session = tf.Session())
  133. assert np.all(latent_torch - latent_tf < .000001)
  134. def test_graph_conv():
  135. latent_dense = graph_conv_torch()
  136. latent_sparse = sparse_graph_conv_torch()
  137. assert np.all(latent_dense.detach().numpy() == latent_sparse.detach().numpy())
  138. def setup_function(fun):
  139. if fun == test_dropout_graph_conv_activation or \
  140. fun == test_multi_dgca:
  141. print('Disabling dropout for testing...')
  142. setup_function.old_dropout = decagon_pytorch.convolve.dropout, \
  143. decagon_pytorch.convolve.dropout_sparse
  144. decagon_pytorch.convolve.dropout = lambda x, keep_prob: x
  145. decagon_pytorch.convolve.dropout_sparse = lambda x, keep_prob: x
  146. def teardown_function(fun):
  147. print('Re-enabling dropout...')
  148. if fun == test_dropout_graph_conv_activation or \
  149. fun == test_multi_dgca:
  150. decagon_pytorch.convolve.dropout, \
  151. decagon_pytorch.convolve.dropout_sparse = \
  152. setup_function.old_dropout
  153. def test_dropout_graph_conv_activation():
  154. for i in range(11):
  155. keep_prob = i/10.
  156. if keep_prob == 0:
  157. keep_prob += np.finfo(np.float32).eps
  158. print('keep_prob:', keep_prob)
  159. latent_dense = dropout_graph_conv_activation_torch(keep_prob)
  160. latent_dense = latent_dense.detach().numpy()
  161. print('latent_dense:', latent_dense)
  162. latent_sparse = sparse_dropout_graph_conv_activation_torch(keep_prob)
  163. latent_sparse = latent_sparse.detach().numpy()
  164. print('latent_sparse:', latent_sparse)
  165. nonzero = (latent_dense != 0) & (latent_sparse != 0)
  166. assert np.all(latent_dense[nonzero] == latent_sparse[nonzero])
  167. def test_multi_dgca():
  168. keep_prob = .5
  169. torch.random.manual_seed(0)
  170. latent, adjacency_matrices = prepare_data()
  171. latent_sparse = torch.tensor(latent).to_sparse()
  172. latent = torch.tensor(latent)
  173. assert np.all(latent_sparse.to_dense().numpy() == latent.numpy())
  174. adjacency_matrices_sparse = [ torch.tensor(a).to_sparse() for a in adjacency_matrices ]
  175. adjacency_matrices = [ torch.tensor(a) for a in adjacency_matrices ]
  176. for i in range(len(adjacency_matrices)):
  177. assert np.all(adjacency_matrices[i].numpy() == adjacency_matrices_sparse[i].to_dense().numpy())
  178. torch.random.manual_seed(0)
  179. multi_sparse = decagon_pytorch.convolve.SparseMultiDGCA(10, 10, adjacency_matrices_sparse, keep_prob=keep_prob)
  180. torch.random.manual_seed(0)
  181. multi = decagon_pytorch.convolve.MultiDGCA(10, 10, adjacency_matrices, keep_prob=keep_prob)
  182. for i in range(len(adjacency_matrices)):
  183. assert np.all(multi_sparse.sparse_dgca[i].sparse_graph_conv.weight.detach().numpy() == multi.dgca[i].graph_conv.weight.detach().numpy())
  184. # torch.random.manual_seed(0)
  185. latent_sparse = multi_sparse(latent_sparse)
  186. # torch.random.manual_seed(0)
  187. latent = multi(latent)
  188. assert np.all(latent_sparse.detach().numpy() == latent.detach().numpy())