diff --git a/.DS_Store b/.DS_Store index 2d2b63b3..386a7416 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/espaloma/__init__.py b/espaloma/__init__.py index a3747e80..f9412785 100644 --- a/espaloma/__init__.py +++ b/espaloma/__init__.py @@ -3,6 +3,9 @@ Extensible Surrogate Potential of Ab initio Learned and Optimized by Message-passing Algorithm """ +import dgl +import torch + import espaloma.data from . import metrics, units import espaloma.app diff --git a/espaloma/mm/functional.py b/espaloma/mm/functional.py index b05cb92d..199962e3 100644 --- a/espaloma/mm/functional.py +++ b/espaloma/mm/functional.py @@ -24,6 +24,8 @@ def harmonic(x, k, eq, order=[2]): if isinstance(order, list): order = torch.tensor(order) + order = order.to(device=x.device) + return k * ((x - eq)).pow(order[:, None, None]).permute(1, 2, 0).sum( dim=-1 ) diff --git a/scripts/.DS_Store b/scripts/.DS_Store index fbcc4e22..8562d739 100644 Binary files a/scripts/.DS_Store and b/scripts/.DS_Store differ diff --git a/scripts/force/train_bonded_force.py b/scripts/force/train_bonded_force.py index fb9c3517..3e8b70eb 100644 --- a/scripts/force/train_bonded_force.py +++ b/scripts/force/train_bonded_force.py @@ -70,6 +70,7 @@ def run(args): level='g' ), + esp.metrics.GraphMetric( base_metric=torch.nn.L1Loss(), between=['u', 'u_ref'], @@ -85,12 +86,11 @@ def run(args): between=['u', 'u_ref'], level='g' ) - ] ''' metrics_te = [ - esp.metrics.GraphMetric( + esp.metrics.GraphDerivativeMetric( base_metric=base_metric, between=[param, param + '_ref'], level=term @@ -109,8 +109,8 @@ def run(args): metrics_tr=metrics_tr, metrics_te=metrics_te, n_epochs=args.n_epochs, - normalize=esp.data.normalize.PositiveNotNormalize, - device=torch.device('cuda:0'), + normalize=esp.data.normalize.ESOL100LogNormalNormalize, + optimizer=torch.optim.Adam(net.parameters(), 1e-2), ) results = exp.run() diff --git a/scripts/is_playground/is_playground.ipynb b/scripts/is_playground/is_playground.ipynb new file mode 100644 index 00000000..43c04a23 --- /dev/null +++ b/scripts/is_playground/is_playground.ipynb @@ -0,0 +1,1054 @@ +{ + "cells": [ + { +<<<<<<< Updated upstream + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [], +======= + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# imports" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Warning: Unable to load toolkit 'OpenEye Toolkit'. The Open Force Field Toolkit does not require the OpenEye Toolkits, and can use RDKit/AmberTools instead. However, if you have a valid license for the OpenEye Toolkits, consider installing them for faster performance and additional file format support: https://docs.eyesopen.com/toolkits/python/quickstart-python/linuxosx.html OpenEye offers free Toolkit licenses for academics: https://www.eyesopen.com/academic-licensing\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "b9298d7612a54cd1b3e8fb43f86c88de", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using backend: pytorch\n" + ] + } + ], +>>>>>>> Stashed changes + "source": [ + "import torch\n", + "import espaloma as esp" + ] + }, + { +<<<<<<< Updated upstream + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [], + "source": [ + "class EulerIntegrator(torch.optim.Optimizer):\n", + " def __init__(self, params, lr=1e-3, m=0.1):\n", + " defaults = dict(\n", + " lr=lr,\n", + " m=m,\n", + " )\n", + " super(EulerIntegrator, self).__init__(params, defaults)\n", + " \n", + " # @torch.no_grad()\n", + " def step(self, closure=None):\n", + " loss = None\n", + " if closure is not None:\n", + " with torch.enable_grad():\n", + " loss = closure()\n", + "\n", + " for group in self.param_groups:\n", + " for q in group['params']:\n", + " if q.grad is None:\n", + " continue\n", + "\n", + " state = self.state[q]\n", + " if len(state) == 0:\n", + " state['p'] = torch.zeros_like(q)\n", + "\n", + " state['p'].add(q.grad, alpha=-group['lr']*group['m'])\n", + " q.add(state['p'], alpha=group['lr'])\n", + "\n", + " return loss\n" +======= + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# integrator\n", + "We use a vanilla Euler method as our integrator." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def euler_method(qs, ps, q_grad, lr=1e-3):\n", + " \"\"\" Euler method integration.\n", + " \n", + " Parameters\n", + " ----------\n", + " qs : `List` of `Tensor`\n", + " The trajectories of position variables.\n", + " \n", + " ps : `List` of `Tensor`\n", + " The trajectories of momentum variables.\n", + " \n", + " q_grad : `Tensor`\n", + " Gradients (of energies) w.r.t. position variables at last step.\n", + " \n", + " Returns\n", + " -------\n", + " qs\n", + " ps\n", + "\n", + " \n", + " \"\"\"\n", + " q = qs[-1]\n", + " p = ps[-1]\n", + "\n", + " if q_grad is None:\n", + " q_grad = torch.zeros_like(q)\n", + "\n", + " p = p.clone().add(lr * q_grad)\n", + " q = q.clone().add(lr * p)\n", + " \n", + " ps.append(p)\n", + " qs.append(q)\n", + " \n", + " return qs, ps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# architecture" +>>>>>>> Stashed changes + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 146, +======= + "execution_count": 3, +>>>>>>> Stashed changes + "metadata": {}, + "outputs": [], + "source": [ + "class NodeRNN(torch.nn.Module):\n", +<<<<<<< Updated upstream + " def __init__(self, input_size=32, units=128):\n", + " super(NodeRNN, self).__init__()\n", + " self.rnn = torch.nn.RNN(\n", + " input_size=input_size,\n", +======= + " \"\"\" HyperNode-level RNN to out put lambdas schedule.\n", + " \n", + " Parameters\n", + " ----------\n", + " input_size : `int`\n", + " Input dimension.\n", + " \n", + " units : `int`\n", + " Hidden dimension.\n", + " \n", + " Methods\n", + " -------\n", + " apply_nodes_fn :\n", + " Function that is applied to all hypernodes\n", + " and returns latent representation.\n", + " \n", + " forward :\n", + " Forward pass.\n", + " \n", + " \n", + " Attributes\n", + " ----------\n", + " rnn2 : `torch.nn.GRU`\n", + " Bond-level RNN.\n", + " \n", + " rnn3 : `torch.nn.GRU`\n", + " Angle-level RNN.\n", + " \n", + " d : `torch.nn.Linear`\n", + " Final layer to output lambda scedules.\n", + " \n", + " \n", + " \"\"\"\n", + " def __init__(self, input_size=32, units=128):\n", + " super(NodeRNN, self).__init__()\n", + " self.rnn2 = torch.nn.GRU(\n", + " input_size=input_size+3,\n", + " hidden_size=units,\n", + " batch_first=True,\n", + " bidirectional=True, # just to be more expressive\n", + " )\n", + " \n", + " self.rnn3 = torch.nn.GRU(\n", + " input_size=input_size+3,\n", +>>>>>>> Stashed changes + " hidden_size=units,\n", + " batch_first=True,\n", + " bidirectional=True,\n", + " )\n", +<<<<<<< Updated upstream + " self.d = torch.nn.Linear(\n", + " 2 * units,\n", + " 1\n", + " )\n", + " \n", + " def forward(self, g, windows=48):\n", + " g.apply_nodes(\n", + " lambda node: {'lambs_': self.d(self.rnn(node.data['h'][:, None, :].repeat(1, windows, 1))[0]).squeeze(-1)},\n", +======= + " \n", + " self.windows=48\n", + " self.d = torch.nn.Linear(\n", + " 2 * units,\n", + " 1\n", + " ) # we need to summarize the protocols to one-dimension\n", + "\n", + " def apply_nodes_fn(self, x, rnn):\n", + " \"\"\" Applied to all hypernodes and returns latent representation.\"\"\"\n", + " # (number_of_hypernodes, number_of_windows, units)\n", + " h_gn = x[:, None, :].repeat(1, self.windows, 1)\n", + " \n", + " # (number_of_hypernodes, number_of_windows,)\n", + " h_total_number = torch.tensor([self.windows])[:, None].repeat(\n", + " x.shape[0], self.windows).to(dtype=torch.float32)\n", + " \n", + " # (number_of_hypernodes, number_of_windows,)\n", + " h_index = torch.arange(0, self.windows)[None, :].repeat(\n", + " x.shape[0], 1).to(dtype=torch.float32)\n", + " \n", + " # (number_of_hypernodes, number_of_windows,)\n", + " h_pct = h_index / h_total_number\n", + " \n", + " # (number_of_hypernodes, 3)\n", + " h_indicator = torch.stack(\n", + " [\n", + " h_total_number,\n", + " h_index,\n", + " h_pct\n", + " ],\n", + " dim=2,\n", + " )\n", + " \n", + " # (number_of_hypernodes, number_of_windows, 1)\n", + " h = rnn(torch.cat([h_gn, h_indicator], dim=-1))[0]\n", + "\n", + " return self.d(h).squeeze(-1) # erase dimension (1)\n", + "\n", + " def forward(self, g):\n", + " \"\"\" Forward pass. \"\"\"\n", + " # apply to both bond and angle.\n", + " \n", + " g.apply_nodes(\n", + " lambda node: {'lambs_': self.apply_nodes_fn(node.data['h'], self.rnn2)},\n", +>>>>>>> Stashed changes + " ntype='n2'\n", + " )\n", + " \n", + " g.apply_nodes(\n", +<<<<<<< Updated upstream + " lambda node: {'lambs_': self.d(self.rnn(node.data['h'][:, None, :].repeat(1, windows, 1))[0]).squeeze(-1)},\n", + " ntype='n3'\n", + " )\n", + " \n", + " return g\n", + " " +======= + " lambda node: {'lambs_': self.apply_nodes_fn(node.data['h'], self.rnn3)},\n", + " ntype='n3'\n", + " )\n", + " \n", + " return g" +>>>>>>> Stashed changes + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 167, +======= + "execution_count": 14, +>>>>>>> Stashed changes + "metadata": {}, + "outputs": [], + "source": [ + "class LambdaConstraint(torch.nn.Module):\n", +<<<<<<< Updated upstream +======= + " \"\"\" Constraint lambda schedules such that:\n", + " * It is monotonically increasing.\n", + " * It starts at zero and ends at one.\n", + " \n", + " \"\"\"\n", +>>>>>>> Stashed changes + " def __init__(self):\n", + " super(LambdaConstraint, self).__init__()\n", + " \n", + " def forward(self, g):\n", + " g.apply_nodes(\n", + " lambda node: {'lambs': node.data['lambs_'].softmax(dim=-1).cumsum(dim=-1)},\n", + " ntype='n2'\n", + " )\n", + " \n", + " g.apply_nodes(\n", + " lambda node: {'lambs': node.data['lambs_'].softmax(dim=-1).cumsum(dim=-1)},\n", + " ntype='n3'\n", + " )\n", + " \n", + " return g" + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 168, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 168, +======= + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/wangy1/anaconda3/envs/pinot/lib/python3.7/site-packages/dgl/base.py:25: UserWarning: Currently adjacency_matrix() returns a matrix with destination as rows by default. In 0.5 the result will have source as rows (i.e. transpose=True)\n", + " warnings.warn(msg, warn_type)\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, +>>>>>>> Stashed changes + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ +<<<<<<< Updated upstream + "g = esp.Graph('CN1C=NC2=C1C(=O)N(C(=O)N2C)C')\n", +======= + "g = esp.Graph('CC')\n", +>>>>>>> Stashed changes + "esp.graphs.LegacyForceField('smirnoff99Frosst').parametrize(g)\n" + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 169, + "metadata": {}, + "outputs": [], + "source": [ +======= + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "\n", +>>>>>>> Stashed changes + "layer = esp.nn.dgl_legacy.gn()\n", + "\n", + "representation = esp.nn.Sequential(\n", + " layer,\n", + " [32, 'tanh', 32, 'tanh', 32, 'tanh'],\n", + ")\n", + "\n", + "readout = esp.nn.readout.janossy.JanossyPooling(\n", + " in_features=32,\n", + " config=[32, 'tanh', 32],\n", + " out_features={\n", +<<<<<<< Updated upstream + " 1: {'h': 32},\n", +======= + " 1: {'log_sigma': 1},\n", +>>>>>>> Stashed changes + " 2: {'h': 32},\n", + " 3: {'h': 32},\n", + " }\n", + ")\n", + "\n", + "node_rnn = NodeRNN()\n", + "\n", + "lambda_constraint = LambdaConstraint()\n", + "\n", + "net = torch.nn.Sequential(\n", + " representation,\n", + " readout,\n", + " node_rnn,\n", + " lambda_constraint,\n", + ")" + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 170, + "metadata": {}, + "outputs": [], + "source": [ + "def f(x, idx):\n", + " if idx == 0:\n", + " return (x ** 2).sum(dim=(0, 2))\n", + " \n", + " if idx == 49:\n", + " g.nodes['n1'].data['xyz'] = x\n", + " esp.mm.geometry.geometry_in_graph(g.heterograph)\n", + " esp.mm.energy.energy_in_graph(g.heterograph, suffix='_ref')\n", + " # print(g.nodes['n2'].data['u'].sum(dim=0) + g.nodes['n3'].data['u'].sum(dim=0))\n", + " return 1e-10 * (g.nodes['n2'].data['u_ref'].sum(dim=0) + g.nodes['n3'].data['u_ref'].sum(dim=0))\n", + "\n", +======= + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "def f(x, idx, x_init_distribution):\n", + " \"\"\" Energy function. \"\"\"\n", + " # the first step, return the negative log prob as energy\n", + " if idx == 0: \n", + " return -x_init_distribution.log_prob(x).sum(\n", + " dim=(0, 2), # sum across nodes and space dimension\n", + " )\n", + " \n", + " # the last step, return the target energy\n", + " if idx == 49:\n", + " # assign variable to xyz\n", + " g.nodes['n1'].data['xyz'] = x\n", + " \n", + " # calculate geometries\n", + " esp.mm.geometry.geometry_in_graph(g.heterograph)\n", + " \n", + " # calculate energies\n", + " esp.mm.energy.energy_in_graph(g.heterograph, suffix='_ref')\n", + " \n", + " # only return bond and angle energy\n", + " # (number_of_samples, )\n", + " return 1e-3 * (g.nodes['n2'].data['u_ref'].sum(dim=0) + g.nodes['n3'].data['u_ref'].sum(dim=0))\n", + "\n", + " \n", + " # same logic here,\n", + " # only with biased potentials\n", +>>>>>>> Stashed changes + " g.nodes['n1'].data['xyz'] = x\n", + " esp.mm.geometry.geometry_in_graph(g.heterograph)\n", + " esp.mm.energy.energy_in_graph(g.heterograph, suffix='_ref')\n", + "\n", + " g.heterograph.apply_nodes(\n", + " lambda node: {'u': node.data['u_ref'] * node.data['lambs'][:, idx-1][:, None]},\n", + " ntype='n2'\n", + " )\n", + "\n", + " g.heterograph.apply_nodes(\n", + " lambda node: {'u': node.data['u_ref'] * node.data['lambs'][:, idx-1][:, None]},\n", + " ntype='n3'\n", + " )\n", + "\n", +<<<<<<< Updated upstream + " return 1e-10 * (g.nodes['n2'].data['u'].sum(dim=0) + g.nodes['n3'].data['u'].sum(dim=0))\n", +======= + " return 1e-3 * (g.nodes['n2'].data['u'].sum(dim=0) + g.nodes['n3'].data['u'].sum(dim=0))\n", +>>>>>>> Stashed changes + "\n" + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 171, + "metadata": {}, + "outputs": [], + "source": [ + "def loss():\n", + " x = torch.nn.Parameter(\n", + " torch.randn(\n", + " g.heterograph.number_of_nodes('n1'),\n", + " 128,\n", + " 3\n", + " )\n", + " )\n", + " \n", + " sampler = EulerIntegrator([x], 1e-1)\n", + " \n", + " works = 0.0\n", + " \n", + " net(g.heterograph)\n", + " \n", + " for idx in range(1, 50):\n", + " sampler.zero_grad()\n", + " energy_old = f(x, idx-1)\n", + " energy_new = f(x, idx)\n", + " energy_new.sum().backward(create_graph=True)\n", + " sampler.step()\n", + " works += energy_new - energy_old\n", + " \n", + " return works.sum()\n" +======= + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def loss():\n", + " \"\"\" The loss function for the neural network parameters. \"\"\"\n", + " # parametrize the graph in-place\n", + " net(g.heterograph)\n", + " \n", + " # the scale of the initial distribution is parametrized neurally\n", + " scale = g.nodes['n1'].data['log_sigma'].exp()[:, None, :].repeat(1, 128, 3)\n", + " \n", + " # construct the initial distribution\n", + " x_init_distribution = torch.distributions.normal.Normal(\n", + " loc=torch.zeros(\n", + " g.heterograph.number_of_nodes('n1'),\n", + " 128,\n", + " 3\n", + " ),\n", + " scale=scale,\n", + " )\n", + " \n", + " # sample one for initial conformation\n", + " x = x_init_distribution.sample()\n", + " x.requires_grad = True\n", + "\n", + " # initialize the momentum\n", + " q = torch.zeros_like(x)\n", + "\n", + " # here we record the entire trajectory since the computation graph\n", + " # is always needed for autograd\n", + " xs = [x]\n", + " qs = [q]\n", + " \n", + " # initialize work\n", + " # this broadcasts to (batch_size, )\n", + " works = 0.0\n", + " \n", + " # loop through lambda schedules\n", + " for idx in range(1, 50):\n", + " x = xs[-1]\n", + " q = qs[-1]\n", + "\n", + " # calculate old and new energy\n", + " energy_old = f(x, idx-1, x_init_distribution=x_init_distribution)\n", + " energy_new = f(x, idx, x_init_distribution=x_init_distribution)\n", + "\n", + " # calculate gradient \n", + " x_grad = torch.autograd.grad(\n", + " energy_new.sum(),\n", + " [x],\n", + " create_graph=True,\n", + " )[0]\n", + "\n", + " # integrate\n", + " xs, qs = euler_method(xs, qs, x_grad)\n", + " \n", + " # calculate works\n", + " works += energy_new - energy_old\n", + " \n", + " return works.sum()\n", + "\n" +>>>>>>> Stashed changes + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 171, +======= + "execution_count": 29, +>>>>>>> Stashed changes + "metadata": { + "scrolled": true + }, + "outputs": [ + { +<<<<<<< Updated upstream + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_code\u001b[0;34m(self, code_obj, result, async_)\u001b[0m\n\u001b[1;32m 3330\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3331\u001b[0;31m \u001b[0mexec\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcode_obj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muser_global_ns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0muser_ns\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3332\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0m_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0m_loss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mloss\u001b[0;34m()\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0menergy_old\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m \u001b[0menergy_new\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 20\u001b[0m \u001b[0menergy_new\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcreate_graph\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mf\u001b[0;34m(x, idx)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mesp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgeometry\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgeometry_in_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheterograph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mesp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0menergy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0menergy_in_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheterograph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msuffix\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'_ref'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/Documents/GitHub/espaloma/espaloma/mm/energy.py\u001b[0m in \u001b[0;36menergy_in_graph\u001b[0;34m(g, suffix, terms)\u001b[0m\n\u001b[1;32m 144\u001b[0m },\n\u001b[0;32m--> 145\u001b[0;31m \u001b[0mntype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"g\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 146\u001b[0m )\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/dgl/heterograph.py\u001b[0m in \u001b[0;36mapply_nodes\u001b[0;34m(self, func, v, ntype, inplace)\u001b[0m\n\u001b[1;32m 2639\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_all\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2640\u001b[0;31m \u001b[0mv_ntype\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mutils\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtoindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mslice\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnumber_of_nodes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mntype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2641\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/dgl/heterograph.py\u001b[0m in \u001b[0;36mnumber_of_nodes\u001b[0;34m(self, ntype)\u001b[0m\n\u001b[1;32m 982\u001b[0m \"\"\"\n\u001b[0;32m--> 983\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_graph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnumber_of_nodes\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_ntype_id\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mntype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 984\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/dgl/heterograph_index.py\u001b[0m in \u001b[0;36mnumber_of_nodes\u001b[0;34m(self, ntype)\u001b[0m\n\u001b[1;32m 250\u001b[0m \"\"\"\n\u001b[0;32m--> 251\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_CAPI_DGLHeteroNumVertices\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mntype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 252\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/dgl/_ffi/_ctypes/function.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 177\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 178\u001b[0;31m \u001b[0;32mdef\u001b[0m \u001b[0m__call__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 179\u001b[0m \"\"\"Call the function with positional arguments\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mshowtraceback\u001b[0;34m(self, exc_tuple, filename, tb_offset, exception_only, running_compiled_code)\u001b[0m\n\u001b[1;32m 2043\u001b[0m \u001b[0;31m# in the engines. This should return a list of strings.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2044\u001b[0;31m \u001b[0mstb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_render_traceback_\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2045\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'KeyboardInterrupt' object has no attribute '_render_traceback_'", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mshowtraceback\u001b[0;34m(self, exc_tuple, filename, tb_offset, exception_only, running_compiled_code)\u001b[0m\n\u001b[1;32m 2046\u001b[0m stb = self.InteractiveTB.structured_traceback(etype,\n\u001b[0;32m-> 2047\u001b[0;31m value, tb, tb_offset=tb_offset)\n\u001b[0m\u001b[1;32m 2048\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/ultratb.py\u001b[0m in \u001b[0;36mstructured_traceback\u001b[0;34m(self, etype, value, tb, tb_offset, number_of_lines_of_context)\u001b[0m\n\u001b[1;32m 1413\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1414\u001b[0;31m return FormattedTB.structured_traceback(\n\u001b[0m\u001b[1;32m 1415\u001b[0m self, etype, value, tb, tb_offset, number_of_lines_of_context)\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_ast_nodes\u001b[0;34m(self, nodelist, cell_name, interactivity, compiler, result)\u001b[0m\n\u001b[1;32m 3253\u001b[0m \u001b[0masy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3254\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;32mawait\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0masync_\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0masy\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3255\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_code\u001b[0;34m(self, code_obj, result, async_)\u001b[0m\n\u001b[1;32m 3347\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merror_in_exec\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexc_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3348\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshowtraceback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrunning_compiled_code\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3349\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mshowtraceback\u001b[0;34m(self, exc_tuple, filename, tb_offset, exception_only, running_compiled_code)\u001b[0m\n\u001b[1;32m 2058\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2059\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\n'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_exception_only\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstderr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2060\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mget_exception_only\u001b[0;34m(self, exc_tuple)\u001b[0m\n\u001b[1;32m 2003\u001b[0m \u001b[0metype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_exc_info\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexc_tuple\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2004\u001b[0;31m \u001b[0mmsg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtraceback\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat_exception_only\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0metype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2005\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: ", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/async_helpers.py\u001b[0m in \u001b[0;36m_pseudo_sync_runner\u001b[0;34m(coro)\u001b[0m\n\u001b[1;32m 66\u001b[0m \"\"\"\n\u001b[1;32m 67\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 68\u001b[0;31m \u001b[0mcoro\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 69\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mexc\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mexc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_cell_async\u001b[0;34m(self, raw_cell, store_history, silent, shell_futures)\u001b[0m\n\u001b[1;32m 3061\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3062\u001b[0m has_raised = await self.run_ast_nodes(code_ast.body, cell_name,\n\u001b[0;32m-> 3063\u001b[0;31m interactivity=interactivity, compiler=compiler, result=result)\n\u001b[0m\u001b[1;32m 3064\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3065\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlast_execution_succeeded\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mhas_raised\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/pinot/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_ast_nodes\u001b[0;34m(self, nodelist, cell_name, interactivity, compiler, result)\u001b[0m\n\u001b[1;32m 3252\u001b[0m \u001b[0mcode\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompiler\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmod\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3253\u001b[0m \u001b[0masy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompare\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcode\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3254\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;32mawait\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_code\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0masync_\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0masy\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3255\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " +======= + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/wangy1/anaconda3/envs/pinot/lib/python3.7/site-packages/torch/nn/functional.py:1340: UserWarning: nn.functional.tanh is deprecated. Use torch.tanh instead.\n", + " warnings.warn(\"nn.functional.tanh is deprecated. Use torch.tanh instead.\")\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor(4602.8086, grad_fn=)\n", + "tensor(4580.6865, grad_fn=)\n", + "tensor(4698.6050, grad_fn=)\n", + "tensor(4670.8403, grad_fn=)\n", + "tensor(4799.4810, grad_fn=)\n", + "tensor(4953.8784, grad_fn=)\n", + "tensor(5007.7227, grad_fn=)\n", + "tensor(5003.0312, grad_fn=)\n", + "tensor(4970.0791, grad_fn=)\n", + "tensor(4950.4341, grad_fn=)\n", + "tensor(4840.0820, grad_fn=)\n", + "tensor(4779.9297, grad_fn=)\n", + "tensor(4813.6494, grad_fn=)\n", + "tensor(4871.9746, grad_fn=)\n", + "tensor(4807.5020, grad_fn=)\n", + "tensor(4771.2539, grad_fn=)\n", + "tensor(4926.2700, grad_fn=)\n", + "tensor(4913.1436, grad_fn=)\n", + "tensor(4923.4502, grad_fn=)\n", + "tensor(4860.6128, grad_fn=)\n", + "tensor(4831.3198, grad_fn=)\n", + "tensor(4817.8071, grad_fn=)\n", + "tensor(4787.0615, grad_fn=)\n", + "tensor(4856.5225, grad_fn=)\n", + "tensor(4855.6152, grad_fn=)\n", + "tensor(4847.8315, grad_fn=)\n", + "tensor(4923.6108, grad_fn=)\n", + "tensor(5024.2949, grad_fn=)\n", + "tensor(5026.1597, grad_fn=)\n", + "tensor(5032.7896, grad_fn=)\n", + "tensor(5047.7212, grad_fn=)\n", + "tensor(5079.0693, grad_fn=)\n", + "tensor(5075.9736, grad_fn=)\n", + "tensor(5174.0996, grad_fn=)\n", + "tensor(5090.5938, grad_fn=)\n", + "tensor(5010.7251, grad_fn=)\n", + "tensor(4887.1465, grad_fn=)\n", + "tensor(4855.9922, grad_fn=)\n", + "tensor(4806.8740, grad_fn=)\n", + "tensor(4701.2031, grad_fn=)\n", + "tensor(4652.5342, grad_fn=)\n", + "tensor(4664.1699, grad_fn=)\n", + "tensor(4678.7852, grad_fn=)\n", + "tensor(4641.2148, grad_fn=)\n", + "tensor(4657.2539, grad_fn=)\n", + "tensor(4676.9893, grad_fn=)\n", + "tensor(4678.0342, grad_fn=)\n", + "tensor(4720.7129, grad_fn=)\n", + "tensor(4664.9038, grad_fn=)\n", + "tensor(4683.8525, grad_fn=)\n", + "tensor(4684.8838, grad_fn=)\n", + "tensor(4674.6079, grad_fn=)\n", + "tensor(4678.3794, grad_fn=)\n", + "tensor(4718.4619, grad_fn=)\n", + "tensor(4676.4805, grad_fn=)\n", + "tensor(4701.8857, grad_fn=)\n", + "tensor(4654.2695, grad_fn=)\n", + "tensor(4702.2109, grad_fn=)\n", + "tensor(4691.6992, grad_fn=)\n", + "tensor(4675.4883, grad_fn=)\n", + "tensor(4725.3135, grad_fn=)\n", + "tensor(4653.4473, grad_fn=)\n", + "tensor(4737.8003, grad_fn=)\n", + "tensor(4693.9375, grad_fn=)\n", + "tensor(4735.9136, grad_fn=)\n", + "tensor(4762.6636, grad_fn=)\n", + "tensor(4822.4800, grad_fn=)\n", + "tensor(5027.7983, grad_fn=)\n", + "tensor(5041.3735, grad_fn=)\n", + "tensor(4975.2788, grad_fn=)\n", + "tensor(5138.8716, grad_fn=)\n", + "tensor(5596.6675, grad_fn=)\n", + "tensor(5344.3672, grad_fn=)\n", + "tensor(5792.4736, grad_fn=)\n", + "tensor(5681.0171, grad_fn=)\n", + "tensor(5465.8955, grad_fn=)\n", + "tensor(5355.1362, grad_fn=)\n", + "tensor(5214.5356, grad_fn=)\n", + "tensor(5392.2681, grad_fn=)\n", + "tensor(5015.3579, grad_fn=)\n", + "tensor(4898.6621, grad_fn=)\n", + "tensor(4851.9736, grad_fn=)\n", + "tensor(4989.4819, grad_fn=)\n", + "tensor(4896.0571, grad_fn=)\n", + "tensor(4825.4248, grad_fn=)\n", + "tensor(4722.8223, grad_fn=)\n", + "tensor(4746.7773, grad_fn=)\n", + "tensor(4705.1504, grad_fn=)\n", + "tensor(4644.5435, grad_fn=)\n", + "tensor(4710.5972, grad_fn=)\n", + "tensor(4633.9355, grad_fn=)\n", + "tensor(4735.9463, grad_fn=)\n", + "tensor(4707.1616, grad_fn=)\n", + "tensor(4700.8818, grad_fn=)\n", + "tensor(4662.6050, grad_fn=)\n", + "tensor(4628.9858, grad_fn=)\n", + "tensor(4714.0571, grad_fn=)\n", + "tensor(4718.7305, grad_fn=)\n", + "tensor(4709.2661, grad_fn=)\n", + "tensor(4739.9863, grad_fn=)\n" +>>>>>>> Stashed changes + ] + } + ], + "source": [ +<<<<<<< Updated upstream + "optimizer = torch.optim.SGD(net.parameters(), 1e-2, 1e-2)\n", + "for _ in range(1000):\n", + " optimizer.zero_grad()\n", + " _loss = loss()\n", + " _loss.backward()\n", + " print(_loss)\n", + " print(g.nodes['n2'].data['lambs_'][0].detach())\n", + " optimizer.step()" +======= + "optimizer = torch.optim.Adam(net.parameters(), 1e-3)\n", + "losses = []\n", + "for _ in range(100):\n", + " optimizer.zero_grad()\n", + " def l():\n", + " _loss = loss()\n", + " _loss.backward()\n", + " print(_loss)\n", + " losses.append(_loss.detach().numpy())\n", + " return _loss\n", + " optimizer.step(l)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# analysis" +>>>>>>> Stashed changes + ] + }, + { + "cell_type": "code", +<<<<<<< Updated upstream + "execution_count": 140, +======= + "execution_count": 30, +>>>>>>> Stashed changes + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ +<<<<<<< Updated upstream + "[]" + ] + }, + "execution_count": 140, +======= + "Text(0, 0.5, 'Work std')" + ] + }, + "execution_count": 30, +>>>>>>> Stashed changes + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { +<<<<<<< Updated upstream + "image/png": "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\n", +======= + "image/png": "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\n", +>>>>>>> Stashed changes + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import pyplot as plt\n", +<<<<<<< Updated upstream + "plt.plot(g.nodes['n2'].data['lambs_'][0].detach())\n" +======= + "plt.plot(losses)\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Work std')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Lambda Schedule for the first bond.')" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from matplotlib import pyplot as plt\n", + "plt.plot(g.nodes['n2'].data['lambs'][0].detach())\n", + "plt.xlabel('Steps')\n", + "plt.ylabel('$\\lambda$')\n", + "plt.title('Lambda Schedule for the first bond.')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Lambda Schedule for the first angle.')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(g.nodes['n3'].data['lambs'][0].detach())\n", + "plt.xlabel('Steps')\n", + "plt.ylabel('$\\lambda$')\n", + "plt.title('Lambda Schedule for the first angle.')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "df3633cce4124aa38fbb2f61bf1d9939", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "NGLWidget()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import nglview as nv\n", + "from rdkit.Geometry import Point3D\n", + "from rdkit import Chem\n", + "from rdkit.Chem import AllChem\n", + "\n", + "conf_idx = 0\n", + "\n", + "mol = g.mol.to_rdkit()\n", + "AllChem.EmbedMolecule(mol)\n", + "conf = mol.GetConformer()\n", + "x = g.nodes['n1'].data['xyz'].detach().numpy()\n", + "for idx_atom in range(mol.GetNumAtoms()):\n", + " conf.SetAtomPosition(\n", + " idx_atom,\n", + " Point3D(\n", + " float(x[idx_atom, conf_idx, 0]),\n", + " float(x[idx_atom, conf_idx, 1]),\n", + " float(x[idx_atom, conf_idx, 2]),\n", + " ))\n", + " \n", + "nv.show_rdkit(mol)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[[-3.41263339e-02, 3.52944434e-02, -8.97085965e-02],\n", + " [ 1.69774041e-01, -2.79087927e-02, 4.86264862e-02],\n", + " [-1.31876737e-01, -8.08370709e-02, 1.64929722e-02],\n", + " ...,\n", + " [ 7.92630613e-02, 6.09573489e-03, 2.04126120e-01],\n", + " [-5.97706735e-02, -5.69996089e-02, -4.97680977e-02],\n", + " [ 1.74203008e-01, -5.73492125e-02, 1.57508184e-05]],\n", + "\n", + " [[ 3.63735459e-03, 3.95094156e-02, -1.04997065e-02],\n", + " [-4.83989976e-02, 3.44696417e-02, -6.32497668e-02],\n", + " [-5.02936468e-02, 2.79121976e-02, -3.91660929e-02],\n", + " ...,\n", + " [ 1.71062071e-02, -2.07896829e-01, 1.31265551e-01],\n", + " [-1.39811024e-01, -4.24224697e-02, 9.69814584e-02],\n", + " [ 3.60629000e-02, 2.43871622e-02, -1.05412662e-01]],\n", + "\n", + " [[ 4.21018451e-02, 1.11921087e-01, 2.41540149e-02],\n", + " [-1.15812637e-01, -1.46501750e-01, 1.38379589e-01],\n", + " [ 7.76274428e-02, 5.11942692e-02, -1.04440369e-01],\n", + " ...,\n", + " [ 8.77612680e-02, 2.73689199e-02, -9.95817557e-02],\n", + " [-4.55766693e-02, -4.12325375e-02, -2.75499839e-02],\n", + " [-2.46742949e-01, 4.20030318e-02, 9.35935825e-02]],\n", + "\n", + " ...,\n", + "\n", + " [[ 3.73183656e-03, -3.60215567e-02, -2.07943335e-01],\n", + " [-2.61017829e-02, 1.88863292e-01, -1.24650680e-01],\n", + " [ 6.16022460e-02, -1.62968203e-01, -4.34054025e-02],\n", + " ...,\n", + " [-2.65139937e-01, 2.35548001e-02, -2.01405078e-01],\n", + " [-1.91289186e-02, 1.35458335e-01, 1.04286343e-01],\n", + " [-1.05364369e-02, 2.35631149e-02, -2.80091129e-02]],\n", + "\n", + " [[ 2.16687899e-02, 4.29136977e-02, 6.66253548e-03],\n", + " [ 8.25655982e-02, -1.18774869e-01, -6.11993335e-02],\n", + " [ 7.31565207e-02, -2.56101973e-02, 1.61058977e-01],\n", + " ...,\n", + " [ 1.40669808e-01, 1.36285961e-01, 9.35491323e-02],\n", + " [-5.40552139e-02, -4.45944592e-02, 1.78871274e-01],\n", + " [-5.78228086e-02, 1.16878524e-01, 9.63541642e-02]],\n", + "\n", + " [[-1.59016084e-02, -1.30845690e-02, 5.53522520e-02],\n", + " [-7.31578171e-02, 2.09877267e-02, 1.32140353e-01],\n", + " [ 1.11443952e-01, 9.96201038e-02, -1.02662547e-02],\n", + " ...,\n", + " [-6.12059161e-02, 2.17171460e-02, -1.18476465e-01],\n", + " [ 2.08628207e-01, 2.38694362e-02, 2.18892042e-02],\n", + " [ 3.87141630e-02, 4.26593237e-02, -7.39875808e-02]]],\n", + " dtype=float32)" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x" +>>>>>>> Stashed changes + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/scripts/is_playground/is_playground.py b/scripts/is_playground/is_playground.py new file mode 100644 index 00000000..51c6f859 --- /dev/null +++ b/scripts/is_playground/is_playground.py @@ -0,0 +1,237 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[128]: + + +import torch +import espaloma as esp + +torch.autograd.set_detect_anomaly(True) +# In[145]: + +def euler_method(qs, ps, q_grad, lr=1e-3): + q = qs[-1] + p = ps[-1] + + if q_grad is None: + q_grad = torch.zeros_like(q) + + p = p.clone().add(lr * q_grad) + q = q.clone().add(lr * p) + + ps.append(p) + qs.append(q) + + return qs, ps + + +# In[146]: + + +class NodeRNN(torch.nn.Module): + def __init__(self, input_size=32, units=128): + super(NodeRNN, self).__init__() + self.rnn = torch.nn.RNN( + input_size=input_size, + hidden_size=units, + batch_first=True, + bidirectional=True, + ) + self.windows=48 + self.d = torch.nn.Linear( + 2 * units + self.windows, + 1 + ) + + def apply_nodes_fn(self, x): + h_rnn = self.rnn(x[:, None, :].repeat(1, self.windows, 1))[0] + + h_one_hot = torch.zeros( + self.windows, + self.windows + ).scatter( + 1, + torch.range(0, self.windows-1)[:, None].long(), + 1.0, + )[None, :, :].repeat(x.shape[0], 1, 1) + + h = torch.cat( + [ + h_rnn, + h_one_hot, + ], + dim=-1 + ) + + return self.d(h).squeeze(-1) + + def forward(self, g): + g.apply_nodes( + lambda node: {'lambs_': self.apply_nodes_fn(node.data['h'])}, + ntype='n2' + ) + + g.apply_nodes( + lambda node: {'lambs_': self.apply_nodes_fn(node.data['h'])}, + ntype='n3' + ) + + return g + + + +# In[167]: + + +class LambdaConstraint(torch.nn.Module): + def __init__(self): + super(LambdaConstraint, self).__init__() + + def forward(self, g): + g.apply_nodes( + lambda node: {'lambs': node.data['lambs_'].softmax(dim=-1).cumsum(dim=-1)}, + ntype='n2' + ) + + g.apply_nodes( + lambda node: {'lambs': node.data['lambs_'].softmax(dim=-1).cumsum(dim=-1)}, + ntype='n3' + ) + + return g + + +# In[168]: + + +g = esp.Graph('CN1C=NC2=C1C(=O)N(C(=O)N2C)C') +esp.graphs.LegacyForceField('smirnoff99Frosst').parametrize(g) + + +# In[169]: + + +layer = esp.nn.dgl_legacy.gn() + +representation = esp.nn.Sequential( + layer, + [32, 'tanh', 32, 'tanh', 32, 'tanh'], +) + +readout = esp.nn.readout.janossy.JanossyPooling( + in_features=32, + config=[32, 'tanh', 32], + out_features={ + 1: {'h': 32}, + 2: {'h': 32}, + 3: {'h': 32}, + } +) + +node_rnn = NodeRNN() + +lambda_constraint = LambdaConstraint() + +net = torch.nn.Sequential( + representation, + readout, + node_rnn, + lambda_constraint, +) + + +# In[170]: + + +def f(x, idx, g): + if idx == 0: + return (x ** 2).sum(dim=(0, 2)) + + if idx == 49: + g.heterograph.nodes['n1'].data['xyz'] = x + esp.mm.geometry.geometry_in_graph(g.heterograph) + esp.mm.energy.energy_in_graph(g.heterograph, suffix='_ref') + # print(g.nodes['n2'].data['u'].sum(dim=0) + g.nodes['n3'].data['u'].sum(dim=0)) + return 1e-10 * (g.nodes['n2'].data['u_ref'].sum(dim=0) + g.nodes['n3'].data['u_ref'].sum(dim=0)) + + g.heterograph.nodes['n1'].data['xyz'] = x + esp.mm.geometry.geometry_in_graph(g.heterograph) + esp.mm.energy.energy_in_graph(g.heterograph, suffix='_ref') + + g.heterograph.apply_nodes( + lambda node: {'u': node.data['u_ref'] * node.data['lambs'][:, idx-1][:, None]}, + ntype='n2' + ) + + g.heterograph.apply_nodes( + lambda node: {'u': node.data['u_ref'] * node.data['lambs'][:, idx-1][:, None]}, + ntype='n3' + ) + + return 1e-10 * (g.nodes['n2'].data['u'].sum(dim=0) + g.nodes['n3'].data['u'].sum(dim=0)) + + +# In[171]: + + +def loss(g): + x = torch.randn( + g.heterograph.number_of_nodes('n1'), + 128, + 3 + ) + + x.requires_grad = True + + q = torch.zeros_like(x) + + xs = [x] + qs = [q] + + works = 0.0 + + for idx in range(1, 50): + x = xs[-1] + q = qs[-1] + + energy_old = f(x, idx-1, g) + energy_new = f(x, idx, g) + x_grad = torch.autograd.grad( + energy_new.sum(), + [x], + create_graph=True + )[0] + + xs, qs = euler_method(xs, qs, x_grad) + + works += energy_new - energy_old + + return works.sum() + + +# In[171]: + + +optimizer = torch.optim.SGD(net.parameters(), 1e-2, 1e-2) +for _ in range(1000): + optimizer.zero_grad() + net(g.heterograph) + _loss = loss(g) + _loss.backward(retain_graph=True) + print(_loss) + optimizer.step() + + +# In[140]: + + +from matplotlib import pyplot as plt +plt.plot(g.nodes['n2'].data['lambs_'][0].detach()) + + +# In[ ]: + + + +