Spaces:
Running
Running
MilesCranmer
commited on
Commit
•
a1a766e
1
Parent(s):
1f233a4
Fix torch segfault in colab example
Browse files- examples/pysr_demo.ipynb +46 -39
examples/pysr_demo.ipynb
CHANGED
@@ -152,11 +152,6 @@
|
|
152 |
"import numpy as np\n",
|
153 |
"from matplotlib import pyplot as plt\n",
|
154 |
"from pysr import PySRRegressor\n",
|
155 |
-
"import torch\n",
|
156 |
-
"from torch import nn, optim\n",
|
157 |
-
"from torch.nn import functional as F\n",
|
158 |
-
"from torch.utils.data import DataLoader, TensorDataset\n",
|
159 |
-
"import pytorch_lightning as pl\n",
|
160 |
"from sklearn.model_selection import train_test_split"
|
161 |
]
|
162 |
},
|
@@ -232,8 +227,7 @@
|
|
232 |
"cell_type": "code",
|
233 |
"execution_count": null,
|
234 |
"metadata": {
|
235 |
-
"id": "p4PSrO-NK1Wa"
|
236 |
-
"scrolled": true
|
237 |
},
|
238 |
"outputs": [],
|
239 |
"source": [
|
@@ -412,8 +406,7 @@
|
|
412 |
"cell_type": "code",
|
413 |
"execution_count": null,
|
414 |
"metadata": {
|
415 |
-
"id": "PoEkpvYuGUdy"
|
416 |
-
"scrolled": true
|
417 |
},
|
418 |
"outputs": [],
|
419 |
"source": [
|
@@ -606,8 +599,7 @@
|
|
606 |
"cell_type": "code",
|
607 |
"execution_count": null,
|
608 |
"metadata": {
|
609 |
-
"id": "a07K3KUjOxcp"
|
610 |
-
"scrolled": true
|
611 |
},
|
612 |
"outputs": [],
|
613 |
"source": [
|
@@ -947,8 +939,8 @@
|
|
947 |
]
|
948 |
},
|
949 |
{
|
950 |
-
"attachments": {},
|
951 |
"cell_type": "markdown",
|
|
|
952 |
"metadata": {},
|
953 |
"source": [
|
954 |
"We are all set to go! Let's see if we can find the true relation:"
|
@@ -1019,10 +1011,13 @@
|
|
1019 |
},
|
1020 |
"outputs": [],
|
1021 |
"source": [
|
1022 |
-
"
|
|
|
|
|
|
|
1023 |
"N = 100000\n",
|
1024 |
"Nt = 10\n",
|
1025 |
-
"X = 6 *
|
1026 |
"y_i = X[..., 0] ** 2 + 6 * np.cos(2 * X[..., 2])\n",
|
1027 |
"y = np.sum(y_i, axis=1) / y_i.shape[1]\n",
|
1028 |
"z = y**2\n",
|
@@ -1055,6 +1050,17 @@
|
|
1055 |
"Then, we will fit `g` and `f` **separately** using symbolic regression."
|
1056 |
]
|
1057 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1058 |
{
|
1059 |
"cell_type": "code",
|
1060 |
"execution_count": null,
|
@@ -1063,9 +1069,14 @@
|
|
1063 |
},
|
1064 |
"outputs": [],
|
1065 |
"source": [
|
1066 |
-
"
|
1067 |
-
"
|
|
|
|
|
|
|
1068 |
"\n",
|
|
|
|
|
1069 |
"\n",
|
1070 |
"def mlp(size_in, size_out, act=nn.ReLU):\n",
|
1071 |
" return nn.Sequential(\n",
|
@@ -1148,13 +1159,14 @@
|
|
1148 |
},
|
1149 |
"outputs": [],
|
1150 |
"source": [
|
|
|
1151 |
"Xt = torch.tensor(X).float()\n",
|
1152 |
"zt = torch.tensor(z).float()\n",
|
1153 |
"X_train, X_test, z_train, z_test = train_test_split(Xt, zt, random_state=0)\n",
|
1154 |
"train_set = TensorDataset(X_train, z_train)\n",
|
1155 |
-
"train = DataLoader(train_set, batch_size=128, num_workers=
|
1156 |
"test_set = TensorDataset(X_test, z_test)\n",
|
1157 |
-
"test = DataLoader(test_set, batch_size=256, num_workers=
|
1158 |
]
|
1159 |
},
|
1160 |
{
|
@@ -1207,8 +1219,8 @@
|
|
1207 |
"outputs": [],
|
1208 |
"source": [
|
1209 |
"trainer = pl.Trainer(\n",
|
1210 |
-
" max_steps=total_steps, accelerator=\"gpu\", devices=1
|
1211 |
-
")
|
1212 |
]
|
1213 |
},
|
1214 |
{
|
@@ -1262,7 +1274,6 @@
|
|
1262 |
]
|
1263 |
},
|
1264 |
{
|
1265 |
-
"attachments": {},
|
1266 |
"cell_type": "markdown",
|
1267 |
"metadata": {
|
1268 |
"id": "nCCIvvAGuyFi"
|
@@ -1332,8 +1343,7 @@
|
|
1332 |
"cell_type": "code",
|
1333 |
"execution_count": null,
|
1334 |
"metadata": {
|
1335 |
-
"id": "51QdHVSkbDhc"
|
1336 |
-
"scrolled": true
|
1337 |
},
|
1338 |
"outputs": [],
|
1339 |
"source": [
|
@@ -1348,6 +1358,15 @@
|
|
1348 |
"model.fit(g_input[f_sample_idx], g_output[f_sample_idx])"
|
1349 |
]
|
1350 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1351 |
{
|
1352 |
"cell_type": "markdown",
|
1353 |
"metadata": {
|
@@ -1380,7 +1399,7 @@
|
|
1380 |
},
|
1381 |
"outputs": [],
|
1382 |
"source": [
|
1383 |
-
"model"
|
1384 |
]
|
1385 |
},
|
1386 |
{
|
@@ -1389,7 +1408,7 @@
|
|
1389 |
"id": "mlU1hidZkgCY"
|
1390 |
},
|
1391 |
"source": [
|
1392 |
-
"A neural network can easily undo a linear transform, so
|
1393 |
"\n",
|
1394 |
"This likely won't find the exact result, but it should find something similar. You may wish to try again but with many more `total_steps` for the neural network (10,000 is quite small!).\n",
|
1395 |
"\n",
|
@@ -1438,21 +1457,9 @@
|
|
1438 |
},
|
1439 |
"gpuClass": "standard",
|
1440 |
"kernelspec": {
|
1441 |
-
"display_name": "Python
|
1442 |
"language": "python",
|
1443 |
-
"name": "
|
1444 |
-
},
|
1445 |
-
"language_info": {
|
1446 |
-
"codemirror_mode": {
|
1447 |
-
"name": "ipython",
|
1448 |
-
"version": 3
|
1449 |
-
},
|
1450 |
-
"file_extension": ".py",
|
1451 |
-
"mimetype": "text/x-python",
|
1452 |
-
"name": "python",
|
1453 |
-
"nbconvert_exporter": "python",
|
1454 |
-
"pygments_lexer": "ipython3",
|
1455 |
-
"version": "3.10.9"
|
1456 |
}
|
1457 |
},
|
1458 |
"nbformat": 4,
|
|
|
152 |
"import numpy as np\n",
|
153 |
"from matplotlib import pyplot as plt\n",
|
154 |
"from pysr import PySRRegressor\n",
|
|
|
|
|
|
|
|
|
|
|
155 |
"from sklearn.model_selection import train_test_split"
|
156 |
]
|
157 |
},
|
|
|
227 |
"cell_type": "code",
|
228 |
"execution_count": null,
|
229 |
"metadata": {
|
230 |
+
"id": "p4PSrO-NK1Wa"
|
|
|
231 |
},
|
232 |
"outputs": [],
|
233 |
"source": [
|
|
|
406 |
"cell_type": "code",
|
407 |
"execution_count": null,
|
408 |
"metadata": {
|
409 |
+
"id": "PoEkpvYuGUdy"
|
|
|
410 |
},
|
411 |
"outputs": [],
|
412 |
"source": [
|
|
|
599 |
"cell_type": "code",
|
600 |
"execution_count": null,
|
601 |
"metadata": {
|
602 |
+
"id": "a07K3KUjOxcp"
|
|
|
603 |
},
|
604 |
"outputs": [],
|
605 |
"source": [
|
|
|
939 |
]
|
940 |
},
|
941 |
{
|
|
|
942 |
"cell_type": "markdown",
|
943 |
+
"id": "ee30bd41",
|
944 |
"metadata": {},
|
945 |
"source": [
|
946 |
"We are all set to go! Let's see if we can find the true relation:"
|
|
|
1011 |
},
|
1012 |
"outputs": [],
|
1013 |
"source": [
|
1014 |
+
"import numpy as np\n",
|
1015 |
+
"\n",
|
1016 |
+
"rstate = np.random.RandomState(0)\n",
|
1017 |
+
"\n",
|
1018 |
"N = 100000\n",
|
1019 |
"Nt = 10\n",
|
1020 |
+
"X = 6 * rstate.rand(N, Nt, 5) - 3\n",
|
1021 |
"y_i = X[..., 0] ** 2 + 6 * np.cos(2 * X[..., 2])\n",
|
1022 |
"y = np.sum(y_i, axis=1) / y_i.shape[1]\n",
|
1023 |
"z = y**2\n",
|
|
|
1050 |
"Then, we will fit `g` and `f` **separately** using symbolic regression."
|
1051 |
]
|
1052 |
},
|
1053 |
+
{
|
1054 |
+
"cell_type": "markdown",
|
1055 |
+
"metadata": {
|
1056 |
+
"id": "aca54ffa"
|
1057 |
+
},
|
1058 |
+
"source": [
|
1059 |
+
"> **Warning**\n",
|
1060 |
+
">\n",
|
1061 |
+
"> We import torch *after* already starting PyJulia. This is required due to interference between their C bindings. If you use torch, and then run PyJulia, you will likely hit a segfault. So keep this in mind for mixed deep learning + PyJulia/PySR workflows."
|
1062 |
+
]
|
1063 |
+
},
|
1064 |
{
|
1065 |
"cell_type": "code",
|
1066 |
"execution_count": null,
|
|
|
1069 |
},
|
1070 |
"outputs": [],
|
1071 |
"source": [
|
1072 |
+
"import torch\n",
|
1073 |
+
"from torch import nn, optim\n",
|
1074 |
+
"from torch.nn import functional as F\n",
|
1075 |
+
"from torch.utils.data import DataLoader, TensorDataset\n",
|
1076 |
+
"import pytorch_lightning as pl\n",
|
1077 |
"\n",
|
1078 |
+
"hidden = 128\n",
|
1079 |
+
"total_steps = 30_000\n",
|
1080 |
"\n",
|
1081 |
"def mlp(size_in, size_out, act=nn.ReLU):\n",
|
1082 |
" return nn.Sequential(\n",
|
|
|
1159 |
},
|
1160 |
"outputs": [],
|
1161 |
"source": [
|
1162 |
+
"from multiprocessing import cpu_count\n",
|
1163 |
"Xt = torch.tensor(X).float()\n",
|
1164 |
"zt = torch.tensor(z).float()\n",
|
1165 |
"X_train, X_test, z_train, z_test = train_test_split(Xt, zt, random_state=0)\n",
|
1166 |
"train_set = TensorDataset(X_train, z_train)\n",
|
1167 |
+
"train = DataLoader(train_set, batch_size=128, num_workers=cpu_count(), shuffle=True, pin_memory=True)\n",
|
1168 |
"test_set = TensorDataset(X_test, z_test)\n",
|
1169 |
+
"test = DataLoader(test_set, batch_size=256, num_workers=cpu_count(), pin_memory=True)"
|
1170 |
]
|
1171 |
},
|
1172 |
{
|
|
|
1219 |
"outputs": [],
|
1220 |
"source": [
|
1221 |
"trainer = pl.Trainer(\n",
|
1222 |
+
" max_steps=total_steps, accelerator=\"gpu\", devices=1\n",
|
1223 |
+
")"
|
1224 |
]
|
1225 |
},
|
1226 |
{
|
|
|
1274 |
]
|
1275 |
},
|
1276 |
{
|
|
|
1277 |
"cell_type": "markdown",
|
1278 |
"metadata": {
|
1279 |
"id": "nCCIvvAGuyFi"
|
|
|
1343 |
"cell_type": "code",
|
1344 |
"execution_count": null,
|
1345 |
"metadata": {
|
1346 |
+
"id": "51QdHVSkbDhc"
|
|
|
1347 |
},
|
1348 |
"outputs": [],
|
1349 |
"source": [
|
|
|
1358 |
"model.fit(g_input[f_sample_idx], g_output[f_sample_idx])"
|
1359 |
]
|
1360 |
},
|
1361 |
+
{
|
1362 |
+
"cell_type": "markdown",
|
1363 |
+
"metadata": {
|
1364 |
+
"id": "1a738a33"
|
1365 |
+
},
|
1366 |
+
"source": [
|
1367 |
+
"If this segfaults, restart the notebook, and run the initial imports and PyJulia part, but skip the PyTorch training. This is because PyTorch's C binding tends to interefere with PyJulia. You can then re-run the `pkl.load` cell to import the data."
|
1368 |
+
]
|
1369 |
+
},
|
1370 |
{
|
1371 |
"cell_type": "markdown",
|
1372 |
"metadata": {
|
|
|
1399 |
},
|
1400 |
"outputs": [],
|
1401 |
"source": [
|
1402 |
+
"model.equations_[[\"complexity\", \"loss\", \"equation\"]]"
|
1403 |
]
|
1404 |
},
|
1405 |
{
|
|
|
1408 |
"id": "mlU1hidZkgCY"
|
1409 |
},
|
1410 |
"source": [
|
1411 |
+
"A neural network can easily undo a linear transform (which commutes with the summation), so any affine transform in $g$ is to be expected. The network for $f$ has learned to undo the linear transform.\n",
|
1412 |
"\n",
|
1413 |
"This likely won't find the exact result, but it should find something similar. You may wish to try again but with many more `total_steps` for the neural network (10,000 is quite small!).\n",
|
1414 |
"\n",
|
|
|
1457 |
},
|
1458 |
"gpuClass": "standard",
|
1459 |
"kernelspec": {
|
1460 |
+
"display_name": "Python 3",
|
1461 |
"language": "python",
|
1462 |
+
"name": "python3"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1463 |
}
|
1464 |
},
|
1465 |
"nbformat": 4,
|