{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Install packages","metadata":{}},{"cell_type":"code","source":"%%capture\n!pip install /kaggle/input/rsna-2022-whl/{pydicom-2.3.0-py3-none-any.whl,pylibjpeg-1.4.0-py3-none-any.whl,python_gdcm-3.0.15-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl}\n!pip install /kaggle/input/nvidia-dali-wheel/dicomsdl-0.109.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-output":true,"_kg_hide-input":true,"execution":{"iopub.status.busy":"2023-10-15T14:31:53.177091Z","iopub.execute_input":"2023-10-15T14:31:53.177586Z","iopub.status.idle":"2023-10-15T14:33:01.090012Z","shell.execute_reply.started":"2023-10-15T14:31:53.177543Z","shell.execute_reply":"2023-10-15T14:33:01.088564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport sys\nimport cv2\nfrom glob import glob\nimport gdcm\nimport dicomsdl\nimport torch\nimport torch.nn.functional as F\nfrom pydicom.filebase import DicomBytesIO\n\nimport json\nimport shutil\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom pathlib import Path\nimport gc\nfrom multiprocessing import Pool\n\nfrom tqdm.notebook import tqdm\nfrom joblib import Parallel, delayed\n\n\nimport warnings\nwarnings.simplefilter('ignore')\nfrom scipy.special import softmax\ndef sigmoid(x):\n    return 1/(1 + np.exp(-x))","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.093124Z","iopub.execute_input":"2023-10-15T14:33:01.093801Z","iopub.status.idle":"2023-10-15T14:33:01.102777Z","shell.execute_reply.started":"2023-10-15T14:33:01.093754Z","shell.execute_reply":"2023-10-15T14:33:01.101825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEBUG = len(glob(\"/kaggle/input/rsna-2023-abdominal-trauma-detection/test_images/*/*/*.dcm\")) == 3","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.104396Z","iopub.execute_input":"2023-10-15T14:33:01.104809Z","iopub.status.idle":"2023-10-15T14:33:01.128426Z","shell.execute_reply.started":"2023-10-15T14:33:01.104775Z","shell.execute_reply":"2023-10-15T14:33:01.127619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# config","metadata":{}},{"cell_type":"code","source":"segmentation_model_paths = [f'/kaggle/input/rsna-3d-unet-image-v3-v1/fold_{fold}.ckpt' for fold in range(5)]\nsegmentation_model_paths += [f'/kaggle/input/rsna-3dseg-resnet50-v2/fold_{fold}.ckpt' for fold in range(5)]\ncrop_image_pad_ratio0 = 30\ncrop_image_pad_z_ratio0 = 25\n\ncrop_image_pad_ratio1 = 8\ncrop_image_pad_z_ratio1 = 8","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.130871Z","iopub.execute_input":"2023-10-15T14:33:01.131755Z","iopub.status.idle":"2023-10-15T14:33:01.137566Z","shell.execute_reply.started":"2023-10-15T14:33:01.131719Z","shell.execute_reply":"2023-10-15T14:33:01.136698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"debug_fold = 1\nif DEBUG:\n    all_folds = [1]\nelse: \n    all_folds = range(4)","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.139142Z","iopub.execute_input":"2023-10-15T14:33:01.139756Z","iopub.status.idle":"2023-10-15T14:33:01.149526Z","shell.execute_reply.started":"2023-10-15T14:33:01.139722Z","shell.execute_reply":"2023-10-15T14:33:01.148535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if DEBUG:\n    image_dir = \"/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/\"\n    good_patient_ids = [10004, 10005, 10007, 10026, 10051, 10065, 10082, 10104, 10105, 10124, 10127, 10132, 10163, 10169, 10172, 10205, 10217, 10228, 10232, 10249, 10275, 1027, 10292, 10295, 10300, 10430, 10443, 10465, 10494, 10503, 10517, 10550, 10556, 10557, 10565, 10569, 1060, 10683, 10696, 10697, 10721, 10722, 10730, 10759, 10762, 10795, 10814, 10852, 10917, 10925, 10929, 10937, 10967, 10981, 10987, 11021, 11030, 11044, 11046, 11130, 11139, 11177, 11217, 11222, 11301, 11312, 11313, 11335, 11361, 11378, 11379, 11433, 11449, 1144, 11452, 11464, 11474, 11479, 11547, 11553, 11578, 11597, 11604, 11633, 11652, 11656, 11664, 11682, 11695, 11699, 11770, 11793, 11828, 11829, 11832, 11834, 11886, 11891, 11908, 11925, 11927, 1192, 11938, 12008, 12011, 12086, 12138, 12162, 12181, 12192, 12198, 12210, 12258, 12268, 12271, 12299, 122, 1230, 12332, 12347, 12354, 12358, 12408, 12416, 12450, 12451, 12485, 12487, 1250, 12510, 12511, 12522, 12528, 12545, 12580, 12600, 12622, 12629, 12646, 12667, 12685, 12698, 12744, 1278, 12862, 12875, 12879, 12890, 12898, 12930, 12951, 12958, 12967, 12976, 12997, 13012, 13036, 13067, 13083, 13098, 13106, 13107, 13120, 1316, 13182, 13231, 13241, 13250, 1330, 13310, 13316, 13326, 13332, 13385, 13403, 13432, 13465, 13496, 13508, 13517, 1352, 13550, 13563, 13571, 13585, 13589, 13604, 13615, 13620, 13623, 13646, 13657, 13695, 13698, 13719, 13728, 13741, 13769, 13794, 13818, 1381, 13847, 13853, 13857, 13921, 13953, 14018, 1403, 14052, 14063, 14065, 14091, 14102, 14135, 14178, 14251, 14281, 14309, 14321, 14343, 14351, 14371, 14385, 14388, 14393, 1440, 14425, 14429, 14452, 14465, 14469, 14517, 14520, 1452, 14543, 14590, 14601, 14616, 1464, 14654, 14676, 14678, 14684, 14709, 14729, 14759, 14780, 14784, 14788, 14790, 14806, 14807, 14817, 14831, 14846, 14870, 14908, 14924, 14950, 14963, 14989, 15006, 15022, 15035, 15040, 15057, 15089, 15090, 15109, 15114, 15117, 15127, 15132, 15141, 15151, 15160, 15185, 15188, 1518, 15226, 1523, 1526, 15335, 15347, 15362, 15385, 15398, 15404, 15415, 15419, 15425, 15463, 1546, 15472, 15480, 15492, 15511, 15529, 15541, 15545, 15611, 1563, 15645, 15697, 156, 15700, 15758, 15773, 15783, 15809, 15822, 15823, 15853, 15876, 15949, 15956, 15968, 15984, 16000, 16006, 16033, 16036, 16059, 16068, 16069, 16080, 16088, 16090, 16100, 16103, 16120, 16123, 16135, 16140, 16195, 16198, 16202, 16229, 16240, 16244, 16255, 16310, 16327, 16335, 16342, 16343, 16368, 16431, 16436, 16439, 1644, 16450, 16477, 16494, 16518, 16588, 16598, 16602, 16618, 16645, 16682, 16691, 16712, 16722, 16727, 1675, 16776, 16800, 16836, 16859, 16914, 16926, 16930, 16935, 16946, 16963, 17002, 17044, 1705, 17128, 17131, 17138, 1713, 17159, 17185, 17190, 17216, 1723, 17252, 17263, 17264, 17265, 17304, 17326, 17341, 17350, 17373, 17381, 17439, 1743, 17485, 17502, 17542, 17569, 17588, 1758, 17590, 17592, 17598, 17599, 17662, 17750, 17774, 17782, 17806, 17826, 17842, 17843, 17847, 17854, 17858, 17872, 17888, 17890, 17897, 17945, 17952, 17959, 17974, 17978, 17990, 18001, 18025, 18028, 18051, 18053, 18080, 18093, 18148, 1814, 18157, 18210, 18240, 1826, 18287, 18301, 18327, 18356, 18362, 18366, 18377, 18384, 18404, 18407, 18408, 18413, 18426, 18517, 18520, 18523, 18524, 18534, 18628, 18639, 18653, 18682, 18697, 18727, 18737, 18762, 18769, 18775, 18779, 187, 18811, 18821, 18863, 18872, 18877, 18905, 18920, 18947, 18948, 18950, 18965, 1900, 19017, 19018, 1902, 19045, 19050, 19054, 19065, 19082, 1908, 19097, 19120, 19139, 19144, 19160, 19169, 19170, 19247, 19249, 19263, 1927, 19314, 19318, 19330, 19344, 1934, 19366, 19384, 1938, 1939, 19410, 19442, 19448, 19461, 19464, 19486, 19543, 1956, 19574, 19577, 19600, 1960, 19647, 19662, 19664, 19679, 19684, 19691, 19713, 19721, 19740, 19742, 19763, 19766, 19785, 1979, 19826, 19828, 19847, 19855, 19857, 19865, 19881, 19913, 19914, 19916, 19930, 19958, 19, 20087, 20118, 20125, 20135, 201, 20207, 20213, 20225, 20297, 2031, 20369, 20385, 20399, 20423, 20426, 2043, 20454, 2050, 205, 20605, 20621, 20641, 2067, 20689, 20705, 20723, 20740, 20788, 20791, 20830, 20869, 20907, 20930, 20951, 2096, 20981, 21050, 21082, 2112, 21141, 21147, 21151, 21172, 21212, 21234, 21253, 21264, 21293, 21308, 21325, 2133, 21402, 21407, 21411, 21420, 21455, 21471, 2147, 21518, 21538, 2161, 21646, 21673, 21696, 21724, 21734, 21739, 21759, 21773, 21776, 21782, 21795, 21821, 21852, 2185, 21866, 2189, 21905, 21946, 21970, 22005, 22009, 2200, 22015, 22049, 22061, 22064, 22099, 2209, 22102, 22103, 22113, 22122, 22132, 22139, 22155, 22175, 22177, 22200, 22210, 22250, 22260, 222, 2230, 22323, 2232, 22372, 22394, 22443, 22455, 22456, 22461, 22502, 2254, 22580, 22595, 22623, 22626, 22639, 22642, 22676, 22726, 22755, 22758, 22760, 22774, 22810, 22845, 2288, 22931, 22938, 22954, 22957, 22961, 22967, 22984, 23029, 23115, 23139, 23170, 23185, 23188, 23198, 23208, 23241, 23275, 23310, 23311, 23332, 23340, 23361, 23367, 23369, 23387, 23415, 23423, 23424, 23433, 23434, 2345, 23500, 23561, 23571, 23583, 23584, 23602, 23707, 23708, 23709, 23737, 23739, 23749, 23777, 23787, 23817, 23829, 2384, 23857, 23885, 23965, 23979, 23991, 23994, 2402, 24031, 24049, 24064, 24102, 24103, 24156, 24221, 24228, 24229, 24272, 24288, 2429, 24306, 24310, 24322, 24329, 2436, 24372, 24375, 2440, 24422, 24427, 24435, 24439, 24448, 24461, 24464, 24476, 24499, 24513, 24524, 24528, 24529, 24538, 24652, 24654, 24701, 24721, 24736, 24753, 2475, 24780, 24787, 24790, 24829, 2482, 24835, 24849, 24867, 24932, 24969, 24972, 24975, 24977, 24984, 25030, 2504, 25064, 25093, 25095, 25099, 25102, 25110, 25121, 25128, 25160, 25173, 25186, 25196, 25211, 25231, 25245, 25279, 25289, 25293, 25294, 25306, 25309, 25316, 25321, 25347, 25353, 25363, 2539, 25404, 25426, 25479, 25489, 2548, 25537, 25550, 25556, 25598, 25647, 25680, 25716, 25726, 2572, 25746, 25760, 25762, 25779, 25780, 25835, 25839, 25840, 25860, 25869, 25894, 25899, 25922, 25924, 25946, 25957, 25978, 25993, 25999, 26009, 2602, 26045, 26053, 26056, 26074, 26080, 26092, 26098, 26099, 26155, 26164, 2621, 26224, 26231, 26239, 26257, 26272, 2627, 2629, 26305, 26323, 26324, 26328, 26354, 26365, 26369, 26385, 263, 26468, 26471, 26473, 26501, 26510, 26562, 26575, 26587, 26598, 26627, 26628, 26633, 26644, 26659, 26668, 26698, 26711, 26727, 2675, 26763, 26778, 26792, 26801, 26802, 26838, 26883, 26885, 26926, 26983, 26993, 26, 27005, 27030, 27037, 27039, 2703, 27093, 27104, 27127, 27143, 2715, 27196, 27231, 27238, 27289, 27291, 27303, 27333, 27392, 273, 27419, 27421, 27428, 27434, 27436, 27522, 27555, 27575, 27597, 27617, 2763, 27648, 27661, 27667, 27699, 27701, 2770, 27715, 27736, 27773, 27781, 27782, 27816, 27884, 27907, 27910, 27922, 27938, 27954, 27963, 27969, 27971, 27991, 28045, 28055, 28095, 28099, 28123, 28127, 28128, 28144, 28157, 28186, 28202, 28211, 28213, 28224, 28284, 28288, 28294, 28297, 28302, 28306, 28321, 28331, 28371, 28381, 28417, 28433, 28467, 28468, 28473, 28485, 28490, 28511, 28544, 28555, 28556, 28569, 28581, 28585, 28595, 28621, 28624, 28672, 28698, 28704, 28724, 28753, 28769, 28786, 28870, 28892, 2891, 28925, 28927, 28944, 28976, 28983, 2898, 28990, 29005, 29037, 29049, 29062, 29072, 2909, 29128, 29168, 29177, 29181, 29224, 29235, 29259, 29319, 29336, 2937, 29385, 29397, 29407, 2940, 29412, 29433, 29443, 29448, 2945, 29483, 29511, 29518, 29529, 29539, 2953, 29541, 29553, 29565, 29603, 29606, 29624, 29637, 29641, 29647, 29657, 29692, 29700, 29706, 29731, 29749, 29758, 2978, 29831, 29858, 2986, 29876, 29881, 29893, 29931, 29978, 29987, 30064, 30078, 3007, 30091, 30137, 30203, 30204, 3021, 30227, 30286, 30327, 30331, 30356, 30365, 30394, 30396, 30405, 30424, 30427, 30436, 30446, 30454, 30487, 30488, 30489, 30497, 30499, 30510, 30514, 30515, 30566, 30604, 30613, 30628, 30683, 30697, 30698, 30706, 30730, 30758, 30791, 30877, 30890, 30891, 30923, 30938, 30954, 30984, 31014, 31033, 31034, 3103, 31051, 31057, 31070, 31087, 310, 31158, 31177, 31220, 31225, 31228, 31242, 31256, 31275, 31276, 31286, 31289, 31293, 31307, 31308, 31339, 31403, 31462, 31474, 31478, 31490, 31508, 31572, 31583, 31586, 3158, 31636, 31645, 31658, 31667, 31694, 31724, 31728, 31735, 31747, 31749, 31767, 31769, 31777, 31781, 31815, 31842, 31845, 31853, 31860, 31896, 31899, 318, 31919, 31927, 3194, 31972, 31985, 31992, 31995, 32001, 32011, 32036, 32072, 32079, 32081, 3210, 32139, 32154, 32195, 32197, 32235, 3223, 32266, 32269, 32270, 32272, 32340, 32347, 32354, 32379, 32393, 32397, 32405, 32425, 32442, 32448, 32529, 32541, 32565, 32568, 32604, 32605, 32613, 32627, 32628, 32664, 3267, 32703, 32723, 32726, 32734, 32772, 32780, 32819, 3283, 32840, 32848, 32869, 3287, 32905, 32919, 32934, 32943, 3295, 32965, 32982, 32987, 33007, 33029, 3308, 33100, 33111, 33124, 33130, 33133, 33182, 33219, 33230, 33242, 33251, 33308, 33330, 33339, 33348, 33368, 33372, 33382, 3342, 33475, 33483, 33485, 33501, 33566, 33578, 33610, 3361, 33632, 33648, 33696, 3373, 33762, 33780, 33791, 33811, 33823, 33834, 33845, 33848, 33891, 33964, 33967, 33999, 3399, 33, 34012, 3401, 34077, 34089, 34091, 34094, 34098, 34109, 3411, 34132, 34140, 3414, 34190, 34200, 34204, 3426, 34290, 34345, 34354, 34357, 34386, 34401, 34406, 34409, 34422, 34450, 34469, 34512, 34522, 3460, 34717, 3471, 34720, 3475, 34785, 34793, 34802, 34836, 34838, 34848, 34864, 34869, 34870, 34911, 34922, 34943, 34952, 34958, 34965, 35022, 35029, 35056, 35058, 3506, 35072, 35079, 35115, 35118, 35138, 35168, 35185, 35187, 35195, 35231, 35232, 35251, 35288, 35294, 35331, 35348, 35372, 35383, 35404, 35444, 35447, 35468, 35473, 35489, 35511, 35557, 35574, 35580, 35600, 35653, 35659, 3568, 35693, 35708, 35714, 35723, 35756, 3575, 35763, 35765, 35794, 35798, 3580, 3581, 35821, 35839, 35842, 35863, 35885, 35908, 35937, 35941, 35979, 35997, 36017, 36022, 36038, 36042, 36067, 3607, 36081, 36091, 36102, 36105, 36114, 36131, 36150, 36170, 36179, 36251, 36277, 36285, 36289, 36311, 36327, 36356, 36364, 36367, 36411, 36414, 36456, 36491, 36507, 3652, 36542, 36576, 36591, 36622, 36629, 36651, 36686, 36688, 36695, 36700, 36726, 36738, 36782, 36809, 36832, 36859, 3685, 36898, 36921, 36940, 36943, 36944, 36963, 36982, 36984, 37009, 37022, 37028, 37042, 37054, 37062, 37084, 37095, 37096, 37101, 37117, 37119, 37123, 37164, 37169, 37171, 3717, 3720, 37248, 37260, 37273, 37276, 37313, 37328, 37338, 37342, 37352, 37425, 37429, 37436, 37459, 3747, 37489, 37495, 3749, 37502, 37520, 37543, 37551, 37563, 37568, 37575, 37597, 37637, 37648, 37694, 37708, 37741, 37748, 37789, 37802, 37820, 37913, 37942, 37954, 37958, 38001, 38003, 38015, 38021, 3802, 38045, 38056, 38059, 38067, 38088, 38090, 38098, 38109, 38123, 38129, 38150, 38192, 38194, 38200, 38238, 38297, 38299, 38336, 38337, 38343, 38365, 38386, 38427, 38467, 3847, 384, 38511, 38541, 38581, 38706, 38732, 38757, 38761, 38776, 38789, 3881, 38822, 38843, 38867, 38882, 38982, 39005, 39014, 39021, 39031, 39065, 3907, 39093, 39100, 39118, 39127, 39149, 39289, 39293, 3930, 39330, 39335, 3934, 39396, 39405, 39421, 39462, 394, 3950, 39534, 39537, 39544, 39548, 3956, 39580, 39607, 39624, 39632, 3964, 39655, 39661, 39663, 39698, 39720, 39728, 3973, 39750, 3975, 39778, 39787, 39839, 3983, 39848, 39900, 39911, 39918, 39924, 39952, 39984, 40040, 40069, 40089, 40124, 40149, 4015, 40188, 40196, 40221, 40227, 40240, 40251, 40269, 40307, 40317, 40339, 40345, 4037, 40389, 403, 40405, 40406, 40451, 40473, 40488, 40493, 40496, 40508, 40546, 40565, 40633, 40659, 40663, 40666, 40685, 40692, 40740, 40749, 40754, 40756, 40758, 40787, 40792, 40800, 40817, 40819, 40881, 40912, 40922, 4093, 40968, 40975, 4098, 41002, 41007, 41050, 41055, 41083, 41087, 41139, 41150, 41152, 41184, 41238, 41239, 41252, 41268, 41297, 41306, 41360, 41364, 41392, 41434, 41437, 4144, 41450, 41481, 4148, 41496, 41520, 41565, 41583, 41585, 41599, 41623, 41629, 41716, 41734, 41774, 4177, 41792, 41845, 41855, 41864, 41899, 4189, 41905, 41956, 41972, 42008, 42013, 42046, 42080, 42098, 42100, 42109, 42134, 42155, 42159, 42175, 42179, 42232, 42266, 42271, 42319, 42354, 42358, 42412, 42422, 42436, 42487, 42488, 42513, 4253, 42555, 42558, 42564, 42592, 42602, 42612, 42617, 42623, 4265, 42742, 42756, 4275, 42769, 42833, 42837, 4288, 42897, 42915, 42922, 42924, 42939, 42948, 42978, 42982, 42985, 429, 43024, 43057, 43059, 43081, 43082, 43086, 43099, 430, 43122, 4313, 43199, 43203, 43260, 43266, 43294, 4331, 43327, 43329, 43342, 43365, 43366, 43381, 43388, 43399, 43449, 43461, 43468, 43477, 43492, 4353, 43551, 43565, 43639, 4364, 43678, 43734, 43743, 43762, 43770, 43774, 43786, 4384, 43853, 43913, 43922, 43947, 43950, 43995, 44001, 44003, 4406, 44073, 44074, 44102, 44128, 44136, 44182, 44232, 44245, 44322, 44336, 44365, 44374, 44418, 4441, 44438, 44467, 44472, 4447, 44499, 44507, 44515, 44529, 4453, 44592, 44593, 44611, 44620, 44625, 44631, 4463, 44649, 4467, 44693, 44716, 44758, 44759, 44769, 44772, 4477, 44799, 44801, 44861, 44870, 44887, 44895, 44921, 44951, 44954, 44983, 44991, 45053, 45062, 45075, 45135, 45149, 4514, 45164, 45166, 45208, 45265, 45303, 45328, 45361, 45410, 4544, 45472, 45488, 45498, 45530, 45560, 4560, 45611, 4561, 45638, 45666, 45718, 45727, 45767, 45773, 45796, 45797, 45870, 45902, 46003, 46010, 46022, 46056, 46137, 46206, 46234, 46242, 46263, 46269, 46270, 46325, 46334, 46340, 46358, 46378, 46391, 4639, 46400, 4640, 46419, 4645, 46505, 46536, 46555, 46562, 46576, 46583, 46587, 46613, 46614, 46615, 4661, 46623, 46630, 46653, 46680, 4668, 46753, 46764, 46771, 46831, 46849, 46874, 46883, 46884, 46904, 46909, 46942, 46945, 46950, 46964, 4697, 47040, 4704, 47059, 47065, 4706, 470, 47112, 47124, 4712, 47137, 47152, 47157, 47162, 47201, 47203, 4720, 47215, 47238, 47244, 47263, 47272, 47289, 47333, 47377, 47419, 47423, 47473, 47478, 47484, 47486, 47510, 47512, 47534, 47543, 47553, 47574, 47591, 4761, 47653, 47709, 4770, 47732, 47785, 47794, 47848, 47883, 47910, 4791, 47933, 47939, 47942, 47975, 48052, 48071, 4810, 48117, 48128, 48130, 4813, 4818, 48198, 48208, 48210, 48213, 48239, 48261, 48265, 48285, 48307, 48330, 48367, 48384, 48403, 48407, 48414, 4842, 48469, 48483, 48508, 48514, 48527, 4852, 48564, 48621, 48657, 4865, 48681, 48684, 4868, 48691, 48702, 48710, 48728, 48757, 48766, 48778, 48793, 48817, 48830, 48851, 48857, 48858, 48865, 4888, 4889, 48915, 4895, 48961, 49018, 49044, 4905, 49075, 49096, 49125, 49134, 49141, 49145, 49148, 49167, 49178, 49186, 49219, 49225, 49255, 49261, 49274, 49298, 49307, 49314, 49343, 49350, 49372, 49390, 49403, 49404, 49415, 49426, 49443, 49479, 49505, 49506, 49517, 49541, 49545, 49574, 49598, 49617, 49621, 49667, 49669, 4969, 496, 49712, 49737, 49743, 49768, 49773, 49780, 49783, 49814, 49831, 49853, 49868, 4989, 49937, 49954, 49987, 50006, 50107, 5013, 50165, 5016, 50179, 5020, 50219, 50284, 50295, 50296, 50314, 50324, 50330, 50385, 50387, 50398, 50412, 50413, 50435, 5047, 50486, 50518, 50519, 50549, 5057, 50580, 50640, 50647, 50657, 50661, 5067, 5072, 50737, 50747, 50753, 50759, 50779, 50803, 50805, 50820, 50833, 50840, 50857, 50867, 50873, 50878, 50910, 50915, 50916, 50925, 50938, 50955, 51007, 51026, 51035, 51038, 51039, 51076, 51078, 51080, 51121, 51135, 51136, 51177, 51187, 51192, 51272, 51298, 5129, 51338, 51357, 51410, 51430, 51438, 51439, 51458, 5145, 51476, 5149, 51515, 51520, 51531, 51545, 51546, 51611, 51623, 51650, 51670, 51673, 51675, 51677, 51694, 51716, 51719, 51721, 51728, 51736, 51764, 51775, 51778, 51779, 51807, 51813, 51822, 51849, 51863, 51865, 51874, 51885, 51896, 5189, 51927, 51930, 51959, 51987, 52007, 52044, 52063, 52075, 52106, 52117, 52123, 52125, 52130, 52160, 52177, 521, 52223, 52227, 52246, 52256, 52257, 52297, 52319, 52326, 52360, 52387, 52416, 52443, 52446, 52458, 52507, 52513, 5251, 52564, 5260, 52623, 52634, 52688, 52714, 52733, 5273, 52783, 52797, 52813, 52827, 52863, 52920, 52921, 52991, 52993, 53018, 53096, 5309, 53108, 53163, 53170, 53186, 531, 53203, 5325, 53294, 53322, 53348, 53356, 53364, 53376, 5337, 53395, 53416, 53423, 53474, 53475, 53482, 53510, 53513, 53517, 53581, 5361, 53620, 53625, 53652, 53723, 53761, 53784, 53788, 537, 53819, 53832, 53853, 53900, 53906, 53908, 53912, 5392, 53936, 53960, 54011, 54037, 54049, 5404, 54053, 54061, 54062, 54066, 54100, 54183, 5418, 54190, 54227, 54243, 5425, 54285, 54286, 5429, 54309, 54310, 54343, 54361, 54371, 54373, 54374, 5437, 54394, 54399, 54421, 54431, 54441, 54465, 54472, 54519, 54523, 54525, 54557, 5457, 54586, 54596, 5462, 54641, 54656, 54668, 54669, 54698, 54719, 54721, 54722, 54727, 5472, 54774, 54776, 54814, 54817, 54828, 54832, 54835, 54841, 54852, 54890, 54938, 54953, 54961, 54963, 54977, 54997, 55074, 55081, 55082, 55176, 55177, 55206, 55207, 55209, 55240, 55251, 55254, 55255, 55260, 5527, 55303, 55321, 55332, 55353, 55410, 55451, 55486, 55490, 55500, 5552, 55530, 55561, 55567, 55573, 55580, 55592, 5560, 55615, 55628, 55639, 55663, 55681, 55683, 5568, 55710, 55735, 55737, 55742, 55750, 55755, 55785, 5584, 55882, 55888, 55889, 55903, 55919, 55920, 55947, 55967, 56006, 56017, 56018, 56034, 56038, 56046, 56050, 56053, 56064, 56066, 56071, 56082, 5608, 56090, 56126, 5612, 56130, 56139, 5616, 56215, 56269, 56284, 56307, 56310, 56333, 56344, 56386, 56400, 56441, 56457, 5649, 56503, 56527, 56534, 56569, 56581, 56637, 56650, 56685, 56689, 56690, 56719, 56729, 5674, 56751, 56776, 56810, 56816, 56836, 56841, 56858, 56879, 56880, 56882, 56901, 56903, 56930, 56948, 56981, 57003, 57018, 57029, 57034, 57038, 57055, 57058, 57061, 57064, 57087, 57106, 57126, 57140, 57149, 57185, 57260, 57295, 5729, 57328, 57338, 57359, 57364, 57370, 57444, 57480, 57482, 57487, 57504, 57534, 57563, 57572, 57574, 57581, 57601, 57612, 57618, 57622, 57640, 57652, 57714, 57718, 5775, 5777, 57785, 57804, 57815, 5781, 57826, 57835, 57853, 57878, 57887, 57901, 57904, 57905, 57967, 57981, 57987, 57988, 57995, 58006, 58025, 58046, 58063, 58077, 58078, 58097, 5811, 58127, 58147, 58165, 5817, 58180, 58193, 581, 58236, 58237, 58309, 58316, 58324, 58359, 58360, 58425, 58434, 58435, 58465, 58475, 58480, 58482, 58485, 58524, 58538, 5853, 58540, 58547, 58606, 58637, 58701, 58708, 58719, 58729, 58737, 58744, 58757, 58773, 5877, 58789, 5880, 58810, 58834, 58863, 58865, 58871, 58876, 58886, 58901, 58929, 58966, 5897, 58980, 59001, 5900, 59076, 590, 59107, 5914, 59194, 59208, 59214, 5923, 59261, 59262, 59270, 59273, 59276, 59299, 59302, 59315, 59427, 59429, 59442, 59445, 59456, 59478, 59525, 59528, 59537, 59544, 59548, 59635, 59664, 59687, 59704, 59725, 59737, 5973, 59744, 59749, 59784, 59791, 59811, 59817, 59856, 59889, 59900, 59938, 5996, 59982, 60007, 60014, 60021, 60029, 60058, 60082, 60115, 60151, 60153, 60159, 60178, 60193, 60196, 60258, 60309, 6032, 60373, 60442, 60450, 60455, 60457, 60466, 60472, 60499, 60515, 60583, 60593, 60619, 60640, 6064, 60706, 60708, 60724, 60725, 60726, 60744, 60793, 60836, 6083, 60846, 60851, 60900, 60934, 60944, 60978, 6097, 60993, 61000, 61005, 61035, 61040, 61061, 61101, 61128, 61131, 61229, 61231, 61255, 61342, 61399, 61425, 61439, 61462, 61464, 61468, 61482, 61490, 61499, 61530, 61537, 61547, 61560, 61576, 61619, 61620, 61635, 61651, 61684, 61688, 61701, 61742, 61768, 61800, 61832, 61834, 6186, 61897, 61916, 61917, 61987, 61993, 6200, 62022, 6203, 62062, 62066, 62088, 62095, 62116, 62118, 62171, 62179, 62246, 62273, 62280, 62292, 622, 6230, 62330, 62360, 62376, 62397, 6239, 62423, 62488, 62494, 62513, 62600, 62705, 62763, 62764, 62780, 62818, 62820, 62822, 62826, 62845, 62918, 62961, 63012, 63063, 63069, 63078, 63113, 63139, 63177, 6317, 63193, 63226, 63272, 63279, 63306, 63316, 63319, 63325, 63338, 63384, 63399, 63443, 63449, 63457, 63472, 63501, 63550, 63551, 63561, 63572, 6358, 63601, 63603, 63620, 63649, 63662, 63665, 63673, 63783, 63795, 63811, 63833, 63875, 63877, 63882, 63915, 63948, 63950, 63957, 63970, 639, 64008, 64011, 64017, 64019, 64034, 64068, 64079, 64086, 64091, 64194, 64204, 64219, 64234, 6423, 64244, 64246, 64256, 64263, 64320, 64333, 64350, 64387, 64405, 64428, 64469, 6449, 64501, 64513, 64555, 64566, 64567, 64573, 64586, 64591, 64593, 64594, 64612, 64632, 64645, 64665, 64710, 64732, 64739, 64769, 64777, 64794, 64814, 64823, 64835, 64845, 64851, 6485, 64881, 6488, 648, 64932, 6493, 64969, 64982, 64983, 64987, 65005, 65031, 65066, 65083, 65089, 65118, 65126, 65149, 65231, 65289, 65310, 65326, 65355, 65360, 6539, 65407, 65415, 65438, 65450, 65456, 6545, 65495, 65504, 65508, 6550, 6579, 6602, 6604, 6625, 6642, 6643, 6654, 6766, 6773, 6780, 6788, 6879, 687, 6881, 6884, 6962, 6968, 697, 6990, 6992, 6996, 7017, 7026, 7030, 7054, 7064, 706, 7084, 7093, 7098, 7110, 7115, 7141, 7162, 716, 7184, 7185, 7188, 7190, 7202, 7290, 7307, 732, 7346, 7358, 7369, 7392, 7393, 7411, 7429, 7434, 7435, 7437, 7476, 7482, 7493, 7513, 7530, 7574, 7603, 7611, 7642, 7654, 7657, 766, 7712, 7715, 7749, 7754, 7784, 7789, 7819, 7904, 7933, 7944, 796, 7995, 8031, 8044, 8054, 8076, 8094, 8104, 820, 8218, 821, 8263, 8314, 8325, 8327, 8371, 8389, 8395, 8411, 8420, 8424, 8464, 8499, 8502, 8506, 851, 8537, 8576, 8621, 8648, 8684, 8691, 8692, 8707, 871, 8771, 8774, 878, 8833, 8848, 8889, 8935, 8958, 8964, 8978, 8996, 902, 904, 9081, 908, 9093, 9125, 9132, 9164, 9179, 9190, 9264, 9289, 9363, 9373, 9386, 9388, 9408, 9424, 943, 9446, 9485, 9493, 9510, 951, 9528, 9532, 9537, 9549, 9553, 9555, 958, 9611, 9620, 9632, 965, 96, 9703, 9753, 9801, 9808, 980, 9813, 9835, 9860, 9951, 9960, 9961, 9980, 9983]\n    tr = pd.read_csv('/kaggle/input/kaggle-upload-tmp/multi_label_stratified_folds.csv')\n    tr = tr[tr.patient_id.isin(good_patient_ids)]\n    tr = tr[tr.fold==debug_fold]\n    patient_ids = tr.patient_id.astype(str).unique().tolist()\n    patient_ids = patient_ids[:10]    \n    print('Number of training patients :', len(patient_ids))\n    meta = pd.read_csv('/kaggle/input/rsna-2023-abdominal-trauma-detection/train_series_meta.csv')\nelse:    \n    image_dir = \"/kaggle/input/rsna-2023-abdominal-trauma-detection/test_images/\"\n    patient_ids = os.listdir(image_dir)\n    meta = pd.read_csv('/kaggle/input/rsna-2023-abdominal-trauma-detection/test_series_meta.csv')","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.151347Z","iopub.execute_input":"2023-10-15T14:33:01.152141Z","iopub.status.idle":"2023-10-15T14:33:01.434592Z","shell.execute_reply.started":"2023-10-15T14:33:01.152106Z","shell.execute_reply":"2023-10-15T14:33:01.433551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patient_ids","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.436136Z","iopub.execute_input":"2023-10-15T14:33:01.437065Z","iopub.status.idle":"2023-10-15T14:33:01.445143Z","shell.execute_reply.started":"2023-10-15T14:33:01.437025Z","shell.execute_reply":"2023-10-15T14:33:01.443984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfs = []\nfor id, idf in meta.groupby('patient_id'):\n    dfs.append(idf[idf.aortic_hu==idf.aortic_hu.min()].iloc[:1])\nmeta = pd.concat(dfs)","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:01.446949Z","iopub.execute_input":"2023-10-15T14:33:01.447603Z","iopub.status.idle":"2023-10-15T14:33:04.478439Z","shell.execute_reply.started":"2023-10-15T14:33:01.447558Z","shell.execute_reply":"2023-10-15T14:33:04.477369Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3d segmentation","metadata":{}},{"cell_type":"code","source":"DEVICE = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:04.479848Z","iopub.execute_input":"2023-10-15T14:33:04.480215Z","iopub.status.idle":"2023-10-15T14:33:04.485245Z","shell.execute_reply.started":"2023-10-15T14:33:04.48018Z","shell.execute_reply":"2023-10-15T14:33:04.484208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n!ln -s /kaggle/input/timm092/pytorch-image-models-0.9.2/timm\n!ln -s /kaggle/input/smp033/segmentation_models.pytorch-0.3.3/segmentation_models_pytorch\n!pip install /kaggle/input/monai-whl/monai-1.1.0-202212191849-py3-none-any.whl\n!pip install /kaggle/input/pretrainedmodels-wheels/pretrainedmodels-0.7.4-py3-none-any.whl\nimport timm\nfrom timm.layers.conv2d_same import Conv2dSame\n\nimport sys\nsys.path = [\n    '../input/smp20210127/pretrained-models.pytorch-master/pretrained-models.pytorch-master',\n    '../input/smp20210127/EfficientNet-PyTorch-master/EfficientNet-PyTorch-master',\n] + sys.path\nimport segmentation_models_pytorch as smp","metadata":{"execution":{"iopub.status.busy":"2023-10-15T14:33:04.490166Z","iopub.execute_input":"2023-10-15T14:33:04.490933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torch\nimport math\nimport torch.nn.functional as F\nfrom typing import Tuple, Optional, List\nfrom pdb import set_trace as st\n\n# Calculate symmetric padding for a convolution\ndef get_padding(kernel_size: int, stride: int = 1, dilation: int = 1, **_) -> int:\n    padding = ((stride - 1) + dilation * (kernel_size - 1)) // 2\n    return padding\n\n\n# Calculate asymmetric TensorFlow-like 'SAME' padding for a convolution\ndef get_same_padding(x: int, k: int, s: int, d: int):\n    return max((math.ceil(x / s) - 1) * s + (k - 1) * d + 1 - x, 0)\n\n\n# Can SAME padding for given args be done statically?\ndef is_static_pad(kernel_size: int, stride: int = 1, dilation: int = 1, **_):\n    return stride == 1 and (dilation * (kernel_size - 1)) % 2 == 0\n\n\n# Dynamically pad input x with 'SAME' padding for conv with specified args\ndef pad_same(x, k: List[int], s: List[int], d: List[int] = (1, 1, 1), value: float = 0):\n    ih, iw, iz = x.size()[-3:]\n    pad_h = get_same_padding(ih, k[0], s[0], d[0])\n    pad_w = get_same_padding(iw, k[1], s[1], d[1])\n    pad_z = get_same_padding(iz, k[2], s[2], d[2])\n    if pad_h > 0 or pad_w > 0 or pad_z > 0:\n        x = F.pad(x, [pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2, pad_z // 2, pad_z - pad_z // 2], value=value)\n    return x\n\n\ndef get_padding_value(padding, kernel_size, **kwargs) -> Tuple[Tuple, bool]:\n    dynamic = False\n    if isinstance(padding, str):\n        # for any string padding, the padding will be calculated for you, one of three ways\n        padding = padding.lower()\n        if padding == 'same':\n            # TF compatible 'SAME' padding, has a performance and GPU memory allocation impact\n            if is_static_pad(kernel_size, **kwargs):\n                # static case, no extra overhead\n                padding = get_padding(kernel_size, **kwargs)\n            else:\n                # dynamic 'SAME' padding, has runtime/GPU memory overhead\n                padding = 0\n                dynamic = True\n        elif padding == 'valid':\n            # 'VALID' padding, same as padding=0\n            padding = 0\n        else:\n            # Default to PyTorch style 'same'-ish symmetric padding\n            padding = get_padding(kernel_size, **kwargs)\n    return padding, dynamic\n\n\ndef conv3d_same(\n        x, weight: torch.Tensor, bias: Optional[torch.Tensor] = None, stride: Tuple[int, int, int] = (1, 1, 1),\n        padding: Tuple[int, int, int] = (0, 0, 0), dilation: Tuple[int, int, int] = (1, 1, 1), groups: int = 1):\n    x = pad_same(x, weight.shape[-3:], stride, dilation)\n    return F.conv3d(x, weight, bias, stride, (0, 0, 0), dilation, groups)\n\n\nclass Conv3dSame(nn.Conv3d):\n    \"\"\" Tensorflow like 'SAME' convolution wrapper for 3d convolutions\n    \"\"\"\n\n    def __init__(self, in_channels, out_channels, kernel_size, stride=1,\n                 padding=0, dilation=1, groups=1, bias=True):\n        super(Conv3dSame, self).__init__(\n            in_channels, out_channels, kernel_size, stride, 0, dilation, groups, bias)\n\n    def forward(self, x):\n        return conv3d_same(x, self.weight, self.bias, self.stride, self.padding, self.dilation, self.groups)\n\n\ndef create_conv3d_pad(in_chs, out_chs, kernel_size, **kwargs):\n    padding = kwargs.pop('padding', '')\n    kwargs.setdefault('bias', False)\n    padding, is_dynamic = get_padding_value(padding, kernel_size, **kwargs)\n    if is_dynamic:\n        return Conv3dSame(in_chs, out_chs, kernel_size, **kwargs)\n    else:\n        return nn.Conv3d(in_chs, out_chs, kernel_size, padding=padding, **kwargs)\n\nclass TimmSegModel(nn.Module):\n    def __init__(self, backbone, segtype='unet', pretrained=False, num_classes=1, drop_rate=0., drop_path_rate=0.):\n        super(TimmSegModel, self).__init__()\n\n        self.n_blocks = 4\n\n        self.encoder = timm.create_model(\n            backbone,\n            in_chans=3,\n            features_only=True,\n            drop_rate=drop_rate,\n            drop_path_rate=drop_path_rate,\n            pretrained=pretrained\n        )\n        g = self.encoder(torch.rand(1, 3, 64, 64))\n        encoder_channels = [1] + [_.shape[1] for _ in g]\n        decoder_channels = [256, 128, 64, 32, 16]\n        if segtype == 'unet':\n            # st()\n            self.decoder = smp.decoders.unet.decoder.UnetDecoder(\n                encoder_channels=encoder_channels[:self.n_blocks+1],\n                decoder_channels=decoder_channels[:self.n_blocks],\n                n_blocks=self.n_blocks,\n            )\n\n        self.segmentation_head = nn.Conv2d(decoder_channels[self.n_blocks-1], num_classes, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n\n    def forward(self, x):\n        global_features = [0] + self.encoder(x)[:self.n_blocks]\n        global_features[1].size(), global_features[2].size(), global_features[3].size(), global_features[4].size()\n        seg_features = self.decoder(*global_features)\n        seg_features = self.segmentation_head(seg_features)\n        return seg_features\n\n\n\n\ndef convert_3d(module):\n\n    module_output = module\n    if isinstance(module, torch.nn.BatchNorm2d):\n        module_output = torch.nn.BatchNorm3d(\n            module.num_features,\n            module.eps,\n            module.momentum,\n            module.affine,\n            module.track_running_stats,\n        )\n        if module.affine:\n            with torch.no_grad():\n                module_output.weight = module.weight\n                module_output.bias = module.bias\n        module_output.running_mean = module.running_mean\n        module_output.running_var = module.running_var\n        module_output.num_batches_tracked = module.num_batches_tracked\n        if hasattr(module, \"qconfig\"):\n            module_output.qconfig = module.qconfig\n\n    elif isinstance(module, Conv2dSame):\n        module_output = Conv3dSame(\n            in_channels=module.in_channels,\n            out_channels=module.out_channels,\n            kernel_size=module.kernel_size[0],\n            stride=module.stride[0],\n            padding=module.padding[0],\n            dilation=module.dilation[0],\n            groups=module.groups,\n            bias=module.bias is not None,\n        )\n        module_output.weight = torch.nn.Parameter(module.weight.unsqueeze(-1).repeat(1,1,1,1,module.kernel_size[0]))\n\n    elif isinstance(module, torch.nn.Conv2d):\n        module_output = torch.nn.Conv3d(\n            in_channels=module.in_channels,\n            out_channels=module.out_channels,\n            kernel_size=module.kernel_size[0],\n            stride=module.stride[0],\n            padding=module.padding[0],\n            dilation=module.dilation[0],\n            groups=module.groups,\n            bias=module.bias is not None,\n            padding_mode=module.padding_mode\n        )\n        module_output.weight = torch.nn.Parameter(module.weight.unsqueeze(-1).repeat(1,1,1,1,module.kernel_size[0]))\n\n    elif isinstance(module, torch.nn.MaxPool2d):\n        module_output = torch.nn.MaxPool3d(\n            kernel_size=module.kernel_size,\n            stride=module.stride,\n            padding=module.padding,\n            dilation=module.dilation,\n            ceil_mode=module.ceil_mode,\n        )\n    elif isinstance(module, torch.nn.AvgPool2d):\n        module_output = torch.nn.AvgPool3d(\n            kernel_size=module.kernel_size,\n            stride=module.stride,\n            padding=module.padding,\n            ceil_mode=module.ceil_mode,\n        )\n\n    for name, child in module.named_children():\n        module_output.add_module(\n            name, convert_3d(child)\n        )\n    del module\n\n    return module_output\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = []\nfor model_path in segmentation_model_paths:\n    print(model_path)\n    if 'resnet50' in model_path:\n        model = TimmSegModel('resnet50', pretrained=False, num_classes=5)\n    else:\n        model = TimmSegModel('resnet18', pretrained=False, num_classes=5)\n    model = convert_3d(model)    \n    \n    state_dict = torch.load(model_path, map_location=torch.device('cpu'))['state_dict']\n    torch_state_dict = {}\n    for k, v in state_dict.items():\n        torch_state_dict[k[6:]] = v\n    model.load_state_dict(torch_state_dict)    \n    model.to(DEVICE)\n    model.eval()\n    models.append(model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /kaggle/temp/z_pos_csvs","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom monai.transforms import Resize\n\ndef read_patient_dicom(patient_id):\n    p_meta = meta[meta.patient_id==int(patient_id)]\n    study = p_meta.series_id.values[0]\n    imgs = {}\n    numbers = []\n    zs = []\n    for f in sorted(glob(image_dir + f\"{patient_id}/{study}/*.dcm\")):\n        instance_number = int(f.split('/')[-1].replace('.dcm', ''))\n#         if instance_number % 2 == 1:\n#             continue\n        \n        try:\n            dicom = dicomsdl.open(f)\n\n            img = dicom.pixelData(storedvalue = True)\n            if dicom['PixelRepresentation'] == 1:\n                bit_shift = dicom['BitsAllocated'] - dicom['BitsStored']\n                dtype = img.dtype\n                img = (img << bit_shift).astype(dtype) >>  bit_shift\n            img = img.astype(np.float32)\n\n            intercept = dicom['RescaleIntercept']\n            slope = dicom['RescaleSlope']\n            img = img * slope + intercept\n\n            pos_z = dicom['ImagePositionPatient'][-1]\n\n            imgs3 = []\n            for width, level in [(400, 50), (150, 30), (1800, 400)]:\n                img_w = np.clip(img, level - width // 2, level + width // 2)\n                img_w = img_w - np.min(img_w)\n                img_w = img_w / np.max(img_w)\n                img_w = (img_w*255.0).astype('uint8')\n                img_w = (img_w - img_w.min()) / (img_w.max() - img_w.min() + 1e-6)\n\n                if dicom.PhotometricInterpretation == \"MONOCHROME1\":\n                    img_w = 1 - img_w\n\n                break\n            imgs[pos_z] = img_w            \n            numbers.append(instance_number)\n            zs.append(pos_z)\n        except:\n            pass\n    sorted_images = []\n    df = pd.DataFrame({\n        'instance_number': numbers,\n        'z_pos': zs\n    })\n    df['image_id'] = f'{patient_id}_{study}'\n    df.to_csv(f'/kaggle/temp/z_pos_csvs/{patient_id}_{study}.csv', index=False)\n    for i, k in enumerate(sorted(imgs.keys())):\n        img = imgs[k]\n        sorted_images.append((img * 255).astype(np.uint8))\n\n    return sorted_images, f'{patient_id}_{study}'\n\nclass SegmentationDataset(Dataset):\n    def __init__(self, patient_ids):\n        self.patient_ids = patient_ids\n        self.resize = Resize((128, 128, 128))\n\n    def __len__(self):\n        return len(self.patient_ids)\n\n    def __getitem__(self, idx):\n        patient_id = self.patient_ids[idx]\n        origin_images, image_id = read_patient_dicom(patient_id)\n        origin_images = np.array(origin_images)\n        images = origin_images[np.newaxis]\n        images = self.resize(images)\n\n        images = images.astype(np.float32).repeat(3, 0)\n        images = images / 255.\n        images = torch.tensor(images).float()\n\n        return images, origin_images, image_id","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def custom_collate(batch):\n    images, origin_images, image_id = zip(*batch)\n    return torch.stack(images), origin_images, image_id","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\n\n!mkdir -p /kaggle/temp/z_pos_csvs/\n!mkdir -p /kaggle/temp/cropped_images\nds = SegmentationDataset(patient_ids)\nloader = DataLoader(ds, batch_size=2, shuffle=False, drop_last=False, num_workers=2, collate_fn=custom_collate)\npreds = []\nall_image_ids = []\nall_classes = []\nx_mins, x_maxes, y_mins, y_maxes, z_mins, z_maxes = [], [], [], [], [], []\nx_mins_0, x_maxes_0, y_mins_0, y_maxes_0, z_mins_0, z_maxes_0 = [], [], [], [], [], []\nx_mins_30, x_maxes_30, y_mins_30, y_maxes_30, z_mins_30, z_maxes_30 = [], [], [], [], [], []\ncrop_image_pad_ratios = []\nfor images, origin_images, image_ids in tqdm(loader, smoothing=0):\n    images = images.to(DEVICE)\n    masks = np.zeros((len(images), 5, 128, 128, 128)).astype(np.float16)\n    for model in models:\n        masks += model(images).detach().cpu().numpy()/len(models)\n    for mask, origin_image, image_id in zip(masks, origin_images, image_ids):\n        z, y, x = origin_image.shape\n        mask = sigmoid(mask)\n        mask = mask>0.2\n        for crop_image_pad_ratio, crop_image_pad_z_ratio in zip([crop_image_pad_ratio1, crop_image_pad_ratio0], [crop_image_pad_z_ratio1, crop_image_pad_z_ratio0]):\n            all_mask = mask[0]+mask[1]+mask[2]+mask[3]+mask[4]\n\n            all_idx = np.where(all_mask >= 1)\n            all_min_idx = np.min(all_idx, axis=1)\n            all_max_idx = np.max(all_idx, axis=1) + 1\n\n            crop_image_pad_z = (all_max_idx[0]-all_min_idx[0])*z/128/crop_image_pad_z_ratio\n            crop_image_pad_y = (all_max_idx[1]-all_min_idx[1])*y/128/crop_image_pad_ratio\n            crop_image_pad_x = (all_max_idx[2]-all_min_idx[2])*x/128/crop_image_pad_ratio\n            for c in range(5):\n                if c == 3:\n                    continue\n                one_class_mask = mask[c].copy()\n                if np.sum(one_class_mask)>0:\n                    idx = np.where(one_class_mask >= 1)\n                    min_idx = np.min(idx, axis=1)\n                    max_idx = np.max(idx, axis=1) + 1\n\n                    min_z = int(max(0, min_idx[0]*z/128-crop_image_pad_z))\n                    min_y = int(max(0, min_idx[1]*y/128-crop_image_pad_y))\n                    min_x = int(max(0, min_idx[2]*x/128-crop_image_pad_x))\n                    max_z = int(min(max_idx[0]*z/128+crop_image_pad_z, z))\n                    max_y = int(min(max_idx[1]*y/128+crop_image_pad_y, y))\n                    max_x = int(min(max_idx[2]*x/128+crop_image_pad_x, x))\n                    all_classes.append(c)\n                    all_image_ids.append(image_id)\n                    z_mins.append(min_z)\n                    z_maxes.append(max_z)\n                    y_mins.append(min_y)\n                    y_maxes.append(max_y)\n                    x_mins.append(min_x)\n                    x_maxes.append(max_x)\n                    crop_image_pad_ratios.append(crop_image_pad_ratio)\n                    cim = origin_image[min_z:max_z, min_y:max_y, min_x:max_x]\n                    np.save(f'/kaggle/temp/cropped_images/{image_id}_{crop_image_pad_ratio}_{c}.npy', cim[::2])\n                    if (c == 0) & (crop_image_pad_ratio == 30):\n                        mask0 = one_class_mask[np.newaxis]\n                        resize = Resize((z, y, x))\n                        mask0 = resize(mask0)[0]\n\n                        cim0 = origin_image*mask0\n                        cim0 = cim0[int(min_idx[0]*z/128):int(max_idx[0]*z/128), int(min_idx[1]*y/128):int(max_idx[1]*y/128), int(min_idx[2]*x/128):int(max_idx[2]*x/128)]\n                        np.save(f'/kaggle/temp/cropped_images/{image_id}_{crop_image_pad_ratio}_{c}_masked.npy', cim0[::2])\n            mask23 = mask[2]+mask[3]\n            if np.sum(mask23)>0:\n                idx = np.where(mask23 >= 1)\n                min_idx = np.min(idx, axis=1)\n                max_idx = np.max(idx, axis=1) + 1\n\n                min_z = int(max(0, min_idx[0]*z/128-crop_image_pad_z))\n                min_y = int(max(0, min_idx[1]*y/128-crop_image_pad_y))\n                min_x = int(max(0, min_idx[2]*x/128-crop_image_pad_x))\n                max_z = int(min(max_idx[0]*z/128+crop_image_pad_z, z))\n                max_y = int(min(max_idx[1]*y/128+crop_image_pad_y, y))\n                max_x = int(min(max_idx[2]*x/128+crop_image_pad_x, x))\n                all_classes.append(23)\n                all_image_ids.append(image_id)\n                z_mins.append(min_z)\n                z_maxes.append(max_z)\n                y_mins.append(min_y)\n                y_maxes.append(max_y)\n                x_mins.append(min_x)\n                x_maxes.append(max_x)\n                crop_image_pad_ratios.append(crop_image_pad_ratio)\n                cim = origin_image[min_z:max_z, min_y:max_y, min_x:max_x]\n                np.save(f'/kaggle/temp/cropped_images/{image_id}_{crop_image_pad_ratio}_23.npy', cim[::2])\nseg_preds = pd.DataFrame({\n    'image_id': all_image_ids,\n    'mask_class': all_classes,\n    'x_min': x_mins,\n    'x_max': x_maxes,\n    'y_min': y_mins,\n    'y_max': y_maxes,\n    'z_min': z_mins,\n    'z_max': z_maxes,\n    'crop_image_pad_ratio': crop_image_pad_ratios,\n})\nseg_preds.to_csv('seg_preds.csv', index=False)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im = images[-1][0].cpu().numpy()\nim = im[::-1]\nmask = mask[:, ::-1, :, :]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seg_preds.image_id.nunique()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pr = seg_preds[seg_preds.image_id==image_id]\npr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_map = {\n    0: 'liver',\n    1: 'spleen',\n    2: 'kidney_left',\n    3: 'kidney_right',\n    4: 'bowel'    \n}\nfor c in range(5):\n    try:\n        print(f'↓{class_map[c]}↓')\n        y_min, y_max = pr[pr.mask_class==c][['y_min', 'y_max']].values[0]\n\n        rows = 10\n        for n, y in enumerate(range(y_min//4, y_max//4, 2)):\n            if n % rows == 0:\n                fig = plt.figure(figsize=(14, 14))\n            fig.add_subplot(1, rows, n%rows+1)\n            plt.imshow(cv2.resize((im[:,y,:]*255).astype(np.uint8), (96,96)), 'gray')\n            plt.imshow(cv2.resize(mask[c][:,y,:].astype(np.uint8), (96, 96)), alpha=0.5)\n\n            if (n % rows == rows-1) | (y>=y_max//4-2):\n                plt.show()    \n    except:\n        pass","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seg_preds['path'] = '/kaggle/temp/cropped_images/' + seg_preds.image_id + '_' + seg_preds.crop_image_pad_ratio.astype(str) + '_' + seg_preds.mask_class.astype(str) + '.npy'\nseg_preds['patient_id'] = seg_preds.image_id.apply(lambda x: int(x.split('_')[0]))\nseg_preds['series_id'] = seg_preds.image_id.apply(lambda x: int(x.split('_')[1]))\n!ls {seg_preds.path.values[0]}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from __future__ import print_function, division, absolute_import\nfrom collections import OrderedDict\nimport math\n\nfrom torch.utils import model_zoo\n\nclass SEModule(nn.Module):\n\n    def __init__(self, channels, reduction):\n        super(SEModule, self).__init__()\n        self.avg_pool = nn.AdaptiveAvgPool2d(1)\n        self.fc1 = nn.Conv2d(channels, channels // reduction, kernel_size=1,\n                             padding=0)\n        self.relu = nn.ReLU(inplace=True)\n        self.fc2 = nn.Conv2d(channels // reduction, channels, kernel_size=1,\n                             padding=0)\n        self.sigmoid = nn.Sigmoid()\n\n    def forward(self, x):\n        module_input = x\n        x = self.avg_pool(x)\n        x = self.fc1(x)\n        x = self.relu(x)\n        x = self.fc2(x)\n        x = self.sigmoid(x)\n        return module_input * x\n\n\nclass Bottleneck(nn.Module):\n    \"\"\"\n    Base class for bottlenecks that implements `forward()` method.\n    \"\"\"\n\n    def forward(self, x):\n        residual = x\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out = self.relu(out)\n\n        out = self.conv3(out)\n        out = self.bn3(out)\n\n        if self.downsample is not None:\n            residual = self.downsample(x)\n\n        out = self.se_module(out) + residual\n        out = self.relu(out)\n\n        return out\n\n\nclass SEBottleneck(Bottleneck):\n    \"\"\"\n    Bottleneck for SENet154.\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None):\n        super(SEBottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes * 2, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes * 2)\n        self.conv2 = nn.Conv2d(planes * 2, planes * 4, kernel_size=3,\n                               stride=stride, padding=1, groups=groups,\n                               bias=False)\n        self.bn2 = nn.BatchNorm2d(planes * 4)\n        self.conv3 = nn.Conv2d(planes * 4, planes * 4, kernel_size=1,\n                               bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SEResNetBottleneck(Bottleneck):\n    \"\"\"\n    ResNet bottleneck with a Squeeze-and-Excitation module. It follows Caffe\n    implementation and uses `stride=stride` in `conv1` and not in `conv2`\n    (the latter is used in the torchvision implementation of ResNet).\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None):\n        super(SEResNetBottleneck, self).__init__()\n        self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False,\n                               stride=stride)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, padding=1,\n                               groups=groups, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n        self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SEResNeXtBottleneck(Bottleneck):\n    \"\"\"\n    ResNeXt bottleneck type C with a Squeeze-and-Excitation module.\n    \"\"\"\n    expansion = 4\n\n    def __init__(self, inplanes, planes, groups, reduction, stride=1,\n                 downsample=None, base_width=4):\n        super(SEResNeXtBottleneck, self).__init__()\n        width = math.floor(planes * (base_width / 64)) * groups\n        self.conv1 = nn.Conv2d(inplanes, width, kernel_size=1, bias=False,\n                               stride=1)\n        self.bn1 = nn.BatchNorm2d(width)\n        self.conv2 = nn.Conv2d(width, width, kernel_size=3, stride=stride,\n                               padding=1, groups=groups, bias=False)\n        self.bn2 = nn.BatchNorm2d(width)\n        self.conv3 = nn.Conv2d(width, planes * 4, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(planes * 4)\n        self.relu = nn.ReLU(inplace=True)\n        self.se_module = SEModule(planes * 4, reduction=reduction)\n        self.downsample = downsample\n        self.stride = stride\n\n\nclass SENet(nn.Module):\n\n    def __init__(self, block, layers, groups, reduction, dropout_p=0.2,\n                 inplanes=128, input_3x3=True, downsample_kernel_size=3,\n                 downsample_padding=1, num_classes=1000):\n        \"\"\"\n        Parameters\n        ----------\n        block (nn.Module): Bottleneck class.\n            - For SENet154: SEBottleneck\n            - For SE-ResNet models: SEResNetBottleneck\n            - For SE-ResNeXt models:  SEResNeXtBottleneck\n        layers (list of ints): Number of residual blocks for 4 layers of the\n            network (layer1...layer4).\n        groups (int): Number of groups for the 3x3 convolution in each\n            bottleneck block.\n            - For SENet154: 64\n            - For SE-ResNet models: 1\n            - For SE-ResNeXt models:  32\n        reduction (int): Reduction ratio for Squeeze-and-Excitation modules.\n            - For all models: 16\n        dropout_p (float or None): Drop probability for the Dropout layer.\n            If `None` the Dropout layer is not used.\n            - For SENet154: 0.2\n            - For SE-ResNet models: None\n            - For SE-ResNeXt models: None\n        inplanes (int):  Number of input channels for layer1.\n            - For SENet154: 128\n            - For SE-ResNet models: 64\n            - For SE-ResNeXt models: 64\n        input_3x3 (bool): If `True`, use three 3x3 convolutions instead of\n            a single 7x7 convolution in layer0.\n            - For SENet154: True\n            - For SE-ResNet models: False\n            - For SE-ResNeXt models: False\n        downsample_kernel_size (int): Kernel size for downsampling convolutions\n            in layer2, layer3 and layer4.\n            - For SENet154: 3\n            - For SE-ResNet models: 1\n            - For SE-ResNeXt models: 1\n        downsample_padding (int): Padding for downsampling convolutions in\n            layer2, layer3 and layer4.\n            - For SENet154: 1\n            - For SE-ResNet models: 0\n            - For SE-ResNeXt models: 0\n        num_classes (int): Number of outputs in `last_linear` layer.\n            - For all models: 1000\n        \"\"\"\n        super(SENet, self).__init__()\n        self.inplanes = inplanes\n        if input_3x3:\n            layer0_modules = [\n                ('conv1', nn.Conv2d(3, 64, 3, stride=2, padding=1,\n                                    bias=False)),\n                ('bn1', nn.BatchNorm2d(64)),\n                ('relu1', nn.ReLU(inplace=True)),\n                ('conv2', nn.Conv2d(64, 64, 3, stride=1, padding=1,\n                                    bias=False)),\n                ('bn2', nn.BatchNorm2d(64)),\n                ('relu2', nn.ReLU(inplace=True)),\n                ('conv3', nn.Conv2d(64, inplanes, 3, stride=1, padding=1,\n                                    bias=False)),\n                ('bn3', nn.BatchNorm2d(inplanes)),\n                ('relu3', nn.ReLU(inplace=True)),\n            ]\n        else:\n            layer0_modules = [\n                ('conv1', nn.Conv2d(3, inplanes, kernel_size=7, stride=2,\n                                    padding=3, bias=False)),\n                ('bn1', nn.BatchNorm2d(inplanes)),\n                ('relu1', nn.ReLU(inplace=True)),\n            ]\n        # To preserve compatibility with Caffe weights `ceil_mode=True`\n        # is used instead of `padding=1`.\n        layer0_modules.append(('pool', nn.MaxPool2d(3, stride=2,\n                                                    ceil_mode=True)))\n        self.layer0 = nn.Sequential(OrderedDict(layer0_modules))\n        self.layer1 = self._make_layer(\n            block,\n            planes=64,\n            blocks=layers[0],\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=1,\n            downsample_padding=0\n        )\n        self.layer2 = self._make_layer(\n            block,\n            planes=128,\n            blocks=layers[1],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        self.layer3 = self._make_layer(\n            block,\n            planes=256,\n            blocks=layers[2],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        self.layer4 = self._make_layer(\n            block,\n            planes=512,\n            blocks=layers[3],\n            stride=2,\n            groups=groups,\n            reduction=reduction,\n            downsample_kernel_size=downsample_kernel_size,\n            downsample_padding=downsample_padding\n        )\n        # self.avg_pool = nn.AvgPool2d(7, stride=1)\n        self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n        self.dropout = nn.Dropout(dropout_p) if dropout_p is not None else None\n        self.last_linear = nn.Linear(512 * block.expansion, num_classes)\n\n    def _make_layer(self, block, planes, blocks, groups, reduction, stride=1,\n                    downsample_kernel_size=1, downsample_padding=0):\n        downsample = None\n        if stride != 1 or self.inplanes != planes * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.inplanes, planes * block.expansion,\n                          kernel_size=downsample_kernel_size, stride=stride,\n                          padding=downsample_padding, bias=False),\n                nn.BatchNorm2d(planes * block.expansion),\n            )\n\n        layers = []\n        layers.append(block(self.inplanes, planes, groups, reduction, stride,\n                            downsample))\n        self.inplanes = planes * block.expansion\n        for i in range(1, blocks):\n            layers.append(block(self.inplanes, planes, groups, reduction))\n\n        return nn.Sequential(*layers)\n\n    def features(self, x):\n        x = self.layer0(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        return x\n\n    def logits(self, x):\n        x = self.avg_pool(x)\n        if self.dropout is not None:\n            x = self.dropout(x)\n        x = x.view(x.size(0), -1)\n        x = self.last_linear(x)\n        return x\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.logits(x)\n        return x\n\n\ndef initialize_pretrained_model(model, num_classes, settings):\n    assert num_classes == settings['num_classes'], \\\n        'num_classes should be {}, but is {}'.format(\n            settings['num_classes'], num_classes)\n    model.load_state_dict(model_zoo.load_url(settings['url']))\n    model.input_space = settings['input_space']\n    model.input_size = settings['input_size']\n    model.input_range = settings['input_range']\n    model.mean = settings['mean']\n    model.std = settings['std']\n\ndef se_resnext50_32x4d(num_classes=1000, pretrained='imagenet'):\n    model = SENet(SEResNeXtBottleneck, [3, 4, 6, 3], groups=32, reduction=16,\n                  dropout_p=None, inplanes=64, input_3x3=False,\n                  downsample_kernel_size=1, downsample_padding=0,\n                  num_classes=num_classes)\n    return model\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.nn.parameter import Parameter\n\n\nclass AdaptiveConcatPool2d(nn.Module):\n    def __init__(self, sz=None, flatten=False):\n        super().__init__()\n        sz = sz or (1, 1)\n        self.ap = nn.AdaptiveAvgPool2d(sz)\n        self.mp = nn.AdaptiveMaxPool2d(sz)\n        self.flatten_layer = Flatten()\n        self.flatten = flatten\n\n    def forward(self, x):\n        x = torch.cat([self.mp(x), self.ap(x)], 1)\n        if self.flatten:\n            x = self.flatten_layer(x)\n        return x\n    \nclass Flatten(nn.Module):\n    def __init__(self, dim=1):\n        super().__init__()\n        self.dim = dim\n\n    def forward(self, x):\n        input_shape = x.shape\n        output_shape = [input_shape[i] for i in range(self.dim)] + [-1]\n        return x.view(*output_shape)\n    \ndef drop_fc(model):\n    if model.__class__.__name__ in ['Xcit', 'Cait']:\n        nc = model.head.in_features\n        model.norm = nn.Identity()\n        model.head_drop = nn.Identity()\n        model.head = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'RegNet':\n        nc = model.head.fc.in_features\n        model.head.global_pool = nn.Identity()\n        model.head.flatten = nn.Identity()\n        model.head.drop = nn.Identity()\n        model.head.fc = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'MetaFormer':\n        nc = model.head.fc.fc1.in_features\n        model.head.global_pool = nn.Identity()\n        model.head.norm = nn.Identity()\n        model.head.flatten = nn.Identity()\n        model.head.drop = nn.Identity()\n        model.head.fc = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'Sequencer2D':\n        nc = model.head.in_features\n        model.head = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'Sam':\n        new_model = model.image_encoder\n        nc = new_model.neck[0].out_channels\n    elif 'SwinTransformer' in model.__class__.__name__:\n        nc = model.head.in_features\n        model.head = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'ConvNeXt':\n        nc = model.head.fc.in_features\n        model.head.global_pool = nn.Identity()\n        model.head.norm = nn.Identity()\n        model.head.flatten = nn.Identity()\n        model.head.drop = nn.Identity()\n        model.head.fc = nn.Identity()\n        new_model = model\n    elif model.__class__.__name__ == 'FeatureEfficientNet':\n        new_model = model\n        nc = model._fc.in_features\n    elif model.__class__.__name__ == 'RegNetX':\n        new_model = nn.Sequential(*list(model.children())[0])[:-1]\n        nc = list(model.children())[0][-1].fc.in_features\n    elif model.__class__.__name__ == 'DenseNet':\n        new_model = nn.Sequential(*list(model.children())[:-1])\n        nc = list(model.children())[-1].in_features\n    # elif model.__class__.__name__ == 'EfficientNet':\n    #     new_model = nn.Sequential(*list(model.children())[:-2])\n    #     import pdb;pdb.set_trace()\n    #     nc = 1280\n    else:\n        new_model = nn.Sequential(*list(model.children())[:-2])\n        nc = list(model.children())[-1].in_features\n    return new_model, nc\n\ndef senet_mod(base_model, in_channel=3, num_classes=1000, pretrained=False):\n    '''\n    '''\n    _pretrained = 'imagenet' if pretrained else None\n    model = base_model(pretrained=_pretrained)\n    model_name = model.__class__.__name__\n\n    if in_channel != 3:\n        model.layer0.conv1 = nn.Conv2d(in_channel, 64,\n                                    kernel_size=7, stride=2, padding=3,\n                                    bias=False)\n\n        if pretrained:  # adjust weight dim\n            with torch.no_grad():\n                trained_weight = model.layer0.conv1.weight\n                model.layer0.conv1.weight[:, :] = torch.stack(\n                    [torch.mean(trained_weight, 1)] * in_channel, dim=1)\n\n    # modify output classes\n    if num_classes is not None:\n        in_features = model.last_linear.in_features\n        model.last_linear = nn.Linear(in_features, num_classes)\n\n    return model\n\n\nclass Rsna2ndModel(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=5,\n        base_model=None,\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        self.head = nn.Sequential(\n            AdaptiveConcatPool2d(),\n            Flatten(),\n            nn.Linear(2 * nc, 512),\n            nn.ReLU(inplace=True),\n        )\n        self.fc = nn.Linear(512, num_classes)\n\n    def forward(self, x):\n        bs, n, ch, w, h = x.shape # 8, 5, 3, 384, 384\n        x = x.view(bs * n, ch, w, h) # 40, 3, 384, 384\n        x = self.encoder(x) # 40, 2048, 20, 20\n        bs2, ch2, w2, h2 = x.shape\n\n        x = (\n            x.view(-1, n, ch2, w2, h2)\n            .permute(0, 2, 1, 3, 4)\n            .contiguous()\n            .view(bs, ch2, n * w2, h2)\n        )  # x: bs x C' x N W'' x W''\n        x.size() # 16, 384, 135, 27\n        x = self.head(x)\n        x = self.fc(x)\n        return x\n    \nclass Rsna2ndModelV2(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=5,\n        center_loss_feat_dim=512,\n        base_model=None,\n        pool='avg'\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.center_loss_feat_dim = center_loss_feat_dim\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        if pool == 'avg':\n            self.pool = nn.AdaptiveAvgPool2d((1,1))\n        else:\n            self.pool = nn.AdaptiveMaxPool2d((1,1))\n        self.head = nn.Sequential(\n            Flatten(),\n            nn.Linear(nc, self.center_loss_feat_dim),\n            nn.ReLU(inplace=True),\n        )\n        self.fc = nn.Linear(self.center_loss_feat_dim, num_classes)\n\n    def forward(self, x):\n        # st()\n        # np.all(np.load('/groups/gca50041/ariyasu/rsna/results/c.npy') == x.cpu().numpy())\n        # np.save('/groups/gca50041/ariyasu/rsna/results/c.npy', x.cpu().numpy())\n        bs, n, ch, w, h = x.shape # 8, 5, 3, 384, 384\n        x = x.view(bs * n, ch, w, h) # 40, 3, 384, 384\n        x = self.encoder(x) # 40, 2048, 20, 20\n        bs2, ch2, w2, h2 = x.shape\n\n        x = (\n            x.view(-1, n, ch2, w2, h2)\n            .permute(0, 2, 1, 3, 4)\n            .contiguous()\n            .view(bs, ch2, n * w2, h2)\n        )  # x: bs x C' x N W'' x W''\n        x = self.pool(x)\n        x = self.head(x)\n        x = self.fc(x)\n        return x    \n    \nclass RSNA2ndModelV3(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=5,\n        base_model=senet_mod(se_resnext50_32x4d, pretrained=True),\n        pool='avg',\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        self.head = nn.Sequential(\n            AdaptiveConcatPool2d(),\n            Flatten(),\n            nn.Linear(2 * nc, num_classes),\n        )\n    def forward(self, x):\n        # st()\n        # np.all(np.load('/groups/gca50041/ariyasu/rsna/results/c.npy') == x.cpu().numpy())\n        # np.save('/groups/gca50041/ariyasu/rsna/results/c.npy', x.cpu().numpy())\n        bs, n, ch, w, h = x.shape # 8, 5, 3, 384, 384\n        x = x.view(bs * n, ch, w, h) # 40, 3, 384, 384\n        x = self.encoder(x) # 40, 2048, 20, 20\n        bs2, ch2, w2, h2 = x.shape\n\n        x = (\n            x.view(-1, n, ch2, w2, h2)\n            .permute(0, 2, 1, 3, 4)\n            .contiguous()\n            .view(bs, ch2, n * w2, h2)\n        )  # x: bs x C' x N W'' x W''\n        x = self.head(x)\n        return x\n    \n    \nclass Rsna2ndGRU(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=5,\n        base_model=None,\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        self.pool = nn.Sequential(\n            AdaptiveConcatPool2d(),\n        )\n        hidden_dim = 256\n        self.gru = nn.GRU(nc*2, hidden_dim, 2, batch_first=True, bidirectional=True)\n        self.fc = nn.Linear(hidden_dim*2*n_instance, num_classes)\n\n    def forward(self, x):\n        bs, n, ch, w, h = x.shape # 8, 5, 3, 384, 384\n        x = x.view(bs * n, ch, w, h) # 40, 3, 384, 384\n        x = self.encoder(x) # 40, 2048, 20, 20\n        # st()\n        x = self.pool(x)\n        x = x.view(bs, n, -1)\n        x, _ = self.gru(x)                        # (B, seq_len, hidden_dim*2)\n        x = x.reshape(bs, -1)\n        x = self.fc(x)\n        return x    \n    \nclass Rsna2ndLSTM(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=5,\n        base_model=senet_mod(se_resnext50_32x4d, pretrained=True),\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        self.pool = nn.Sequential(\n            AdaptiveConcatPool2d(),\n        )\n        hidden_dim = 256\n        self.lstm = nn.LSTM(nc*2, hidden_dim, num_layers=2, dropout=0, bidirectional=True, batch_first=True)\n        self.fc = nn.Linear(hidden_dim*2*n_instance, num_classes)\n\n    def forward(self, x):\n        bs, n, ch, w, h = x.shape\n        x = x.view(bs * n, ch, w, h)\n        x = self.encoder(x)\n        x = self.pool(x)\n        x = x.view(bs, n, -1)\n        x, _ = self.lstm(x)\n        x = x.reshape(bs, -1)\n        x = self.fc(x)\n        return x    \n    \nclass RsnaLstmXcit(nn.Module):\n    def __init__(\n        self,\n        num_classes=1,\n        n_instance=15,\n        center_loss_feat_dim=512,\n        base_model=None,\n    ):\n        super().__init__()\n        self.n_instance = n_instance\n        self.criterion = nn.CrossEntropyLoss()\n        self.center_loss_feat_dim = center_loss_feat_dim\n        self.model_name = base_model.__class__.__name__\n        self.encoder, nc = drop_fc(base_model)\n        self.pool = nn.Sequential(\n            AdaptiveConcatPool2d(),\n        )\n        hidden_dim = 256\n        self.lstm = nn.LSTM(nc, hidden_dim, num_layers=2, dropout=0, bidirectional=True, batch_first=True)\n        self.fc = nn.Linear(hidden_dim*2*n_instance, num_classes)\n\n    def forward(self, x):\n        bs, n, ch, w, h = x.shape # 1, 15, 3, 384, 384\n        x = x.view(bs * n, ch, w, h) # 15, 3, 384, 384\n        x = self.encoder(x) # 15, 384\n        x = x.view(bs, n, -1) # 1, 15, 384\n#         import pdb;pdb.set_trace()\n        x, _ = self.lstm(x)   # (1, 15, hidden_dim*2)\n        x = x.reshape(bs, -1)\n        x = self.fc(x)\n        return x\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\n\ndef select_numbers_around_m(N, m, in_chans, stride):\n    results = []\n    for i in range(in_chans):\n        i-=(in_chans-1)//2\n        i*=stride\n        if i < 0:\n            results.append(max(0, m+i))\n        else:\n            results.append(min(N, m+i))\n    return results\n\ndef get_middle_numbers(N, num_groups=15):\n    bins = np.linspace(0, N, num_groups+1, dtype=int)\n\n    middle_nums = []\n    for i in range(len(bins)-1):\n        start = bins[i]\n        end = bins[i+1]\n        mid = (start + end) // 2\n        middle_nums.append(mid)\n\n    return middle_nums\n\n\nclass RSNADataset(Dataset):\n    def __init__(self, cfg):\n        self.cfg = cfg\n        self.transforms = cfg.transforms\n\n    def __len__(self):\n        return len(self.cfg.df)\n\n    def __getitem__(self, idx):\n        images = np.load(self.cfg.df.path.values[idx])\n        if getattr(self.cfg, 'skip_each_n_slice', False):\n            images = images[[i for i in range(len(images)) if i % self.cfg.skip_each_n_slice == 0]]\n\n        indexes = get_middle_numbers(len(images), num_groups=self.cfg.n_slice_per_c)\n        transformed_images = []\n        for i in indexes:\n            ids = select_numbers_around_m(len(images)-1, i, self.cfg.in_chans, self.cfg.stride)\n            image = images[ids]\n            image = image.transpose((1,2,0))\n            image = self.transforms(image=image)['image']\n            image = image.transpose(2, 0, 1).astype(np.float32) / 255.\n            transformed_images.append(image)\n\n        images = np.stack(transformed_images, 0)\n        images = torch.tensor(images).float()\n        return images\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nimport timm\n\nclass base():\n    def __init__(self):\n        self.model_name = 'convnext_small'\n        self.batch_size = 2\n        self.tta = False\n        self.in_chans = 3\n        self.skip_each_n_slice = 1\n        self.stride = 1\n        self.n_slice_per_c = 15\n        self.label_features = ['bowel_injury', 'extravasation_injury', 'kidney_healthy', 'kidney_low', 'kidney_high', 'liver_healthy', 'liver_low', 'liver_high', 'spleen_healthy', 'spleen_low', 'spleen_high']\nclass cfg_class0_3classes_masked_caformer(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df['path'] = self.df['path'].apply(lambda x: x.replace('.npy', '_masked.npy'))\n        self.image_size = 192\n        self.config_name = 'class0_masked_192_2segmodels_pad0_caformer'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.label_features = ['liver_healthy', 'liver_low', 'liver_high']\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'caformer_s36'\nclass cfg_class0_3classes_masked_v1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df['path'] = self.df['path'].apply(lambda x: x.replace('.npy', '_masked.npy'))\n        self.image_size = 192\n        self.config_name = 'class0_masked_192_2segmodels_pad0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.label_features = ['liver_healthy', 'liver_low', 'liver_high']\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'        \nclass cfg_class0_3classes_masked_v2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df['path'] = self.df['path'].apply(lambda x: x.replace('.npy', '_masked.npy'))\n        self.image_size = 192\n        self.config_name = 'class0_masked_192_2segmodels_30epochs_pad0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.label_features = ['liver_healthy', 'liver_low', 'liver_high']\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\nclass cfg_class0_3classes_masked_v3(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df['path'] = self.df['path'].apply(lambda x: x.replace('.npy', '_masked.npy'))\n        self.image_size = 224\n        self.config_name = 'class0_masked_224_2segmodels_pad0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.label_features = ['liver_healthy', 'liver_low', 'liver_high']\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\nclass cfg_class0_3classes_masked_v4(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df['path'] = self.df['path'].apply(lambda x: x.replace('.npy', '_masked.npy'))\n        self.image_size = 256\n        self.config_name = 'class0_masked_256_2segmodels_pad0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/d/yujiariyasu/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/d/yujiariyasu/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.label_features = ['liver_healthy', 'liver_low', 'liver_high']\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\n\nclass cfg_class0_gru(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.config_name = 'class0_gru_chaug_256_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndGRU\nclass cfg_class0_gru_caformer(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 224\n        self.config_name = 'class0_gru_chaug_224_2segmodels_v3_caformer_v2'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}-v1.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}-v1.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'caformer_s36'\n        self.model_class = Rsna2ndModelV2\nclass cfg_class0_gru_rand0(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.config_name = 'class0_gru_chaug_256_2segmodels_v3_rand0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndGRU\nclass cfg_class0_maxvit(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 224\n        self.config_name = 'class0_maxvit_224_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\n\nclass cfg_class1_gru(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 128\n        self.config_name = 'class1_gru_128_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndGRU\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class1_gru_rand0(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 128\n        self.config_name = 'class1_gru_128_2segmodels_v3_rand0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndGRU\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class1_gru_rand50(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 128\n        self.config_name = 'class1_gru_128_2segmodels_v3_rand50'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndGRU\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class1_maxvit(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 224\n        self.config_name = 'class1_maxvit_224_2segmodels_25epochs_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\nclass cfg_class1_lstm(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 112\n        self.config_name = 'class1_lstm_112_2segmodels_20epochs_auc_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndLSTM\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class1_lstm_pretraind(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 112\n        self.config_name = 'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/class1-lstm-112-20epochs-auc-v3-pretrained2-fix/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/class1-lstm-112-20epochs-auc-v3-pretrained2-fix/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndLSTM\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class1_all_v1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 128\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{\"class_all_256_128_192_288_pad30_8\".replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{\"class_all_256_128_192_288_pad30_8\".replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = 'class_all_256_128_192_288_pad30_8_class1'\n        \nclass cfg_class23_all_v1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 192\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{\"class_all_256_128_192_288_pad30_8\".replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{\"class_all_256_128_192_288_pad30_8\".replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = 'class_all_256_128_192_288_pad30_8_class23'\n\nclass cfg_class2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 2]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 128\n        self.config_name = 'class_all_128_v3_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\nclass cfg_class23_xait_lstm(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.batch_size = 1\n        self.config_name = 'class23_2segmodels_v3_xcit_small'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.image_size = (192, 192)\n        self.transforms = A.Compose([\n            A.Resize(self.image_size[0], self.image_size[1])\n        ])\n        self.model_class = RsnaLstmXcit\n        self.model_name = 'xcit_small'\n\nclass cfg_class23_lstm(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.label_features = ['kidney_healthy', 'kidney_low', 'kidney_high']\n        self.config_name = 'class23_lstm_128_288_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.image_size = (128, 288)\n        self.transforms = A.Compose([\n            A.Resize(self.image_size[0], self.image_size[1])\n        ])\n        self.model_class = Rsna2ndLSTM\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class23_lstm_rand0(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.label_features = ['kidney_healthy', 'kidney_low', 'kidney_high']\n        self.config_name = 'class23_lstm_128_288_2segmodels_v3_rand0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.image_size = (128, 288)\n        self.transforms = A.Compose([\n            A.Resize(self.image_size[0], self.image_size[1])\n        ])\n        self.model_class = Rsna2ndLSTM\n        self.model_name = 'se_resnext50_32x4d'\n\nclass cfg_class23_lstm_rand50(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.label_features = ['kidney_healthy', 'kidney_low', 'kidney_high']\n        self.config_name = 'class23_lstm_128_288_2segmodels_v3_rand50'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.image_size = (128, 288)\n        self.transforms = A.Compose([\n            A.Resize(self.image_size[0], self.image_size[1])\n        ])\n        self.model_class = Rsna2ndLSTM\n        self.model_name = 'se_resnext50_32x4d'\nclass cfg_class23_maxvit(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.config_name = 'class23_maxvit_224_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\n\nclass cfg_class4_lstm_n15(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 15\n        self.config_name = 'class4_lstm_256_n15_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndLSTM\nclass cfg_class4_lstm_n15_rand0(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 15\n        self.config_name = 'class4_lstm_256_n15_2segmodels_v3_rand0'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndLSTM\nclass cfg_class4_n25(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 25\n        self.config_name = 'class4_pretrain_288_n25_2segmodels_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\nclass cfg_class4_n25_25epochs(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 25\n        self.config_name = 'class4_pretrain_288_n25_2segmodels_25epochs_v3'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\n\n\nclass cfg_class0_maxvit_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 224\n        self.config_name = 'class0_maxvit_224_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\n\nclass cfg_class23_maxvit_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.config_name = 'class23_maxvit_224_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\nclass cfg_class23_maxvit_pretrained(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.config_name = 'class23_maxvit_224_2segmodels_v4_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\n        \nclass cfg_class23_maxvit_25epochs_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.batch_size = 1\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.config_name = 'class23_maxvit_224_2segmodels_25epochs_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.model_class = Rsna2ndModel\n\nclass cfg_class4_lstm_n15_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 15\n        self.config_name = 'class4_lstm_256_n15_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndLSTM\nclass cfg_class4_lstm_n15_288_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 288\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 15\n        self.config_name = 'class4_lstm_288_n15_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_name = 'se_resnext50_32x4d'\n        self.model_class = Rsna2ndLSTM\n\nclass cfg_class4_n25_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 25\n        self.config_name = 'class4_pretrain_288_n25_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\n\nclass cfg_class4_n25_320_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 320\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 25\n        self.config_name = 'class4_pretrain_320_n25_2segmodels_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\nclass cfg_class4_n25_25epochs_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.model_name = 'convnext_small'\n        self.n_slice_per_c = 25\n        self.config_name = 'class4_pretrain_288_n25_2segmodels_25epochs_v4'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'convnext_small'\n\nclass cfg_class_all_maxvit_class1_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 224\n        self.n_slice_per_c = 15\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_maxvit_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.config_name = self.config_name+'_class1'\nclass cfg_class_all_maxvit_class0_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 224\n        self.n_slice_per_c = 15\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_maxvit_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n\n        self.config_name = self.config_name+'_class0'\nclass cfg_class_all_caformer_class0_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_caformer'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'caformer_s36'\n        self.config_name = self.config_name+'_class0'\nclass cfg_class_all_caformer_class0_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_caformer_crop2'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'caformer_s36'\n        self.config_name = self.config_name+'_class0'\nclass cfg_class_all_seresnext_class0_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 256\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_seresnext_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'se_resnext50_32x4d'\n        self.config_name = self.config_name+'_class0'\nclass cfg_class_all_seresnext_class0_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_seresnext_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'se_resnext50_32x4d'\n        self.config_name = self.config_name+'_class0'\nclass cfg_class_all_convnext_class1_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 112\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_convnext_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = self.config_name+'_class1'\nclass cfg_class_all_convnext_class1_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 1]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 128\n        self.n_slice_per_c = 15\n        self.config_name = 'class_all_pad30_convnext_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = self.config_name+'_class1'\nclass cfg_class_all_maxvit_class23_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.n_slice_per_c = 15\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_maxvit_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n        self.config_name = self.config_name+'_class23'\nclass cfg_class_all_maxvit_class23_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 224\n        self.n_slice_per_c = 15\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_maxvit_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModel\n        self.model_name = 'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k'\n\n        self.config_name = self.config_name+'_class23'\nclass cfg_class_all_caformer_class23_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 0]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.df.path = self.df.path.apply(lambda x: x.replace('0.npy', '23.npy'))\n        self.image_size = 192\n        self.n_slice_per_c = 15\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_caformer'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'caformer_s36'\n        self.config_name = self.config_name+'_class23'\nclass cfg_class_all_caformer_class4_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 256\n        self.n_slice_per_c = 25\n        self.batch_size = 1\n        self.config_name = 'class_all_pad30_caformer_crop2'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'caformer_s36'\n        self.config_name = self.config_name+'_class4'\nclass cfg_class_all_seresnext_class4_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 288\n        self.n_slice_per_c = 30\n        self.config_name = 'class_all_pad30_seresnext_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'se_resnext50_32x4d'\n        self.config_name = self.config_name+'_class4'\nclass cfg_class_all_seresnext_class4_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 288\n        self.n_slice_per_c = 30\n        self.config_name = 'class_all_pad30_seresnext_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = RSNA2ndModelV3\n        self.model_name = 'se_resnext50_32x4d'\n        self.config_name = self.config_name+'_class4'\nclass cfg_class_all_convnext_class4_datav1(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio0]\n        self.image_size = 280\n        self.n_slice_per_c = 25\n        self.config_name = 'class_all_pad30_convnext_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = self.config_name+'_class4'\nclass cfg_class_all_convnext_class4_datav2(base):\n    def __init__(self):\n        super().__init__()\n        self.df = seg_preds[seg_preds.mask_class == 4]\n        self.df = self.df[self.df.crop_image_pad_ratio == crop_image_pad_ratio1]\n        self.image_size = 288\n        self.n_slice_per_c = 25\n        self.config_name = 'class_all_pad30_convnext_crop2_pretrained'\n        if DEBUG:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{debug_fold}.ckpt' for fold in all_folds]\n        else:\n            self.model_paths = [f'/kaggle/input/{self.config_name.replace(\"_\", \"-\")}/last_fold{fold}.ckpt' for fold in all_folds]\n        self.transforms = A.Compose([\n            A.Resize(self.image_size, self.image_size)\n        ])\n        self.model_class = Rsna2ndModelV2\n        self.model_name = 'convnext_small'\n        self.config_name = self.config_name+'_class4'\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"use_config_classes = ['class0_masked_192_2segmodels_pad0_caformer', 'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2', 'class23_maxvit_224_2segmodels_v4_pretrained', 'class4_pretrain_288_n25_2segmodels_25epochs_v3', 'class4_pretrain_288_n25_2segmodels_25epochs_v4', 'class4_pretrain_288_n25_2segmodels_v3', 'class4_pretrain_288_n25_2segmodels_v4', 'class0_gru_chaug_256_2segmodels_v3', 'class0_masked_192_2segmodels_pad0', 'class23_2segmodels_v3_xcit_small', 'class_all_pad30_convnext_pretrained_class1', 'class_all_pad30_maxvit_pretrained_class1', 'class_all_pad30_maxvit_pretrained_class23', 'class_all_pad30_maxvit_crop2_pretrained_class0', 'class_all_pad30_seresnext_crop2_pretrained_class4', 'class_all_pad30_caformer_class23']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_configs = [cfg_class0_3classes_masked_v1, cfg_class0_3classes_masked_caformer, cfg_class0_gru_caformer, cfg_class_all_convnext_class4_datav2, cfg_class_all_maxvit_class23_datav2, cfg_class23_xait_lstm, cfg_class0_3classes_masked_v2, cfg_class0_3classes_masked_v3, cfg_class0_3classes_masked_v4, cfg_class0_gru, cfg_class0_gru_rand0, cfg_class0_maxvit, cfg_class1_gru, cfg_class1_gru_rand0, cfg_class1_gru_rand50, cfg_class1_maxvit, cfg_class1_lstm, cfg_class1_lstm_pretraind, cfg_class1_all_v1, cfg_class23_all_v1, cfg_class2, cfg_class23_lstm, cfg_class23_lstm_rand0, cfg_class23_lstm_rand50, cfg_class23_maxvit, cfg_class4_lstm_n15, cfg_class4_lstm_n15_rand0, cfg_class4_n25, cfg_class4_n25_25epochs, cfg_class0_maxvit_datav2, cfg_class23_maxvit_datav2, cfg_class23_maxvit_pretrained, cfg_class23_maxvit_25epochs_datav2, cfg_class4_lstm_n15_datav2, cfg_class4_lstm_n15_288_datav2, cfg_class4_n25_datav2, cfg_class4_n25_320_datav2, cfg_class4_n25_25epochs_datav2, cfg_class_all_maxvit_class1_datav1, cfg_class_all_maxvit_class0_datav2, cfg_class_all_caformer_class0_datav1, cfg_class_all_caformer_class0_datav2, cfg_class_all_seresnext_class0_datav1, cfg_class_all_seresnext_class0_datav2, cfg_class_all_convnext_class1_datav1, cfg_class_all_convnext_class1_datav2, cfg_class_all_maxvit_class23_datav1, cfg_class_all_caformer_class23_datav1, cfg_class_all_caformer_class4_datav2, cfg_class_all_seresnext_class4_datav1, cfg_class_all_seresnext_class4_datav2, cfg_class_all_convnext_class4_datav1]\n\ncfgs = []\nfor cfg_class in all_configs:\n    cfg = cfg_class()\n    if cfg.config_name in use_config_classes:\n        print(cfg.config_name)        \n        cfgs.append(cfg)\nprint(len(cfgs))\nassert len(cfgs)==len(use_config_classes)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfgs[0].df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfgs[-1].df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import gc\n\ntorch.cuda.empty_cache()\ngc.collect()\n\n!nvidia-smi","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nimport copy\nbase_models = {\n    'convnext_small': timm.create_model('convnext_small', pretrained=False, num_classes=1),\n    'se_resnext50_32x4d': senet_mod(se_resnext50_32x4d, pretrained=False),\n    'maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k': timm.create_model('maxvit_rmlp_base_rw_224.sw_in12k_ft_in1k', pretrained=False, num_classes=1),\n    'caformer_s36': timm.create_model('caformer_s36.sail_in22k_ft_in1k', pretrained=False, num_classes=1),\n    'xcit_small': timm.create_model('xcit_small_24_p8_224.fb_dist_in1k', pretrained=False, num_classes=1),\n}\n\nfor i, cfg in enumerate(cfgs):\n\n    models = []\n    for model_path in cfg.model_paths:\n        print(model_path)\n        model = cfg.model_class(base_model=copy.deepcopy(base_models[cfg.model_name]), n_instance=cfg.n_slice_per_c, num_classes=len(cfg.label_features))\n        state_dict = torch.load(model_path, map_location=torch.device('cpu'))['state_dict']\n        torch_state_dict = {}\n        for k, v in state_dict.items():\n            torch_state_dict[k[6:]] = v\n        model.load_state_dict(torch_state_dict)\n        model.to(DEVICE)\n        model.eval()\n        models.append(model)\n\n\n    ds = RSNADataset(cfg)\n    loader = DataLoader(ds, batch_size=cfg.batch_size, shuffle=False, drop_last=False, num_workers=2)\n    preds = []\n    for images in tqdm(loader, smoothing=0):\n        images = images.to(DEVICE)\n        batch_preds = []\n        for model in models:\n            batch_preds.append(model(images).detach().cpu().numpy())\n\n        if cfg.tta:\n            imsize = images.size()\n            images = torch.flip(images, (3,))\n            assert imsize == images.size()\n            for model in models:\n                batch_preds.append(model(images).detach().cpu().numpy())\n\n        preds += np.mean(batch_preds, axis=0).tolist()\n    fs = [f'{cfg.config_name}_pred_{col}' for col in cfg.label_features]\n    cfg.df[fs] = sigmoid(np.array(preds))\n    cfg.df.to_csv(f'pred_{cfg.config_name}.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if DEBUG:\n    # corr with local\n    targets = ['bowel_injury','extravasation_injury', 'kidney_healthy', 'kidney_low', 'kidney_high', 'liver_healthy', 'liver_low', 'liver_high', 'spleen_healthy', 'spleen_low', 'spleen_high']\n    configs = [cfg.config_name for cfg in cfgs]\n    for config in configs:\n        try:\n            train = pd.read_csv(\"/kaggle/input/kaggle-upload-tmp/results_16configs.csv\")\n            train = train.sort_values('image_id')\n            df = pd.read_csv(f'pred_{config}.csv')\n            train = train[train.image_id.isin(df.image_id)]\n            df = df[df.image_id.isin(train.image_id)]\n            assert np.all(df.image_id.values==train.image_id.values)\n            scores = []\n            for target in targets:\n                if f'{config}_pred_{target}' in list(df):\n                    a = df[f'{config}_pred_{target}']\n                    b = train[f'{config}_pred_{target}']\n                    score = np.corrcoef(a, b)[0][1]\n                    scores.append(score)\n            print(config, np.mean(scores))\n        except Exception as e:\n            print('error!', e)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import log_loss\n\ndef normalize_probabilities_to_one(df: pd.DataFrame, group_columns: list) -> pd.DataFrame:\n    # Normalize the sum of each row's probabilities to 100%.\n    # 0.75, 0.75 => 0.5, 0.5\n    # 0.1, 0.1 => 0.5, 0.5\n    row_totals = df[group_columns].sum(axis=1)\n    if row_totals.min() == 0:\n        raise ParticipantVisibleError('All rows must contain at least one non-zero prediction')\n    for col in group_columns:\n        df[col] /= row_totals\n    return df\n\n\ndef score_(solution: pd.DataFrame, submission: pd.DataFrame, row_id_column_name: str) -> float:\n    '''\n    Pseudocode:\n    1. For every label group (liver, bowel, etc):\n        - Normalize the sum of each row's probabilities to 100%.\n        - Calculate the sample weighted log loss.\n    2. Derive a new any_injury label by taking the max of 1 - p(healthy) for each label group\n    3. Calculate the sample weighted log loss for the new label group\n    4. Return the average of all of the label group log losses as the final score.\n    '''\n    del solution[row_id_column_name]\n    del submission[row_id_column_name]\n\n    # Run basic QC checks on the inputs\n    if not pd.api.types.is_numeric_dtype(submission.values):\n        raise ParticipantVisibleError('All submission values must be numeric')\n\n    if not np.isfinite(submission.values).all():\n        raise ParticipantVisibleError('All submission values must be finite')\n\n    if solution.min().min() < 0:\n        raise ParticipantVisibleError('All labels must be at least zero')\n    if submission.min().min() < 0:\n        raise ParticipantVisibleError('All predictions must be at least zero')\n\n    # Calculate the label group log losses\n    binary_targets = ['bowel', 'extravasation']\n    triple_level_targets = ['kidney', 'liver', 'spleen']\n    all_target_categories = binary_targets + triple_level_targets\n\n    label_group_losses = []\n    for category in all_target_categories:\n        if category in binary_targets:\n            col_group = [f'{category}_healthy', f'{category}_injury']\n        else:\n            col_group = [f'{category}_healthy', f'{category}_low', f'{category}_high']\n\n        solution = normalize_probabilities_to_one(solution, col_group)\n\n        for col in col_group:\n            if col not in submission.columns:\n                raise ParticipantVisibleError(f'Missing submission column {col}')\n        submission = normalize_probabilities_to_one(submission, col_group)\n        label_group_losses.append(\n            log_loss(\n                y_true=solution[col_group].values,\n                y_pred=submission[col_group].values,\n                sample_weight=solution[f'{category}_weight'].values\n            )\n        )\n\n    # Derive a new any_injury label by taking the max of 1 - p(healthy) for each label group\n    healthy_cols = [x + '_healthy' for x in all_target_categories]\n    any_injury_labels = (1 - solution[healthy_cols]).max(axis=1)\n    any_injury_predictions = (1 - submission[healthy_cols]).max(axis=1)\n    any_injury_loss = log_loss(\n        y_true=any_injury_labels.values,\n        y_pred=any_injury_predictions.values,\n        sample_weight=solution['any_injury_weight'].values\n    )\n\n    label_group_losses.append(any_injury_loss)\n    return label_group_losses\n\n# Assign the appropriate weights to each category\ndef create_training_solution(y_train):\n    sol_train = y_train.copy()\n    \n    # bowel healthy|injury sample weight = 1|2\n    sol_train['bowel_weight'] = np.where(sol_train['bowel_injury'] == 1, 2, 1)\n    \n    # extravasation healthy/injury sample weight = 1|6\n    sol_train['extravasation_weight'] = np.where(sol_train['extravasation_injury'] == 1, 6, 1)\n    \n    # kidney healthy|low|high sample weight = 1|2|4\n    sol_train['kidney_weight'] = np.where(sol_train['kidney_low'] == 1, 2, np.where(sol_train['kidney_high'] == 1, 4, 1))\n    \n    # liver healthy|low|high sample weight = 1|2|4\n    sol_train['liver_weight'] = np.where(sol_train['liver_low'] == 1, 2, np.where(sol_train['liver_high'] == 1, 4, 1))\n    \n    # spleen healthy|low|high sample weight = 1|2|4\n    sol_train['spleen_weight'] = np.where(sol_train['spleen_low'] == 1, 2, np.where(sol_train['spleen_high'] == 1, 4, 1))\n    \n    # any healthy|injury sample weight = 1|6\n    sol_train['any_injury_weight'] = np.where(sol_train['any_injury'] == 1, 6, 1)\n    return sol_train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"config_weight_map = {'bowel_injury': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.0,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.09760990923198125,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.017484029299020234,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.15557507585208313,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.3471958037714562,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.0002920103452726994,\n  'class0_gru_chaug_256_2segmodels_v3': 0.05102002806193439,\n  'class23_2segmodels_v3_xcit_small': 8.597365646523263e-06,\n  'class_all_pad30_convnext_pretrained_class1': 2.145636640582671e-06,\n  'class_all_pad30_maxvit_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class23': 0.04406096361732614,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.2577656094556067,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.028958163141525155,\n  'class_all_pad30_caformer_class23': 2.7664221507002947e-05},\n 'extravasation_injury': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.01773348131393702,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.00032921454733611565,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 7.318518409077412e-05,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.1852411451619099,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.0006165243730621772,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.28224235472393655,\n  'class0_gru_chaug_256_2segmodels_v3': 0.21888276791138542,\n  'class23_2segmodels_v3_xcit_small': 0.12280157100258621,\n  'class_all_pad30_convnext_pretrained_class1': 0.04388770613351647,\n  'class_all_pad30_maxvit_pretrained_class1': 0.04225903997425848,\n  'class_all_pad30_maxvit_pretrained_class23': 0.0005940536081254339,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 9.816636086934144e-06,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.08521387554654238,\n  'class_all_pad30_caformer_class23': 0.00011526388322612811},\n 'kidney_healthy': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.04024521630010135,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.15570063889539532,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.05331309055867876,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.14046459871906472,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.05909721479516499,\n  'class4_pretrain_288_n25_2segmodels_v4': 3.8026178609552865e-06,\n  'class0_gru_chaug_256_2segmodels_v3': 2.2485787826142488e-07,\n  'class23_2segmodels_v3_xcit_small': 0.06630278751876553,\n  'class_all_pad30_convnext_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class1': 0.008888853469286764,\n  'class_all_pad30_maxvit_pretrained_class23': 0.20253927110417294,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.13407730414884014,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.04612663256386639,\n  'class_all_pad30_caformer_class23': 0.09324036445092385},\n 'kidney_low': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.07326460858720989,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.17978807434959634,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.04557880295020966,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.11653082878973132,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.023962534988961465,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.0,\n  'class0_gru_chaug_256_2segmodels_v3': 0.0034975020603592805,\n  'class23_2segmodels_v3_xcit_small': 0.031553755280529734,\n  'class_all_pad30_convnext_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class1': 0.0002858767318897195,\n  'class_all_pad30_maxvit_pretrained_class23': 0.18005977053720743,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.2199262866532473,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.0002441665190898848,\n  'class_all_pad30_caformer_class23': 0.125307792551968},\n 'kidney_high': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.0,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.35880761904005737,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 9.999813051192072e-05,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 1.5348056935726654e-05,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.0,\n  'class4_pretrain_288_n25_2segmodels_v4': 3.276200218978046e-05,\n  'class0_gru_chaug_256_2segmodels_v3': 7.007355460708246e-06,\n  'class23_2segmodels_v3_xcit_small': 0.13733404952254602,\n  'class_all_pad30_convnext_pretrained_class1': 7.408938323522561e-06,\n  'class_all_pad30_maxvit_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class23': 0.1764642644836654,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.23770966082019188,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 1.7994334503328415e-05,\n  'class_all_pad30_caformer_class23': 0.08950388731561416},\n 'liver_healthy': {'class0_masked_192_2segmodels_pad0_caformer': 0.35640096924568954,\n  'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 5.2671948328299444e-05,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.07443756858816378,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.009270814876601939,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.00020300414919794952,\n  'class4_pretrain_288_n25_2segmodels_v3': 5.50173699604284e-05,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.07418221975437064,\n  'class0_gru_chaug_256_2segmodels_v3': 0.08380050280031154,\n  'class0_masked_192_2segmodels_pad0': 0.20073442909844016,\n  'class23_2segmodels_v3_xcit_small': 9.214736323829903e-06,\n  'class_all_pad30_convnext_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class1': 3.1742845805153846e-06,\n  'class_all_pad30_maxvit_pretrained_class23': 0.01656988568865506,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.10769297180033947,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.0,\n  'class_all_pad30_caformer_class23': 0.07658755565903685},\n 'liver_low': {'class0_masked_192_2segmodels_pad0_caformer': 0.400956761738372,\n  'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 5.2715524033282384e-05,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.0,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.022574143696804,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.043188794172523824,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.025196956494929708,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.0049001607004717975,\n  'class0_gru_chaug_256_2segmodels_v3': 0.08263224334334181,\n  'class0_masked_192_2segmodels_pad0': 0.1692723460652936,\n  'class23_2segmodels_v3_xcit_small': 0.0,\n  'class_all_pad30_convnext_pretrained_class1': 0.01772748097175195,\n  'class_all_pad30_maxvit_pretrained_class1': 0.0003023410128433735,\n  'class_all_pad30_maxvit_pretrained_class23': 0.0,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.16314709342687655,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.0005579025117737483,\n  'class_all_pad30_caformer_class23': 0.06949106034098437},\n 'liver_high': {'class0_masked_192_2segmodels_pad0_caformer': 0.5284426988644598,\n  'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.0033427182923129028,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.026836765047524528,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.006858639538660821,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.0,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.0046126801055347295,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.0,\n  'class0_gru_chaug_256_2segmodels_v3': 0.00214825445457919,\n  'class0_masked_192_2segmodels_pad0': 0.2183691179737026,\n  'class23_2segmodels_v3_xcit_small': 1.546646105018104e-05,\n  'class_all_pad30_convnext_pretrained_class1': 0.013619283115761709,\n  'class_all_pad30_maxvit_pretrained_class1': 0.0,\n  'class_all_pad30_maxvit_pretrained_class23': 0.07837921740811048,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.1164672198052341,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.00025458733289442906,\n  'class_all_pad30_caformer_class23': 0.0006533516001746512},\n 'spleen_healthy': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.10537134414286883,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.08202138721441507,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.0025387458336458414,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 2.9140388105997628e-06,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.03989522709536908,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.025607878092980596,\n  'class0_gru_chaug_256_2segmodels_v3': 0.0,\n  'class23_2segmodels_v3_xcit_small': 0.025586889531219816,\n  'class_all_pad30_convnext_pretrained_class1': 0.11690601441540494,\n  'class_all_pad30_maxvit_pretrained_class1': 0.38366035785290664,\n  'class_all_pad30_maxvit_pretrained_class23': 0.1301944670982606,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.03506566346533577,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.03559553232174026,\n  'class_all_pad30_caformer_class23': 0.01755357889704201},\n 'spleen_low': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.1212736707407892,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 0.16758691248214355,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 2.9348049561528243e-06,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 0.041763060754558344,\n  'class4_pretrain_288_n25_2segmodels_v3': 2.0780139099425803e-05,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.022957644509919363,\n  'class0_gru_chaug_256_2segmodels_v3': 8.663561977713262e-07,\n  'class23_2segmodels_v3_xcit_small': 0.06451031504273048,\n  'class_all_pad30_convnext_pretrained_class1': 0.10594965617776053,\n  'class_all_pad30_maxvit_pretrained_class1': 0.3193166660046087,\n  'class_all_pad30_maxvit_pretrained_class23': 0.14094774080566053,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.0,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.0,\n  'class_all_pad30_caformer_class23': 0.015669752181576013},\n 'spleen_high': {'class1_lstm_112_2segmodels_20epochs_auc_v3_pretrained2': 0.16916463922263758,\n  'class23_maxvit_224_2segmodels_v4_pretrained': 1.0881469444440651e-06,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v3': 0.07232866991111923,\n  'class4_pretrain_288_n25_2segmodels_25epochs_v4': 1.4932459836652226e-06,\n  'class4_pretrain_288_n25_2segmodels_v3': 0.0322176953034101,\n  'class4_pretrain_288_n25_2segmodels_v4': 0.04888051313680189,\n  'class0_gru_chaug_256_2segmodels_v3': 0.0,\n  'class23_2segmodels_v3_xcit_small': 2.4656184218280352e-06,\n  'class_all_pad30_convnext_pretrained_class1': 0.29668150601724863,\n  'class_all_pad30_maxvit_pretrained_class1': 0.2564415849430282,\n  'class_all_pad30_maxvit_pretrained_class23': 3.173045620012575e-06,\n  'class_all_pad30_maxvit_crop2_pretrained_class0': 0.009242935503606883,\n  'class_all_pad30_seresnext_crop2_pretrained_class4': 0.061352542943100274,\n  'class_all_pad30_caformer_class23': 0.05368169296207717}}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = cfgs[0].df.copy()\nfor cfg_n, cfg in enumerate(cfgs):\n    if cfg_n==0: continue\n    df = cfg.df.drop_duplicates('patient_id')\n\n    fs = []\n    for col in ['bowel_injury', 'extravasation_injury', 'kidney_healthy', 'kidney_low', 'kidney_high', 'liver_healthy', 'liver_low', 'liver_high', 'spleen_healthy', 'spleen_low', 'spleen_high']:\n        fs += [c for c in list(df) if col in c]\n    preds = preds.merge(df[fs+['patient_id']], on='patient_id', how='left')\n\nfs = ['bowel_injury', 'extravasation_injury', 'kidney_healthy', 'kidney_low', 'kidney_high', 'liver_healthy', 'liver_low', 'liver_high', 'spleen_healthy', 'spleen_low', 'spleen_high']\nfor col in fs:\n    predictions = 0\n    for cfg in cfgs:\n        if f'{cfg.config_name}_pred_{col}' in list(cfg.df):\n            preds[f'{cfg.config_name}_pred_{col}'] = preds[f'{cfg.config_name}_pred_{col}'].fillna(preds[f'{cfg.config_name}_pred_{col}'].mean())\n            predictions+=preds[f'{cfg.config_name}_pred_{col}'].values*config_weight_map[col][cfg.config_name]\n    preds[col] = predictions\npreds = preds[['patient_id']+fs]\n\npreds['bowel_healthy'] = 1- preds['bowel_injury']\npreds['extravasation_healthy'] = 1- preds['extravasation_injury']\n\nws = [('bowel_healthy', 0.0835), ('bowel_injury', 0.2004), ('extravasation_healthy', 0.0795), ('extravasation_injury', 0.9113), ('kidney_healthy', 0.0704), ('kidney_low', 0.223), ('kidney_high', 0.4324), ('liver_healthy', 0.0733), ('liver_low', 0.2027), ('liver_high', 0.4026), ('spleen_healthy', 0.0718), ('spleen_low', 0.2428), ('spleen_high', 0.3802)]\n\nfor w in ws:\n    preds[w[0]] = preds[w[0]]*w[1]\n\npreds.to_csv('submission.csv', index=False)    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if len(glob(\"/kaggle/input/rsna-2023-abdominal-trauma-detection/test_images/*/*/*.dcm\")) == 3:\n    try:\n        train = pd.read_csv('/kaggle/input/kaggle-upload-tmp/train2.5d_bad_fold_v3_th0.2.csv')\n        train = train[train.patient_id.isin(preds.patient_id)].drop_duplicates('patient_id')\n        solution_train = create_training_solution(train[['patient_id', 'any_injury','bowel_healthy','bowel_injury','extravasation_healthy', 'extravasation_injury', 'kidney_healthy', 'kidney_low', 'kidney_high', 'liver_healthy', 'liver_low', 'liver_high', 'spleen_healthy', 'spleen_low', 'spleen_high']])\n        scores = score_(solution_train.copy(), preds.copy(),'patient_id')\n        print(f'score: {np.mean(scores)}')\n        print([(m, round(v, 4)) for v,m in zip(scores, ['bowel', 'extravasation', 'kidney', 'liver', 'spleen', 'all'])])\n    except Exception as e:\n        print(e)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}