pronobis / libspn-keras

Library for learning and inference with Sum-product Networks utilizing TensorFlow 2.x and Keras
Other
47 stars 9 forks source link

Poon-Domingos structure in LibSPN-Keras #38

Open twebr opened 3 years ago

twebr commented 3 years ago

I am trying to implement the Poon-Domingos structure for spatial data in LibSPN-Keras, as introduced in their seminal 2011 paper Sum-product networks: A new deep architecture. While a Poon-Domingos is structurally similar to a RAT-SPN (like in this example), the splits should not be made at random, but based on the spatial structure of the data.

How could I go about recreating the Poon-Domingos structure in LibSPN-Keras? I first tried region graphs with region_graph_to_dense_spn, but then the generated SPN only has a single decomposition. An alternative approach I thought of is using a PermuteAndPadScopes layer, but I am not sure how I should define the permutations parameter.

Do you know what would be a good approach for implementing the Poon-Domingos structure in LibSPN-Keras? Thank you!

jostosh commented 3 years ago

Thanks for raising this. I admit with the current state of the library that's going to be a complicated thing to do. The region_graph_to_dense_spn indeed is now limited to building an SPN with just one decomposition. It should be doable though to change that to an arbitrary number of decompositions, but I'm not sure if that generalization alone is enough.

If the SPN can be expressed as N sub-SPNs, each having its own decomposition, then you could repeatedly call the region_graph_to_dense_spn method to get the job done. If the SPN is more complicated than that and built up from decompositions recursively (which I think does apply for Poon and Domingos architecture), then it will be a more complicated thing to do.

I think I'd have to build more tooling for this in the library to get this to work. I will get back to you in a few days and give it some thought.

twebr commented 3 years ago

Thank you for considering this!

jostosh commented 3 years ago

I have given it some thought and had a shot at an initial draft implementation. I think I know what piece to add to the puzzle. A convenient way of achieving this would be to use another type of Region node. This node will not be to split up a given scope, but to enlist possible splits of the same scope, e.g.:

spnk.RegionSplits([
    spnk.RegionNode([
        spnk.RegionVariable(0),
        spnk.RegionNode([
            spnk.RegionVariable(1),
            spnk.RegionVariable(2),
        ])
    ]),
    spnk.RegionNode([
        spnk.RegionNode([
            spnk.RegionVariable(0),
            spnk.RegionVariable(1),
        ]),
        spnk.RegionVariable(2),
    ]),
])

Notice the new RegionSplits node which takes a list of nodes with identical scopes, but a unique way of splitting them up.

Here there are just two splits. For the Poon & Domingos architecture, you'd need way more. I'm working on tooling to transform this kind of region graph to a stack of Keras layers. Will keep you posted.

jostosh commented 3 years ago

I managed to complete the conversion, but I'm afraid that a single stack of Keras layers would require lots and lots of zero padding. For a 4x4 block (the finer regions in the Poon & Domingos have that size), this results in about 90% of leaf variables being padded. Perhaps alternatively, the way to do it is to make a non-Sequential Keras model and model sums and products with smaller tensors so that padding can be avoided. I will give that a go later and then share what I have.