Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
87f2e90
Structures testing, starting with memory
pverges May 19, 2022
1932257
Structures testing, starting with multiset
pverges May 19, 2022
a750d6d
Structures testing, starting with multiset
pverges May 19, 2022
07a6daf
Structures testing, hashtable done
pverges May 20, 2022
6bb956b
Structures testing, sequence done, two functions do not work
pverges May 23, 2022
097c430
Structures testing, graph done, node neighbors not working and contai…
pverges May 24, 2022
0a5aa09
tests
pverges May 24, 2022
4de5699
Merge branch 'main' into test-structures
pverges May 24, 2022
e91f7b1
Structures testing sequence done
pverges May 24, 2022
65c9550
Structures testing, sequence and graph fix. Tree and FSA done
pverges May 24, 2022
4adfd7c
Structures testing, starting with memory
pverges May 19, 2022
b149f04
Structures testing, starting with multiset
pverges May 19, 2022
c582a05
Structures testing, starting with multiset
pverges May 19, 2022
14b83c6
Structures testing, hashtable done
pverges May 20, 2022
e716f28
Structures testing, sequence done, two functions do not work
pverges May 23, 2022
4559844
Structures testing, graph done, node neighbors not working and contai…
pverges May 24, 2022
da755f7
tests
pverges May 24, 2022
898ac6c
Structures testing sequence done
pverges May 24, 2022
7ca5208
Structures testing, sequence and graph fix. Tree and FSA done
pverges May 24, 2022
e84ddf2
Structures testing, graph fixed
pverges May 25, 2022
ded8d0a
Merge remote-tracking branch 'origin/test-structures' into test-struc…
pverges May 25, 2022
7130a87
Structures testing, distinct sequence. Fixed Distinct Sequence init f…
pverges May 25, 2022
810f5af
random hd incorrect out parameter
pverges May 25, 2022
6edd0dc
Use identity hv for distinct sequence
mikeheddes May 25, 2022
596776f
Update formatting
mikeheddes May 25, 2022
1cc75a7
Fix tests
mikeheddes May 26, 2022
ddd870f
Fix embeddings out usage
mikeheddes May 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions torchhd/embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def reset_parameters(self):
"device": self.weight.data.device,
"dtype": self.weight.data.dtype,
}
functional.identity_hv(
self.num_embeddings,
self.embedding_dim,
out=self.weight.data,
**factory_kwargs

self.weight.data.copy_(
functional.identity_hv(
self.num_embeddings, self.embedding_dim, **factory_kwargs
)
)

self._fill_padding_idx_with_zero()
Expand Down Expand Up @@ -84,11 +84,11 @@ def reset_parameters(self):
"device": self.weight.data.device,
"dtype": self.weight.data.dtype,
}
functional.random_hv(
self.num_embeddings,
self.embedding_dim,
out=self.weight.data,
**factory_kwargs

self.weight.data.copy_(
functional.random_hv(
self.num_embeddings, self.embedding_dim, **factory_kwargs
)
)

self._fill_padding_idx_with_zero()
Expand Down Expand Up @@ -140,12 +140,14 @@ def reset_parameters(self):
"device": self.weight.data.device,
"dtype": self.weight.data.dtype,
}
functional.level_hv(
self.num_embeddings,
self.embedding_dim,
randomness=self.randomness,
out=self.weight.data,
**factory_kwargs

self.weight.data.copy_(
functional.level_hv(
self.num_embeddings,
self.embedding_dim,
randomness=self.randomness,
**factory_kwargs
)
)

self._fill_padding_idx_with_zero()
Expand Down Expand Up @@ -204,12 +206,14 @@ def reset_parameters(self):
"device": self.weight.data.device,
"dtype": self.weight.data.dtype,
}
functional.circular_hv(
self.num_embeddings,
self.embedding_dim,
randomness=self.randomness,
out=self.weight.data,
**factory_kwargs

self.weight.data.copy_(
functional.circular_hv(
self.num_embeddings,
self.embedding_dim,
randomness=self.randomness,
**factory_kwargs
)
)

self._fill_padding_idx_with_zero()
Expand Down
16 changes: 9 additions & 7 deletions torchhd/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Memory:

"""

def __init__(self, threshold=0.0):
def __init__(self, threshold=0.5):
self.threshold = threshold
self.keys: List[Tensor] = []
self.values: List[Any] = []
Expand Down Expand Up @@ -82,7 +82,7 @@ def index(self, key: Tensor) -> int:
value, index = torch.max(sim, 0)

if value.item() < self.threshold:
raise IndexError()
raise IndexError("No elements in memory")

return index

Expand Down Expand Up @@ -241,7 +241,7 @@ def clear(self) -> None:

@classmethod
def from_ngrams(cls, input: Tensor, n=3):
"""Creates a multiset from the ngrams of a set of hypervectors.
r"""Creates a multiset from the ngrams of a set of hypervectors.

See: :func:`~torchhd.functional.ngrams`.

Expand Down Expand Up @@ -273,7 +273,7 @@ def from_tensor(cls, input: Tensor):
>>> M = structures.Multiset.from_tensor(x)

"""
value = functional.multiset(input, dim=-2)
value = functional.multiset(input)
return cls(value, size=input.size(-2))


Expand Down Expand Up @@ -434,7 +434,7 @@ def from_tensors(cls, keys: Tensor, values: Tensor):

"""
value = functional.hash_table(keys, values)
return cls(value, size=input.size(-2))
return cls(value, size=keys.size(-2))


class Sequence:
Expand Down Expand Up @@ -663,7 +663,9 @@ def __init__(self, dim_or_input: int, **kwargs):
else:
dtype = kwargs.get("dtype", torch.get_default_dtype())
device = kwargs.get("device", None)
self.value = torch.zeros(dim_or_input, dtype=dtype, device=device)
self.value = functional.identity_hv(
1, dim_or_input, dtype=dtype, device=device
).squeeze(0)

def append(self, input: Tensor) -> None:
"""Appends the input tensor to the right of the sequence.
Expand Down Expand Up @@ -766,7 +768,7 @@ def clear(self) -> None:
>>> DS.clear()

"""
self.value.fill_(0.0)
self.value.fill_(1.0)
self.size = 0

@classmethod
Expand Down
Empty file.
123 changes: 123 additions & 0 deletions torchhd/tests/structures/test_distinct_sequence.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import pytest
import torch
import string

from torchhd import structures, functional

seed = 2147483644
letters = list(string.ascii_lowercase)


class TestDistinctSequence:
def test_creation_dim(self):
S = structures.DistinctSequence(10000)
assert torch.equal(S.value, torch.ones(10000))

def test_creation_tensor(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)

S = structures.DistinctSequence(hv[0])
assert torch.equal(S.value, hv[0])

def test_generator(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv1 = functional.random_hv(60, 10000, generator=generator)

generator = torch.Generator()
generator.manual_seed(seed)
hv2 = functional.random_hv(60, 10000, generator=generator)

assert (hv1 == hv2).min().item()

def test_append(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.append(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5

def test_appendleft(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.appendleft(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5

def test_pop(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.append(hv[0])
S.append(hv[1])
S.pop(hv[1])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5
S.pop(hv[0])
S.append(hv[2])
assert functional.cosine_similarity(S.value, hv)[2] > 0.5
S.append(hv[3])
S.pop(hv[3])
assert functional.cosine_similarity(S.value, hv)[2] > 0.5

def test_popleft(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.appendleft(hv[0])
S.appendleft(hv[1])
S.popleft(hv[1])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5
S.popleft(hv[0])
S.appendleft(hv[2])
assert functional.cosine_similarity(S.value, hv)[2] > 0.5
S.appendleft(hv[3])
S.popleft(hv[3])
assert functional.cosine_similarity(S.value, hv)[2] > 0.5

def test_replace(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.append(hv[0])
assert functional.cosine_similarity(S.value, hv)[0] > 0.5
S.replace(0, hv[0], hv[1])
assert functional.cosine_similarity(S.value, hv)[1] > 0.5

def test_length(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
assert len(S) == 4
S.pop(hv[0])
S.pop(hv[0])
S.pop(hv[0])
assert len(S) == 1
S.pop(hv[0])
assert len(S) == 0
S.append(hv[0])
assert len(S) == 1

def test_clear(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv = functional.random_hv(len(letters), 10000, generator=generator)
S = structures.DistinctSequence(10000)
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
S.append(hv[0])
assert len(S) == 4
S.clear()
assert len(S) == 0
103 changes: 103 additions & 0 deletions torchhd/tests/structures/test_fsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import pytest
import torch
import string

from torchhd import structures, functional

seed = 2147483644
seed1 = 2147483643
letters = list(string.ascii_lowercase)


class TestFSA:
def test_creation_dim(self):
F = structures.FiniteStateAutomata(10000)
assert torch.equal(F.value, torch.zeros(10000))

def test_generator(self):
generator = torch.Generator()
generator.manual_seed(seed)
hv1 = functional.random_hv(60, 10000, generator=generator)

generator = torch.Generator()
generator.manual_seed(seed)
hv2 = functional.random_hv(60, 10000, generator=generator)

assert (hv1 == hv2).min().item()

def test_add_transition(self):
generator = torch.Generator()
generator1 = torch.Generator()
generator.manual_seed(seed)
generator1.manual_seed(seed1)
tokens = functional.random_hv(10, 10, generator=generator)
actions = functional.random_hv(10, 10, generator=generator1)

F = structures.FiniteStateAutomata(10)

F.add_transition(tokens[0], actions[1], actions[2])
assert torch.equal(
F.value,
torch.tensor([1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0]),
)
F.add_transition(tokens[1], actions[1], actions[3])
assert torch.equal(
F.value, torch.tensor([0.0, 0.0, -2.0, 2.0, 0.0, 2.0, 0.0, -2.0, -2.0, 0.0])
)
F.add_transition(tokens[2], actions[1], actions[3])
assert torch.equal(
F.value,
torch.tensor([1.0, 1.0, -3.0, 1.0, 1.0, 3.0, -1.0, -1.0, -1.0, 1.0]),
)

def test_transition(self):
generator = torch.Generator()
generator1 = torch.Generator()
generator.manual_seed(seed)
generator1.manual_seed(seed1)
tokens = functional.random_hv(10, 10, generator=generator)
states = functional.random_hv(10, 10, generator=generator1)

F = structures.FiniteStateAutomata(10)

F.add_transition(tokens[0], states[1], states[2])
F.add_transition(tokens[1], states[1], states[3])
F.add_transition(tokens[2], states[1], states[5])

assert (
torch.argmax(
functional.cosine_similarity(F.transition(states[1], tokens[0]), states)
).item()
== 2
)
assert (
torch.argmax(
functional.cosine_similarity(F.transition(states[1], tokens[1]), states)
).item()
== 3
)
assert (
torch.argmax(
functional.cosine_similarity(F.transition(states[1], tokens[2]), states)
).item()
== 5
)

def test_clear(self):
generator = torch.Generator()
generator1 = torch.Generator()
generator.manual_seed(seed)
generator1.manual_seed(seed1)
tokens = functional.random_hv(10, 10, generator=generator)
states = functional.random_hv(10, 10, generator=generator1)

F = structures.FiniteStateAutomata(10)

F.add_transition(tokens[0], states[1], states[2])
F.add_transition(tokens[1], states[1], states[3])
F.add_transition(tokens[2], states[1], states[5])

F.clear()
assert torch.equal(
F.value, torch.tensor([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
)
Loading