Reinforcement learning on Dynamic Knowledge Graphs (ReDKG) - это библиотека глубокого обучения с подкреплением на динамических графах знаний.
Библиотека предназначена для кодирования статических и динамических графов знаний (ГЗ) при помощи построения векторных представлений сущностей и отношений. Алгоритм обучения с подкреплением на основе векторных представлений предназначен для обучения рекомендательных моделей и моделей систем поддержки принятия решений на основе обучения с подкреплением (RL) на основе векторных представлений графов.
Для работы библиотеки необходим интерпретатор языка программирования Python версии не ниже 3.9
На первом шаге необходимо выполнить установку библиотеки, Pytorch Geometric и Torch 1.1.2.
# CUDA 10.2
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=10.2 -c pytorch
# CUDA 11.3
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.3 -c pytorch
# CUDA 11.6
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.6 -c pytorch -c conda-forge
# CPU Only
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cpuonly -c pytorch
После установки необходимых библиотек необходимо скопировать репозиторий и выполнить следующую команду, находясь в директории проекта:
pip install .
Тестовый набор данных может быть получен по ссылке movielens и
распакован в директорию /data/
.
После распаковки директория /data/ должна содержать следующий набор файлов:
ratings.csv
- исходный файл оценок пользователей;attributes.csv
- исходный файл атрибутов объектов;kg.txt
- файл, содержащий граф знаний;item_index2enity_id.txt
- сопоставление индексов объектов в исходном файле оценок пользователей с индексами объектов в графе знаний;
from redkg.config import Config
from redkg.preprocess import DataPreprocessor
config = Config()
preprocessor = DataPreprocessor(config)
preprocessor.process_data()
kge_model = KGEModel(
model_name="TransE",
nentity=info['nentity'],
nrelation=info['nrelation'],
hidden_dim=128,
gamma=12.0,
double_entity_embedding=True,
double_relation_embedding=True,
evaluator=evaluator
)
training_logs, test_logs = train_kge_model(kge_model, train_pars, info, train_triples, valid_triples)
Данные модели реализуют алгоритм предсказания связей в графе знаний.
Дополнительную информацию о шагах обучения можно найти в примере basic_link_prediction.ipynb.
Тестовый набор данных может быть получен по ссылке jd_data2.json
и положен в директорию /data/
.
Для предобработки потребуется выполнить чтение данных из файла и преобразование их в формат PyTorch Geometric.
import json
import torch
from torch_geometric.data import Data
# Прочтём данные из файла
with open('jd_data2.json', 'r') as f:
graph_data = json.load(f)
# Извлечём список узлов и преобразуем его в словарь для быстрого поиска
node_list = [node['id'] for node in graph_data['nodes']]
node_mapping = {node_id: i for i, node_id in enumerate(node_list)}
node_index = {index: node for node, index in node_mapping.items()}
# Создадим список рёбер в формате PyTorch Geometric
edge_index = [[node_mapping[link['source']], node_mapping[link['target']]] for link in graph_data['links']]
edge_index = torch.tensor(edge_index, dtype=torch.long).t().contiguous()
features = torch.randn(len(node_list), 1)
labels = torch.tensor(list(range(len(graph_data['nodes']))), dtype=torch.long)
large_dataset = Data(x=features, edge_index=edge_index, y=labels, node_mapping=node_mapping, node_index=node_index)
torch.save(large_dataset, 'large_dataset.pth')
large_dataset.cuda()
Далее необходимо сгенерировать подграфы для обучения модели. Для этого можно использовать следующий код:
import json
import os
from redkg.generate_subgraphs import generate_subgraphs
# Сгенерируем датасет на 1000 подграфов, каждый из которых будет содержать от 3 до 15 узлов
if not os.path.isfile('subgraphs.json'):
subgraphs = generate_subgraphs(graph_data, num_subgraphs=1000, min_nodes=3, max_nodes=15)
with open('subgraphs.json', 'w') as f:
json.dump(subgraphs, f)
else:
with open('subgraphs.json', 'r') as f:
subgraphs = json.load(f)
Далее необходимо выполнить преобразование подграфов в формат PyTorch Geometric:
from redkg.generate_subgraphs import generate_subgraphs_dataset
dataset = generate_subgraphs_dataset(subgraphs, large_dataset)
Выполним инициализацию оптимизатора и модели в режиме обучения:
from redkg.models.graphsage import GraphSAGE
from torch.optim import Adam
# Обучим модель GraphSAGE (так же можно использовать GCN или GAT)
# количество входных и выходных признаков совпадает с количеством узлов в большом графе - 177
# количество слоёв - 64
model = GraphSAGE(large_dataset.num_node_features, 64, large_dataset.num_node_features)
model.train()
# Используем оптимизатор Adam
# скорость обучения - 0.0001
# весовой коэффициент - 1e-5
optimizer = Adam(model.parameters(), lr=0.0001, weight_decay=1e-5)
Запустим обучение модели в 2 эпохи:
from redkg.train import train_gnn_model
from redkg.negative_samples import generate_negative_samples
# Model training
loss_values = []
for epoch in range(2):
for subgraph in dataset:
positive_edges = subgraph.edge_index.t().tolist()
negative_edges = generate_negative_samples(subgraph.edge_index, subgraph.num_nodes, len(positive_edges))
if len(negative_edges) == 0:
continue
loss = train_gnn_model(model, optimizer, subgraph, positive_edges, negative_edges)
loss_values.append(loss)
print(f"Epoch: {epoch}, Loss: {loss}")
ReDKG - это фреймворк, реализующий алгоритмы сильного ИИ в части глубокого обучения с подкреплением на динамических графах знаний для задач поддержки принятия решений. На рисунке ниже приведена общая структура компонента. Она включает в себя четыре основных модуля:
- модули кодирования графа в векторные представления (кодировщик):
- KGE, реализованный с помощью класса KGEModel в
redkg.models.kge
- GCN, реализованный с помощью класса GCN в
redkg.models.gcn
- GAT, реализованный с помощью класса GAT в
redkg.models.gat
- GraphSAGE, реализованный с помощью класса GraphSAGE в
redkg.models.graphsage
- KGE, реализованный с помощью класса KGEModel в
- модуль представления состояния (представление состояния), реализованный с помощью класса GCNGRU в
redkg.models.gcn_gru_layers
- модуль выбора объектов-кандидатов (отбор возможных действий)
- модуль Q-обучения (Q-network), реализованный классом TrainPipeline в
redkg.train
Последняя стабильная версия проекта проекта доступна по ссылке
Репозиторий проекта включает в себя следующие директории:
- директория
redkg
- содержит основные классы и функции проекта; - директория
examples
- содержит несколько примеров использования; - директория
data
- должна содержать данные для моделирования; - директория
raw_bellman_ford
- содержит модульную реализацию алгоритма Беллмана-Форда; - все модульные и интеграционные тесты можно посмотреть в директории
test
; - документация содержится в директории
docs
.
Для обучения векторных представлений с параметрами по умолчанию выполните следующую команду в командной строке:
python kg_run
Для обучение векторных представлений в своем проекте используйте:
from kge import KGEModel
from edge_predict import Evaluator
evaluator = Evaluator()
kge_model = KGEModel(
model_name="TransE",
nentity=info['nentity'],
nrelation=info['nrelation'],
hidden_dim=128,
gamma=12.0,
double_entity_embedding=True,
double_relation_embedding=True,
evaluator=evaluator
)
Для обучения модели KGQR на собственных данных используйте:
negative_sample_size = 128
nentity = len(entity_vocab.keys())
train_count = calc_state_kg(triples)
dataset = TrainDavaset (triples,
nentity,
len(relation_vocab.keys()),
negative_sample_size,
"mode",
train_count)
conf = Config()
#Building Net
model = GCNGRU(Config(), entity_vocab, relation_vocab, 50)
# Embedding pretrain by TransE
crain_kge_model (model_kge_model, train pars, info, triples, None)
#Training using RL
optimizer = optim.Adam(model.parameters(), lr=0.001)
train(Config(), item_vocab, model, optimizer)
Для визуализации графов и гиперграфов используется система справочников
для установки параметров визуализации, а также система контрактов
для установки графических элементов.
Пример визуализации графа:
graph_contract: GraphContract = GraphContract(
vertex_num=10,
edge_list=(
[(0, 7), (2, 7), (4, 9), (3, 7), (1, 8), (5, 7), (2, 3), (4, 5), (5, 6), (4, 8), (6, 9), (4, 7)],
[1.0] * 12,
),
edge_num=12,
edge_weights=list(tensor([1.0] * 24)),
)
vis_contract: GraphVisualizationContract = GraphVisualizationContract(graph=graph_contract)
vis: GraphVisualizer = GraphVisualizer(vis_contract)
fig = vis.draw()
fig.show()
Пример визуализации гиперграфа:
graph_contract: HypergraphContract = HypergraphContract(
vertex_num=10,
edge_list=(
[(3, 4, 5, 9), (0, 4, 7), (4, 6), (0, 1, 2, 4), (3, 6), (0, 3, 9), (2, 5), (4, 7)],
[1.0] * 8,
),
edge_num=8,
edge_weights=list(tensor([1.0] * 10)),
)
vis_contract: HypergraphVisualizationContract = HypergraphVisualizationContract(graph=graph_contract)
vis: HypergraphVisualizer = HypergraphVisualizer(vis_contract)
fig = vis.draw()
fig.show()
Для визуализации графов и гиперграфов используется система справочников
для установки параметров визуализации, а также система контрактов
для установки графических элементов.
Пример визуализации графа:
graph_contract: GraphContract = GraphContract(
vertex_num=10,
edge_list=(
[(0, 7), (2, 7), (4, 9), (3, 7), (1, 8), (5, 7), (2, 3), (4, 5), (5, 6), (4, 8), (6, 9), (4, 7)],
[1.0] * 12,
),
edge_num=12,
edge_weights=list(tensor([1.0] * 24)),
)
vis_contract: GraphVisualizationContract = GraphVisualizationContract(graph=graph_contract)
vis: GraphVisualizer = GraphVisualizer(vis_contract)
fig = vis.draw()
fig.show()
Пример визуализации гиперграфа:
graph_contract: HypergraphContract = HypergraphContract(
vertex_num=10,
edge_list=(
[(3, 4, 5, 9), (0, 4, 7), (4, 6), (0, 1, 2, 4), (3, 6), (0, 3, 9), (2, 5), (4, 7)],
[1.0] * 8,
),
edge_num=8,
edge_weights=list(tensor([1.0] * 10)),
)
vis_contract: HypergraphVisualizationContract = HypergraphVisualizationContract(graph=graph_contract)
vis: HypergraphVisualizer = HypergraphVisualizer(vis_contract)
fig = vis.draw()
fig.show()
BellmanFordLayerModified
- это PyTorch-слой, реализующий модифицированный алгоритм Беллмана-Форда для анализа свойств графов и извлечения признаков из графовой структуры. Этот слой может использоваться в задачах графового машинного обучения, таких как предсказание путей и анализ графовых структур.
import torch
from raw_bellman_ford.layers.bellman_ford_modified import BellmanFordLayerModified
# Инициализация слоя с указанием количества узлов и числа признаков
num_nodes = 4
num_features = 5
bellman_ford_layer = BellmanFordLayerModified(num_nodes, num_features)
# Определение матрицы смежности графа и начального узла
adj_matrix = torch.tensor([[0, 2, float('inf'), 1],
[float('inf'), 0, -1, float('inf')],
[float('inf'), float('inf'), 0, -2],
[float('inf'), float('inf'), float('inf'), 0]])
source_node = 0
# Вычисление признаков графа, диаметра и эксцентриситета
node_features, diameter, eccentricity = bellman_ford_layer(adj_matrix, source_node)
print("Node Features:")
print(node_features)
print("Graph Diameter:", diameter)
print("Graph Eccentricity:", eccentricity)
num_nodes
: Количество узлов в графе.num_features
: Количество признаков, извлекаемых из графа.edge_weights
: Веса ребер между узлами (обучаемые параметры).node_embedding
: Вложение узлов для извлечения признаков.
BellmanFordLayerModified
полезен, когда вас помимо путей интересуют дополнительные характеристики графа, такие как диаметр и эксцентриситет.
HypergraphCoverageSolver
- это Python-класс, представляющий алгоритм решения задачи покрытия для гиперграфа. Задача заключается в определении, может ли Беспилотный Летательный Аппарат (БПЛА) покрыть все объекты в гиперграфе, учитывая радиус действия БПЛА.
from raw_bellman_ford.algorithms.coverage_solver import HypergraphCoverageSolver
# Задайте узлы, ребра, гиперребра, типы узлов, типы ребер и типы гиперребер
nodes = [1, 2, 3, 4, 5]
edges = [(1, 2), (2, 3), (3, 1), ((1, 2, 3), 4), ((1, 2, 3), 5), (4, 5)]
hyperedges = [(1, 2, 3)]
node_types = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
edge_types = {(1, 2): 1.4, (2, 3): 1.5, (3, 1): 1.6, ((1, 2, 3), 4): 2.5, ((1, 2, 3), 5): 24.6, (4, 5): 25.7}
hyperedge_types = {(1, 2, 3): 1}
# Создайте экземпляр класса
hypergraph_solver = HypergraphCoverageSolver(nodes, edges, hyperedges, node_types, edge_types, hyperedge_types)
# Задайте радиус действия БПЛА
drone_radius = 40
# Проверьте, может ли БПЛА покрыть все объекты в гиперграфе
if hypergraph_solver.can_cover_objects(drone_radius):
print("БПЛА может покрыть все объекты в гиперграфе.")
else:
print("БПЛА не может покрыть все объекты в гиперграфе.")
Алгоритм решения задачи покрытия для гиперграфа сначала вычисляет минимальный радиус, необходимый для покрытия всех объектов. Для этого он рассматривает как обычные ребра, так и гиперребра, учитывая их веса. Затем алгоритм сравнивает вычисленный минимальный радиус с радиусом действия БПЛА. Если радиус БПЛА не меньше минимального радиуса, то считается, что БПЛА может покрыть все объекты в гиперграфе.
Для внесения своего вклада в проект необходимо следовать текущему соглашению о коде и документации. Проект запускает линтеры и тесты для каждого реквест-запроса, чтобы установить линтеры и тестовые пакеты локально, запустите
pip install -r requirements-dev.txt
Для избежания лишних коммитов, пожалуйста, исправьте все ошибки после запуска каждого линтера:
pflake8 .
black .
isort .
mypy stable_gnn
pytest tests
- Разработчик
- Natural System Simulation Team https://itmo-nss-team.github.io/
Подробная информация и описание библиотеки ReDKG доступны по ссылке
Исследование проводится при поддержке Исследовательского центра сильного искусственного интеллекта в промышленности Университета ИТМО в рамках мероприятия программы центра: Разработка и испытания экспериментального образца библиотеки алгоритмов сильного ИИ в части глубокого обучения с подкреплением на динамических графах знаний для задач поддержки принятия решений
Если используете библиотеку в ваших работах, пожалуйста, процитируйте статью (и другие соответствующие статьи используемых методов):
@article{EGOROVA2022284,
title = {Customer transactional behaviour analysis through embedding interpretation},
author = {Elena Egorova and Gleb Glukhov and Egor Shikov},
journal = {Procedia Computer Science},
volume = {212},
pages = {284-294},
year = {2022},
doi = {https://doi.org/10.1016/j.procs.2022.11.012},
url = {https://www.sciencedirect.com/science/article/pii/S1877050922017033}
}