[![Python](https://img.shields.io/badge/-Python_3.8+-blue?logo=python&logoColor=white)](https://www.python.org/)
[![Pytorch](https://img.shields.io/badge/PyTorch_2.0+-ee4c2c?logo=pytorch&logoColor=white)](https://pytorch.org/get-started/locally/)
[![Paper](http://img.shields.io/badge/paper-arxiv.2407.12671-B31B1B.svg)](https://arxiv.org/abs/2407.12671)
[![Conference](http://img.shields.io/badge/ISMIR-2024-4b44ce.svg)](https://ismir2024.ismir.net/papers)
[![Latest Release](https://img.shields.io/github/v/release/manoskary/graphmuse)](https://github.com/manoskary/graphmuse/releases)
[![Pypi Package](https://badge.fury.io/py/graphmuse.svg)](https://badge.fury.io/py/graphmuse)
[![Unittest Status](https://github.com/manoskary/graphmuse/workflows/Tests/badge.svg)](https://github.com/manoskary/graphmuse/actions?query=workflow%3ATests)
<p align="center">
<img src="graphmuse/assets/graphmuse.png" height="300">
</p>
# GraphMuse
GraphMuse is a Python Library for Graph Deep Learning on Symbolic Music.
This library intents to address Graph Deep Learning techniques and models applied specifically to Music Scores.
It contains a core set of graph-based music representations, based on Pytorch Geometric Data and HeteroData classes.
It includes functionalities for these graphs such as Sampling and several Graph Convolutional Networks.
The main core of the library includes sampling strategies for Music Score Graphs, Dataloaders, Graph Creation classes, and Graph Convolutional Networks.
The graph creation is implemented partly in C and works in unison with the Partitura library for parsing symbolic music.
It implements a variety of graph neural networks for music, including MusGConv, NoteGNN, MeasureGNn, BeatGNN, MetricalGNN, and HybridGNN.
Read the GraphMuse paper [here](https://arxiv.org/abs/2407.12671).
### Why GraphMuse?
GraphMuse is a library for symbolic music graph processing. It provides a set of tools for creating, manipulating, and learning from symbolic music graphs. It is built on top of PyTorch Geometric and provides a set of graph convolutional networks tailored to music data. GraphMuse is designed to be easy to use and flexible, allowing users to experiment with different graph representations and models for their music data.
GraphMuse aims to provide a set of tools for symbolic music graph processing that are easy to use and flexible.
## Installation
GraphMuse is built on top of PyTorch and Pytorch Geometric. Therefore you need to install Pytorch and Pytorch Geometric first.
We recommend to use conda or any other virtual environment to install and experiment with _GraphMuse_. _GraphMuse_ is compatible with python 3.8 or later.
To install a conda environment ensure that conda is installed in your system ([info here](https://docs.anaconda.com/miniconda/miniconda-install/)) and then use:
```shell
conda install -n graphmuse python=3.11 pip
```
#### Pytorch and Pytorch Geometric Installation
First you need to install the Pytorch version suitable for your system.
You can find the instructions [here](https://pytorch.org/get-started/locally/).
You also need to install Pytorch Geometric. You can find the instructions [here](https://pytorch-geometric.readthedocs.io/en/latest/notes/installation.html).
We recommend to use conda:
```shell
conda install pyg -c pyg
```
#### GraphMuse Installation
##### Using pip
You can install graphmuse along with the dependencies using pip:
```shell
pip install graphmuse
```
##### Troubleshooting
If you encounter problems during the installation due to missing the `pyg-lib` package you can install it using:
```shell
pip install pyg-lib -f https://data.pyg.org/whl/torch-${TORCH}+${CUDA}.html
```
by replacing your version of Torch and CUDA. To use CPU just type `cpu`. More info [here](https://github.com/pyg-team/pyg-lib).
Sometimes the optional dependencies of Pytorch Geometric that Graphmuse needs to work properly might cause problems due to C compilation or system compatibility.
If you have problems with some of the torch scatter, sparse, cluster, or pyg-lib packages please follow the instructions [here](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html#additional-libraries).
When encountering problems with some of these dependency packages usually the best solution is to start fresh with the installation.
##### Installing from Source
You can also install GraphMuse from source. First, clone the repository:
```shell
git clone https://github.com/manoskary/graphmuse.git
cd graphmuse
```
Then use pip for the rest of the dependencies:
```shell
pip install --verbose git+https://github.com/pyg-team/pyg-lib.git
pip install --verbose torch_scatter
pip install --verbose torch_sparse
pip install --verbose torch_cluster
pip install partitura
```
and install using the setup file:
```shell
python setup.py install
```
## Usage
The GraphMuse processing pipeline:
<p align="center">
<img src="assets/graphmuse_pipeline.png" height="150">
</p>
### Graph Convolution
GraphMuse includes a variety of graph convolutional layers for music graphs.
Using the `MetricalGNN` model a simple example of a forward pass is shown below.
```python
import graphmuse.nn as gmnn
import torch
# Define the number of input features, output features, and edge features
num_input_features = 10
num_hidden_features = 10
num_output_features = 10
num_layers = 1
# metadata needs to be provided for the metrical graph similarly to Pytorch Geometric heterogeneous graph modules.
metadata = (
['note'],
[('note', 'onset', 'note')]
)
# Create an instance of the MetricalGNN class
metrical_gnn = gmnn.MetricalGNN(num_input_features, num_hidden_features, num_output_features, num_layers, metadata=metadata)
# Create some dummy data for the forward pass
num_nodes = 5
x_dict = {'note': torch.rand((num_nodes, num_input_features))}
edge_index_dict = {('note', 'onset', 'note'): torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]])}
# Perform a forward pass
out = metrical_gnn(x_dict, edge_index_dict)
print(out)
```
### Score Graphs
GraphMuse includes accelerated implementations of graph creation for music scores.
You can create a score graph from a musicxml file using the [Partitura Python Library](https://github.com/CPJKU/partitura) and the `create_score_graph` function from GraphMuse.
```python
import graphmuse as gm
import partitura
import torch
score = partitura.load_musicxml('path_to_musicxml')
note_array = score.note_array()
feature_array = torch.rand((len(note_array), 10))
score_graph = gm.create_score_graph(feature_array, note_array)
print(score_graph)
```
A score graph is a PyTorch Geometric HeteroData object that follows the following conceptual structure:
<p align="center">
<img src="assets/satie_graph.png" height="200">
</p>
### Sampling and Batching
GraphMuse includes a dataloader for sampling and batching music graphs together.
It uses the node-wise sampling strategy for each graph and batching them together.
You can specify the number of graphs to sample (`batch_size`) and the size of the subgraph to sample (`subgraph_size`).
Then, you can create an instance of the MuseNeighborLoader class by passing the list of graphs, the subgraph size, the batch size, and the number of neighbors as arguments.
Finally, you can iterate over the dataloader to get batches of subgraphs.
```python
from graphmuse.loader import MuseNeighborLoader
from graphmuse.utils import create_random_music_graph
import numpy as np
import torch
# Create a random graph
num_graphs = 10
max_nodes = 200
min_nodes = 100
max_dur = 20
min_dur = 1
subgraph_size = 50
batch_size = 4
feature_size = 10
labels = 4
graphs = list()
for i in range(num_graphs):
l = np.random.randint(min_nodes, max_nodes)
graph = create_random_music_graph(
graph_size=l, min_duration=min_dur, max_duration=max_dur, feature_size=feature_size, add_beat_nodes=True)
label = np.random.randint(0, labels, graph["note"].x.shape[0])
graph["note"].y = torch.tensor(label, dtype=torch.long)
graphs.append(graph)
# Create dataloader
dataloader = MuseNeighborLoader(graphs, subgraph_size=subgraph_size, batch_size=batch_size,
num_neighbors=[3, 3, 3])
# Iterate over the dataloader
for batch in dataloader:
print(batch)
```
The conceptual structure of sampling from each score graph is shown below:
<p align="center">
<img src="assets/sampling_graphmuse.png" height="400">
</p>
## Citing GraphMuse
GraphMuse was published at ISMIR 2024. To cite our work:
```bibtex
@inproceedings{karystinaios2024graphmuse,
title={GraphMuse: A Library for Symbolic Music Graph Processing},
author={Karystinaios, Emmanouil and Widmer, Gerhard},
booktitle={Proceedings of the International Society for Music Information Retrieval Conference (ISMIR)},
year={2024}
}
```
Raw data
{
"_id": null,
"home_page": null,
"name": "graphmuse",
"maintainer": "Emmanouil Karystinaios",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "deep-learning, symbolic-music, pytorch, geometric-deep-learning, graph-neural-networks, graph-convolutional-networks",
"author": "Emmanouil Karystinaios",
"author_email": null,
"download_url": null,
"platform": null,
"description": "[![Python](https://img.shields.io/badge/-Python_3.8+-blue?logo=python&logoColor=white)](https://www.python.org/)\n[![Pytorch](https://img.shields.io/badge/PyTorch_2.0+-ee4c2c?logo=pytorch&logoColor=white)](https://pytorch.org/get-started/locally/)\n[![Paper](http://img.shields.io/badge/paper-arxiv.2407.12671-B31B1B.svg)](https://arxiv.org/abs/2407.12671)\n[![Conference](http://img.shields.io/badge/ISMIR-2024-4b44ce.svg)](https://ismir2024.ismir.net/papers)\n[![Latest Release](https://img.shields.io/github/v/release/manoskary/graphmuse)](https://github.com/manoskary/graphmuse/releases)\n[![Pypi Package](https://badge.fury.io/py/graphmuse.svg)](https://badge.fury.io/py/graphmuse)\n[![Unittest Status](https://github.com/manoskary/graphmuse/workflows/Tests/badge.svg)](https://github.com/manoskary/graphmuse/actions?query=workflow%3ATests)\n\n<p align=\"center\">\n <img src=\"graphmuse/assets/graphmuse.png\" height=\"300\">\n</p>\n\n\n\n# GraphMuse\nGraphMuse is a Python Library for Graph Deep Learning on Symbolic Music.\nThis library intents to address Graph Deep Learning techniques and models applied specifically to Music Scores.\n\nIt contains a core set of graph-based music representations, based on Pytorch Geometric Data and HeteroData classes.\nIt includes functionalities for these graphs such as Sampling and several Graph Convolutional Networks.\n\nThe main core of the library includes sampling strategies for Music Score Graphs, Dataloaders, Graph Creation classes, and Graph Convolutional Networks.\nThe graph creation is implemented partly in C and works in unison with the Partitura library for parsing symbolic music.\n\n\nIt implements a variety of graph neural networks for music, including MusGConv, NoteGNN, MeasureGNn, BeatGNN, MetricalGNN, and HybridGNN.\n\nRead the GraphMuse paper [here](https://arxiv.org/abs/2407.12671).\n\n### Why GraphMuse?\n\nGraphMuse is a library for symbolic music graph processing. It provides a set of tools for creating, manipulating, and learning from symbolic music graphs. It is built on top of PyTorch Geometric and provides a set of graph convolutional networks tailored to music data. GraphMuse is designed to be easy to use and flexible, allowing users to experiment with different graph representations and models for their music data.\n\nGraphMuse aims to provide a set of tools for symbolic music graph processing that are easy to use and flexible. \n\n\n## Installation\n\nGraphMuse is built on top of PyTorch and Pytorch Geometric. Therefore you need to install Pytorch and Pytorch Geometric first.\nWe recommend to use conda or any other virtual environment to install and experiment with _GraphMuse_. _GraphMuse_ is compatible with python 3.8 or later.\nTo install a conda environment ensure that conda is installed in your system ([info here](https://docs.anaconda.com/miniconda/miniconda-install/)) and then use:\n```shell\nconda install -n graphmuse python=3.11 pip\n```\n\n#### Pytorch and Pytorch Geometric Installation\n\nFirst you need to install the Pytorch version suitable for your system.\nYou can find the instructions [here](https://pytorch.org/get-started/locally/).\n\nYou also need to install Pytorch Geometric. You can find the instructions [here](https://pytorch-geometric.readthedocs.io/en/latest/notes/installation.html).\nWe recommend to use conda:\n```shell\nconda install pyg -c pyg\n```\n\n#### GraphMuse Installation\n\n##### Using pip\n\nYou can install graphmuse along with the dependencies using pip:\n```shell\npip install graphmuse\n```\n\n##### Troubleshooting\n\nIf you encounter problems during the installation due to missing the `pyg-lib` package you can install it using:\n```shell \npip install pyg-lib -f https://data.pyg.org/whl/torch-${TORCH}+${CUDA}.html\n```\nby replacing your version of Torch and CUDA. To use CPU just type `cpu`. More info [here](https://github.com/pyg-team/pyg-lib).\n\nSometimes the optional dependencies of Pytorch Geometric that Graphmuse needs to work properly might cause problems due to C compilation or system compatibility.\nIf you have problems with some of the torch scatter, sparse, cluster, or pyg-lib packages please follow the instructions [here](https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html#additional-libraries). \n\nWhen encountering problems with some of these dependency packages usually the best solution is to start fresh with the installation.\n\n##### Installing from Source\n\nYou can also install GraphMuse from source. First, clone the repository:\n```shell\ngit clone https://github.com/manoskary/graphmuse.git\ncd graphmuse\n```\n\nThen use pip for the rest of the dependencies:\n```shell\npip install --verbose git+https://github.com/pyg-team/pyg-lib.git\npip install --verbose torch_scatter\npip install --verbose torch_sparse\npip install --verbose torch_cluster\npip install partitura\n```\n\nand install using the setup file:\n```shell\npython setup.py install\n```\n\n## Usage\n\nThe GraphMuse processing pipeline:\n<p align=\"center\">\n <img src=\"assets/graphmuse_pipeline.png\" height=\"150\">\n</p>\n\n### Graph Convolution\n\nGraphMuse includes a variety of graph convolutional layers for music graphs.\nUsing the `MetricalGNN` model a simple example of a forward pass is shown below.\n\n\n```python\nimport graphmuse.nn as gmnn\nimport torch\n\n# Define the number of input features, output features, and edge features\nnum_input_features = 10\nnum_hidden_features = 10\nnum_output_features = 10\nnum_layers = 1\n# metadata needs to be provided for the metrical graph similarly to Pytorch Geometric heterogeneous graph modules.\nmetadata = (\n ['note'],\n [('note', 'onset', 'note')]\n)\n\n# Create an instance of the MetricalGNN class\nmetrical_gnn = gmnn.MetricalGNN(num_input_features, num_hidden_features, num_output_features, num_layers, metadata=metadata)\n\n# Create some dummy data for the forward pass\nnum_nodes = 5\nx_dict = {'note': torch.rand((num_nodes, num_input_features))}\nedge_index_dict = {('note', 'onset', 'note'): torch.tensor([[0, 1, 2, 3, 4], [1, 2, 3, 4, 0]])}\n\n# Perform a forward pass\nout = metrical_gnn(x_dict, edge_index_dict)\n\nprint(out)\n```\n\n\n### Score Graphs\n\nGraphMuse includes accelerated implementations of graph creation for music scores.\nYou can create a score graph from a musicxml file using the [Partitura Python Library](https://github.com/CPJKU/partitura) and the `create_score_graph` function from GraphMuse.\n\n```python\nimport graphmuse as gm\nimport partitura\nimport torch\n\nscore = partitura.load_musicxml('path_to_musicxml')\nnote_array = score.note_array()\nfeature_array = torch.rand((len(note_array), 10)) \nscore_graph = gm.create_score_graph(feature_array, note_array)\nprint(score_graph)\n```\n\nA score graph is a PyTorch Geometric HeteroData object that follows the following conceptual structure:\n\n<p align=\"center\">\n <img src=\"assets/satie_graph.png\" height=\"200\">\n</p>\n\n### Sampling and Batching\n\nGraphMuse includes a dataloader for sampling and batching music graphs together.\nIt uses the node-wise sampling strategy for each graph and batching them together.\nYou can specify the number of graphs to sample (`batch_size`) and the size of the subgraph to sample (`subgraph_size`).\n\nThen, you can create an instance of the MuseNeighborLoader class by passing the list of graphs, the subgraph size, the batch size, and the number of neighbors as arguments. \n\nFinally, you can iterate over the dataloader to get batches of subgraphs.\n\n```python\nfrom graphmuse.loader import MuseNeighborLoader\nfrom graphmuse.utils import create_random_music_graph\nimport numpy as np\nimport torch\n\n# Create a random graph\nnum_graphs = 10\nmax_nodes = 200\nmin_nodes = 100\nmax_dur = 20\nmin_dur = 1\nsubgraph_size = 50\nbatch_size = 4\nfeature_size = 10\nlabels = 4\n\ngraphs = list()\nfor i in range(num_graphs):\n l = np.random.randint(min_nodes, max_nodes)\n graph = create_random_music_graph(\n graph_size=l, min_duration=min_dur, max_duration=max_dur, feature_size=feature_size, add_beat_nodes=True)\n label = np.random.randint(0, labels, graph[\"note\"].x.shape[0])\n graph[\"note\"].y = torch.tensor(label, dtype=torch.long)\n graphs.append(graph)\n\n# Create dataloader\ndataloader = MuseNeighborLoader(graphs, subgraph_size=subgraph_size, batch_size=batch_size,\n num_neighbors=[3, 3, 3])\n\n# Iterate over the dataloader\nfor batch in dataloader:\n print(batch)\n```\n\nThe conceptual structure of sampling from each score graph is shown below:\n\n<p align=\"center\">\n <img src=\"assets/sampling_graphmuse.png\" height=\"400\">\n</p>\n\n\n## Citing GraphMuse\n\nGraphMuse was published at ISMIR 2024. To cite our work:\n```bibtex\n@inproceedings{karystinaios2024graphmuse,\n title={GraphMuse: A Library for Symbolic Music Graph Processing},\n author={Karystinaios, Emmanouil and Widmer, Gerhard},\n booktitle={Proceedings of the International Society for Music Information Retrieval Conference (ISMIR)},\n year={2024}\n}\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "GraphMuse is a Python Library for Graph Deep Learning on Symbolic Music.",
"version": "0.0.4",
"project_urls": null,
"split_keywords": [
"deep-learning",
" symbolic-music",
" pytorch",
" geometric-deep-learning",
" graph-neural-networks",
" graph-convolutional-networks"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fd571524b39f0f8fec688e824b6b188f46b950b5bb7195a608511f8aeca2914f",
"md5": "6d76ab64615c40a53ca67e614b569b32",
"sha256": "63b93a0236cde29250c692368d27ae172c6f0b2cf54bfc342592dd1e636afb53"
},
"downloads": -1,
"filename": "graphmuse-0.0.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "6d76ab64615c40a53ca67e614b569b32",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 78884,
"upload_time": "2024-10-18T10:35:27",
"upload_time_iso_8601": "2024-10-18T10:35:27.083686Z",
"url": "https://files.pythonhosted.org/packages/fd/57/1524b39f0f8fec688e824b6b188f46b950b5bb7195a608511f8aeca2914f/graphmuse-0.0.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d83d89579472aebc5bef10e201a17fcdf9387a8c361c7fea6fb0fe7464cfd51f",
"md5": "567d19422ef3581ca284f5d9adeee556",
"sha256": "fce066c0ccd687fe33e468c080860dbe7fd3e20979a93be79b6f0b0173664e28"
},
"downloads": -1,
"filename": "graphmuse-0.0.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "567d19422ef3581ca284f5d9adeee556",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 78950,
"upload_time": "2024-10-18T10:35:28",
"upload_time_iso_8601": "2024-10-18T10:35:28.466460Z",
"url": "https://files.pythonhosted.org/packages/d8/3d/89579472aebc5bef10e201a17fcdf9387a8c361c7fea6fb0fe7464cfd51f/graphmuse-0.0.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-18 10:35:27",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "graphmuse"
}