neural-memorygraph 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- memorygraph/__init__.py +142 -0
- memorygraph/core/__init__.py +4 -0
- memorygraph/core/edge.py +219 -0
- memorygraph/core/graph.py +867 -0
- memorygraph/core/node.py +485 -0
- memorygraph/core/types.py +206 -0
- memorygraph/decay/__init__.py +5 -0
- memorygraph/decay/forgetting.py +465 -0
- memorygraph/memory/__init__.py +1 -0
- memorygraph/memory/working.py +370 -0
- memorygraph/neural/__init__.py +47 -0
- memorygraph/neural/encoder.py +404 -0
- memorygraph/neural/hopfield.py +364 -0
- memorygraph/neural/retriever.py +383 -0
- memorygraph/persistence/__init__.py +4 -0
- memorygraph/persistence/storage.py +564 -0
- memorygraph/retrieval/__init__.py +1 -0
- memorygraph/retrieval/spreading.py +370 -0
- memorygraph/utils/__init__.py +0 -0
- neural_memorygraph-1.0.0.dist-info/METADATA +611 -0
- neural_memorygraph-1.0.0.dist-info/RECORD +24 -0
- neural_memorygraph-1.0.0.dist-info/WHEEL +5 -0
- neural_memorygraph-1.0.0.dist-info/licenses/LICENSE +21 -0
- neural_memorygraph-1.0.0.dist-info/top_level.txt +1 -0
memorygraph/__init__.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
memorygraph
|
|
3
|
+
===========
|
|
4
|
+
Yapay zekalar için grafik tabanlı hafıza sistemi.
|
|
5
|
+
|
|
6
|
+
Modern Hopfield Ağları, yayılma aktivasyonu, Ebbinghaus unutma eğrisi
|
|
7
|
+
ve differansiyellenebilir hafıza bileşenleri içerir.
|
|
8
|
+
|
|
9
|
+
Hızlı başlangıç::
|
|
10
|
+
|
|
11
|
+
from memorygraph import MemoryGraph, MemoryNode, MemoryEdge
|
|
12
|
+
from memorygraph import MemoryType, EdgeType
|
|
13
|
+
from memorygraph import SpacedRepetitionScheduler
|
|
14
|
+
from memorygraph import SpreadingActivation, SpreadingConfig
|
|
15
|
+
from memorygraph import WorkingMemoryBuffer
|
|
16
|
+
from memorygraph import GraphStorageManager
|
|
17
|
+
|
|
18
|
+
# Graf oluştur
|
|
19
|
+
graph = MemoryGraph(embedding_dim=768, name="agent_memory")
|
|
20
|
+
|
|
21
|
+
# Düğüm ekle
|
|
22
|
+
node = MemoryNode(
|
|
23
|
+
content = "Python dilini öğrendim",
|
|
24
|
+
memory_type= MemoryType.EPISODIC,
|
|
25
|
+
importance = 0.8,
|
|
26
|
+
)
|
|
27
|
+
graph.add_node(node)
|
|
28
|
+
|
|
29
|
+
# Yayılma aktivasyonu
|
|
30
|
+
spreader = SpreadingActivation(graph)
|
|
31
|
+
results = spreader.spread([node.id])
|
|
32
|
+
|
|
33
|
+
# Aralıklı tekrar zamanlayıcısı
|
|
34
|
+
scheduler = SpacedRepetitionScheduler(model="fsrs")
|
|
35
|
+
scheduler.register_node(node.id)
|
|
36
|
+
|
|
37
|
+
# Kalıcı depolama
|
|
38
|
+
storage = GraphStorageManager(backend="sqlite")
|
|
39
|
+
storage.save(graph, "memory.db")
|
|
40
|
+
graph2 = storage.load("memory.db")
|
|
41
|
+
|
|
42
|
+
PyTorch modülleri::
|
|
43
|
+
|
|
44
|
+
from memorygraph.neural import (
|
|
45
|
+
ModernHopfieldLayer,
|
|
46
|
+
HopfieldMemoryPool,
|
|
47
|
+
HopfieldStack,
|
|
48
|
+
MemoryEncoder,
|
|
49
|
+
NeuralMemoryModule,
|
|
50
|
+
MemoryNetwork,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
hopfield = ModernHopfieldLayer(input_dim=512, hidden_dim=512, num_heads=8)
|
|
54
|
+
query = torch.randn(2, 10, 512)
|
|
55
|
+
patterns = torch.randn(2, 64, 512)
|
|
56
|
+
out, attn = hopfield(query, patterns)
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
from .core.types import (
|
|
60
|
+
MemoryType,
|
|
61
|
+
EdgeType,
|
|
62
|
+
ConsolidationState,
|
|
63
|
+
DecayFunction,
|
|
64
|
+
RetrievalStrategy,
|
|
65
|
+
ImportanceLevel,
|
|
66
|
+
RetrievalResult,
|
|
67
|
+
GraphStats,
|
|
68
|
+
NodeID,
|
|
69
|
+
EdgeID,
|
|
70
|
+
Embedding,
|
|
71
|
+
# Exceptions
|
|
72
|
+
MemoryGraphError,
|
|
73
|
+
NodeNotFoundError,
|
|
74
|
+
EdgeNotFoundError,
|
|
75
|
+
EmbeddingDimensionError,
|
|
76
|
+
WorkingMemoryCapacityError,
|
|
77
|
+
ConsolidationError,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
from .core.node import MemoryNode, TemporalInfo
|
|
81
|
+
from .core.edge import MemoryEdge
|
|
82
|
+
from .core.graph import MemoryGraph
|
|
83
|
+
|
|
84
|
+
from .memory.working import (
|
|
85
|
+
WorkingMemoryBuffer,
|
|
86
|
+
WorkingMemoryItem,
|
|
87
|
+
WorkingMemorySlot,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
from .retrieval.spreading import (
|
|
91
|
+
SpreadingActivation,
|
|
92
|
+
SpreadingConfig,
|
|
93
|
+
ActivationResult,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
from .decay.forgetting import (
|
|
97
|
+
ForgettingModel,
|
|
98
|
+
EbbinghausModel,
|
|
99
|
+
PowerLawModel,
|
|
100
|
+
SM2Model,
|
|
101
|
+
SM2Card,
|
|
102
|
+
FSRSModel,
|
|
103
|
+
SpacedRepetitionScheduler,
|
|
104
|
+
ReviewScheduleEntry,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
from .persistence.storage import (
|
|
108
|
+
StorageBackend,
|
|
109
|
+
JSONBackend,
|
|
110
|
+
PickleBackend,
|
|
111
|
+
SQLiteBackend,
|
|
112
|
+
GraphStorageManager,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
__version__ = "1.0.0"
|
|
117
|
+
__author__ = "memorygraph"
|
|
118
|
+
__license__ = "MIT"
|
|
119
|
+
|
|
120
|
+
__all__ = [
|
|
121
|
+
# Core
|
|
122
|
+
"MemoryGraph", "MemoryNode", "MemoryEdge", "TemporalInfo",
|
|
123
|
+
# Types & Enums
|
|
124
|
+
"MemoryType", "EdgeType", "ConsolidationState", "DecayFunction",
|
|
125
|
+
"RetrievalStrategy", "ImportanceLevel",
|
|
126
|
+
"RetrievalResult", "GraphStats",
|
|
127
|
+
"NodeID", "EdgeID", "Embedding",
|
|
128
|
+
# Exceptions
|
|
129
|
+
"MemoryGraphError", "NodeNotFoundError", "EdgeNotFoundError",
|
|
130
|
+
"EmbeddingDimensionError", "WorkingMemoryCapacityError", "ConsolidationError",
|
|
131
|
+
# Working Memory
|
|
132
|
+
"WorkingMemoryBuffer", "WorkingMemoryItem", "WorkingMemorySlot",
|
|
133
|
+
# Retrieval
|
|
134
|
+
"SpreadingActivation", "SpreadingConfig", "ActivationResult",
|
|
135
|
+
# Decay & Forgetting
|
|
136
|
+
"ForgettingModel", "EbbinghausModel", "PowerLawModel",
|
|
137
|
+
"SM2Model", "SM2Card", "FSRSModel",
|
|
138
|
+
"SpacedRepetitionScheduler", "ReviewScheduleEntry",
|
|
139
|
+
# Persistence
|
|
140
|
+
"StorageBackend", "JSONBackend", "PickleBackend",
|
|
141
|
+
"SQLiteBackend", "GraphStorageManager",
|
|
142
|
+
]
|
memorygraph/core/edge.py
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""
|
|
2
|
+
memorygraph.core.edge
|
|
3
|
+
=====================
|
|
4
|
+
MemoryEdge — iki hafıza düğümü arasındaki ilişki.
|
|
5
|
+
|
|
6
|
+
Kenarlar yönlü veya yönsüz olabilir, ağırlık taşır ve
|
|
7
|
+
zamansal meta veriye sahiptir.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import time
|
|
13
|
+
import uuid
|
|
14
|
+
from dataclasses import dataclass, field
|
|
15
|
+
from typing import Any, Dict, Optional
|
|
16
|
+
|
|
17
|
+
from .types import EdgeID, EdgeType, Metadata, NodeID
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MemoryEdge:
|
|
21
|
+
"""
|
|
22
|
+
Hafıza düğümleri arasındaki ilişkiyi modelleyen kenar.
|
|
23
|
+
|
|
24
|
+
Özellikler:
|
|
25
|
+
- **Ağırlık**: ilişkinin güçü (0-1 arası, öğrenilebilir)
|
|
26
|
+
- **Yön**: kaynak → hedef (yönsüz graflar için iki yönlü kenar)
|
|
27
|
+
- **Tür**: semantik ilişki kategorisi (causal, temporal, vb.)
|
|
28
|
+
- **Güven**: bu ilişkiye duyulan güven düzeyi
|
|
29
|
+
- **Zamansal**: ne zaman oluşturuldu/güncellendi
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
__slots__ = (
|
|
33
|
+
"_id", "_source_id", "_target_id", "_edge_type",
|
|
34
|
+
"_weight", "_confidence", "_directed",
|
|
35
|
+
"_created_at", "_last_updated", "_update_count",
|
|
36
|
+
"_metadata",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
source_id: NodeID,
|
|
42
|
+
target_id: NodeID,
|
|
43
|
+
edge_type: EdgeType = EdgeType.ASSOCIATION,
|
|
44
|
+
weight: float = 1.0,
|
|
45
|
+
confidence: float = 1.0,
|
|
46
|
+
directed: bool = True,
|
|
47
|
+
metadata: Optional[Metadata] = None,
|
|
48
|
+
edge_id: Optional[EdgeID] = None,
|
|
49
|
+
) -> None:
|
|
50
|
+
if not (0.0 <= weight <= 1.0):
|
|
51
|
+
raise ValueError(f"Kenar ağırlığı 0-1 arasında olmalı, alınan: {weight}")
|
|
52
|
+
if not (0.0 <= confidence <= 1.0):
|
|
53
|
+
raise ValueError(f"Güven değeri 0-1 arasında olmalı, alınan: {confidence}")
|
|
54
|
+
|
|
55
|
+
self._id: EdgeID = edge_id or str(uuid.uuid4())
|
|
56
|
+
self._source_id: NodeID = source_id
|
|
57
|
+
self._target_id: NodeID = target_id
|
|
58
|
+
self._edge_type: EdgeType = edge_type
|
|
59
|
+
self._weight: float = weight
|
|
60
|
+
self._confidence: float = confidence
|
|
61
|
+
self._directed: bool = directed
|
|
62
|
+
self._created_at: float = time.time()
|
|
63
|
+
self._last_updated: float = self._created_at
|
|
64
|
+
self._update_count: int = 0
|
|
65
|
+
self._metadata: Metadata = dict(metadata or {})
|
|
66
|
+
|
|
67
|
+
# -----------------------------------------------------------------------
|
|
68
|
+
# Özellikler
|
|
69
|
+
# -----------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def id(self) -> EdgeID:
|
|
73
|
+
return self._id
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def source_id(self) -> NodeID:
|
|
77
|
+
return self._source_id
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def target_id(self) -> NodeID:
|
|
81
|
+
return self._target_id
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def edge_type(self) -> EdgeType:
|
|
85
|
+
return self._edge_type
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def weight(self) -> float:
|
|
89
|
+
return self._weight
|
|
90
|
+
|
|
91
|
+
@weight.setter
|
|
92
|
+
def weight(self, value: float) -> None:
|
|
93
|
+
if not (0.0 <= value <= 1.0):
|
|
94
|
+
raise ValueError(f"Ağırlık 0-1 arasında olmalı: {value}")
|
|
95
|
+
self._weight = value
|
|
96
|
+
self._last_updated = time.time()
|
|
97
|
+
self._update_count += 1
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def confidence(self) -> float:
|
|
101
|
+
return self._confidence
|
|
102
|
+
|
|
103
|
+
@confidence.setter
|
|
104
|
+
def confidence(self, value: float) -> None:
|
|
105
|
+
self._confidence = max(0.0, min(1.0, value))
|
|
106
|
+
self._last_updated = time.time()
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def directed(self) -> bool:
|
|
110
|
+
return self._directed
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def effective_weight(self) -> float:
|
|
114
|
+
"""Güvenle ağırlıklandırılmış etkin kenar gücü."""
|
|
115
|
+
return self._weight * self._confidence
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def age_seconds(self) -> float:
|
|
119
|
+
return time.time() - self._created_at
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def metadata(self) -> Metadata:
|
|
123
|
+
return self._metadata
|
|
124
|
+
|
|
125
|
+
def get_other_end(self, node_id: NodeID) -> Optional[NodeID]:
|
|
126
|
+
"""Verilen düğümün diğer ucunu döndürür."""
|
|
127
|
+
if node_id == self._source_id:
|
|
128
|
+
return self._target_id
|
|
129
|
+
if node_id == self._target_id and not self._directed:
|
|
130
|
+
return self._source_id
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
def connects(self, a: NodeID, b: NodeID) -> bool:
|
|
134
|
+
"""Bu kenar a ve b'yi bağlıyor mu?"""
|
|
135
|
+
if self._directed:
|
|
136
|
+
return self._source_id == a and self._target_id == b
|
|
137
|
+
return (self._source_id == a and self._target_id == b) or \
|
|
138
|
+
(self._source_id == b and self._target_id == a)
|
|
139
|
+
|
|
140
|
+
# -----------------------------------------------------------------------
|
|
141
|
+
# Hebbian öğrenme güncellemesi
|
|
142
|
+
# -----------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
def hebbian_update(
|
|
145
|
+
self,
|
|
146
|
+
delta: float = 0.05,
|
|
147
|
+
decay: float = 0.01,
|
|
148
|
+
max_weight: float = 1.0,
|
|
149
|
+
) -> None:
|
|
150
|
+
"""
|
|
151
|
+
Hebbian öğrenme kuralı: "Birlikte ateşlenen nöronlar birbirine bağlanır."
|
|
152
|
+
|
|
153
|
+
Δw = δ · (1 - w) - λ · w
|
|
154
|
+
|
|
155
|
+
delta: öğrenme oranı
|
|
156
|
+
decay: ağırlık çürümesi (normalize edici)
|
|
157
|
+
"""
|
|
158
|
+
dw = delta * (max_weight - self._weight) - decay * self._weight
|
|
159
|
+
self._weight = float(max(0.0, min(max_weight, self._weight + dw)))
|
|
160
|
+
self._last_updated = time.time()
|
|
161
|
+
self._update_count += 1
|
|
162
|
+
|
|
163
|
+
def decay_weight(self, rate: float = 0.001) -> None:
|
|
164
|
+
"""Kenar ağırlığını zamanla zayıflat."""
|
|
165
|
+
self._weight = max(0.0, self._weight * (1.0 - rate))
|
|
166
|
+
self._last_updated = time.time()
|
|
167
|
+
|
|
168
|
+
# -----------------------------------------------------------------------
|
|
169
|
+
# Serileştirme
|
|
170
|
+
# -----------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
173
|
+
return {
|
|
174
|
+
"id": self._id,
|
|
175
|
+
"source_id": self._source_id,
|
|
176
|
+
"target_id": self._target_id,
|
|
177
|
+
"edge_type": self._edge_type.value,
|
|
178
|
+
"weight": self._weight,
|
|
179
|
+
"confidence": self._confidence,
|
|
180
|
+
"directed": self._directed,
|
|
181
|
+
"created_at": self._created_at,
|
|
182
|
+
"last_updated": self._last_updated,
|
|
183
|
+
"update_count": self._update_count,
|
|
184
|
+
"metadata": self._metadata,
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def from_dict(cls, data: Dict[str, Any]) -> "MemoryEdge":
|
|
189
|
+
edge = cls(
|
|
190
|
+
source_id = data["source_id"],
|
|
191
|
+
target_id = data["target_id"],
|
|
192
|
+
edge_type = EdgeType(data.get("edge_type", "association")),
|
|
193
|
+
weight = data.get("weight", 1.0),
|
|
194
|
+
confidence = data.get("confidence", 1.0),
|
|
195
|
+
directed = data.get("directed", True),
|
|
196
|
+
metadata = data.get("metadata", {}),
|
|
197
|
+
edge_id = data.get("id"),
|
|
198
|
+
)
|
|
199
|
+
edge._created_at = data.get("created_at", edge._created_at)
|
|
200
|
+
edge._last_updated = data.get("last_updated", edge._last_updated)
|
|
201
|
+
edge._update_count = data.get("update_count", 0)
|
|
202
|
+
return edge
|
|
203
|
+
|
|
204
|
+
# -----------------------------------------------------------------------
|
|
205
|
+
# Dunder metodları
|
|
206
|
+
# -----------------------------------------------------------------------
|
|
207
|
+
|
|
208
|
+
def __repr__(self) -> str:
|
|
209
|
+
arrow = "→" if self._directed else "↔"
|
|
210
|
+
return (
|
|
211
|
+
f"MemoryEdge('{self._source_id[:8]}' {arrow} '{self._target_id[:8]}', "
|
|
212
|
+
f"type={self._edge_type.name}, w={self._weight:.3f})"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
def __hash__(self) -> int:
|
|
216
|
+
return hash(self._id)
|
|
217
|
+
|
|
218
|
+
def __eq__(self, other: object) -> bool:
|
|
219
|
+
return isinstance(other, MemoryEdge) and self._id == other._id
|