File size: 150,692 Bytes
592e96e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 |
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "3d5d52d1-4874-44b5-b532-ef03da47644a",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"from rdkit import Chem\n",
"from rdkit.Chem import Descriptors, rdMolDescriptors, Crippen, Lipinski\n",
"from tqdm import tqdm\n",
"import warnings\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.model_selection import train_test_split\n",
"import random\n",
"from concurrent.futures import ProcessPoolExecutor\n",
"import multiprocessing\n",
"\n",
"def analyze_polymer_features_rdkit(smiles):\n",
" mol = Chem.MolFromSmiles(smiles)\n",
" if mol is None:\n",
" return None\n",
" \n",
" features = {}\n",
" \n",
" # Basic molecular properties\n",
" features['mol_weight'] = Descriptors.MolWt(mol)\n",
" features['exact_mol_weight'] = Descriptors.ExactMolWt(mol)\n",
" features['num_heavy_atoms'] = mol.GetNumHeavyAtoms()\n",
" features['num_atoms'] = mol.GetNumAtoms()\n",
" features['num_bonds'] = mol.GetNumBonds()\n",
" \n",
" # Hydrogen bonding features\n",
" features['num_hbond_donors'] = Descriptors.NumHDonors(mol)\n",
" features['num_hbond_acceptors'] = Descriptors.NumHAcceptors(mol)\n",
" features['num_heteroatoms'] = Descriptors.NumHeteroatoms(mol)\n",
" \n",
" # Structural complexity\n",
" features['num_rotatable_bonds'] = Descriptors.NumRotatableBonds(mol)\n",
" features['num_saturated_rings'] = Descriptors.NumSaturatedRings(mol)\n",
" features['num_aromatic_rings'] = Descriptors.NumAromaticRings(mol)\n",
" features['num_aliphatic_rings'] = Descriptors.NumAliphaticRings(mol)\n",
" features['ring_count'] = Descriptors.RingCount(mol)\n",
" features['fraction_csp3'] = Descriptors.FractionCSP3(mol)\n",
" \n",
" # Surface area and polarity\n",
" features['tpsa'] = Descriptors.TPSA(mol)\n",
" features['polar_surface_area'] = rdMolDescriptors.CalcTPSA(mol)\n",
" \n",
" # Lipophilicity and solubility\n",
" features['logp'] = Descriptors.MolLogP(mol)\n",
" features['crippen_logp'] = Crippen.MolLogP(mol)\n",
" features['crippen_mr'] = Crippen.MolMR(mol) # Molar refractivity\n",
" \n",
" # Flexibility and rigidity\n",
" features['kappa1'] = Descriptors.Kappa1(mol) # Molecular shape index\n",
" features['kappa2'] = Descriptors.Kappa2(mol)\n",
" features['kappa3'] = Descriptors.Kappa3(mol)\n",
" features['chi0v'] = Descriptors.Chi0v(mol) # Connectivity indices\n",
" features['chi1v'] = Descriptors.Chi1v(mol)\n",
" features['chi2v'] = Descriptors.Chi2v(mol)\n",
" \n",
" # Electronic properties\n",
" features['balaban_j'] = Descriptors.BalabanJ(mol)\n",
" features['bertz_ct'] = Descriptors.BertzCT(mol) # Complexity index\n",
" \n",
" # Polymer-specific features\n",
" features['num_radical_electrons'] = Descriptors.NumRadicalElectrons(mol)\n",
" features['num_valence_electrons'] = Descriptors.NumValenceElectrons(mol)\n",
" \n",
" # Atom type counts\n",
" atom_counts = {}\n",
" for atom in mol.GetAtoms():\n",
" symbol = atom.GetSymbol()\n",
" atom_counts[symbol] = atom_counts.get(symbol, 0) + 1\n",
" \n",
" # Add individual atom counts as features\n",
" for element in ['C', 'N', 'O', 'S', 'P', 'F', 'Cl', 'Br', 'I']:\n",
" features[f'count_{element}'] = atom_counts.get(element, 0)\n",
" features[f'ratio_{element}'] = atom_counts.get(element, 0) / features['num_atoms'] if features['num_atoms'] > 0 else 0\n",
" \n",
" # Bond type analysis\n",
" bond_types = {'SINGLE': 0, 'DOUBLE': 0, 'TRIPLE': 0, 'AROMATIC': 0}\n",
" for bond in mol.GetBonds():\n",
" bond_type = str(bond.GetBondType())\n",
" if bond_type in bond_types:\n",
" bond_types[bond_type] += 1\n",
" \n",
" for bond_type, count in bond_types.items():\n",
" features[f'num_{bond_type.lower()}_bonds'] = count\n",
" features[f'ratio_{bond_type.lower()}_bonds'] = count / features['num_bonds'] if features['num_bonds'] > 0 else 0\n",
" \n",
" # Hybridization analysis\n",
" hybridization_counts = {'SP': 0, 'SP2': 0, 'SP3': 0, 'SP3D': 0, 'SP3D2': 0}\n",
" for atom in mol.GetAtoms():\n",
" hyb = str(atom.GetHybridization())\n",
" if hyb in hybridization_counts:\n",
" hybridization_counts[hyb] += 1\n",
" \n",
" for hyb_type, count in hybridization_counts.items():\n",
" features[f'num_{hyb_type.lower()}_carbons'] = count\n",
" features[f'ratio_{hyb_type.lower()}_carbons'] = count / features['num_atoms'] if features['num_atoms'] > 0 else 0\n",
" \n",
" # Formal charge analysis\n",
" formal_charges = [atom.GetFormalCharge() for atom in mol.GetAtoms()]\n",
" features['total_formal_charge'] = sum(formal_charges)\n",
" features['abs_total_formal_charge'] = sum(abs(charge) for charge in formal_charges)\n",
" features['max_formal_charge'] = max(formal_charges) if formal_charges else 0\n",
" features['min_formal_charge'] = min(formal_charges) if formal_charges else 0\n",
" \n",
" # Aromaticity features\n",
" aromatic_atoms = sum(1 for atom in mol.GetAtoms() if atom.GetIsAromatic())\n",
" features['num_aromatic_atoms'] = aromatic_atoms\n",
" features['aromatic_ratio'] = aromatic_atoms / features['num_atoms'] if features['num_atoms'] > 0 else 0\n",
" \n",
" # Ring size analysis\n",
" ring_info = mol.GetRingInfo()\n",
" ring_sizes = [len(ring) for ring in ring_info.AtomRings()]\n",
" if ring_sizes:\n",
" features['avg_ring_size'] = sum(ring_sizes) / len(ring_sizes)\n",
" features['max_ring_size'] = max(ring_sizes)\n",
" features['min_ring_size'] = min(ring_sizes)\n",
" features['num_3_rings'] = sum(1 for size in ring_sizes if size == 3)\n",
" features['num_4_rings'] = sum(1 for size in ring_sizes if size == 4)\n",
" features['num_5_rings'] = sum(1 for size in ring_sizes if size == 5)\n",
" features['num_6_rings'] = sum(1 for size in ring_sizes if size == 6)\n",
" features['num_7_rings'] = sum(1 for size in ring_sizes if size == 7)\n",
" features['num_large_rings'] = sum(1 for size in ring_sizes if size > 7)\n",
" else:\n",
" features.update({\n",
" 'avg_ring_size': 0, 'max_ring_size': 0, 'min_ring_size': 0,\n",
" 'num_3_rings': 0, 'num_4_rings': 0, 'num_5_rings': 0,\n",
" 'num_6_rings': 0, 'num_7_rings': 0, 'num_large_rings': 0\n",
" })\n",
" \n",
" # Polymer-specific structural features\n",
" features['has_polymer_notation'] = '*' in smiles\n",
" features['smiles_length'] = len(smiles)\n",
" features['branch_count'] = smiles.count('(')\n",
" features['branch_ratio'] = smiles.count('(') / len(smiles) if len(smiles) > 0 else 0\n",
" \n",
" return features\n",
"\n",
"def add_features(df, num_workers=None):\n",
" \"\"\"\n",
" Improved version using multiprocessing to calculate RDKit descriptors efficiently.\n",
" \n",
" Parameters:\n",
" df: pandas DataFrame with 'Smiles' column\n",
" num_workers: Number of worker processes (defaults to number of CPU cores)\n",
" \"\"\"\n",
" if num_workers is None:\n",
" num_workers = multiprocessing.cpu_count()\n",
" \n",
" smiles_list = df['Smiles'].tolist()\n",
" \n",
" with ProcessPoolExecutor(max_workers=num_workers) as executor:\n",
" # Use tqdm with executor.map for progress tracking\n",
" features_list = list(tqdm(executor.map(analyze_polymer_features_rdkit, smiles_list), \n",
" total=len(smiles_list), \n",
" desc=\"Computing RDKit descriptors\"))\n",
" \n",
" # Convert results to DataFrame\n",
" features_df = pd.DataFrame(features_list)\n",
" \n",
" # Concatenate with original DataFrame\n",
" df_result = pd.concat([df, features_df], axis=1)\n",
" \n",
" return df_result\n",
"\n",
"def get_list_dif(l1, l2):\n",
" return list(set(l1) - set(l2))\n",
"\n",
"# Usage example:\n",
"# df_with_features = add_features(df, num_workers=4)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "155598af-79f3-4933-8b5c-1fd11f64b870",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv('/home/jovyan/simson_training_bolgov/regression/PI_Tg_P308K_synth_db_chem.csv').drop(columns=['Unnamed: 0'], axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c69cc497-9fb6-4f74-96eb-257d7aa4a91a",
"metadata": {},
"outputs": [],
"source": [
"df = pd.read_csv('/home/jovyan/simson_training_bolgov/kaggle_comp/train.csv')\n",
"df['Smiles'] = df['SMILES']\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7b076c55-d6ef-4780-af97-5fccd5062661",
"metadata": {},
"outputs": [],
"source": [
"sample_df = df.iloc[:10_000]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "96313883-c2ca-4eb8-9ec7-9aaca8dba077",
"metadata": {},
"outputs": [],
"source": [
"features_df = add_features(sample_df)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "41c7f85a-ea65-42e5-b315-ef304ba311c4",
"metadata": {},
"outputs": [],
"source": [
"selected_features = ['mol_weight', 'exact_mol_weight', 'num_heavy_atoms', 'num_atoms',\n",
" 'num_bonds', 'num_hbond_donors', 'num_hbond_acceptors',\n",
" 'num_heteroatoms', 'num_rotatable_bonds', 'num_saturated_rings',\n",
" 'num_aromatic_rings', 'num_aliphatic_rings', 'ring_count',\n",
" 'fraction_csp3', 'tpsa', 'polar_surface_area', 'logp', 'crippen_logp',\n",
" 'crippen_mr', 'kappa1', 'kappa2', 'kappa3', 'chi0v', 'chi1v', 'chi2v',\n",
" 'balaban_j', 'bertz_ct', 'num_radical_electrons',\n",
" 'num_valence_electrons',\n",
" 'count_O', 'ratio_O', 'count_S', 'ratio_S', 'count_P', 'ratio_P',\n",
" 'count_F', 'ratio_F', 'count_Cl', 'ratio_Cl', 'count_Br', 'ratio_Br',\n",
" 'count_I', 'ratio_I', 'num_single_bonds', 'ratio_single_bonds',\n",
" 'num_double_bonds', 'ratio_double_bonds', 'num_triple_bonds',\n",
" 'ratio_triple_bonds', 'num_aromatic_bonds', 'ratio_aromatic_bonds',\n",
" 'num_sp_carbons', 'ratio_sp_carbons', 'num_sp2_carbons',\n",
" 'ratio_sp2_carbons', 'num_sp3_carbons', 'ratio_sp3_carbons',\n",
" 'num_sp3d_carbons', 'ratio_sp3d_carbons', 'num_sp3d2_carbons',\n",
" 'ratio_sp3d2_carbons', 'total_formal_charge', 'abs_total_formal_charge',\n",
" 'max_formal_charge', 'min_formal_charge', 'num_aromatic_atoms',\n",
" 'aromatic_ratio', 'avg_ring_size', 'max_ring_size', 'min_ring_size',\n",
" 'num_3_rings', 'num_4_rings', 'num_5_rings', 'num_6_rings',\n",
" 'num_7_rings', 'num_large_rings', 'has_polymer_notation',\n",
" 'branch_count', 'branch_ratio']"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "fc31605d-cc21-4533-b04e-f8acdaef1a65",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['id', 'SMILES', 'Tg', 'FFV', 'Tc', 'Density', 'Rg', 'Smiles',\n",
" 'mol_weight', 'exact_mol_weight', 'num_heavy_atoms', 'num_atoms',\n",
" 'num_bonds', 'num_hbond_donors', 'num_hbond_acceptors',\n",
" 'num_heteroatoms', 'num_rotatable_bonds', 'num_saturated_rings',\n",
" 'num_aromatic_rings', 'num_aliphatic_rings', 'ring_count',\n",
" 'fraction_csp3', 'tpsa', 'polar_surface_area', 'logp', 'crippen_logp',\n",
" 'crippen_mr', 'kappa1', 'kappa2', 'kappa3', 'chi0v', 'chi1v', 'chi2v',\n",
" 'balaban_j', 'bertz_ct', 'num_radical_electrons',\n",
" 'num_valence_electrons', 'count_C', 'ratio_C', 'count_N', 'ratio_N',\n",
" 'count_O', 'ratio_O', 'count_S', 'ratio_S', 'count_P', 'ratio_P',\n",
" 'count_F', 'ratio_F', 'count_Cl', 'ratio_Cl', 'count_Br', 'ratio_Br',\n",
" 'count_I', 'ratio_I', 'num_single_bonds', 'ratio_single_bonds',\n",
" 'num_double_bonds', 'ratio_double_bonds', 'num_triple_bonds',\n",
" 'ratio_triple_bonds', 'num_aromatic_bonds', 'ratio_aromatic_bonds',\n",
" 'num_sp_carbons', 'ratio_sp_carbons', 'num_sp2_carbons',\n",
" 'ratio_sp2_carbons', 'num_sp3_carbons', 'ratio_sp3_carbons',\n",
" 'num_sp3d_carbons', 'ratio_sp3d_carbons', 'num_sp3d2_carbons',\n",
" 'ratio_sp3d2_carbons', 'total_formal_charge', 'abs_total_formal_charge',\n",
" 'max_formal_charge', 'min_formal_charge', 'num_aromatic_atoms',\n",
" 'aromatic_ratio', 'avg_ring_size', 'max_ring_size', 'min_ring_size',\n",
" 'num_3_rings', 'num_4_rings', 'num_5_rings', 'num_6_rings',\n",
" 'num_7_rings', 'num_large_rings', 'has_polymer_notation',\n",
" 'smiles_length', 'branch_count', 'branch_ratio'],\n",
" dtype='object')"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"scalers = []\n",
"for col in selected_features:\n",
" scaler = StandardScaler()\n",
" features_df[col] = scaler.fit_transform(features_df[col].to_numpy().reshape(-1, 1)).flatten()\n",
" scalers.append(scaler)\n",
" \n",
"features_df.columns"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "f2f1a614-0ba7-4a01-9731-532afc1d14e0",
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'features_df' is not defined",
"output_type": "error",
"traceback": [
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 4\u001b[39m\n\u001b[32m 1\u001b[39m new_features = []\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m feature \u001b[38;5;129;01min\u001b[39;00m selected_features:\n\u001b[32m----> \u001b[39m\u001b[32m4\u001b[39m unique_list = \u001b[43mfeatures_df\u001b[49m[feature].unique()\n\u001b[32m 5\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(unique_list) > \u001b[32m300\u001b[39m:\n\u001b[32m 6\u001b[39m new_features.append(feature)\n",
"\u001b[31mNameError\u001b[39m: name 'features_df' is not defined"
]
}
],
"source": [
"new_features = []\n",
"\n",
"for feature in selected_features:\n",
" unique_list = features_df[feature].unique()\n",
" if len(unique_list) > 300:\n",
" new_features.append(feature)\n",
"new_features.append('Smiles')\n",
"print(new_features)\n",
"len(new_features), len(selected_features)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "28cbac75-8a9f-4292-aedb-11f33f5a6056",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "c065d950-7a63-4424-9923-1072d2e2268c",
"metadata": {},
"outputs": [],
"source": [
"features_df.to_csv('7k_w_descriptors.csv', index=False)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "069a9021-d440-4bf1-9882-a2af25f2e801",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>id</th>\n",
" <th>SMILES</th>\n",
" <th>Tg</th>\n",
" <th>FFV</th>\n",
" <th>Tc</th>\n",
" <th>Density</th>\n",
" <th>Rg</th>\n",
" <th>Smiles</th>\n",
" <th>mol_weight</th>\n",
" <th>exact_mol_weight</th>\n",
" <th>...</th>\n",
" <th>num_3_rings</th>\n",
" <th>num_4_rings</th>\n",
" <th>num_5_rings</th>\n",
" <th>num_6_rings</th>\n",
" <th>num_7_rings</th>\n",
" <th>num_large_rings</th>\n",
" <th>has_polymer_notation</th>\n",
" <th>smiles_length</th>\n",
" <th>branch_count</th>\n",
" <th>branch_ratio</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>87817</td>\n",
" <td>*CC(*)c1ccccc1C(=O)OCCCCCC</td>\n",
" <td>NaN</td>\n",
" <td>0.374645</td>\n",
" <td>0.205667</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*CC(*)c1ccccc1C(=O)OCCCCCC</td>\n",
" <td>-0.875755</td>\n",
" <td>-0.875617</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>-0.788904</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>26</td>\n",
" <td>-0.985221</td>\n",
" <td>-0.813832</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>106919</td>\n",
" <td>*Nc1ccc([C@H](CCC)c2ccc(C3(c4ccc([C@@H](CCC)c5...</td>\n",
" <td>NaN</td>\n",
" <td>0.370410</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*Nc1ccc([C@H](CCC)c2ccc(C3(c4ccc([C@@H](CCC)c5...</td>\n",
" <td>0.651876</td>\n",
" <td>0.651916</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>0.736852</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>82</td>\n",
" <td>0.336345</td>\n",
" <td>-0.286141</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>388772</td>\n",
" <td>*Oc1ccc(S(=O)(=O)c2ccc(Oc3ccc(C4(c5ccc(Oc6ccc(...</td>\n",
" <td>NaN</td>\n",
" <td>0.378860</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*Oc1ccc(S(=O)(=O)c2ccc(Oc3ccc(C4(c5ccc(Oc6ccc(...</td>\n",
" <td>2.336573</td>\n",
" <td>2.336165</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>2.644047</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>134</td>\n",
" <td>1.657910</td>\n",
" <td>-0.109289</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>519416</td>\n",
" <td>*Nc1ccc(-c2c(-c3ccc(C)cc3)c(-c3ccc(C)cc3)c(N*)...</td>\n",
" <td>NaN</td>\n",
" <td>0.387324</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*Nc1ccc(-c2c(-c3ccc(C)cc3)c(-c3ccc(C)cc3)c(N*)...</td>\n",
" <td>0.417716</td>\n",
" <td>0.417722</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>1.118291</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>79</td>\n",
" <td>0.556606</td>\n",
" <td>0.132247</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>539187</td>\n",
" <td>*Oc1ccc(OC(=O)c2cc(OCCCCCCCCCOCC3CCCN3c3ccc([N...</td>\n",
" <td>NaN</td>\n",
" <td>0.355470</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*Oc1ccc(OC(=O)c2cc(OCCCCCCCCCOCC3CCCN3c3ccc([N...</td>\n",
" <td>2.178003</td>\n",
" <td>2.178499</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>1.501149</td>\n",
" <td>0.355413</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>118</td>\n",
" <td>0.556606</td>\n",
" <td>-0.830501</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7968</th>\n",
" <td>2146592435</td>\n",
" <td>*Oc1cc(CCCCCCCC)cc(OC(=O)c2cccc(C(*)=O)c2)c1</td>\n",
" <td>NaN</td>\n",
" <td>0.367498</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*Oc1cc(CCCCCCCC)cc(OC(=O)c2cccc(C(*)=O)c2)c1</td>\n",
" <td>-0.375261</td>\n",
" <td>-0.375084</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>-0.407465</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>44</td>\n",
" <td>-0.324438</td>\n",
" <td>0.124891</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7969</th>\n",
" <td>2146810552</td>\n",
" <td>*C(=O)OCCN(CCOC(=O)c1ccc2c(c1)C(=O)N(c1cccc(N3...</td>\n",
" <td>NaN</td>\n",
" <td>0.353280</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*C(=O)OCCN(CCOC(=O)c1ccc2c(c1)C(=O)N(c1cccc(N3...</td>\n",
" <td>1.284275</td>\n",
" <td>1.284737</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>1.501149</td>\n",
" <td>0.736852</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>110</td>\n",
" <td>1.217388</td>\n",
" <td>0.008668</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7970</th>\n",
" <td>2147191531</td>\n",
" <td>*c1cc(C(=O)NCCCCCCCC)cc(N2C(=O)c3ccc(-c4ccc5c(...</td>\n",
" <td>NaN</td>\n",
" <td>0.369411</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*c1cc(C(=O)NCCCCCCCC)cc(N2C(=O)c3ccc(-c4ccc5c(...</td>\n",
" <td>0.329570</td>\n",
" <td>0.329823</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>1.501149</td>\n",
" <td>-0.026026</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>73</td>\n",
" <td>0.336345</td>\n",
" <td>0.021405</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7971</th>\n",
" <td>2147435020</td>\n",
" <td>*C=C(*)c1ccccc1C</td>\n",
" <td>261.662355</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*C=C(*)c1ccccc1C</td>\n",
" <td>-1.359802</td>\n",
" <td>-1.359728</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>-0.626991</td>\n",
" <td>-0.788904</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>16</td>\n",
" <td>-1.205481</td>\n",
" <td>-1.182617</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7972</th>\n",
" <td>2147438299</td>\n",
" <td>*c1ccc(OCCCCCCCCCCCOC(=O)CCCCC(=O)OCCCCCCCCCCC...</td>\n",
" <td>NaN</td>\n",
" <td>0.374049</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>*c1ccc(OCCCCCCCCCCCOC(=O)CCCCC(=O)OCCCCCCCCCCC...</td>\n",
" <td>1.160667</td>\n",
" <td>1.160653</td>\n",
" <td>...</td>\n",
" <td>-0.048476</td>\n",
" <td>-0.069289</td>\n",
" <td>0.437079</td>\n",
" <td>-0.407465</td>\n",
" <td>-0.051542</td>\n",
" <td>-0.047917</td>\n",
" <td>0.0</td>\n",
" <td>72</td>\n",
" <td>-0.324438</td>\n",
" <td>-1.005054</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>7973 rows Γ 92 columns</p>\n",
"</div>"
],
"text/plain": [
" id SMILES \\\n",
"0 87817 *CC(*)c1ccccc1C(=O)OCCCCCC \n",
"1 106919 *Nc1ccc([C@H](CCC)c2ccc(C3(c4ccc([C@@H](CCC)c5... \n",
"2 388772 *Oc1ccc(S(=O)(=O)c2ccc(Oc3ccc(C4(c5ccc(Oc6ccc(... \n",
"3 519416 *Nc1ccc(-c2c(-c3ccc(C)cc3)c(-c3ccc(C)cc3)c(N*)... \n",
"4 539187 *Oc1ccc(OC(=O)c2cc(OCCCCCCCCCOCC3CCCN3c3ccc([N... \n",
"... ... ... \n",
"7968 2146592435 *Oc1cc(CCCCCCCC)cc(OC(=O)c2cccc(C(*)=O)c2)c1 \n",
"7969 2146810552 *C(=O)OCCN(CCOC(=O)c1ccc2c(c1)C(=O)N(c1cccc(N3... \n",
"7970 2147191531 *c1cc(C(=O)NCCCCCCCC)cc(N2C(=O)c3ccc(-c4ccc5c(... \n",
"7971 2147435020 *C=C(*)c1ccccc1C \n",
"7972 2147438299 *c1ccc(OCCCCCCCCCCCOC(=O)CCCCC(=O)OCCCCCCCCCCC... \n",
"\n",
" Tg FFV Tc Density Rg \\\n",
"0 NaN 0.374645 0.205667 NaN NaN \n",
"1 NaN 0.370410 NaN NaN NaN \n",
"2 NaN 0.378860 NaN NaN NaN \n",
"3 NaN 0.387324 NaN NaN NaN \n",
"4 NaN 0.355470 NaN NaN NaN \n",
"... ... ... ... ... .. \n",
"7968 NaN 0.367498 NaN NaN NaN \n",
"7969 NaN 0.353280 NaN NaN NaN \n",
"7970 NaN 0.369411 NaN NaN NaN \n",
"7971 261.662355 NaN NaN NaN NaN \n",
"7972 NaN 0.374049 NaN NaN NaN \n",
"\n",
" Smiles mol_weight \\\n",
"0 *CC(*)c1ccccc1C(=O)OCCCCCC -0.875755 \n",
"1 *Nc1ccc([C@H](CCC)c2ccc(C3(c4ccc([C@@H](CCC)c5... 0.651876 \n",
"2 *Oc1ccc(S(=O)(=O)c2ccc(Oc3ccc(C4(c5ccc(Oc6ccc(... 2.336573 \n",
"3 *Nc1ccc(-c2c(-c3ccc(C)cc3)c(-c3ccc(C)cc3)c(N*)... 0.417716 \n",
"4 *Oc1ccc(OC(=O)c2cc(OCCCCCCCCCOCC3CCCN3c3ccc([N... 2.178003 \n",
"... ... ... \n",
"7968 *Oc1cc(CCCCCCCC)cc(OC(=O)c2cccc(C(*)=O)c2)c1 -0.375261 \n",
"7969 *C(=O)OCCN(CCOC(=O)c1ccc2c(c1)C(=O)N(c1cccc(N3... 1.284275 \n",
"7970 *c1cc(C(=O)NCCCCCCCC)cc(N2C(=O)c3ccc(-c4ccc5c(... 0.329570 \n",
"7971 *C=C(*)c1ccccc1C -1.359802 \n",
"7972 *c1ccc(OCCCCCCCCCCCOC(=O)CCCCC(=O)OCCCCCCCCCCC... 1.160667 \n",
"\n",
" exact_mol_weight ... num_3_rings num_4_rings num_5_rings \\\n",
"0 -0.875617 ... -0.048476 -0.069289 -0.626991 \n",
"1 0.651916 ... -0.048476 -0.069289 -0.626991 \n",
"2 2.336165 ... -0.048476 -0.069289 -0.626991 \n",
"3 0.417722 ... -0.048476 -0.069289 -0.626991 \n",
"4 2.178499 ... -0.048476 -0.069289 1.501149 \n",
"... ... ... ... ... ... \n",
"7968 -0.375084 ... -0.048476 -0.069289 -0.626991 \n",
"7969 1.284737 ... -0.048476 -0.069289 1.501149 \n",
"7970 0.329823 ... -0.048476 -0.069289 1.501149 \n",
"7971 -1.359728 ... -0.048476 -0.069289 -0.626991 \n",
"7972 1.160653 ... -0.048476 -0.069289 0.437079 \n",
"\n",
" num_6_rings num_7_rings num_large_rings has_polymer_notation \\\n",
"0 -0.788904 -0.051542 -0.047917 0.0 \n",
"1 0.736852 -0.051542 -0.047917 0.0 \n",
"2 2.644047 -0.051542 -0.047917 0.0 \n",
"3 1.118291 -0.051542 -0.047917 0.0 \n",
"4 0.355413 -0.051542 -0.047917 0.0 \n",
"... ... ... ... ... \n",
"7968 -0.407465 -0.051542 -0.047917 0.0 \n",
"7969 0.736852 -0.051542 -0.047917 0.0 \n",
"7970 -0.026026 -0.051542 -0.047917 0.0 \n",
"7971 -0.788904 -0.051542 -0.047917 0.0 \n",
"7972 -0.407465 -0.051542 -0.047917 0.0 \n",
"\n",
" smiles_length branch_count branch_ratio \n",
"0 26 -0.985221 -0.813832 \n",
"1 82 0.336345 -0.286141 \n",
"2 134 1.657910 -0.109289 \n",
"3 79 0.556606 0.132247 \n",
"4 118 0.556606 -0.830501 \n",
"... ... ... ... \n",
"7968 44 -0.324438 0.124891 \n",
"7969 110 1.217388 0.008668 \n",
"7970 73 0.336345 0.021405 \n",
"7971 16 -1.205481 -1.182617 \n",
"7972 72 -0.324438 -1.005054 \n",
"\n",
"[7973 rows x 92 columns]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"features_df = pd.read_csv('7k_w_descriptors.csv')\n",
"features_df"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "49998b8a-3925-4383-917a-116f70187d46",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n"
]
}
],
"source": [
"old_len = len(features_df)\n",
"new_len = len(features_df.drop_duplicates())\n",
"print(new_len - old_len)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "c2f08ca9-21f6-4a79-ab94-80556b8dab1d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|βββββββββββββββββββββββββββββββββββββ| 6378/6378 [00:01<00:00, 3492.45it/s]\n",
"100%|βββββββββββββββββββββββββββββββββββββ| 1595/1595 [00:00<00:00, 3576.37it/s]\n"
]
}
],
"source": [
"import torch\n",
"from tqdm import tqdm\n",
"import copy\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"def create_splits(df):\n",
" train, test = train_test_split(df, test_size=0.2)\n",
" return train, test\n",
"\n",
"def create_samples(df, features):\n",
" samples = []\n",
" features_without_smiles = copy.deepcopy(features)\n",
" features_without_smiles.remove('Smiles')\n",
" for i, row in tqdm(df.iterrows(), total=len(df)):\n",
" properties = torch.Tensor(row[features_without_smiles].to_list())\n",
" sample = {'Smiles': row['Smiles'], 'property_tensor': properties}\n",
" samples.append(sample)\n",
" return samples\n",
"\n",
"train, val = create_splits(features_df.reset_index(drop=True))\n",
"\n",
"train = train.reset_index(drop=True)\n",
"val = val.reset_index(drop=True)\n",
"\n",
"train_list = create_samples(train, new_features)\n",
"val_list = create_samples(val, new_features)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "2fdb3171-deda-4c1f-ae4b-853d781ffdd5",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|βββββββββββββββββββββββββββββββββββββββ| 20/20 [00:00<00:00, 106050.67it/s]\n"
]
}
],
"source": [
"from sklearn.metrics.pairwise import cosine_similarity\n",
"\n",
"prop_vectors = [el['property_tensor'] for el in train_list[:20]]\n",
"\n",
"sim_matrix = cosine_similarity(prop_vectors)\n",
" \n",
"n = len(prop_vectors)\n",
"positive_pairs, negative_candidates = [], []\n",
"sims = []\n",
"\n",
"positive_threshold = 0.9\n",
"negative_threshold = 0.2\n",
"\n",
"for i in tqdm(range(n)):\n",
" for j in range(i + 1, n):\n",
" sim = sim_matrix[i, j]\n",
"\n",
" if sim > positive_threshold:\n",
" positive_pairs.append((i, j, sim))\n",
" elif sim < negative_threshold:\n",
" negative_candidates.append((i, j, sim))\n",
" sims.append(float(sim))\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "54f29e98-7c32-441c-bb1b-cdaf3fd1df49",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(3, 126)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(positive_pairs), len(negative_candidates)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "22e0f46e-2673-4840-95fd-f98914e57b78",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f8e7e795220>]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs/XucZFdZLo4/e1dVV3fPTM8lc8skE3IBE2JuGEgIooCMJBCVfPVoomAkPwxHNHg0Hi7xcDOoEUVEMBpBwuUIwlEBBTUQIwGBXCAhQCAJJCSZJHO/9vStui7798eud613vXutvdeue3fv5/OZT/dUV+1atWvvtd71vM/7vEEURREKFChQoECBAgWWEcJhD6BAgQIFChQoUKDXKAKcAgUKFChQoMCyQxHgFChQoECBAgWWHYoAp0CBAgUKFCiw7FAEOAUKFChQoECBZYciwClQoECBAgUKLDsUAU6BAgUKFChQYNmhCHAKFChQoECBAssO5WEPYBhotVrYtWsX1qxZgyAIhj2cAgUKFChQoIAHoijCsWPHsG3bNoRhOkezIgOcXbt2Yfv27cMeRoECBQoUKFCgAzzxxBM48cQTU5+zIgOcNWvWAIhP0NTU1JBHU6BAgQIFChTwwfT0NLZv367W8TSsyACH0lJTU1NFgFOgQIECBQosMfjISwqRcYECBQoUKFBg2aEIcAoUKFCgQIECyw5FgFOgQIECBQoUWHYoApwCBQoUKFCgwLJDEeAUKFCgQIECBZYdigCnQIECBQoUKLDsUAQ4BQoUKFCgQIFlh74GOF/+8pfxsz/7s9i2bRuCIMBnPvOZzNfcfvvt+LEf+zFUq1U8/elPx4c//OHEc2688UacfPLJGB8fx4UXXoi7776794MvUKBAgQIFCixZ9DXAmZ2dxbnnnosbb7zR6/mPPvooLr30UrzoRS/Cfffdh9/5nd/Br//6r+Pzn/+8es4nP/lJXHvttXjb296Ge++9F+eeey4uvvhi7Nu3r18fo0CBAgUKFCiwxBBEURQN5I2CAJ/+9Kdx2WWXOZ/zxje+Ef/2b/+G+++/Xz12xRVX4MiRI7jlllsAABdeeCGe85zn4K/+6q8AxI0zt2/fjte97nV405ve5DWW6elprF27FkePHi2cjAsUKFCgQIElgjzr90hpcO644w7s2LHDeOziiy/GHXfcAQBYXFzEPffcYzwnDEPs2LFDPceGWq2G6elp41+BAgUKFChQYPlipAKcPXv2YMuWLcZjW7ZswfT0NObn53HgwAE0m03rc/bs2eM87g033IC1a9eqf0Un8QIFChQoUGB5Y6QCnH7huuuuw9GjR9W/J554YthDKlCgQIECBbrC4wdn8bdfegSztcawhzKSGKlu4lu3bsXevXuNx/bu3YupqSlMTEygVCqhVCpZn7N161bncavVKqrVal/GXKBAgQIFCgwD7/uvh/FP9zyJ9ZNj+KXnFJkJiZFicC666CLcdtttxmO33norLrroIgDA2NgYzj//fOM5rVYLt912m3pOgQIFChQosBIwPV8HABxt/yxgoq8BzszMDO677z7cd999AOIy8Pvuuw87d+4EEKeOrrzySvX83/iN38APf/hDvOENb8CDDz6Iv/7rv8b/+3//D7/7u7+rnnPttdfiAx/4AD7ykY/ggQcewGtf+1rMzs7iqquu6udHKVCgQIECBUYKjVZcBL3YbA15JKOJvqaovvGNb+BFL3qR+v+1114LAPi1X/s1fPjDH8bu3btVsAMAp5xyCv7t3/4Nv/u7v4u//Mu/xIknnoi/+7u/w8UXX6yec/nll2P//v1461vfij179uC8887DLbfckhAeFyhQoECBAssZ9XZgU2sUAY4NA/PBGSUUPjgFChQoUGCp44r334E7f3gIv/GC0/Cml54x7OEMBEvWB6dAgQIFChRYLphbbODfv7MbM32qcmo02ymqgsGxoghwChQoUKBAgT7gY3fuxG9+7F7c/JVH+3L8eluDUy80OFYUAU6BAgUKFCjQBxyYqQEADs0u9uX4jXZgUzA4dhQBToECBQoUKNAHUJVTq09SV5WiKhgcK4oAp0CBAgUKFOgDiGHpV4BTbxUMThqKAKdAgQIFChToAzSD06fjtxmcokzcjiLAKVCgQIECBfoACkD65caiNDhFisqKIsApUKBAgQIF+gDF4PQp/qAqqsVGsz9vsMRRBDgFCljwg73H8J/f25v9xAIFChRwoNHqrwanqKJKRxHgFChgwev+4Zv49Y9+AzsPzg17KAUKFFiiGJQGp95ccQ0JvFAEOAUKWEC+FYfn+uNfUaBAgeUPYlj6pcFZLBicVBQBToECFjT77F9RoECB5Y9+zyNFN/F0FAFOgQIW1JV/xZAHUqBAgSULSh31Yx6J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qKgo5OTk4PDhw9I2t9uNw4cPIzc3V8OS+YcQAqtWrcKBAwdw5MgRZGdn9/uaqqoqAEBmZmaASxdYra2tuHDhAjIzM5GTkwOLxaJo5+rqaly6dCns23nv3r1IS0vDI4880ud+emlXAMjOzkZGRoaiPZubm1FRUSG1Z25uLhobG1FZWSntc+TIEbjdbinYCxee4ObcuXM4dOgQhg8f3u9rqqqqYDQafW7lhKNvv/0WV69elf529dS2crt370ZOTg6mTp3a7756al9VWmc568Xbb78trFar2Ldvn/j666/FihUrhM1mE06nU+uiDdnKlStFUlKSOHbsmKirq5MebW1tQgghzp8/LzZt2iQ+//xzUVNTI95//30xZswY8cADD2hc8sFbt26dOHbsmKipqRH/+Mc/RH5+vkhJSRFXrlwRQgjx7LPPipEjR4ojR46Izz//XOTm5orc3FyNSz003d3dYuTIkaK4uFixXQ/t2tLSIk6fPi1Onz4tAIjt27eL06dPSyOHtmzZImw2m3j//ffFF198IebNmyeys7PF9evXpfcoKCgQ06ZNExUVFeLjjz8W48ePFwsXLtSqSjfVV107OzvF3LlzRVZWlqiqqlIcxx0dHUIIIT755BPxyiuviKqqKnHhwgXx+uuvi9TUVLFo0SKNa6aur/q2tLSI9evXi/LyclFTUyMOHTok7rnnHjF+/HjR3t4uvUe4tK0Q/f8tCyFEU1OTiI2NFa+99prP68Otff2BAY4fvfrqq2LkyJEiKipKzJgxQ3z66adaF8kvAKg+9u7dK4QQ4tKlS+KBBx4QycnJwmq1inHjxomf/vSnoqmpSduC34Knn35aZGZmiqioKHHbbbeJp59+Wpw/f156/vr16+K5554Tw4YNE7GxseLxxx8XdXV1GpZ46P76178KAKK6ulqxXQ/tevToUdW/3cWLFwsheoaKl5SUiPT0dGG1WkVeXp7P53D16lWxcOFCER8fLxITE8XSpUtFS0uLBrXpW191rampuelxfPToUSGEEJWVlcLhcIikpCQRHR0tJk2aJDZv3qwICEJJX/Vta2sTs2bNEqmpqcJisYhRo0aJ5cuX+1xwhkvbCtH/37IQQvz2t78VMTExorGx0ef14da+/mAQQoiAdhERERERBRlzcIoc+iwAAABZSURBVIiIiEh3GOAQERGR7jDAISIiIt1hgENERES6wwCHiIiIdIcBDhEREekOAxwiIiLSHQY4REREpDsMcIiIiEh3GOAQERGR7jDAISIiIt1hgENERES68/+8pnSB5k4hHAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from matplotlib import pyplot as plt\n",
"\n",
"plt.plot(sims)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "79e7e873-7950-4123-ab13-299360ae19ca",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import torch\n",
"from torch.utils.data import Dataset, DataLoader\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"from transformers import BertConfig, BertModel, AutoTokenizer\n",
"import pickle\n",
"import numpy as np\n",
"from sklearn.metrics.pairwise import cosine_similarity\n",
"\n",
"def global_ap(x):\n",
" return torch.mean(x.view(x.size(0), x.size(1), -1), dim=1)\n",
"\n",
"class SimSonEncoder(nn.Module):\n",
" def __init__(self, config: BertConfig, max_len: int, dropout: float = 0.1):\n",
" super(SimSonEncoder, self).__init__()\n",
" self.config = config\n",
" self.max_len = max_len\n",
" \n",
" self.bert = BertModel(config, add_pooling_layer=False)\n",
" \n",
" self.linear = nn.Linear(config.hidden_size, max_len)\n",
" self.dropout = nn.Dropout(dropout)\n",
" \n",
" def forward(self, input_ids, attention_mask=None):\n",
" if attention_mask is None:\n",
" attention_mask = input_ids.ne(0)\n",
" \n",
" outputs = self.bert(\n",
" input_ids=input_ids,\n",
" attention_mask=attention_mask\n",
" )\n",
" \n",
" hidden_states = outputs.last_hidden_state\n",
" \n",
" hidden_states = self.dropout(hidden_states)\n",
" \n",
" pooled = global_ap(hidden_states)\n",
" \n",
" out = self.linear(pooled)\n",
" \n",
" return out\n",
"\n",
"def initialize_model_and_tokenizer():\n",
" \"\"\"Initialize BERT model from config and ChemBERTa tokenizer\"\"\"\n",
" \n",
" \n",
" tokenizer = AutoTokenizer.from_pretrained(\"DeepChem/ChemBERTa-77M-MTR\")\n",
" config = BertConfig(\n",
" vocab_size=tokenizer.vocab_size,\n",
" hidden_size=768,\n",
" num_hidden_layers=4,\n",
" num_attention_heads=12,\n",
" intermediate_size=2048,\n",
" max_position_embeddings=512,\n",
" )\n",
" model = SimSonEncoder(config=config, max_len=512).cuda()\n",
" return model, tokenizer\n"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "8a3adaff-da65-46b4-b9ee-95851d786a67",
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"\n",
"class MolecularContrastiveDataset(Dataset):\n",
" def __init__(self, data_list, tokenizer, positive_threshold=0.9, cache_path=None, split_type='train'):\n",
" \"\"\"\n",
" Dataset that only contains positive pairs for NT-Xent contrastive learning\n",
" \"\"\"\n",
" self.data_list = data_list\n",
" self.tokenizer = tokenizer\n",
" self.positive_threshold = positive_threshold\n",
" self.cache_path = cache_path\n",
" self.split_type = split_type\n",
"\n",
" # Load or compute pairs\n",
" if cache_path and os.path.exists(cache_path) and os.path.getsize(cache_path) > 0:\n",
" print(f\"Loading cached pairs from {cache_path}\")\n",
" self._load_pairs()\n",
" else:\n",
" print(\"Computing positive pairs only...\")\n",
" self._compute_positive_pairs()\n",
" if cache_path:\n",
" self._save_pairs()\n",
" \n",
" def _compute_positive_pairs(self):\n",
" \"\"\"\n",
" Compute ONLY positive pairs based on descriptor similarity\n",
" \"\"\"\n",
" # --- 1. Cosine-similarity matrix ---------------------------------------\n",
" prop_vectors = torch.stack(\n",
" [item['property_tensor'] for item in self.data_list]\n",
" ).numpy()\n",
" sim_matrix = cosine_similarity(prop_vectors)\n",
"\n",
" n = len(self.data_list)\n",
" positive_pairs = []\n",
" pairs_per_molecule = 1 # STRICTLY ONE FOR CREATING PROPER NEGATIVE PAIRS\n",
" current_pairs_per_molecule = 0\n",
" # --- 2. Collect only positive pairs ------------------------------------\n",
" print(f'Collecting positive pairs with similarity threshold {self.positive_threshold}')\n",
" for i in tqdm(range(n)):\n",
" for j in range(i + 1, n):\n",
" sim = sim_matrix[i, j]\n",
" if sim > self.positive_threshold:\n",
" positive_pairs.append((i, j, sim))\n",
" current_pairs_per_molecule += 1\n",
" if current_pairs_per_molecule > pairs_per_molecule:\n",
" current_pairs_per_molecule = 0\n",
" break\n",
"\n",
" # --- 3. Store only positive pairs --------------------------------------\n",
" if len(positive_pairs) == 0:\n",
" raise ValueError(\"No positive pairs found β lower the positive_threshold.\")\n",
"\n",
" # No shuffling - we want consistent positive pairs\n",
" self.pairs = [(i, j) for i, j, _ in positive_pairs]\n",
" self.descriptor_similarities = [sim for _, _, sim in positive_pairs]\n",
"\n",
" print(f\"Generated {len(self.pairs)} positive pairs\")\n",
"\n",
" def _save_pairs(self):\n",
" \"\"\"Save computed pairs to cache file\"\"\"\n",
" cache_data = {\n",
" 'pairs': self.pairs,\n",
" 'descriptor_similarities': self.descriptor_similarities\n",
" }\n",
" with open(self.cache_path, 'wb') as f:\n",
" pickle.dump(cache_data, f)\n",
" print(f\"Cached pairs saved to {self.cache_path}\")\n",
" \n",
" def _load_pairs(self):\n",
" \"\"\"Load pairs from cache file\"\"\"\n",
" with open(self.cache_path, 'rb') as f:\n",
" cache_data = pickle.load(f)\n",
" \n",
" self.pairs = cache_data['pairs']\n",
" self.descriptor_similarities = cache_data['descriptor_similarities']\n",
" \n",
" def __len__(self):\n",
" return len(self.pairs)\n",
" \n",
" def __getitem__(self, idx):\n",
" i, j = self.pairs[idx]\n",
" desc_sim = self.descriptor_similarities[idx]\n",
" \n",
" # Get SMILES for both molecules\n",
" smiles_i = self.data_list[i]['Smiles']\n",
" smiles_j = self.data_list[j]['Smiles']\n",
" if self.split_type == 'val':\n",
" print(f'POSITIVE PAIR SMILES: \\n{smiles_i} \\n {smiles_j}')\n",
" # Tokenize SMILES\n",
" tokens_i = self.tokenizer(\n",
" smiles_i, \n",
" return_tensors='pt', \n",
" padding='max_length', \n",
" truncation=True, \n",
" max_length=256\n",
" )\n",
" tokens_j = self.tokenizer(\n",
" smiles_j, \n",
" return_tensors='pt', \n",
" padding='max_length', \n",
" truncation=True, \n",
" max_length=256\n",
" )\n",
" \n",
" # Remove batch dimension\n",
" tokens_i = {key: val.squeeze(0) for key, val in tokens_i.items()}\n",
" tokens_j = {key: val.squeeze(0) for key, val in tokens_j.items()}\n",
" \n",
" # Get property vectors\n",
" prop_vec_i = self.data_list[i]['property_tensor']\n",
" prop_vec_j = self.data_list[j]['property_tensor']\n",
" \n",
" return {\n",
" 'tokens_i': tokens_i,\n",
" 'tokens_j': tokens_j,\n",
" 'descriptor_similarity': torch.tensor(desc_sim, dtype=torch.float32),\n",
" 'property_tensor_i': prop_vec_i,\n",
" 'property_tensor_j': prop_vec_j\n",
" }\n",
"\n",
"\n",
"def contrastive_collate_fn(batch):\n",
" \"\"\"\n",
" Collate function that creates proper NT-Xent batches:\n",
" - Element 0 and 1 are positive pairs\n",
" - Element 2 and 3 are positive pairs \n",
" - etc.\n",
" \"\"\"\n",
" batch_size = len(batch)\n",
" \n",
" # Ensure even batch size for proper pairing\n",
" if batch_size % 2 != 0:\n",
" batch = batch[:-1] # Drop last element if odd\n",
" batch_size = len(batch)\n",
" \n",
" # Interleave: [sample1_i, sample1_j, sample2_i, sample2_j, ...]\n",
" tokens_list = []\n",
" desc_similarities = []\n",
" \n",
" for i in range(0, batch_size, 1):\n",
" # Add first molecule of pair i\n",
" tokens_list.append(batch[i]['tokens_i'])\n",
" desc_similarities.append(batch[i]['descriptor_similarity'])\n",
" \n",
" # Add second molecule of pair i (positive pair)\n",
" tokens_list.append(batch[i]['tokens_j'])\n",
" desc_similarities.append(batch[i]['descriptor_similarity']) # Same similarity for both elements in pair\n",
" \n",
" # Stack all tokens\n",
" tokens = {}\n",
" for key in tokens_list[0].keys():\n",
" tokens[key] = torch.stack([item[key] for item in tokens_list])\n",
" \n",
" desc_similarities_tensor = torch.stack(desc_similarities)\n",
" \n",
" return {\n",
" 'tokens': tokens,\n",
" 'descriptor_similarities': desc_similarities_tensor,\n",
" }\n",
"\n",
"\n",
"def create_dataloaders(train_list, val_list, tokenizer, batch_size=32, \n",
" positive_threshold=0.85, cache_dir=\"cache\"):\n",
" \"\"\"Create train and validation dataloaders for NT-Xent\"\"\"\n",
" os.makedirs(cache_dir, exist_ok=True)\n",
" \n",
" # Ensure even batch size for proper pairing\n",
" if batch_size % 2 != 0:\n",
" batch_size += 1\n",
" print(f\"Adjusted batch_size to {batch_size} (must be even for NT-Xent)\")\n",
" \n",
" train_cache = os.path.join(cache_dir, 'train_positive_pairs.pkl')\n",
" val_cache = os.path.join(cache_dir, 'val_positive_pairs.pkl')\n",
" \n",
" train_dataset = MolecularContrastiveDataset(\n",
" train_list, tokenizer, positive_threshold=positive_threshold, cache_path=train_cache\n",
" )\n",
" val_dataset = MolecularContrastiveDataset(\n",
" val_list, tokenizer, positive_threshold=positive_threshold, cache_path=val_cache, split_type='val',\n",
" )\n",
" \n",
" train_loader = DataLoader(\n",
" train_dataset, batch_size=batch_size, shuffle=True, collate_fn=contrastive_collate_fn, drop_last=True, pin_memory=True\n",
" )\n",
" val_loader = DataLoader(\n",
" val_dataset, batch_size=batch_size, shuffle=False, collate_fn=contrastive_collate_fn, drop_last=True, pin_memory=True\n",
" )\n",
" \n",
" return train_loader, val_loader\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "f956a50b-85a5-49df-b7c6-6e40dce160e1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model initialized with 23,299,840 trainable parameters\n"
]
}
],
"source": [
"def nt_xent_loss_with_temp_scaling(embeddings1, embeddings2, descriptor_similarity, base_temp=0.02):\n",
" batch_size = embeddings1.shape[0]\n",
" device = embeddings1.device\n",
" #individual_temperatures = sigmoid_temp_scaling(descriptor_similarity, base_temp)\n",
" #temperature = individual_temperatures.mean() # Single temperature for the whole batch\n",
" temperature = base_temp\n",
" # Normalize projections\n",
" z_i = F.normalize(embeddings1, p=2, dim=1)\n",
" z_j = F.normalize(embeddings2, p=2, dim=1)\n",
" \n",
" # Concatenate for similarity matrix calculation\n",
" representations = torch.cat([z_i, z_j], dim=0)\n",
" # Calculate cosine similarity between all pairs\n",
" similarity_matrix = F.cosine_similarity(representations.unsqueeze(1), representations.unsqueeze(0), dim=2)\n",
" #similarity_matrix = torch.clamp(similarity_matrix, min=-0.999, max=0.999)\n",
" sim_ij = torch.diag(similarity_matrix, batch_size)\n",
" sim_ji = torch.diag(similarity_matrix, -batch_size)\n",
" positives = torch.cat([sim_ij, sim_ji], dim=0)\n",
" \n",
" # Create a mask to exclude self-comparisons\n",
" nominator = torch.exp(positives / temperature)\n",
" mask = (~torch.eye(batch_size * 2, batch_size * 2, dtype=torch.bool, device=device)).float()\n",
" denominator = mask * torch.exp(similarity_matrix / temperature)\n",
" \n",
" # Calculate the final loss\n",
" loss = -torch.log(nominator / torch.sum(denominator, dim=1))\n",
" if torch.isnan(loss).any():\n",
" print(similarity_matrix)\n",
" print(f\"Temperature: {temperature}\")\n",
" print(f\"Nominator range: {nominator.min().item():.6f} to {nominator.max().item():.6f}\")\n",
" \n",
" return torch.sum(loss) / (2 * batch_size)\n",
"\n",
"\n",
"def sigmoid_temp_scaling(descriptor_similarity, base_temp=0.05, steepness=10.0, midpoint=0.5):\n",
" \"\"\"Smooth sigmoid-based temperature scaling\"\"\"\n",
" sigmoid_factor = torch.sigmoid(steepness * (descriptor_similarity - midpoint))\n",
" temperature = base_temp * (2.0 - sigmoid_factor)\n",
" return temperature\n",
"\n",
"\n",
"def train_step(batch, model, optimizer, device, scheduler, base_temp=0.1):\n",
" \"\"\"Single training step for NT-Xent\"\"\"\n",
" model.train()\n",
" optimizer.zero_grad()\n",
" \n",
" # Move batch to device\n",
" tokens = {k: v.to(device) for k, v in batch['tokens'].items()}\n",
" desc_similarities = batch['descriptor_similarities'].to(device)\n",
" \n",
" # Forward pass - get embeddings for all samples\n",
" outputs = model(**tokens) # i1, j1, i2, j2 ...\n",
" embeddings = outputs\n",
" \n",
" # Split embeddings: even indices are embeddings1, odd indices are embeddings2\n",
" embeddings1 = embeddings[::2] # [0, 2, 4, ...]\n",
" embeddings2 = embeddings[1::2] # [1, 3, 5, ...]\n",
" \n",
" # Get descriptor similarities for each pair (take every other one since they're duplicated)\n",
" pair_desc_similarities = desc_similarities[::2]\n",
" #print(f'FIRST TRAIN EMBED: {embeddings1}')\n",
" #print(f'SECOND TRAIN EMBED: {embeddings2}')\n",
" #print(f'COSINE SIM BETWEEN THEM TRAIN: {F.cosine_similarity(embeddings1, embeddings2, dim=1)}')\n",
" # Calculate NT-Xent loss\n",
" loss = nt_xent_loss_with_temp_scaling(embeddings1, embeddings2, pair_desc_similarities, base_temp=base_temp)\n",
" \n",
" # Backward pass\n",
" loss.backward()\n",
" optimizer.step()\n",
" torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)\n",
" scheduler.step()\n",
" return loss.item()\n",
"\n",
"def val_step(batch, model, device, base_temp=0.1):\n",
" \"\"\"Single validation step for NT-Xent\"\"\"\n",
" model.eval()\n",
" with torch.no_grad():\n",
" # Move batch to device\n",
" tokens = {k: v.to(device) for k, v in batch['tokens'].items()}\n",
" desc_similarities = batch['descriptor_similarities'].to(device)\n",
" \n",
" # Forward pass\n",
" outputs = model(**tokens)\n",
" embeddings = outputs\n",
" \n",
" # Split embeddings\n",
" embeddings1 = embeddings[::2]\n",
" embeddings2 = embeddings[1::2]\n",
" \n",
" # Get descriptor similarities for pairs\n",
" pair_desc_similarities = desc_similarities[::2]\n",
" \n",
" print(f'FIRST VAL EMBED: {embeddings1}')\n",
" print(f'SECOND VAL EMBED: {embeddings2}')\n",
" print(f'COSINE SIM BETWEEN THEM: {F.cosine_similarity(embeddings1, embeddings2, dim=1)}')\n",
" #print(f'SECOND VAL EMBED: {embeddings2}')\n",
" loss = nt_xent_loss_with_temp_scaling(embeddings1, embeddings2, pair_desc_similarities, base_temp=base_temp)\n",
" print(f'VAL LOSS: {loss}')\n",
" \n",
" return loss.item()\n",
"\n",
"def train_epoch(train_loader, model, optimizer, scheduler, base_temp=0.01):\n",
" \"\"\"Train for one epoch\"\"\"\n",
" total_loss = 0\n",
" num_batches = 0\n",
" \n",
" progress_bar = tqdm(train_loader, desc=\"Training\")\n",
" \n",
" for batch in progress_bar:\n",
" loss = train_step(batch, model, optimizer, 'cuda', scheduler, base_temp=base_temp)\n",
" total_loss += loss\n",
" num_batches += 1\n",
" \n",
" # Calculate running average loss\n",
" avg_loss = total_loss / num_batches\n",
" \n",
" # Update progress bar with current loss info\n",
" progress_bar.set_postfix({\n",
" 'Loss': f'{loss:.4f}',\n",
" 'Avg Loss': f'{avg_loss:.4f}'\n",
" })\n",
" \n",
" return total_loss / num_batches if num_batches > 0 else 0\n",
"\n",
"\n",
"def validate_epoch(val_loader, model, base_temp=0.01):\n",
" \"\"\"Validate for one epoch\"\"\"\n",
" total_loss = 0\n",
" num_batches = 0\n",
" print('nah twin')\n",
" return 0\n",
" for batch in val_loader:\n",
" loss = val_step(batch, model, 'cuda', base_temp=base_temp)\n",
" total_loss += loss\n",
" num_batches += 1\n",
" \n",
" return total_loss / num_batches if num_batches > 0 else 0\n",
"\n",
"def training_loop(train_loader, val_loader, model, tokenizer, epochs=50, patience=5, lr=1e-4, base_temp=0.02,\n",
" device_name='cuda', save_path='best_model.pt'):\n",
" \"\"\"Main training loop with early stopping\"\"\"\n",
" device = torch.device(device_name if torch.cuda.is_available() else 'cpu')\n",
" print(f\"Using device: {device}\")\n",
" \n",
" # Initialize model and optimizer\n",
" optimizer = torch.optim.Adam(model.parameters(), lr=lr)\n",
" optimizer.zero_grad()\n",
"\n",
" total_steps = epochs * len(train_loader)\n",
" scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_mult=1, T_0=total_steps)\n",
" # Early stopping variables\n",
" best_val_loss = float('inf')\n",
" no_improve_epochs = 0\n",
" \n",
" print(\"Starting training...\")\n",
" \n",
" for epoch in range(epochs):\n",
" # Training\n",
" with torch.autocast(dtype=torch.float16, device_type='cuda'):\n",
" train_loss = train_epoch(train_loader, model, optimizer, scheduler, base_temp=base_temp)\n",
" print('END TRAIN')\n",
" # Validation\n",
" val_loss = validate_epoch(val_loader, model)\n",
" \n",
" print(f\"Epoch {epoch + 1}/{epochs}: Train Loss = {train_loss:.4f}, Val Loss = {val_loss:.4f}\")\n",
" \n",
" # Early stopping check\n",
" if val_loss < best_val_loss:\n",
" best_val_loss = val_loss\n",
" no_improve_epochs = 0\n",
" # Save best model\n",
" torch.save(model.state_dict(), save_path)\n",
" print(f\"New best model saved with val loss: {val_loss:.4f}\")\n",
" else:\n",
" no_improve_epochs += 1\n",
" print(f\"No improvement for {no_improve_epochs} epochs\")\n",
" \n",
" if no_improve_epochs >= patience:\n",
" print(f\"Early stopping triggered after {epoch + 1} epochs\")\n",
" break\n",
" \n",
" # Load best model\n",
" print(f\"Loading best model from {save_path}\")\n",
" model.load_state_dict(torch.load(save_path))\n",
" model.eval()\n",
" \n",
" print(f\"Training completed. Best validation loss: {best_val_loss:.4f}\")\n",
"\n",
"\n",
"model, tokenizer = initialize_model_and_tokenizer()\n",
"#model.load_state_dict(torch.load('/home/jovyan/simson_training_bolgov/regression/actual_encoder_state.pkl', weights_only=False))\n",
"print(f\"Model initialized with {sum(p.numel() for p in model.parameters() if p.requires_grad):,} trainable parameters\")\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c73e2bba-59c1-4b41-b2ff-235526dd2912",
"metadata": {},
"outputs": [],
"source": [
"!rm -rf cache"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0072c8f5-c5e9-4590-9544-c73cf1fac1e8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Computing positive pairs only...\n",
"Collecting positive pairs with similarity threshold 0.8\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|ββββββββββββββββββββββββββββββββββββ| 6378/6378 [00:00<00:00, 55896.48it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated 12538 positive pairs\n",
"Cached pairs saved to cache/train_positive_pairs.pkl\n",
"Computing positive pairs only...\n",
"Collecting positive pairs with similarity threshold 0.8\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|βββββββββββββββββββββββββββββββββββββ| 100/100 [00:00<00:00, 206209.64it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Generated 129 positive pairs\n",
"Cached pairs saved to cache/val_positive_pairs.pkl\n",
"Using device: cuda\n",
"Starting training...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Training: 100%|β| 1567/1567 [00:31<00:00, 49.37it/s, Loss=0.9300, Avg Loss=0.989\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"END TRAIN\n",
"nah twin\n",
"Epoch 1/10: Train Loss = 0.9891, Val Loss = 0.0000\n",
"New best model saved with val loss: 0.0000\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Training: 100%|β| 1567/1567 [00:31<00:00, 50.05it/s, Loss=2.7072, Avg Loss=2.712\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"END TRAIN\n",
"nah twin\n",
"Epoch 2/10: Train Loss = 2.7125, Val Loss = 0.0000\n",
"No improvement for 1 epochs\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Training: 77%|β| 1204/1567 [00:24<00:07, 49.73it/s, Loss=2.7080, Avg Loss=2.708"
]
}
],
"source": [
"train_loader, val_loader = create_dataloaders(\n",
" train_list, val_list[:100], tokenizer, \n",
" batch_size=128, positive_threshold=0.8\n",
")\n",
"\n",
"training_loop(\n",
" train_loader, val_loader, model, tokenizer,\n",
" epochs=10, patience=5, lr=1e-3, \n",
" device_name='cuda', base_temp=0.1\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "58343b16-1bdb-4476-ac61-e797fbc661d2",
"metadata": {},
"outputs": [],
"source": [
"print(train_list[:5], '\\n\\n', val_list[:5])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "47561022-5f57-4b7b-b903-ef1f8773f903",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "5fcef978-3630-4201-9301-6963a8560517",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:.mlspace-bolgov_simson_training]",
"language": "python",
"name": "conda-env-.mlspace-bolgov_simson_training-py"
},
"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.12.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
|