Skip to content

Commit

Permalink
Remove redundant identity transformation functions
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasZahradnik committed Jun 15, 2024
1 parent 6fa0f0c commit 7f18c28
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 95 deletions.
84 changes: 25 additions & 59 deletions benchmarks/pyneuralogic_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,14 @@
def gcn(activation: Transformation, output_size: int, num_features: int, dim: int = 10):
template = Template()

template += (R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)) | [Transformation.IDENTITY]
template += R.atom_embed / 1 | [Transformation.IDENTITY]
template += R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)

template += (R.l1_embed(V.X)[dim, dim] <= (R.atom_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += (R.l1_embed(V.X)[dim, dim] <= (R.atom_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]
template += R.l1_embed / 1 | [Transformation.RELU]

template += (R.l2_embed(V.X)[dim, dim] <= (R.l1_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += R.l2_embed / 1 | [Transformation.IDENTITY]
template += (R.l2_embed(V.X)[dim, dim] <= (R.l1_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]

template += (R.predict[output_size, dim] <= R.l2_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l2_embed(V.X)) | [Aggregation.AVG]
template += R.predict / 0 | [activation]

return template
Expand All @@ -44,65 +36,47 @@ def gcn(activation: Transformation, output_size: int, num_features: int, dim: in
def gin(activation: Transformation, output_size: int, num_features: int, dim: int = 10):
template = Template()

template += (R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)) | [Transformation.IDENTITY]
template += R.atom_embed / 1 | [Transformation.IDENTITY]
template += R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)

template += (R.l1_embed(V.X) <= (R.atom_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM, Transformation.IDENTITY]
template += (R.l1_embed(V.X) <= R.atom_embed(V.X)) | [Transformation.IDENTITY]
template += R.l1_embed / 1 | [Transformation.IDENTITY]
template += R.l1_embed(V.X) <= R.atom_embed(V.X)

template += (R.l1_mlp_embed(V.X)[dim, dim] <= R.l1_embed(V.X)[dim, dim]) | [Transformation.RELU]
template += R.l1_mlp_embed / 1 | [Transformation.RELU]

# --
template += (R.l2_embed(V.X) <= (R.l1_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += (R.l2_embed(V.X) <= R.l1_mlp_embed(V.X)) | [Transformation.IDENTITY]
template += R.l2_embed / 1 | [Transformation.IDENTITY]
template += (R.l2_embed(V.X) <= (R.l1_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]
template += R.l2_embed(V.X) <= R.l1_mlp_embed(V.X)

template += (R.l2_mlp_embed(V.X)[dim, dim] <= R.l2_embed(V.X)[dim, dim]) | [Transformation.RELU]
template += R.l2_mlp_embed / 1 | [Transformation.RELU]

# --
template += (R.l3_embed(V.X) <= (R.l2_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += (R.l3_embed(V.X) <= R.l2_mlp_embed(V.X)) | [Transformation.IDENTITY]
template += R.l3_embed / 1 | [Transformation.IDENTITY]
template += (R.l3_embed(V.X) <= (R.l2_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]
template += R.l3_embed(V.X) <= R.l2_mlp_embed(V.X)

template += (R.l3_mlp_embed(V.X)[dim, dim] <= R.l3_embed(V.X)[dim, dim]) | [Transformation.RELU]
template += R.l3_mlp_embed / 1 | [Transformation.RELU]

# --
template += (R.l4_embed(V.X) <= (R.l3_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += (R.l4_embed(V.X) <= R.l3_mlp_embed(V.X)) | [Transformation.IDENTITY]
template += R.l4_embed / 1 | [Transformation.IDENTITY]
template += (R.l4_embed(V.X) <= (R.l3_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]
template += R.l4_embed(V.X) <= R.l3_mlp_embed(V.X)

template += (R.l4_mlp_embed(V.X)[dim, dim] <= R.l4_embed(V.X)[dim, dim]) | [Transformation.RELU]
template += R.l4_mlp_embed / 1 | [Transformation.RELU]

# --
template += (R.l5_embed(V.X) <= (R.l4_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.SUM,
Transformation.IDENTITY,
]
template += (R.l5_embed(V.X) <= R.l4_mlp_embed(V.X)) | [Transformation.IDENTITY]
template += R.l5_embed / 1 | [Transformation.IDENTITY]
template += (R.l5_embed(V.X) <= (R.l4_mlp_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.SUM]
template += R.l5_embed(V.X) <= R.l4_mlp_embed(V.X)

template += (R.l5_mlp_embed(V.X)[dim, dim] <= R.l5_embed(V.X)[dim, dim]) | [Transformation.RELU]
template += R.l5_mlp_embed / 1 | [Transformation.RELU]

template += (R.predict[output_size, dim] <= R.l1_mlp_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l2_mlp_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l3_mlp_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l4_mlp_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l5_mlp_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l1_mlp_embed(V.X)) | [Aggregation.AVG]
template += (R.predict[output_size, dim] <= R.l2_mlp_embed(V.X)) | [Aggregation.AVG]
template += (R.predict[output_size, dim] <= R.l3_mlp_embed(V.X)) | [Aggregation.AVG]
template += (R.predict[output_size, dim] <= R.l4_mlp_embed(V.X)) | [Aggregation.AVG]
template += (R.predict[output_size, dim] <= R.l5_mlp_embed(V.X)) | [Aggregation.AVG]

template += R.predict / 0 | [activation]

Expand All @@ -112,24 +86,16 @@ def gin(activation: Transformation, output_size: int, num_features: int, dim: in
def gsage(activation: Transformation, output_size: int, num_features: int, dim: int = 10):
template = Template()

template += (R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)) | [Transformation.IDENTITY]
template += R.atom_embed / 1 | [Transformation.IDENTITY]
template += R.atom_embed(V.X)[dim, num_features] <= R.node_feature(V.X)

template += (R.l1_embed(V.X)[dim, dim] <= R.atom_embed(V.X)) | [Transformation.IDENTITY]
template += (R.l1_embed(V.X)[dim, dim] <= (R.atom_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.AVG,
Transformation.IDENTITY,
]
template += R.l1_embed(V.X)[dim, dim] <= R.atom_embed(V.X)
template += R.l1_embed(V.X)[dim, dim] <= (R.atom_embed(V.Y), R._edge(V.Y, V.X)) | [Aggregation.AVG]
template += R.l1_embed / 1 | [Transformation.RELU]

template += (R.l2_embed(V.X)[dim, dim] <= R.l1_embed(V.X)) | [Transformation.IDENTITY]
template += (R.l2_embed(V.X)[dim, dim] <= (R.l1_embed(V.Y), R._edge(V.Y, V.X))) | [
Aggregation.AVG,
Transformation.IDENTITY,
]
template += R.l2_embed / 1 | [Transformation.IDENTITY]
template += R.l2_embed(V.X)[dim, dim] <= R.l1_embed(V.X)
template += (R.l2_embed(V.X)[dim, dim] <= (R.l1_embed(V.Y), R._edge(V.Y, V.X))) | [Aggregation.AVG]

template += (R.predict[output_size, dim] <= R.l2_embed(V.X)) | [Aggregation.AVG, Transformation.IDENTITY]
template += (R.predict[output_size, dim] <= R.l2_embed(V.X)) | [Aggregation.AVG]
template += R.predict / 0 | [activation]

return template
Expand Down
3 changes: 2 additions & 1 deletion neuralogic/core/constructs/java_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jpype

from neuralogic import is_initialized, initialize
from neuralogic.core.constructs.metadata import Metadata
from neuralogic.core.constructs.function import FContainer
from neuralogic.core.constructs.term import Variable, Constant
from neuralogic.core.settings import SettingsProxy, Settings
Expand Down Expand Up @@ -332,7 +333,7 @@ def get_rule(self, rule):

metadata = rule.metadata
if isinstance(rule.body, FContainer):
metadata = metadata.copy()
metadata = metadata.copy() if metadata is not None else Metadata()
metadata.combination = rule.body.to_function()

java_rule.setMetadata(self.get_metadata(metadata, self.rule_metadata))
Expand Down
2 changes: 1 addition & 1 deletion neuralogic/core/settings/settings_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(
for key, value in params.items():
self.__setattr__(key, value)

self.rule_transformation = Transformation.TANH
self.rule_transformation = Transformation.IDENTITY
self.relation_transformation = Transformation.IDENTITY
self.rule_combination = Combination.SUM
self.relation_combination = Combination.SUM
Expand Down
2 changes: 1 addition & 1 deletion neuralogic/nn/module/gnn/rgcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def __init__(

def __call__(self):
head = R.get(self.output_name)(V.I)
metadata = Metadata(transformation=Transformation.IDENTITY, aggregation=self.aggregation)
metadata = Metadata(aggregation=self.aggregation)
feature = R.get(self.feature_name)(V.J)[self.out_channels, self.in_channels]

if self.edge_name is not None:
Expand Down
5 changes: 1 addition & 4 deletions tests/test_evaluation_inference_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,12 @@ def test_evaluation_inference_engine_london_shortest_path() -> None:
R.connected(C.leicester_square, C.charing_cross, C.northern)[-7],
]

metadata = Metadata(aggregation=Aggregation.MAX, transformation=Transformation.IDENTITY)
metadata = Metadata(aggregation=Aggregation.MAX)

template += [
(R.shortest(V.X, V.Y, C.first) <= R.connected(V.X, V.Y, V.L)) | metadata,
(R.shortest(V.X, V.Y, C.second) <= (R.connected(V.X, V.Z, V.L), R.shortest(V.Z, V.Y, V.D))) | metadata,
(R.shortest_path(V.X, V.Y) <= R.shortest(V.X, V.Y, V.D)) | metadata,
R.shortest / 3 | Metadata(transformation=Transformation.IDENTITY),
R.connected / 3 | Metadata(transformation=Transformation.IDENTITY),
R.shortest_path / 2 | Metadata(transformation=Transformation.IDENTITY),
]

engine = EvaluationInferenceEngine(template)
Expand Down
9 changes: 3 additions & 6 deletions tests/test_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ def test_transformation_body_function(torch_fun, fun):
torch_result = torch_fun(data).detach().numpy().round(3)

template = Template()
template += (R.h <= fun(R.input)) | [F.identity]
template += R.h / 0 | [F.identity]
template += R.h <= fun(R.input)

model = template.build(Settings(iso_value_compression=False, chain_pruning=False))
dataset = Dataset([Sample(R.h, R.input[data.tolist()])])
Expand Down Expand Up @@ -56,8 +55,7 @@ def test_slice_function():
)

template = Template()
template += (R.h <= F.slice(R.input, rows=(1, 3))) | [F.identity]
template += R.h / 0 | [F.identity]
template += R.h <= F.slice(R.input, rows=(1, 3))

model = template.build(Settings(iso_value_compression=False, chain_pruning=False))
dataset = Dataset([Sample(R.h, [R.input[data]])])
Expand All @@ -69,7 +67,6 @@ def test_slice_function():

template = Template()
template += (R.h <= R.input) | [F.slice(rows=(1, 3))]
template += R.h / 0 | [F.identity]

model = template.build(Settings(iso_value_compression=False, chain_pruning=False))
dataset = Dataset(Sample(R.h, [R.input[data]]))
Expand All @@ -80,7 +77,7 @@ def test_slice_function():
assert np.allclose(res, results)

template = Template()
template += (R.h <= R.input) | [F.identity]
template += R.h <= R.input
template += R.h / 0 | [F.slice(rows=(1, 3))]

model = template.build(Settings(iso_value_compression=False, chain_pruning=False))
Expand Down
16 changes: 8 additions & 8 deletions tests/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def test_rgcnconv():
template += RGCNConv(1, 2, "h1", "h0", "_edge", ["a", "b", "c"])
template_str = str(template).split("\n")

assert template_str[0] == "h1(I) :- {2, 1} h0(I). [transformation=identity, aggregation=avg]"
assert template_str[1] == "h1(I) :- {2, 1} h0(J), *edge(J, a, I). [transformation=identity, aggregation=avg]"
assert template_str[2] == "h1(I) :- {2, 1} h0(J), *edge(J, b, I). [transformation=identity, aggregation=avg]"
assert template_str[3] == "h1(I) :- {2, 1} h0(J), *edge(J, c, I). [transformation=identity, aggregation=avg]"
assert template_str[0] == "h1(I) :- {2, 1} h0(I). [aggregation=avg]"
assert template_str[1] == "h1(I) :- {2, 1} h0(J), *edge(J, a, I). [aggregation=avg]"
assert template_str[2] == "h1(I) :- {2, 1} h0(J), *edge(J, b, I). [aggregation=avg]"
assert template_str[3] == "h1(I) :- {2, 1} h0(J), *edge(J, c, I). [aggregation=avg]"
assert template_str[4] == "h1/1 [transformation=identity]"


Expand All @@ -31,10 +31,10 @@ def test_rgcnconv_relations_edge_replace():
template += RGCNConv(1, 2, "h1", "h0", None, ["a", "b", "c"], Transformation.SIGMOID)
template_str = str(template).split("\n")

assert template_str[0] == "h1(I) :- {2, 1} h0(I). [transformation=identity, aggregation=avg]"
assert template_str[1] == "h1(I) :- {2, 1} h0(J), a(J, I). [transformation=identity, aggregation=avg]"
assert template_str[2] == "h1(I) :- {2, 1} h0(J), b(J, I). [transformation=identity, aggregation=avg]"
assert template_str[3] == "h1(I) :- {2, 1} h0(J), c(J, I). [transformation=identity, aggregation=avg]"
assert template_str[0] == "h1(I) :- {2, 1} h0(I). [aggregation=avg]"
assert template_str[1] == "h1(I) :- {2, 1} h0(J), a(J, I). [aggregation=avg]"
assert template_str[2] == "h1(I) :- {2, 1} h0(J), b(J, I). [aggregation=avg]"
assert template_str[3] == "h1(I) :- {2, 1} h0(J), c(J, I). [aggregation=avg]"
assert template_str[4] == "h1/1 [transformation=sigmoid]"


Expand Down
15 changes: 4 additions & 11 deletions tests/test_recurrent_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,14 @@ def test_lstm_module_simple(input_size, hidden_size, sequence_len, epochs):
template = Template()

template += [
(R.h(0) <= R.h0) | [Transformation.IDENTITY],
(R.h__c(0) <= R.c0) | [Transformation.IDENTITY],
R.h(0) <= R.h0,
R.h__c(0) <= R.c0,
(R.h__i(V.T) <= R.f(V.T)[5, 10] + R.h(V.Z)[5, 5] + R.special.next(V.Z, V.T)) | [Transformation.SIGMOID],
(R.h__f(V.T) <= R.f(V.T)[5, 10] + R.h(V.Z)[5, 5] + R.special.next(V.Z, V.T)) | [Transformation.SIGMOID],
(R.h__o(V.T) <= R.f(V.T)[5, 10] + R.h(V.Z)[5, 5] + R.special.next(V.Z, V.T)) | [Transformation.SIGMOID],
(R.h__n(V.T) <= R.f(V.T)[5, 10] + R.h(V.Z)[5, 5] + R.special.next(V.Z, V.T)) | [Transformation.TANH],
(R.h__c(V.T) <= R.h__f(V.T) * R.h__c(V.Z) + R.h__i(V.T) * R.h__n(V.T) + R.special.next(V.Z, V.T))
| [Transformation.IDENTITY],
(R.h(V.T) <= R.h__o(V.T) * Transformation.TANH(R.h__c(V.T))) | [Transformation.IDENTITY],
R.h / 1 | [Transformation.IDENTITY],
R.h__f / 1 | [Transformation.IDENTITY],
R.h__i / 1 | [Transformation.IDENTITY],
R.h__o / 1 | [Transformation.IDENTITY],
R.h__n / 1 | [Transformation.IDENTITY],
R.h__c / 1 | [Transformation.IDENTITY],
R.h__c(V.T) <= R.h__f(V.T) * R.h__c(V.Z) + R.h__i(V.T) * R.h__n(V.T) + R.special.next(V.Z, V.T),
R.h(V.T) <= R.h__o(V.T) * Transformation.TANH(R.h__c(V.T)),
]

model = template.build(
Expand Down
6 changes: 2 additions & 4 deletions tests/test_torch_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ def test_torch_function_with_parameters():
neuralogic.manual_seed(1)

template = Template()
template += (Relation.xor[1, 8] <= Relation.xy) | [F.identity]
template += Relation.xor / 0 | [F.identity]
template += Relation.xor[1, 8] <= Relation.xy

def to_logic(tensor_data):
return [Relation.xy[tensor_data]]
Expand Down Expand Up @@ -60,8 +59,7 @@ def test_torch_function_without_parameters():
neuralogic.manual_seed(1)

template = Template()
template += (Relation.xor <= Relation.xy) | [F.identity]
template += Relation.xor / 0 | [F.identity]
template += Relation.xor <= Relation.xy

def to_logic(tensor_data):
return [Relation.xy[tensor_data]]
Expand Down

0 comments on commit 7f18c28

Please sign in to comment.