{
  "id": 101091,
  "title": "How to best describe the problem in a Graph Neural Network?",
  "url": "/competitions/champs-scalar-coupling/discussion/101091",
  "author_name": "",
  "post_date": "2019-07-23T07:09:22.205809400Z",
  "votes": 34,
  "comment_count": 19,
  "views": 0,
  "content": "<p>I’m trying to get my head around graph neural networks and the terminology behind them. In the typical chemistry examples I have seen:\n•   Molecule = Graph\n•   Atom = Node\n•   Bond = Edge</p>\n\n<p>However, this problem seems to be a bit different since we are trying to predict a y parameter that is dependent on a pair of nodes. So I thought maybe the nodes should be pairs of adjacent atoms instead and I tried sketching out what this graph might look like for ethane (<code>dsgdb9nsd_000007</code>).</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/582430/13857/IMG_0462.JPG\" alt=\"\"></p>\n\n<p>The issue is that the middle C-C node won’t have an associated y value (i.e. a 1JCC coupling). Similarly, for the other coupling types, we may not have all the information in this format. Or maybe we don't need that C-C node?</p>\n\n<p>I think I’m confusing myself here so any ideas on how to represent this dataset in a graph network would be appreciated!</p>\n\n<p><a href=\"https://github.com/pfnet-research/chainer-chemistry/blob/master/chainer_chemistry/models/weavenet.py#L34\">WeaveNet </a>has <code>AtomToPair</code> and <code>PairToAtom</code> classes but I'm not entirely sure what is going on here. <a href=\"https://arxiv.org/abs/1603.00856\">Link to paper</a></p>",
  "messages": [
    {
      "id": "582430",
      "postDate": "07/23/2019 07:09:22",
      "content": "<p>I’m trying to get my head around graph neural networks and the terminology behind them. In the typical chemistry examples I have seen:\n•   Molecule = Graph\n•   Atom = Node\n•   Bond = Edge</p>\n\n<p>However, this problem seems to be a bit different since we are trying to predict a y parameter that is dependent on a pair of nodes. So I thought maybe the nodes should be pairs of adjacent atoms instead and I tried sketching out what this graph might look like for ethane (<code>dsgdb9nsd_000007</code>).</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/582430/13857/IMG_0462.JPG\" alt=\"\"></p>\n\n<p>The issue is that the middle C-C node won’t have an associated y value (i.e. a 1JCC coupling). Similarly, for the other coupling types, we may not have all the information in this format. Or maybe we don't need that C-C node?</p>\n\n<p>I think I’m confusing myself here so any ideas on how to represent this dataset in a graph network would be appreciated!</p>\n\n<p><a href=\"https://github.com/pfnet-research/chainer-chemistry/blob/master/chainer_chemistry/models/weavenet.py#L34\">WeaveNet </a>has <code>AtomToPair</code> and <code>PairToAtom</code> classes but I'm not entirely sure what is going on here. <a href=\"https://arxiv.org/abs/1603.00856\">Link to paper</a></p>",
      "rawMarkdown": "I’m trying to get my head around graph neural networks and the terminology behind them. In the typical chemistry examples I have seen:\n•\tMolecule = Graph\n•\tAtom = Node\n•\tBond = Edge\n\nHowever, this problem seems to be a bit different since we are trying to predict a y parameter that is dependent on a pair of nodes. So I thought maybe the nodes should be pairs of adjacent atoms instead and I tried sketching out what this graph might look like for ethane (`dsgdb9nsd_000007`).\n\n![](https://storage.googleapis.com/kaggle-forum-message-attachments/582430/13857/IMG_0462.JPG)\n\nThe issue is that the middle C-C node won’t have an associated y value (i.e. a 1JCC coupling). Similarly, for the other coupling types, we may not have all the information in this format. Or maybe we don't need that C-C node?\n\nI think I’m confusing myself here so any ideas on how to represent this dataset in a graph network would be appreciated!\n\n[WeaveNet ](https://github.com/pfnet-research/chainer-chemistry/blob/master/chainer_chemistry/models/weavenet.py#L34)has `AtomToPair` and `PairToAtom` classes but I'm not entirely sure what is going on here. [Link to paper](https://arxiv.org/abs/1603.00856)",
      "votes": null
    },
    {
      "id": "582459",
      "postDate": "07/23/2019 07:47:42",
      "content": "<p>I am with you, trying to get the right representation.  Let me know when you find one ;)</p>\n\n<p>A minor comment: what you call pair model is usually called the dual graph of the original graph.</p>",
      "rawMarkdown": "I am with you, trying to get the right representation.  Let me know when you find one ;)\n\nA minor comment: what you call pair model is usually called the dual graph of the original graph.",
      "votes": null
    },
    {
      "id": "582561",
      "postDate": "07/23/2019 10:21:38",
      "content": "<p>Well maybe I'm entirely wrong in this, but here's my thought about this:\nSince we're not asked to predict nJCC coupling constants you're good to go with your idea</p>",
      "rawMarkdown": "Well maybe I'm entirely wrong in this, but here's my thought about this:\nSince we're not asked to predict nJCC coupling constants you're good to go with your idea",
      "votes": null
    },
    {
      "id": "583190",
      "postDate": "07/24/2019 06:26:18",
      "content": "<p>If I had an advice on graph models, it would be to first make a list of all the different models out there and figure out (roughly) how they work and what makes them different. There are a number of great reviews on the web. This will give you a much clearer picture and I found it helped a lot.</p>\n\n<p>Basically graph models (eg. weave, deep tensor neural net, graph conv net, mpnn, etc.) have a featurization process followed by a training model, and each model initially came out with its own featurization process. Some has only node features, some add edges, some (like weave or mpnn) add atom pair features, etc.</p>\n\n<p>As a first step I don't think you should try to make your own featurization process by trying to find the best graph out of your molecule. Just keep your initial graph, and use the model's default featurization, which should work well in most cases.</p>",
      "rawMarkdown": "If I had an advice on graph models, it would be to first make a list of all the different models out there and figure out (roughly) how they work and what makes them different. There are a number of great reviews on the web. This will give you a much clearer picture and I found it helped a lot.\n\nBasically graph models (eg. weave, deep tensor neural net, graph conv net, mpnn, etc.) have a featurization process followed by a training model, and each model initially came out with its own featurization process. Some has only node features, some add edges, some (like weave or mpnn) add atom pair features, etc.\n\nAs a first step I don't think you should try to make your own featurization process by trying to find the best graph out of your molecule. Just keep your initial graph, and use the model's default featurization, which should work well in most cases.",
      "votes": null
    },
    {
      "id": "583337",
      "postDate": "07/24/2019 10:57:12",
      "content": "<p>Isn't it the line graph? I thought the dual graph is a graph with vertices for <em>faces</em> of the original graph</p>",
      "rawMarkdown": "Isn't it the line graph? I thought the dual graph is a graph with vertices for *faces* of the original graph",
      "votes": null
    },
    {
      "id": "583339",
      "postDate": "07/24/2019 11:02:40",
      "content": "<p>So, your normal model makes sense, but why restrict yourself to covalent bonds? I mean, we are asked to predict for example 2JHH and 3JHH, for which there will never be a covalent bond (and thus edge in your model) in this dataset.   </p>\n\n<p>Atoms still affect each other even if they are not covalently bonded. </p>",
      "rawMarkdown": "So, your normal model makes sense, but why restrict yourself to covalent bonds? I mean, we are asked to predict for example 2JHH and 3JHH, for which there will never be a covalent bond (and thus edge in your model) in this dataset.   \n\nAtoms still affect each other even if they are not covalently bonded.",
      "votes": null
    },
    {
      "id": "583348",
      "postDate": "07/24/2019 11:20:18",
      "content": "<p>Agreed. And that's where atom pair features come into play. It allows to account for that without physically connecting the atoms.</p>",
      "rawMarkdown": "Agreed. And that's where atom pair features come into play. It allows to account for that without physically connecting the atoms.",
      "votes": null
    },
    {
      "id": "583418",
      "postDate": "07/24/2019 13:06:39",
      "content": "<p>To give a concrete example, a very basic model could look like:</p>\n\n<ol>\n<li><p>Input a vector representing the atoms (size B x n atom types x n atoms) and an adjacency matrix for the molecule (size B x n_atoms x n_atoms). These are the bare minimum inputs for graph convolutions.</p></li>\n<li><p>Apply graph convolutions to get a featurized vector of the atoms (size B x n features x n atoms).</p></li>\n<li><p>Combine atom features in an order invariant way to get a matrix of interactions. For example, you can do a matrix multiplication (B x n features x n atoms x 1) @ (B x n features x 1 x n atoms) = (B x n features x n atoms x n atoms). Whatever method you come up with, the resultant matrix should be symmetric.</p></li>\n<li><p>Apply 1x1 convolutions over this interaction matrix to get a (B x 1 x n atoms x n atoms) coupling matrix. This will give you predictions for all pairs, including ones that have no scalar coupling constant. And, again, is still symmetric.</p></li>\n<li><p>Measure loss only on pairs that have a scalar coupling constant.</p></li>\n</ol>\n\n<p>Step 2 is the \"featurization\" process, step 4 is the regression \"head\". In practice, a model this basic won't give good results at all on this problem. But hopefully, this gives you a good sense of a workable approach.</p>",
      "rawMarkdown": "To give a concrete example, a very basic model could look like:\n\n1. Input a vector representing the atoms (size B x n atom types x n atoms) and an adjacency matrix for the molecule (size B x n_atoms x n_atoms). These are the bare minimum inputs for graph convolutions.\n\n2. Apply graph convolutions to get a featurized vector of the atoms (size B x n features x n atoms).\n\n3. Combine atom features in an order invariant way to get a matrix of interactions. For example, you can do a matrix multiplication (B x n features x n atoms x 1) @ (B x n features x 1 x n atoms) = (B x n features x n atoms x n atoms). Whatever method you come up with, the resultant matrix should be symmetric.\n\n4. Apply 1x1 convolutions over this interaction matrix to get a (B x 1 x n atoms x n atoms) coupling matrix. This will give you predictions for all pairs, including ones that have no scalar coupling constant. And, again, is still symmetric.\n\n5. Measure loss only on pairs that have a scalar coupling constant.\n\nStep 2 is the \"featurization\" process, step 4 is the regression \"head\". In practice, a model this basic won't give good results at all on this problem. But hopefully, this gives you a good sense of a workable approach.",
      "votes": null
    },
    {
      "id": "585871",
      "postDate": "07/28/2019 08:26:07",
      "content": "<p>See this kernel for an example of how one might to it: https://www.kaggle.com/fnands/makegraphinput   </p>\n\n<p>This is just a very basic example, and it is pretty inefficient, but it gets the job done. </p>",
      "rawMarkdown": "See this kernel for an example of how one might to it: [https://www.kaggle.com/fnands/makegraphinput ](Here!)  \n\nThis is just a very basic example, and it is pretty inefficient, but it gets the job done.",
      "votes": null
    },
    {
      "id": "585938",
      "postDate": "07/28/2019 11:17:24",
      "content": "<p>you're right, it is the line graph.</p>",
      "rawMarkdown": "you're right, it is the line graph.",
      "votes": null
    },
    {
      "id": "586244",
      "postDate": "07/28/2019 21:34:15",
      "content": "<p>Thanks conradr71 for your outline.  I'm slightly confused about your notation.  For example, what is \"B\"?  Is that the batch (sample) dimension?  Also, \"n\" looks like the number of atoms in a molecule.  But since different molecules have different numbers of atoms (up to a maximum of 29), what do you have in mind as the best way to pad the data out so as to produce conformable arrays?</p>",
      "rawMarkdown": "Thanks conradr71 for your outline.  I'm slightly confused about your notation.  For example, what is \"B\"?  Is that the batch (sample) dimension?  Also, \"n\" looks like the number of atoms in a molecule.  But since different molecules have different numbers of atoms (up to a maximum of 29), what do you have in mind as the best way to pad the data out so as to produce conformable arrays?",
      "votes": null
    },
    {
      "id": "586246",
      "postDate": "07/28/2019 21:45:28",
      "content": "<p><a href=\"/dslate\">@dslate</a> , correct on all counts! Or at least that seems to be the most straightforward way of doing it. </p>",
      "rawMarkdown": "dslate , correct on all counts! Or at least that seems to be the most straightforward way of doing it.",
      "votes": null
    },
    {
      "id": "586274",
      "postDate": "07/28/2019 23:48:03",
      "content": "<p>Yes, B is for batch size (the given dimensions are based on pytorch).</p>\n\n<p>I pad everything out to 29 so that all sizes are handled. Depending on the architecture you use this can make things a bit hairy. For example, in graph attention layers there's usually a softmax operation applied over a node and its neighbors. To prevent the zero padding from interfering with the softmax you need to convert all padding values to large negative numbers (-9e15) (which go to zero after the activation). </p>\n\n<p>I think that handling the data like square \"images\" is easier from a visualization and debugging standpoint. Just be aware that unlike regular CNN models, padding might effect performance if you're not careful. </p>",
      "rawMarkdown": "Yes, B is for batch size (the given dimensions are based on pytorch).\n\nI pad everything out to 29 so that all sizes are handled. Depending on the architecture you use this can make things a bit hairy. For example, in graph attention layers there's usually a softmax operation applied over a node and its neighbors. To prevent the zero padding from interfering with the softmax you need to convert all padding values to large negative numbers (-9e15) (which go to zero after the activation). \n\nI think that handling the data like square \"images\" is easier from a visualization and debugging standpoint. Just be aware that unlike regular CNN models, padding might effect performance if you're not careful.",
      "votes": null
    },
    {
      "id": "588509",
      "postDate": "07/30/2019 17:23:07",
      "content": "<p>After an unsuccessful play with an adapted Deepchem MPNN and my own implementation of Chainer Weavenet in pytorch have just realised that my initial featurization didn't include any distances. Hopefully tomorrow I'll be able to use <a href=\"/cpmpml\">@cpmpml</a> 's distance matrix as edge features and get more luck ✌️ </p>",
      "rawMarkdown": "After an unsuccessful play with an adapted Deepchem MPNN and my own implementation of Chainer Weavenet in pytorch have just realised that my initial featurization didn't include any distances. Hopefully tomorrow I'll be able to use @cpmpml 's distance matrix as edge features and get more luck ✌️",
      "votes": null
    },
    {
      "id": "589533",
      "postDate": "08/01/2019 03:30:58",
      "content": "<p>Thanks for the itemized highlights of the operation, very informative. Could you please expand a bit on point 3, especially as to the 'order invariant' on what that means specifically? Also, for point 4, what is a 1x1 convolution? Is that not a convolution that ignores itself? I thought the convolutions are typically 3x3.</p>",
      "rawMarkdown": "Thanks for the itemized highlights of the operation, very informative. Could you please expand a bit on point 3, especially as to the 'order invariant' on what that means specifically? Also, for point 4, what is a 1x1 convolution? Is that not a convolution that ignores itself? I thought the convolutions are typically 3x3.",
      "votes": null
    },
    {
      "id": "589562",
      "postDate": "08/01/2019 05:16:45",
      "content": "<p>order invariant means that if you permute your atoms then you should get the same end result.</p>",
      "rawMarkdown": "order invariant means that if you permute your atoms then you should get the same end result.",
      "votes": null
    },
    {
      "id": "589806",
      "postDate": "08/01/2019 12:03:25",
      "content": "<p>A 1x1 convolution is effectively the same as a linear (also called dense or fully connected) layer. The key difference is that it applies the same linear operation (Wx + b) to each pixel in an image. Because we're making multiple predictions for each molecule it's a much cleaner approach than taking each pair,  flattening the feature vector and then applying an MLP.</p>",
      "rawMarkdown": "A 1x1 convolution is effectively the same as a linear (also called dense or fully connected) layer. The key difference is that it applies the same linear operation (Wx + b) to each pixel in an image. Because we're making multiple predictions for each molecule it's a much cleaner approach than taking each pair,  flattening the feature vector and then applying an MLP.",
      "votes": null
    },
    {
      "id": "605369",
      "postDate": "08/22/2019 10:00:39",
      "content": "<p>Trying to get my head round the matrix multiplication/message function generation in Gilmer i.e. when you have edge features rather than just an adjacency matrix. </p>\n\n<p>Your matrix A (edge features embedded to dimensions dxd) looks to me something like: (B,n_atoms,n_atoms,d,d)\nYour current state matrix H is: (B,n_atoms,d)</p>\n\n<p>Then I'm struggling with the matrix maths. Need to use multiplication M=AH. Have tried following some of the tensorflow examples but can't follow the dimensions of the objects and i'm implementing <a href=\"/fnands\">@fnands</a> MPNN in pytorch.</p>\n\n<p>We want to have something like M: (B,n_atoms,n_atoms,d)\nWhich we can sum-aggregate to M:(B,n_atoms,d) after masking. </p>\n\n<p>And then apply update.</p>\n\n<p>Anybody able to offer some insight? </p>",
      "rawMarkdown": "Trying to get my head round the matrix multiplication/message function generation in Gilmer i.e. when you have edge features rather than just an adjacency matrix. \n\nYour matrix A (edge features embedded to dimensions dxd) looks to me something like: (B,n_atoms,n_atoms,d,d)\nYour current state matrix H is: (B,n_atoms,d)\n\nThen I'm struggling with the matrix maths. Need to use multiplication M=AH. Have tried following some of the tensorflow examples but can't follow the dimensions of the objects and i'm implementing @fnands MPNN in pytorch.\n\nWe want to have something like M: (B,n_atoms,n_atoms,d)\nWhich we can sum-aggregate to M:(B,n_atoms,d) after masking. \n\nAnd then apply update.\n\nAnybody able to offer some insight?",
      "votes": null
    },
    {
      "id": "605372",
      "postDate": "08/22/2019 10:04:38",
      "content": "<p>I can follow the adjacency matrix case where you have A=(B,n_atoms,n_atoms) and H=(B,n_atoms,d)\nThen M = AH = (B,n_atoms,d)</p>",
      "rawMarkdown": "I can follow the adjacency matrix case where you have A=(B,n_atoms,n_atoms) and H=(B,n_atoms,d)\nThen M = AH = (B,n_atoms,d)",
      "votes": null
    },
    {
      "id": "2380259",
      "postDate": "08/08/2023 14:03:53",
      "content": "<p>can we use GNN for time series problems ?</p>",
      "rawMarkdown": "can we use GNN for time series problems ?",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 2380259,
      "author_name": "bibhumohapatra18",
      "author_url": "",
      "post_date": "08/08/2023 14:03:53",
      "content": "<p>can we use GNN for time series problems ?</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 582459,
      "author_name": "cpmpml",
      "author_url": "",
      "post_date": "07/23/2019 07:47:42",
      "content": "<p>I am with you, trying to get the right representation.  Let me know when you find one ;)</p>\n\n<p>A minor comment: what you call pair model is usually called the dual graph of the original graph.</p>",
      "votes": null,
      "replies": [
        {
          "id": 583337,
          "author_name": "fnands",
          "author_url": "",
          "post_date": "07/24/2019 10:57:12",
          "content": "<p>Isn't it the line graph? I thought the dual graph is a graph with vertices for <em>faces</em> of the original graph</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 585938,
          "author_name": "cpmpml",
          "author_url": "",
          "post_date": "07/28/2019 11:17:24",
          "content": "<p>you're right, it is the line graph.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 582561,
      "author_name": "stanislavblinov",
      "author_url": "",
      "post_date": "07/23/2019 10:21:38",
      "content": "<p>Well maybe I'm entirely wrong in this, but here's my thought about this:\nSince we're not asked to predict nJCC coupling constants you're good to go with your idea</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 583190,
      "author_name": "borisdee",
      "author_url": "",
      "post_date": "07/24/2019 06:26:18",
      "content": "<p>If I had an advice on graph models, it would be to first make a list of all the different models out there and figure out (roughly) how they work and what makes them different. There are a number of great reviews on the web. This will give you a much clearer picture and I found it helped a lot.</p>\n\n<p>Basically graph models (eg. weave, deep tensor neural net, graph conv net, mpnn, etc.) have a featurization process followed by a training model, and each model initially came out with its own featurization process. Some has only node features, some add edges, some (like weave or mpnn) add atom pair features, etc.</p>\n\n<p>As a first step I don't think you should try to make your own featurization process by trying to find the best graph out of your molecule. Just keep your initial graph, and use the model's default featurization, which should work well in most cases.</p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 583339,
      "author_name": "fnands",
      "author_url": "",
      "post_date": "07/24/2019 11:02:40",
      "content": "<p>So, your normal model makes sense, but why restrict yourself to covalent bonds? I mean, we are asked to predict for example 2JHH and 3JHH, for which there will never be a covalent bond (and thus edge in your model) in this dataset.   </p>\n\n<p>Atoms still affect each other even if they are not covalently bonded. </p>",
      "votes": null,
      "replies": [
        {
          "id": 583348,
          "author_name": "borisdee",
          "author_url": "",
          "post_date": "07/24/2019 11:20:18",
          "content": "<p>Agreed. And that's where atom pair features come into play. It allows to account for that without physically connecting the atoms.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 583418,
      "author_name": "conradr71",
      "author_url": "",
      "post_date": "07/24/2019 13:06:39",
      "content": "<p>To give a concrete example, a very basic model could look like:</p>\n\n<ol>\n<li><p>Input a vector representing the atoms (size B x n atom types x n atoms) and an adjacency matrix for the molecule (size B x n_atoms x n_atoms). These are the bare minimum inputs for graph convolutions.</p></li>\n<li><p>Apply graph convolutions to get a featurized vector of the atoms (size B x n features x n atoms).</p></li>\n<li><p>Combine atom features in an order invariant way to get a matrix of interactions. For example, you can do a matrix multiplication (B x n features x n atoms x 1) @ (B x n features x 1 x n atoms) = (B x n features x n atoms x n atoms). Whatever method you come up with, the resultant matrix should be symmetric.</p></li>\n<li><p>Apply 1x1 convolutions over this interaction matrix to get a (B x 1 x n atoms x n atoms) coupling matrix. This will give you predictions for all pairs, including ones that have no scalar coupling constant. And, again, is still symmetric.</p></li>\n<li><p>Measure loss only on pairs that have a scalar coupling constant.</p></li>\n</ol>\n\n<p>Step 2 is the \"featurization\" process, step 4 is the regression \"head\". In practice, a model this basic won't give good results at all on this problem. But hopefully, this gives you a good sense of a workable approach.</p>",
      "votes": null,
      "replies": [
        {
          "id": 586244,
          "author_name": "dslate",
          "author_url": "",
          "post_date": "07/28/2019 21:34:15",
          "content": "<p>Thanks conradr71 for your outline.  I'm slightly confused about your notation.  For example, what is \"B\"?  Is that the batch (sample) dimension?  Also, \"n\" looks like the number of atoms in a molecule.  But since different molecules have different numbers of atoms (up to a maximum of 29), what do you have in mind as the best way to pad the data out so as to produce conformable arrays?</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 586246,
          "author_name": "fnands",
          "author_url": "",
          "post_date": "07/28/2019 21:45:28",
          "content": "<p><a href=\"/dslate\">@dslate</a> , correct on all counts! Or at least that seems to be the most straightforward way of doing it. </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 586274,
          "author_name": "conradr71",
          "author_url": "",
          "post_date": "07/28/2019 23:48:03",
          "content": "<p>Yes, B is for batch size (the given dimensions are based on pytorch).</p>\n\n<p>I pad everything out to 29 so that all sizes are handled. Depending on the architecture you use this can make things a bit hairy. For example, in graph attention layers there's usually a softmax operation applied over a node and its neighbors. To prevent the zero padding from interfering with the softmax you need to convert all padding values to large negative numbers (-9e15) (which go to zero after the activation). </p>\n\n<p>I think that handling the data like square \"images\" is easier from a visualization and debugging standpoint. Just be aware that unlike regular CNN models, padding might effect performance if you're not careful. </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 588509,
          "author_name": "jameschapman19",
          "author_url": "",
          "post_date": "07/30/2019 17:23:07",
          "content": "<p>After an unsuccessful play with an adapted Deepchem MPNN and my own implementation of Chainer Weavenet in pytorch have just realised that my initial featurization didn't include any distances. Hopefully tomorrow I'll be able to use <a href=\"/cpmpml\">@cpmpml</a> 's distance matrix as edge features and get more luck ✌️ </p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 589533,
          "author_name": "alexvassman",
          "author_url": "",
          "post_date": "08/01/2019 03:30:58",
          "content": "<p>Thanks for the itemized highlights of the operation, very informative. Could you please expand a bit on point 3, especially as to the 'order invariant' on what that means specifically? Also, for point 4, what is a 1x1 convolution? Is that not a convolution that ignores itself? I thought the convolutions are typically 3x3.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 589562,
          "author_name": "cpmpml",
          "author_url": "",
          "post_date": "08/01/2019 05:16:45",
          "content": "<p>order invariant means that if you permute your atoms then you should get the same end result.</p>",
          "votes": null,
          "replies": []
        },
        {
          "id": 589806,
          "author_name": "conradr71",
          "author_url": "",
          "post_date": "08/01/2019 12:03:25",
          "content": "<p>A 1x1 convolution is effectively the same as a linear (also called dense or fully connected) layer. The key difference is that it applies the same linear operation (Wx + b) to each pixel in an image. Because we're making multiple predictions for each molecule it's a much cleaner approach than taking each pair,  flattening the feature vector and then applying an MLP.</p>",
          "votes": null,
          "replies": []
        }
      ]
    },
    {
      "id": 585871,
      "author_name": "fnands",
      "author_url": "",
      "post_date": "07/28/2019 08:26:07",
      "content": "<p>See this kernel for an example of how one might to it: https://www.kaggle.com/fnands/makegraphinput   </p>\n\n<p>This is just a very basic example, and it is pretty inefficient, but it gets the job done. </p>",
      "votes": null,
      "replies": []
    },
    {
      "id": 605369,
      "author_name": "jameschapman19",
      "author_url": "",
      "post_date": "08/22/2019 10:00:39",
      "content": "<p>Trying to get my head round the matrix multiplication/message function generation in Gilmer i.e. when you have edge features rather than just an adjacency matrix. </p>\n\n<p>Your matrix A (edge features embedded to dimensions dxd) looks to me something like: (B,n_atoms,n_atoms,d,d)\nYour current state matrix H is: (B,n_atoms,d)</p>\n\n<p>Then I'm struggling with the matrix maths. Need to use multiplication M=AH. Have tried following some of the tensorflow examples but can't follow the dimensions of the objects and i'm implementing <a href=\"/fnands\">@fnands</a> MPNN in pytorch.</p>\n\n<p>We want to have something like M: (B,n_atoms,n_atoms,d)\nWhich we can sum-aggregate to M:(B,n_atoms,d) after masking. </p>\n\n<p>And then apply update.</p>\n\n<p>Anybody able to offer some insight? </p>",
      "votes": null,
      "replies": [
        {
          "id": 605372,
          "author_name": "jameschapman19",
          "author_url": "",
          "post_date": "08/22/2019 10:04:38",
          "content": "<p>I can follow the adjacency matrix case where you have A=(B,n_atoms,n_atoms) and H=(B,n_atoms,d)\nThen M = AH = (B,n_atoms,d)</p>",
          "votes": null,
          "replies": []
        }
      ]
    }
  ],
  "raw_markdown_by_id": {
    "582430": "I’m trying to get my head around graph neural networks and the terminology behind them. In the typical chemistry examples I have seen:\n•\tMolecule = Graph\n•\tAtom = Node\n•\tBond = Edge\n\nHowever, this problem seems to be a bit different since we are trying to predict a y parameter that is dependent on a pair of nodes. So I thought maybe the nodes should be pairs of adjacent atoms instead and I tried sketching out what this graph might look like for ethane (`dsgdb9nsd_000007`).\n\n![](https://storage.googleapis.com/kaggle-forum-message-attachments/582430/13857/IMG_0462.JPG)\n\nThe issue is that the middle C-C node won’t have an associated y value (i.e. a 1JCC coupling). Similarly, for the other coupling types, we may not have all the information in this format. Or maybe we don't need that C-C node?\n\nI think I’m confusing myself here so any ideas on how to represent this dataset in a graph network would be appreciated!\n\n[WeaveNet ](https://github.com/pfnet-research/chainer-chemistry/blob/master/chainer_chemistry/models/weavenet.py#L34)has `AtomToPair` and `PairToAtom` classes but I'm not entirely sure what is going on here. [Link to paper](https://arxiv.org/abs/1603.00856)",
    "582459": "I am with you, trying to get the right representation.  Let me know when you find one ;)\n\nA minor comment: what you call pair model is usually called the dual graph of the original graph.",
    "582561": "Well maybe I'm entirely wrong in this, but here's my thought about this:\nSince we're not asked to predict nJCC coupling constants you're good to go with your idea",
    "583190": "If I had an advice on graph models, it would be to first make a list of all the different models out there and figure out (roughly) how they work and what makes them different. There are a number of great reviews on the web. This will give you a much clearer picture and I found it helped a lot.\n\nBasically graph models (eg. weave, deep tensor neural net, graph conv net, mpnn, etc.) have a featurization process followed by a training model, and each model initially came out with its own featurization process. Some has only node features, some add edges, some (like weave or mpnn) add atom pair features, etc.\n\nAs a first step I don't think you should try to make your own featurization process by trying to find the best graph out of your molecule. Just keep your initial graph, and use the model's default featurization, which should work well in most cases.",
    "583337": "Isn't it the line graph? I thought the dual graph is a graph with vertices for *faces* of the original graph",
    "583339": "So, your normal model makes sense, but why restrict yourself to covalent bonds? I mean, we are asked to predict for example 2JHH and 3JHH, for which there will never be a covalent bond (and thus edge in your model) in this dataset.   \n\nAtoms still affect each other even if they are not covalently bonded.",
    "583348": "Agreed. And that's where atom pair features come into play. It allows to account for that without physically connecting the atoms.",
    "583418": "To give a concrete example, a very basic model could look like:\n\n1. Input a vector representing the atoms (size B x n atom types x n atoms) and an adjacency matrix for the molecule (size B x n_atoms x n_atoms). These are the bare minimum inputs for graph convolutions.\n\n2. Apply graph convolutions to get a featurized vector of the atoms (size B x n features x n atoms).\n\n3. Combine atom features in an order invariant way to get a matrix of interactions. For example, you can do a matrix multiplication (B x n features x n atoms x 1) @ (B x n features x 1 x n atoms) = (B x n features x n atoms x n atoms). Whatever method you come up with, the resultant matrix should be symmetric.\n\n4. Apply 1x1 convolutions over this interaction matrix to get a (B x 1 x n atoms x n atoms) coupling matrix. This will give you predictions for all pairs, including ones that have no scalar coupling constant. And, again, is still symmetric.\n\n5. Measure loss only on pairs that have a scalar coupling constant.\n\nStep 2 is the \"featurization\" process, step 4 is the regression \"head\". In practice, a model this basic won't give good results at all on this problem. But hopefully, this gives you a good sense of a workable approach.",
    "585871": "See this kernel for an example of how one might to it: [https://www.kaggle.com/fnands/makegraphinput ](Here!)  \n\nThis is just a very basic example, and it is pretty inefficient, but it gets the job done.",
    "585938": "you're right, it is the line graph.",
    "586244": "Thanks conradr71 for your outline.  I'm slightly confused about your notation.  For example, what is \"B\"?  Is that the batch (sample) dimension?  Also, \"n\" looks like the number of atoms in a molecule.  But since different molecules have different numbers of atoms (up to a maximum of 29), what do you have in mind as the best way to pad the data out so as to produce conformable arrays?",
    "586246": "dslate , correct on all counts! Or at least that seems to be the most straightforward way of doing it.",
    "586274": "Yes, B is for batch size (the given dimensions are based on pytorch).\n\nI pad everything out to 29 so that all sizes are handled. Depending on the architecture you use this can make things a bit hairy. For example, in graph attention layers there's usually a softmax operation applied over a node and its neighbors. To prevent the zero padding from interfering with the softmax you need to convert all padding values to large negative numbers (-9e15) (which go to zero after the activation). \n\nI think that handling the data like square \"images\" is easier from a visualization and debugging standpoint. Just be aware that unlike regular CNN models, padding might effect performance if you're not careful.",
    "588509": "After an unsuccessful play with an adapted Deepchem MPNN and my own implementation of Chainer Weavenet in pytorch have just realised that my initial featurization didn't include any distances. Hopefully tomorrow I'll be able to use @cpmpml 's distance matrix as edge features and get more luck ✌️",
    "589533": "Thanks for the itemized highlights of the operation, very informative. Could you please expand a bit on point 3, especially as to the 'order invariant' on what that means specifically? Also, for point 4, what is a 1x1 convolution? Is that not a convolution that ignores itself? I thought the convolutions are typically 3x3.",
    "589562": "order invariant means that if you permute your atoms then you should get the same end result.",
    "589806": "A 1x1 convolution is effectively the same as a linear (also called dense or fully connected) layer. The key difference is that it applies the same linear operation (Wx + b) to each pixel in an image. Because we're making multiple predictions for each molecule it's a much cleaner approach than taking each pair,  flattening the feature vector and then applying an MLP.",
    "605369": "Trying to get my head round the matrix multiplication/message function generation in Gilmer i.e. when you have edge features rather than just an adjacency matrix. \n\nYour matrix A (edge features embedded to dimensions dxd) looks to me something like: (B,n_atoms,n_atoms,d,d)\nYour current state matrix H is: (B,n_atoms,d)\n\nThen I'm struggling with the matrix maths. Need to use multiplication M=AH. Have tried following some of the tensorflow examples but can't follow the dimensions of the objects and i'm implementing @fnands MPNN in pytorch.\n\nWe want to have something like M: (B,n_atoms,n_atoms,d)\nWhich we can sum-aggregate to M:(B,n_atoms,d) after masking. \n\nAnd then apply update.\n\nAnybody able to offer some insight?",
    "605372": "I can follow the adjacency matrix case where you have A=(B,n_atoms,n_atoms) and H=(B,n_atoms,d)\nThen M = AH = (B,n_atoms,d)",
    "2380259": "can we use GNN for time series problems ?"
  },
  "source": "meta"
}