[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AFQ12HAETYMGJSMQED9XHD":3,"skill-same:01M6AFQ12HAETYMGJSMQED9XHD":97},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":44,"repositoryHtmlUrl":45,"repositoryHomepageUrl":46,"ownerHtmlUrl":47,"ownerBlogUrl":48,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M6AFQ12HAETYMGJSMQED9XHD","torch-geometric",null,"Graph Neural Networks (PyG). Node\u002Fgraph classification, link prediction, GCN, GAT, GraphSAGE, heterogeneous graphs, molecular property prediction, for geometric deep learning.","davila7\u002Fclaude-code-templates","davila7","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6216945?v=4","01M6ADEWWFPS191NFM0Y1EX1JH","Daniel Avila","01M6ADJHGM78PHQRD3XZTFDVKK",33481,"MIT","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"torch geometric","Neural","prediction","graph neural networks","for","link","gat","molecular","graphs","deep","deep learning","node","learning","classification","networks","graph","neural networks","2026-11-10 10:12:30",false,"---\nname: torch-geometric\ndescription: \"Graph Neural Networks (PyG). Node\u002Fgraph classification, link prediction, GCN, GAT, GraphSAGE, heterogeneous graphs, molecular property prediction, for geometric deep learning.\"\n---\n\n# PyTorch Geometric (PyG)\n\n## Overview\n\nPyTorch Geometric is a library built on PyTorch for developing and training Graph Neural Networks (GNNs). Apply this skill for deep learning on graphs and irregular structures, including mini-batch processing, multi-GPU training, and geometric deep learning applications.\n\n## When to Use This Skill\n\nThis skill should be used when working with:\n- **Graph-based machine learning**: Node classification, graph classification, link prediction\n- **Molecular property prediction**: Drug discovery, chemical property prediction\n- **Social network analysis**: Community detection, influence prediction\n- **Citation networks**: Paper classification, recommendation systems\n- **3D geometric data**: Point clouds, meshes, molecular structures\n- **Heterogeneous graphs**: Multi-type nodes and edges (e.g., knowledge graphs)\n- **Large-scale graph learning**: Neighbor sampling, distributed training\n\n## Quick Start\n\n### Installation\n\n```bash\nuv pip install torch_geometric\n```\n\nFor additional dependencies (sparse operations, clustering):\n```bash\nuv pip install pyg_lib torch_scatter torch_sparse torch_cluster torch_spline_conv -f https:\u002F\u002Fdata.pyg.org\u002Fwhl\u002Ftorch-${TORCH}+${CUDA}.html\n```\n\n### Basic Graph Creation\n\n```python\nimport torch\nfrom torch_geometric.data import Data\n\n# Create a simple graph with 3 nodes\nedge_index = torch.tensor([[0, 1, 1, 2],  # source nodes\n                           [1, 0, 2, 1]], dtype=torch.long)  # target nodes\nx = torch.tensor([[-1], [0], [1]], dtype=torch.float)  # node features\n\ndata = Data(x=x, edge_index=edge_index)\nprint(f\"Nodes: {data.num_nodes}, Edges: {data.num_edges}\")\n```\n\n### Loading a Benchmark Dataset\n\n```python\nfrom torch_geometric.datasets import Planetoid\n\n# Load Cora citation network\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')\ndata = dataset[0]  # Get the first (and only) graph\n\nprint(f\"Dataset: {dataset}\")\nprint(f\"Nodes: {data.num_nodes}, Edges: {data.num_edges}\")\nprint(f\"Features: {data.num_node_features}, Classes: {dataset.num_classes}\")\n```\n\n## Core Concepts\n\n### Data Structure\n\nPyG represents graphs using the `torch_geometric.data.Data` class with these key attributes:\n\n- **`data.x`**: Node feature matrix `[num_nodes, num_node_features]`\n- **`data.edge_index`**: Graph connectivity in COO format `[2, num_edges]`\n- **`data.edge_attr`**: Edge feature matrix `[num_edges, num_edge_features]` (optional)\n- **`data.y`**: Target labels for nodes or graphs\n- **`data.pos`**: Node spatial positions `[num_nodes, num_dimensions]` (optional)\n- **Custom attributes**: Can add any attribute (e.g., `data.train_mask`, `data.batch`)\n\n**Important**: These attributes are not mandatory—extend Data objects with custom attributes as needed.\n\n### Edge Index Format\n\nEdges are stored in COO (coordinate) format as a `[2, num_edges]` tensor:\n- First row: source node indices\n- Second row: target node indices\n\n```python\n# Edge list: (0→1), (1→0), (1→2), (2→1)\nedge_index = torch.tensor([[0, 1, 1, 2],\n                           [1, 0, 2, 1]], dtype=torch.long)\n```\n\n### Mini-Batch Processing\n\nPyG handles batching by creating block-diagonal adjacency matrices, concatenating multiple graphs into one large disconnected graph:\n\n- Adjacency matrices are stacked diagonally\n- Node features are concatenated along the node dimension\n- A `batch` vector maps each node to its source graph\n- No padding needed—computationally efficient\n\n```python\nfrom torch_geometric.loader import DataLoader\n\nloader = DataLoader(dataset, batch_size=32, shuffle=True)\nfor batch in loader:\n    print(f\"Batch size: {batch.num_graphs}\")\n    print(f\"Total nodes: {batch.num_nodes}\")\n    # batch.batch maps nodes to graphs\n```\n\n## Building Graph Neural Networks\n\n### Message Passing Paradigm\n\nGNNs in PyG follow a neighborhood aggregation scheme:\n1. Transform node features\n2. Propagate messages along edges\n3. Aggregate messages from neighbors\n4. Update node representations\n\n### Using Pre-Built Layers\n\nPyG provides 40+ convolutional layers. Common ones include:\n\n**GCNConv** (Graph Convolutional Network):\n```python\nfrom torch_geometric.nn import GCNConv\nimport torch.nn.functional as F\n\nclass GCN(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 16)\n        self.conv2 = GCNConv(16, num_classes)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = F.dropout(x, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n**GATConv** (Graph Attention Network):\n```python\nfrom torch_geometric.nn import GATConv\n\nclass GAT(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GATConv(num_features, 8, heads=8, dropout=0.6)\n        self.conv2 = GATConv(8 * 8, num_classes, heads=1, concat=False, dropout=0.6)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = F.dropout(x, p=0.6, training=self.training)\n        x = F.elu(self.conv1(x, edge_index))\n        x = F.dropout(x, p=0.6, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n**GraphSAGE**:\n```python\nfrom torch_geometric.nn import SAGEConv\n\nclass GraphSAGE(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = SAGEConv(num_features, 64)\n        self.conv2 = SAGEConv(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = F.dropout(x, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n### Custom Message Passing Layers\n\nFor custom layers, inherit from `MessagePassing`:\n\n```python\nfrom torch_geometric.nn import MessagePassing\nfrom torch_geometric.utils import add_self_loops, degree\n\nclass CustomConv(MessagePassing):\n    def __init__(self, in_channels, out_channels):\n        super().__init__(aggr='add')  # \"add\", \"mean\", or \"max\"\n        self.lin = torch.nn.Linear(in_channels, out_channels)\n\n    def forward(self, x, edge_index):\n        # Add self-loops to adjacency matrix\n        edge_index, _ = add_self_loops(edge_index, num_nodes=x.size(0))\n\n        # Transform node features\n        x = self.lin(x)\n\n        # Compute normalization\n        row, col = edge_index\n        deg = degree(col, x.size(0), dtype=x.dtype)\n        deg_inv_sqrt = deg.pow(-0.5)\n        norm = deg_inv_sqrt[row] * deg_inv_sqrt[col]\n\n        # Propagate messages\n        return self.propagate(edge_index, x=x, norm=norm)\n\n    def message(self, x_j, norm):\n        # x_j: features of source nodes\n        return norm.view(-1, 1) * x_j\n```\n\nKey methods:\n- **`forward()`**: Main entry point\n- **`message()`**: Constructs messages from source to target nodes\n- **`aggregate()`**: Aggregates messages (usually don't override—set `aggr` parameter)\n- **`update()`**: Updates node embeddings after aggregation\n\n**Variable naming convention**: Appending `_i` or `_j` to tensor names automatically maps them to target or source nodes.\n\n## Working with Datasets\n\n### Loading Built-in Datasets\n\nPyG provides extensive benchmark datasets:\n\n```python\n# Citation networks (node classification)\nfrom torch_geometric.datasets import Planetoid\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')  # or 'CiteSeer', 'PubMed'\n\n# Graph classification\nfrom torch_geometric.datasets import TUDataset\ndataset = TUDataset(root='\u002Ftmp\u002FENZYMES', name='ENZYMES')\n\n# Molecular datasets\nfrom torch_geometric.datasets import QM9\ndataset = QM9(root='\u002Ftmp\u002FQM9')\n\n# Large-scale datasets\nfrom torch_geometric.datasets import Reddit\ndataset = Reddit(root='\u002Ftmp\u002FReddit')\n```\n\nCheck `references\u002Fdatasets_reference.md` for a comprehensive list.\n\n### Creating Custom Datasets\n\nFor datasets that fit in memory, inherit from `InMemoryDataset`:\n\n```python\nfrom torch_geometric.data import InMemoryDataset, Data\nimport torch\n\nclass MyOwnDataset(InMemoryDataset):\n    def __init__(self, root, transform=None, pre_transform=None):\n        super().__init__(root, transform, pre_transform)\n        self.load(self.processed_paths[0])\n\n    @property\n    def raw_file_names(self):\n        return ['my_data.csv']  # Files needed in raw_dir\n\n    @property\n    def processed_file_names(self):\n        return ['data.pt']  # Files in processed_dir\n\n    def download(self):\n        # Download raw data to self.raw_dir\n        pass\n\n    def process(self):\n        # Read data, create Data objects\n        data_list = []\n\n        # Example: Create a simple graph\n        edge_index = torch.tensor([[0, 1], [1, 0]], dtype=torch.long)\n        x = torch.randn(2, 16)\n        y = torch.tensor([0], dtype=torch.long)\n\n        data = Data(x=x, edge_index=edge_index, y=y)\n        data_list.append(data)\n\n        # Apply pre_filter and pre_transform\n        if self.pre_filter is not None:\n            data_list = [d for d in data_list if self.pre_filter(d)]\n\n        if self.pre_transform is not None:\n            data_list = [self.pre_transform(d) for d in data_list]\n\n        # Save processed data\n        self.save(data_list, self.processed_paths[0])\n```\n\nFor large datasets that don't fit in memory, inherit from `Dataset` and implement `len()` and `get(idx)`.\n\n### Loading Graphs from CSV\n\n```python\nimport pandas as pd\nimport torch\nfrom torch_geometric.data import HeteroData\n\n# Load nodes\nnodes_df = pd.read_csv('nodes.csv')\nx = torch.tensor(nodes_df[['feat1', 'feat2']].values, dtype=torch.float)\n\n# Load edges\nedges_df = pd.read_csv('edges.csv')\nedge_index = torch.tensor([edges_df['source'].values,\n                           edges_df['target'].values], dtype=torch.long)\n\ndata = Data(x=x, edge_index=edge_index)\n```\n\n## Training Workflows\n\n### Node Classification (Single Graph)\n\n```python\nimport torch\nimport torch.nn.functional as F\nfrom torch_geometric.datasets import Planetoid\n\n# Load dataset\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')\ndata = dataset[0]\n\n# Create model\nmodel = GCN(dataset.num_features, dataset.num_classes)\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)\n\n# Training\nmodel.train()\nfor epoch in range(200):\n    optimizer.zero_grad()\n    out = model(data)\n    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])\n    loss.backward()\n    optimizer.step()\n\n    if epoch % 10 == 0:\n        print(f'Epoch {epoch}, Loss: {loss.item():.4f}')\n\n# Evaluation\nmodel.eval()\npred = model(data).argmax(dim=1)\ncorrect = (pred[data.test_mask] == data.y[data.test_mask]).sum()\nacc = int(correct) \u002F int(data.test_mask.sum())\nprint(f'Test Accuracy: {acc:.4f}')\n```\n\n### Graph Classification (Multiple Graphs)\n\n```python\nfrom torch_geometric.datasets import TUDataset\nfrom torch_geometric.loader import DataLoader\nfrom torch_geometric.nn import global_mean_pool\n\nclass GraphClassifier(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 64)\n        self.conv2 = GCNConv(64, 64)\n        self.lin = torch.nn.Linear(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index, batch = data.x, data.edge_index, data.batch\n\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = self.conv2(x, edge_index)\n        x = F.relu(x)\n\n        # Global pooling (aggregate node features to graph-level)\n        x = global_mean_pool(x, batch)\n\n        x = self.lin(x)\n        return F.log_softmax(x, dim=1)\n\n# Load dataset\ndataset = TUDataset(root='\u002Ftmp\u002FENZYMES', name='ENZYMES')\nloader = DataLoader(dataset, batch_size=32, shuffle=True)\n\nmodel = GraphClassifier(dataset.num_features, dataset.num_classes)\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n\n# Training\nmodel.train()\nfor epoch in range(100):\n    total_loss = 0\n    for batch in loader:\n        optimizer.zero_grad()\n        out = model(batch)\n        loss = F.nll_loss(out, batch.y)\n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n\n    if epoch % 10 == 0:\n        print(f'Epoch {epoch}, Loss: {total_loss \u002F len(loader):.4f}')\n```\n\n### Large-Scale Graphs with Neighbor Sampling\n\nFor large graphs, use `NeighborLoader` to sample subgraphs:\n\n```python\nfrom torch_geometric.loader import NeighborLoader\n\n# Create a neighbor sampler\ntrain_loader = NeighborLoader(\n    data,\n    num_neighbors=[25, 10],  # Sample 25 neighbors for 1st hop, 10 for 2nd hop\n    batch_size=128,\n    input_nodes=data.train_mask,\n)\n\n# Training\nmodel.train()\nfor batch in train_loader:\n    optimizer.zero_grad()\n    out = model(batch)\n    # Only compute loss on seed nodes (first batch_size nodes)\n    loss = F.nll_loss(out[:batch.batch_size], batch.y[:batch.batch_size])\n    loss.backward()\n    optimizer.step()\n```\n\n**Important**:\n- Output subgraphs are directed\n- Node indices are relabeled (0 to batch.num_nodes - 1)\n- Only use seed node predictions for loss computation\n- Sampling beyond 2-3 hops is generally not feasible\n\n## Advanced Features\n\n### Heterogeneous Graphs\n\nFor graphs with multiple node and edge types, use `HeteroData`:\n\n```python\nfrom torch_geometric.data import HeteroData\n\ndata = HeteroData()\n\n# Add node features for different types\ndata['paper'].x = torch.randn(100, 128)  # 100 papers with 128 features\ndata['author'].x = torch.randn(200, 64)  # 200 authors with 64 features\n\n# Add edges for different types (source_type, edge_type, target_type)\ndata['author', 'writes', 'paper'].edge_index = torch.randint(0, 200, (2, 500))\ndata['paper', 'cites', 'paper'].edge_index = torch.randint(0, 100, (2, 300))\n\nprint(data)\n```\n\nConvert homogeneous models to heterogeneous:\n\n```python\nfrom torch_geometric.nn import to_hetero\n\n# Define homogeneous model\nmodel = GNN(...)\n\n# Convert to heterogeneous\nmodel = to_hetero(model, data.metadata(), aggr='sum')\n\n# Use as normal\nout = model(data.x_dict, data.edge_index_dict)\n```\n\nOr use `HeteroConv` for custom edge-type-specific operations:\n\n```python\nfrom torch_geometric.nn import HeteroConv, GCNConv, SAGEConv\n\nclass HeteroGNN(torch.nn.Module):\n    def __init__(self, metadata):\n        super().__init__()\n        self.conv1 = HeteroConv({\n            ('paper', 'cites', 'paper'): GCNConv(-1, 64),\n            ('author', 'writes', 'paper'): SAGEConv((-1, -1), 64),\n        }, aggr='sum')\n\n        self.conv2 = HeteroConv({\n            ('paper', 'cites', 'paper'): GCNConv(64, 32),\n            ('author', 'writes', 'paper'): SAGEConv((64, 64), 32),\n        }, aggr='sum')\n\n    def forward(self, x_dict, edge_index_dict):\n        x_dict = self.conv1(x_dict, edge_index_dict)\n        x_dict = {key: F.relu(x) for key, x in x_dict.items()}\n        x_dict = self.conv2(x_dict, edge_index_dict)\n        return x_dict\n```\n\n### Transforms\n\nApply transforms to modify graph structure or features:\n\n```python\nfrom torch_geometric.transforms import NormalizeFeatures, AddSelfLoops, Compose\n\n# Single transform\ntransform = NormalizeFeatures()\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora', transform=transform)\n\n# Compose multiple transforms\ntransform = Compose([\n    AddSelfLoops(),\n    NormalizeFeatures(),\n])\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora', transform=transform)\n```\n\nCommon transforms:\n- **Structure**: `ToUndirected`, `AddSelfLoops`, `RemoveSelfLoops`, `KNNGraph`, `RadiusGraph`\n- **Features**: `NormalizeFeatures`, `NormalizeScale`, `Center`\n- **Sampling**: `RandomNodeSplit`, `RandomLinkSplit`\n- **Positional Encoding**: `AddLaplacianEigenvectorPE`, `AddRandomWalkPE`\n\nSee `references\u002Ftransforms_reference.md` for the full list.\n\n### Model Explainability\n\nPyG provides explainability tools to understand model predictions:\n\n```python\nfrom torch_geometric.explain import Explainer, GNNExplainer\n\n# Create explainer\nexplainer = Explainer(\n    model=model,\n    algorithm=GNNExplainer(epochs=200),\n    explanation_type='model',  # or 'phenomenon'\n    node_mask_type='attributes',\n    edge_mask_type='object',\n    model_config=dict(\n        mode='multiclass_classification',\n        task_level='node',\n        return_type='log_probs',\n    ),\n)\n\n# Generate explanation for a specific node\nnode_idx = 10\nexplanation = explainer(data.x, data.edge_index, index=node_idx)\n\n# Visualize\nprint(f'Node {node_idx} explanation:')\nprint(f'Important edges: {explanation.edge_mask.topk(5).indices}')\nprint(f'Important features: {explanation.node_mask[node_idx].topk(5).indices}')\n```\n\n### Pooling Operations\n\nFor hierarchical graph representations:\n\n```python\nfrom torch_geometric.nn import TopKPooling, global_mean_pool\n\nclass HierarchicalGNN(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 64)\n        self.pool1 = TopKPooling(64, ratio=0.8)\n        self.conv2 = GCNConv(64, 64)\n        self.pool2 = TopKPooling(64, ratio=0.8)\n        self.lin = torch.nn.Linear(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index, batch = data.x, data.edge_index, data.batch\n\n        x = F.relu(self.conv1(x, edge_index))\n        x, edge_index, _, batch, _, _ = self.pool1(x, edge_index, None, batch)\n\n        x = F.relu(self.conv2(x, edge_index))\n        x, edge_index, _, batch, _, _ = self.pool2(x, edge_index, None, batch)\n\n        x = global_mean_pool(x, batch)\n        x = self.lin(x)\n        return F.log_softmax(x, dim=1)\n```\n\n## Common Patterns and Best Practices\n\n### Check Graph Properties\n\n```python\n# Undirected check\nfrom torch_geometric.utils import is_undirected\nprint(f\"Is undirected: {is_undirected(data.edge_index)}\")\n\n# Connected components\nfrom torch_geometric.utils import connected_components\nprint(f\"Connected components: {connected_components(data.edge_index)}\")\n\n# Contains self-loops\nfrom torch_geometric.utils import contains_self_loops\nprint(f\"Has self-loops: {contains_self_loops(data.edge_index)}\")\n```\n\n### GPU Training\n\n```python\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = model.to(device)\ndata = data.to(device)\n\n# For DataLoader\nfor batch in loader:\n    batch = batch.to(device)\n    # Train...\n```\n\n### Save and Load Models\n\n```python\n# Save\ntorch.save(model.state_dict(), 'model.pth')\n\n# Load\nmodel = GCN(num_features, num_classes)\nmodel.load_state_dict(torch.load('model.pth'))\nmodel.eval()\n```\n\n### Layer Capabilities\n\nWhen choosing layers, consider these capabilities:\n- **SparseTensor**: Supports efficient sparse matrix operations\n- **edge_weight**: Handles one-dimensional edge weights\n- **edge_attr**: Processes multi-dimensional edge features\n- **Bipartite**: Works with bipartite graphs (different source\u002Ftarget dimensions)\n- **Lazy**: Enables initialization without specifying input dimensions\n\nSee the GNN cheatsheet at `references\u002Flayer_capabilities.md`.\n\n## Resources\n\n### Bundled References\n\nThis skill includes detailed reference documentation:\n\n- **`references\u002Flayers_reference.md`**: Complete listing of all 40+ GNN layers with descriptions and capabilities\n- **`references\u002Fdatasets_reference.md`**: Comprehensive dataset catalog organized by category\n- **`references\u002Ftransforms_reference.md`**: All available transforms and their use cases\n- **`references\u002Fapi_patterns.md`**: Common API patterns and coding examples\n\n### Scripts\n\nUtility scripts are provided in `scripts\u002F`:\n\n- **`scripts\u002Fvisualize_graph.py`**: Visualize graph structure using networkx and matplotlib\n- **`scripts\u002Fcreate_gnn_template.py`**: Generate boilerplate code for common GNN architectures\n- **`scripts\u002Fbenchmark_model.py`**: Benchmark model performance on standard datasets\n\nExecute scripts directly or read them for implementation patterns.\n\n### Official Resources\n\n- **Documentation**: https:\u002F\u002Fpytorch-geometric.readthedocs.io\u002F\n- **GitHub**: https:\u002F\u002Fgithub.com\u002Fpyg-team\u002Fpytorch_geometric\n- **Tutorials**: https:\u002F\u002Fpytorch-geometric.readthedocs.io\u002Fen\u002Flatest\u002Fget_started\u002Fintroduction.html\n- **Examples**: https:\u002F\u002Fgithub.com\u002Fpyg-team\u002Fpytorch_geometric\u002Ftree\u002Fmaster\u002Fexamples\n","# PyTorch Geometric (PyG)\n\n## Overview\n\nPyTorch Geometric is a library built on PyTorch for developing and training Graph Neural Networks (GNNs). Apply this skill for deep learning on graphs and irregular structures, including mini-batch processing, multi-GPU training, and geometric deep learning applications.\n\n## When to Use This Skill\n\nThis skill should be used when working with:\n- **Graph-based machine learning**: Node classification, graph classification, link prediction\n- **Molecular property prediction**: Drug discovery, chemical property prediction\n- **Social network analysis**: Community detection, influence prediction\n- **Citation networks**: Paper classification, recommendation systems\n- **3D geometric data**: Point clouds, meshes, molecular structures\n- **Heterogeneous graphs**: Multi-type nodes and edges (e.g., knowledge graphs)\n- **Large-scale graph learning**: Neighbor sampling, distributed training\n\n## Quick Start\n\n### Installation\n\n```bash\nuv pip install torch_geometric\n```\n\nFor additional dependencies (sparse operations, clustering):\n```bash\nuv pip install pyg_lib torch_scatter torch_sparse torch_cluster torch_spline_conv -f https:\u002F\u002Fdata.pyg.org\u002Fwhl\u002Ftorch-${TORCH}+${CUDA}.html\n```\n\n### Basic Graph Creation\n\n```python\nimport torch\nfrom torch_geometric.data import Data\n\n# Create a simple graph with 3 nodes\nedge_index = torch.tensor([[0, 1, 1, 2],  # source nodes\n                           [1, 0, 2, 1]], dtype=torch.long)  # target nodes\nx = torch.tensor([[-1], [0], [1]], dtype=torch.float)  # node features\n\ndata = Data(x=x, edge_index=edge_index)\nprint(f\"Nodes: {data.num_nodes}, Edges: {data.num_edges}\")\n```\n\n### Loading a Benchmark Dataset\n\n```python\nfrom torch_geometric.datasets import Planetoid\n\n# Load Cora citation network\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')\ndata = dataset[0]  # Get the first (and only) graph\n\nprint(f\"Dataset: {dataset}\")\nprint(f\"Nodes: {data.num_nodes}, Edges: {data.num_edges}\")\nprint(f\"Features: {data.num_node_features}, Classes: {dataset.num_classes}\")\n```\n\n## Core Concepts\n\n### Data Structure\n\nPyG represents graphs using the `torch_geometric.data.Data` class with these key attributes:\n\n- **`data.x`**: Node feature matrix `[num_nodes, num_node_features]`\n- **`data.edge_index`**: Graph connectivity in COO format `[2, num_edges]`\n- **`data.edge_attr`**: Edge feature matrix `[num_edges, num_edge_features]` (optional)\n- **`data.y`**: Target labels for nodes or graphs\n- **`data.pos`**: Node spatial positions `[num_nodes, num_dimensions]` (optional)\n- **Custom attributes**: Can add any attribute (e.g., `data.train_mask`, `data.batch`)\n\n**Important**: These attributes are not mandatory—extend Data objects with custom attributes as needed.\n\n### Edge Index Format\n\nEdges are stored in COO (coordinate) format as a `[2, num_edges]` tensor:\n- First row: source node indices\n- Second row: target node indices\n\n```python\n# Edge list: (0→1), (1→0), (1→2), (2→1)\nedge_index = torch.tensor([[0, 1, 1, 2],\n                           [1, 0, 2, 1]], dtype=torch.long)\n```\n\n### Mini-Batch Processing\n\nPyG handles batching by creating block-diagonal adjacency matrices, concatenating multiple graphs into one large disconnected graph:\n\n- Adjacency matrices are stacked diagonally\n- Node features are concatenated along the node dimension\n- A `batch` vector maps each node to its source graph\n- No padding needed—computationally efficient\n\n```python\nfrom torch_geometric.loader import DataLoader\n\nloader = DataLoader(dataset, batch_size=32, shuffle=True)\nfor batch in loader:\n    print(f\"Batch size: {batch.num_graphs}\")\n    print(f\"Total nodes: {batch.num_nodes}\")\n    # batch.batch maps nodes to graphs\n```\n\n## Building Graph Neural Networks\n\n### Message Passing Paradigm\n\nGNNs in PyG follow a neighborhood aggregation scheme:\n1. Transform node features\n2. Propagate messages along edges\n3. Aggregate messages from neighbors\n4. Update node representations\n\n### Using Pre-Built Layers\n\nPyG provides 40+ convolutional layers. Common ones include:\n\n**GCNConv** (Graph Convolutional Network):\n```python\nfrom torch_geometric.nn import GCNConv\nimport torch.nn.functional as F\n\nclass GCN(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 16)\n        self.conv2 = GCNConv(16, num_classes)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = F.dropout(x, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n**GATConv** (Graph Attention Network):\n```python\nfrom torch_geometric.nn import GATConv\n\nclass GAT(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GATConv(num_features, 8, heads=8, dropout=0.6)\n        self.conv2 = GATConv(8 * 8, num_classes, heads=1, concat=False, dropout=0.6)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = F.dropout(x, p=0.6, training=self.training)\n        x = F.elu(self.conv1(x, edge_index))\n        x = F.dropout(x, p=0.6, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n**GraphSAGE**:\n```python\nfrom torch_geometric.nn import SAGEConv\n\nclass GraphSAGE(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = SAGEConv(num_features, 64)\n        self.conv2 = SAGEConv(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index = data.x, data.edge_index\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = F.dropout(x, training=self.training)\n        x = self.conv2(x, edge_index)\n        return F.log_softmax(x, dim=1)\n```\n\n### Custom Message Passing Layers\n\nFor custom layers, inherit from `MessagePassing`:\n\n```python\nfrom torch_geometric.nn import MessagePassing\nfrom torch_geometric.utils import add_self_loops, degree\n\nclass CustomConv(MessagePassing):\n    def __init__(self, in_channels, out_channels):\n        super().__init__(aggr='add')  # \"add\", \"mean\", or \"max\"\n        self.lin = torch.nn.Linear(in_channels, out_channels)\n\n    def forward(self, x, edge_index):\n        # Add self-loops to adjacency matrix\n        edge_index, _ = add_self_loops(edge_index, num_nodes=x.size(0))\n\n        # Transform node features\n        x = self.lin(x)\n\n        # Compute normalization\n        row, col = edge_index\n        deg = degree(col, x.size(0), dtype=x.dtype)\n        deg_inv_sqrt = deg.pow(-0.5)\n        norm = deg_inv_sqrt[row] * deg_inv_sqrt[col]\n\n        # Propagate messages\n        return self.propagate(edge_index, x=x, norm=norm)\n\n    def message(self, x_j, norm):\n        # x_j: features of source nodes\n        return norm.view(-1, 1) * x_j\n```\n\nKey methods:\n- **`forward()`**: Main entry point\n- **`message()`**: Constructs messages from source to target nodes\n- **`aggregate()`**: Aggregates messages (usually don't override—set `aggr` parameter)\n- **`update()`**: Updates node embeddings after aggregation\n\n**Variable naming convention**: Appending `_i` or `_j` to tensor names automatically maps them to target or source nodes.\n\n## Working with Datasets\n\n### Loading Built-in Datasets\n\nPyG provides extensive benchmark datasets:\n\n```python\n# Citation networks (node classification)\nfrom torch_geometric.datasets import Planetoid\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')  # or 'CiteSeer', 'PubMed'\n\n# Graph classification\nfrom torch_geometric.datasets import TUDataset\ndataset = TUDataset(root='\u002Ftmp\u002FENZYMES', name='ENZYMES')\n\n# Molecular datasets\nfrom torch_geometric.datasets import QM9\ndataset = QM9(root='\u002Ftmp\u002FQM9')\n\n# Large-scale datasets\nfrom torch_geometric.datasets import Reddit\ndataset = Reddit(root='\u002Ftmp\u002FReddit')\n```\n\nCheck `references\u002Fdatasets_reference.md` for a comprehensive list.\n\n### Creating Custom Datasets\n\nFor datasets that fit in memory, inherit from `InMemoryDataset`:\n\n```python\nfrom torch_geometric.data import InMemoryDataset, Data\nimport torch\n\nclass MyOwnDataset(InMemoryDataset):\n    def __init__(self, root, transform=None, pre_transform=None):\n        super().__init__(root, transform, pre_transform)\n        self.load(self.processed_paths[0])\n\n    @property\n    def raw_file_names(self):\n        return ['my_data.csv']  # Files needed in raw_dir\n\n    @property\n    def processed_file_names(self):\n        return ['data.pt']  # Files in processed_dir\n\n    def download(self):\n        # Download raw data to self.raw_dir\n        pass\n\n    def process(self):\n        # Read data, create Data objects\n        data_list = []\n\n        # Example: Create a simple graph\n        edge_index = torch.tensor([[0, 1], [1, 0]], dtype=torch.long)\n        x = torch.randn(2, 16)\n        y = torch.tensor([0], dtype=torch.long)\n\n        data = Data(x=x, edge_index=edge_index, y=y)\n        data_list.append(data)\n\n        # Apply pre_filter and pre_transform\n        if self.pre_filter is not None:\n            data_list = [d for d in data_list if self.pre_filter(d)]\n\n        if self.pre_transform is not None:\n            data_list = [self.pre_transform(d) for d in data_list]\n\n        # Save processed data\n        self.save(data_list, self.processed_paths[0])\n```\n\nFor large datasets that don't fit in memory, inherit from `Dataset` and implement `len()` and `get(idx)`.\n\n### Loading Graphs from CSV\n\n```python\nimport pandas as pd\nimport torch\nfrom torch_geometric.data import HeteroData\n\n# Load nodes\nnodes_df = pd.read_csv('nodes.csv')\nx = torch.tensor(nodes_df[['feat1', 'feat2']].values, dtype=torch.float)\n\n# Load edges\nedges_df = pd.read_csv('edges.csv')\nedge_index = torch.tensor([edges_df['source'].values,\n                           edges_df['target'].values], dtype=torch.long)\n\ndata = Data(x=x, edge_index=edge_index)\n```\n\n## Training Workflows\n\n### Node Classification (Single Graph)\n\n```python\nimport torch\nimport torch.nn.functional as F\nfrom torch_geometric.datasets import Planetoid\n\n# Load dataset\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora')\ndata = dataset[0]\n\n# Create model\nmodel = GCN(dataset.num_features, dataset.num_classes)\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)\n\n# Training\nmodel.train()\nfor epoch in range(200):\n    optimizer.zero_grad()\n    out = model(data)\n    loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])\n    loss.backward()\n    optimizer.step()\n\n    if epoch % 10 == 0:\n        print(f'Epoch {epoch}, Loss: {loss.item():.4f}')\n\n# Evaluation\nmodel.eval()\npred = model(data).argmax(dim=1)\ncorrect = (pred[data.test_mask] == data.y[data.test_mask]).sum()\nacc = int(correct) \u002F int(data.test_mask.sum())\nprint(f'Test Accuracy: {acc:.4f}')\n```\n\n### Graph Classification (Multiple Graphs)\n\n```python\nfrom torch_geometric.datasets import TUDataset\nfrom torch_geometric.loader import DataLoader\nfrom torch_geometric.nn import global_mean_pool\n\nclass GraphClassifier(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 64)\n        self.conv2 = GCNConv(64, 64)\n        self.lin = torch.nn.Linear(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index, batch = data.x, data.edge_index, data.batch\n\n        x = self.conv1(x, edge_index)\n        x = F.relu(x)\n        x = self.conv2(x, edge_index)\n        x = F.relu(x)\n\n        # Global pooling (aggregate node features to graph-level)\n        x = global_mean_pool(x, batch)\n\n        x = self.lin(x)\n        return F.log_softmax(x, dim=1)\n\n# Load dataset\ndataset = TUDataset(root='\u002Ftmp\u002FENZYMES', name='ENZYMES')\nloader = DataLoader(dataset, batch_size=32, shuffle=True)\n\nmodel = GraphClassifier(dataset.num_features, dataset.num_classes)\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n\n# Training\nmodel.train()\nfor epoch in range(100):\n    total_loss = 0\n    for batch in loader:\n        optimizer.zero_grad()\n        out = model(batch)\n        loss = F.nll_loss(out, batch.y)\n        loss.backward()\n        optimizer.step()\n        total_loss += loss.item()\n\n    if epoch % 10 == 0:\n        print(f'Epoch {epoch}, Loss: {total_loss \u002F len(loader):.4f}')\n```\n\n### Large-Scale Graphs with Neighbor Sampling\n\nFor large graphs, use `NeighborLoader` to sample subgraphs:\n\n```python\nfrom torch_geometric.loader import NeighborLoader\n\n# Create a neighbor sampler\ntrain_loader = NeighborLoader(\n    data,\n    num_neighbors=[25, 10],  # Sample 25 neighbors for 1st hop, 10 for 2nd hop\n    batch_size=128,\n    input_nodes=data.train_mask,\n)\n\n# Training\nmodel.train()\nfor batch in train_loader:\n    optimizer.zero_grad()\n    out = model(batch)\n    # Only compute loss on seed nodes (first batch_size nodes)\n    loss = F.nll_loss(out[:batch.batch_size], batch.y[:batch.batch_size])\n    loss.backward()\n    optimizer.step()\n```\n\n**Important**:\n- Output subgraphs are directed\n- Node indices are relabeled (0 to batch.num_nodes - 1)\n- Only use seed node predictions for loss computation\n- Sampling beyond 2-3 hops is generally not feasible\n\n## Advanced Features\n\n### Heterogeneous Graphs\n\nFor graphs with multiple node and edge types, use `HeteroData`:\n\n```python\nfrom torch_geometric.data import HeteroData\n\ndata = HeteroData()\n\n# Add node features for different types\ndata['paper'].x = torch.randn(100, 128)  # 100 papers with 128 features\ndata['author'].x = torch.randn(200, 64)  # 200 authors with 64 features\n\n# Add edges for different types (source_type, edge_type, target_type)\ndata['author', 'writes', 'paper'].edge_index = torch.randint(0, 200, (2, 500))\ndata['paper', 'cites', 'paper'].edge_index = torch.randint(0, 100, (2, 300))\n\nprint(data)\n```\n\nConvert homogeneous models to heterogeneous:\n\n```python\nfrom torch_geometric.nn import to_hetero\n\n# Define homogeneous model\nmodel = GNN(...)\n\n# Convert to heterogeneous\nmodel = to_hetero(model, data.metadata(), aggr='sum')\n\n# Use as normal\nout = model(data.x_dict, data.edge_index_dict)\n```\n\nOr use `HeteroConv` for custom edge-type-specific operations:\n\n```python\nfrom torch_geometric.nn import HeteroConv, GCNConv, SAGEConv\n\nclass HeteroGNN(torch.nn.Module):\n    def __init__(self, metadata):\n        super().__init__()\n        self.conv1 = HeteroConv({\n            ('paper', 'cites', 'paper'): GCNConv(-1, 64),\n            ('author', 'writes', 'paper'): SAGEConv((-1, -1), 64),\n        }, aggr='sum')\n\n        self.conv2 = HeteroConv({\n            ('paper', 'cites', 'paper'): GCNConv(64, 32),\n            ('author', 'writes', 'paper'): SAGEConv((64, 64), 32),\n        }, aggr='sum')\n\n    def forward(self, x_dict, edge_index_dict):\n        x_dict = self.conv1(x_dict, edge_index_dict)\n        x_dict = {key: F.relu(x) for key, x in x_dict.items()}\n        x_dict = self.conv2(x_dict, edge_index_dict)\n        return x_dict\n```\n\n### Transforms\n\nApply transforms to modify graph structure or features:\n\n```python\nfrom torch_geometric.transforms import NormalizeFeatures, AddSelfLoops, Compose\n\n# Single transform\ntransform = NormalizeFeatures()\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora', transform=transform)\n\n# Compose multiple transforms\ntransform = Compose([\n    AddSelfLoops(),\n    NormalizeFeatures(),\n])\ndataset = Planetoid(root='\u002Ftmp\u002FCora', name='Cora', transform=transform)\n```\n\nCommon transforms:\n- **Structure**: `ToUndirected`, `AddSelfLoops`, `RemoveSelfLoops`, `KNNGraph`, `RadiusGraph`\n- **Features**: `NormalizeFeatures`, `NormalizeScale`, `Center`\n- **Sampling**: `RandomNodeSplit`, `RandomLinkSplit`\n- **Positional Encoding**: `AddLaplacianEigenvectorPE`, `AddRandomWalkPE`\n\nSee `references\u002Ftransforms_reference.md` for the full list.\n\n### Model Explainability\n\nPyG provides explainability tools to understand model predictions:\n\n```python\nfrom torch_geometric.explain import Explainer, GNNExplainer\n\n# Create explainer\nexplainer = Explainer(\n    model=model,\n    algorithm=GNNExplainer(epochs=200),\n    explanation_type='model',  # or 'phenomenon'\n    node_mask_type='attributes',\n    edge_mask_type='object',\n    model_config=dict(\n        mode='multiclass_classification',\n        task_level='node',\n        return_type='log_probs',\n    ),\n)\n\n# Generate explanation for a specific node\nnode_idx = 10\nexplanation = explainer(data.x, data.edge_index, index=node_idx)\n\n# Visualize\nprint(f'Node {node_idx} explanation:')\nprint(f'Important edges: {explanation.edge_mask.topk(5).indices}')\nprint(f'Important features: {explanation.node_mask[node_idx].topk(5).indices}')\n```\n\n### Pooling Operations\n\nFor hierarchical graph representations:\n\n```python\nfrom torch_geometric.nn import TopKPooling, global_mean_pool\n\nclass HierarchicalGNN(torch.nn.Module):\n    def __init__(self, num_features, num_classes):\n        super().__init__()\n        self.conv1 = GCNConv(num_features, 64)\n        self.pool1 = TopKPooling(64, ratio=0.8)\n        self.conv2 = GCNConv(64, 64)\n        self.pool2 = TopKPooling(64, ratio=0.8)\n        self.lin = torch.nn.Linear(64, num_classes)\n\n    def forward(self, data):\n        x, edge_index, batch = data.x, data.edge_index, data.batch\n\n        x = F.relu(self.conv1(x, edge_index))\n        x, edge_index, _, batch, _, _ = self.pool1(x, edge_index, None, batch)\n\n        x = F.relu(self.conv2(x, edge_index))\n        x, edge_index, _, batch, _, _ = self.pool2(x, edge_index, None, batch)\n\n        x = global_mean_pool(x, batch)\n        x = self.lin(x)\n        return F.log_softmax(x, dim=1)\n```\n\n## Common Patterns and Best Practices\n\n### Check Graph Properties\n\n```python\n# Undirected check\nfrom torch_geometric.utils import is_undirected\nprint(f\"Is undirected: {is_undirected(data.edge_index)}\")\n\n# Connected components\nfrom torch_geometric.utils import connected_components\nprint(f\"Connected components: {connected_components(data.edge_index)}\")\n\n# Contains self-loops\nfrom torch_geometric.utils import contains_self_loops\nprint(f\"Has self-loops: {contains_self_loops(data.edge_index)}\")\n```\n\n### GPU Training\n\n```python\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = model.to(device)\ndata = data.to(device)\n\n# For DataLoader\nfor batch in loader:\n    batch = batch.to(device)\n    # Train...\n```\n\n### Save and Load Models\n\n```python\n# Save\ntorch.save(model.state_dict(), 'model.pth')\n\n# Load\nmodel = GCN(num_features, num_classes)\nmodel.load_state_dict(torch.load('model.pth'))\nmodel.eval()\n```\n\n### Layer Capabilities\n\nWhen choosing layers, consider these capabilities:\n- **SparseTensor**: Supports efficient sparse matrix operations\n- **edge_weight**: Handles one-dimensional edge weights\n- **edge_attr**: Processes multi-dimensional edge features\n- **Bipartite**: Works with bipartite graphs (different source\u002Ftarget dimensions)\n- **Lazy**: Enables initialization without specifying input dimensions\n\nSee the GNN cheatsheet at `references\u002Flayer_capabilities.md`.\n\n## Resources\n\n### Bundled References\n\nThis skill includes detailed reference documentation:\n\n- **`references\u002Flayers_reference.md`**: Complete listing of all 40+ GNN layers with descriptions and capabilities\n- **`references\u002Fdatasets_reference.md`**: Comprehensive dataset catalog organized by category\n- **`references\u002Ftransforms_reference.md`**: All available transforms and their use cases\n- **`references\u002Fapi_patterns.md`**: Common API patterns and coding examples\n\n### Scripts\n\nUtility scripts are provided in `scripts\u002F`:\n\n- **`scripts\u002Fvisualize_graph.py`**: Visualize graph structure using networkx and matplotlib\n- **`scripts\u002Fcreate_gnn_template.py`**: Generate boilerplate code for common GNN architectures\n- **`scripts\u002Fbenchmark_model.py`**: Benchmark model performance on standard datasets\n\nExecute scripts directly or read them for implementation patterns.\n\n### Official Resources\n\n- **Documentation**: https:\u002F\u002Fpytorch-geometric.readthedocs.io\u002F\n- **GitHub**: https:\u002F\u002Fgithub.com\u002Fpyg-team\u002Fpytorch_geometric\n- **Tutorials**: https:\u002F\u002Fpytorch-geometric.readthedocs.io\u002Fen\u002Flatest\u002Fget_started\u002Fintroduction.html\n- **Examples**: https:\u002F\u002Fgithub.com\u002Fpyg-team\u002Fpytorch_geometric\u002Ftree\u002Fmaster\u002Fexamples\n",{"name":5,"description":7},"main","2b749c82b5d11fac39d9a6e021ce3f5b8a541bd1","cli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric",3931,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates","https:\u002F\u002Faitmpl.com","https:\u002F\u002Fgithub.com\u002Fdavila7","https:\u002F\u002Fdanielavila.me","Building AI dev tools with LLMs","2026-11-14 06:14:46",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add davila7\u002Fclaude-code-templates --skill torch-geometric",{"tool":57,"command":58},"bunx","bunx skills add davila7\u002Fclaude-code-templates --skill torch-geometric",{"tool":60,"command":61},"pnpm","pnpm dlx skills add davila7\u002Fclaude-code-templates --skill torch-geometric","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002FSKILL.md",true,[65,71,75,79,83,89,93],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"checklists\u002Fsecurity-review-checklist.md","REFERENCE","参考文档",9247,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Frsmdt-the-startup\u002Fplugins\u002Fteam\u002Fskills\u002Fquality\u002Fsecurity-assessment\u002Fchecklists\u002Fsecurity-review-checklist.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"references\u002Fdatasets_reference.md",15940,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Freferences\u002Fdatasets_reference.md",{"path":76,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":77,"sourceHtmlUrl":78},"references\u002Flayers_reference.md",17121,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Freferences\u002Flayers_reference.md",{"path":80,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":81,"sourceHtmlUrl":82},"references\u002Ftransforms_reference.md",17950,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Freferences\u002Ftransforms_reference.md",{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"scripts\u002Fbenchmark_model.py","SCRIPT","脚本",10028,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Fscripts\u002Fbenchmark_model.py",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"scripts\u002Fcreate_gnn_template.py",15342,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Fscripts\u002Fcreate_gnn_template.py",{"path":94,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":95,"sourceHtmlUrl":96},"scripts\u002Fvisualize_graph.py",10267,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Ftorch_geometric\u002Fscripts\u002Fvisualize_graph.py",[98,129,156,189,224,248],{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":109,"publishedAt":36},"01M70NHBTQ8BV0A2SCAZXEPHCX","wealthville-pool-scoring","Score DeFi liquidity pools before providing liquidity. Returns a 0-100 pool score and an Enter\u002FHold\u002FExit\u002FReduce\u002FAvoid verdict with calibrated confidence for ~68,800 Solana pools and 575 EVM pools, plus a public miss-inclusive track record. Use when asked whether a pool is worth LPing into, which pools look best right now, or how accurate the scores have actually been.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fweb-data\u002Fwealthville-pool-scoring\u002FSKILL.md",[104],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[110,111,112,113,114,23,115,116,117,118,119,120,121,122,123,124,125,126,127,128],"scoring","pool","wealthville pool scoring","liquidity","which","exit","now","use","when","reduce","with","record","track","verdict","evm","solana","how","public","look",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":136,"publishedAt":36},"01M70MB6VR8ERJ4EM8D5KHBMEV","technical-debt-auditor","Scans a codebase and produces a quantified technical debt report with a prioritized remediation plan. Analyzes dead code, TODO\u002FFIXME\u002FHACK markers, dependency staleness, complexity hotspots, code duplication signals, test coverage gaps, unused exports, and outdated patterns. Use this skill when the user asks to audit their codebase for tech debt, wants a health check of their code quality, says things like \"where should I focus refactoring\", \"find code smells\", \"audit my codebase\", \"what technical debt do we have\", \"prioritize cleanup work\", or asks about code quality metrics. Also trigger when the user mentions \"code rot\", \"legacy cleanup\", \"refactoring priorities\", or wants to understand the overall health of a project before a major effort. Trigger even if the user doesn't say \"technical debt\" explicitly — any request to systematically assess code quality and identify improvement priorities belongs here.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdevelopment\u002Ftechnical-debt-auditor\u002FSKILL.md",[135],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},[137,138,139,140,141,142,143,144,145,146,147,118,148,149,150,151,152,153,154,155],"technical debt","debt","technical","technical debt auditor","auditor","coverage","complexity","markers","project","cleanup","unused","code","todo","work","plan","focus","signals","audit","dependency",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":171,"publishedAt":36},"01M70KPYH9QNHCNME5GJQGE22K","readonly-sql-guard","Make an agent's database access provably read-only. Use when an agent runs caller-supplied SQL against a production\u002FERP\u002Fanalytics database (a \"query\" MCP tool, text-to-SQL, an admin console), or when reviewing DB-access code for write\u002FDDL\u002Fside-effect\u002Ftransaction-escape risks. Checks what a statement CALLS, not just its shape.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdatabase\u002Freadonly-sql-guard\u002FSKILL.md",[162,165,166],{"categoryNo":163,"categoryName":164,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":167,"categoryName":168,"taxonomyType":169,"taxonomyTypeDesc":170},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[172,173,174,175,176,177,178,23,179,180,181,182,183,184,185,117,186,187,118,188],"readonly","guard","sql guard","sql","readonly sql guard","erp","effect","read-only","db","just","tool","calls","only","MCP","access","database","query",{"skillNo":190,"name":191,"nameZh":6,"description":192,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":193,"licenseFileUrl":194,"sourceHtmlUrl":195,"categories":196,"keywords":200,"publishedAt":36},"01M6AFY6F7CC2BBZP1QD6VTNVC","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FSKILL.md",[197],{"categoryNo":198,"categoryName":199,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000009","前端开发",[201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,23,223],"artifacts builder","web","web artifacts builder","artifacts","builder","state","routing","state management","component","css","frontend","ui","Tools","file","components","shadcn","react","Tailwind","suite","jsx","html","single-file","ui components",{"skillNo":225,"name":226,"nameZh":6,"description":227,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":193,"licenseFileUrl":228,"sourceHtmlUrl":229,"categories":230,"keywords":235,"publishedAt":36},"01M6AFWF33SFV9Z3SF4PEEE4BF","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FSKILL.md",[231,234],{"categoryNo":232,"categoryName":233,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":198,"categoryName":199,"taxonomyType":107,"taxonomyTypeDesc":108},[236,237,238,239,240,202,241,211,212,242,243,244,245,23,246,120,247],"webapp testing","testing","webapp","browser","playwright","applications","debugging","toolkit","logs","screenshots","local","behavior",{"skillNo":249,"name":250,"nameZh":6,"description":251,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":193,"licenseFileUrl":252,"sourceHtmlUrl":253,"categories":254,"keywords":262,"publishedAt":36},"01M6AF67Q67JJJ5V51JR2P52KA","discernment-nudge","After you give a substantive answer or draft that the user may act on — advice or recommendations, drafted artifacts such as goals, plans, pitches, proposals, or emails, estimates or projections, analysis or interpretation of data, factual claims they may rely on, or a multi-step argument — invoke this skill BEFORE finalizing your reply and then, if it applies, append 2-3 short follow-up questions, each tied to something specific in what you just produced, that help the user check key facts, probe the reasoning or assumptions, and notice missing context. Do this at most once per conversation. Skip it when the user asked a trivial how-to or simple lookup, wants a purely educational explanation, asked you only to format, convert, or assemble a file from content they provided, is writing code they will run, is doing creative writing or casual chat, or already asked you to double-check, cite, or review — the skill file explains these boundaries and the exact output format.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FSKILL.md",[255,258,259],{"categoryNo":256,"categoryName":257,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},{"categoryNo":260,"categoryName":261,"taxonomyType":169,"taxonomyTypeDesc":170},"01JBSEEDCAT000000000000036","内容创作者",[263,264,265,266,267,268,269,270,204,271,214,148,272,273,274,275,276,184,277,118,278,279,280,281,282,126,283],"discernment nudge","nudge","interpretation","help","run","reasoning","data","writing","lookup","content","review","conversation","short","up","invoke","you","analysis","claims","argument","assemble","recommendations"]