Spaces:
Sleeping
Sleeping
Refactor application
Browse files- app.ipynb +189 -0
- app.py +131 -22
- cnn-swinunet/config.json +1 -0
- cnn-swinunet/metadata.json +1 -0
- cnn.tflite → cnn-swinunet/model.weights.h5 +2 -2
- requirements.txt +7 -3
- swinunet.pth +3 -0
app.ipynb
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 2,
|
6 |
+
"id": "877fa66b",
|
7 |
+
"metadata": {},
|
8 |
+
"outputs": [
|
9 |
+
{
|
10 |
+
"ename": "OSError",
|
11 |
+
"evalue": "Unable to synchronously open file (file signature not found)",
|
12 |
+
"output_type": "error",
|
13 |
+
"traceback": [
|
14 |
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
15 |
+
"\u001b[1;31mOSError\u001b[0m Traceback (most recent call last)",
|
16 |
+
"Cell \u001b[1;32mIn[2], line 95\u001b[0m\n\u001b[0;32m 92\u001b[0m swinunet_model\u001b[38;5;241m.\u001b[39meval()\n\u001b[0;32m 94\u001b[0m \u001b[38;5;66;03m# ----------- Load Classifier Model -----------\u001b[39;00m\n\u001b[1;32m---> 95\u001b[0m classifier_model \u001b[38;5;241m=\u001b[39m \u001b[43mtf\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkeras\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodels\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m./cnn-swinunet.keras\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 97\u001b[0m \u001b[38;5;66;03m# ----------- Transform -----------\u001b[39;00m\n\u001b[0;32m 98\u001b[0m transform \u001b[38;5;241m=\u001b[39m T\u001b[38;5;241m.\u001b[39mCompose([\n\u001b[0;32m 99\u001b[0m T\u001b[38;5;241m.\u001b[39mResize((\u001b[38;5;241m224\u001b[39m, \u001b[38;5;241m224\u001b[39m)),\n\u001b[0;32m 100\u001b[0m T\u001b[38;5;241m.\u001b[39mToTensor()\n\u001b[0;32m 101\u001b[0m ])\n",
|
17 |
+
"File \u001b[1;32mc:\\Users\\PC\\anaconda3\\envs\\main-gpu\\lib\\site-packages\\keras\\utils\\traceback_utils.py:70\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 67\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n\u001b[0;32m 68\u001b[0m \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[0;32m 69\u001b[0m \u001b[38;5;66;03m# `tf.debugging.disable_traceback_filtering()`\u001b[39;00m\n\u001b[1;32m---> 70\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 71\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[0;32m 72\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m filtered_tb\n",
|
18 |
+
"File \u001b[1;32mc:\\Users\\PC\\anaconda3\\envs\\main-gpu\\lib\\site-packages\\h5py\\_hl\\files.py:564\u001b[0m, in \u001b[0;36mFile.__init__\u001b[1;34m(self, name, mode, driver, libver, userblock_size, swmr, rdcc_nslots, rdcc_nbytes, rdcc_w0, track_order, fs_strategy, fs_persist, fs_threshold, fs_page_size, page_buf_size, min_meta_keep, min_raw_keep, locking, alignment_threshold, alignment_interval, meta_block_size, **kwds)\u001b[0m\n\u001b[0;32m 555\u001b[0m fapl \u001b[38;5;241m=\u001b[39m make_fapl(driver, libver, rdcc_nslots, rdcc_nbytes, rdcc_w0,\n\u001b[0;32m 556\u001b[0m locking, page_buf_size, min_meta_keep, min_raw_keep,\n\u001b[0;32m 557\u001b[0m alignment_threshold\u001b[38;5;241m=\u001b[39malignment_threshold,\n\u001b[0;32m 558\u001b[0m alignment_interval\u001b[38;5;241m=\u001b[39malignment_interval,\n\u001b[0;32m 559\u001b[0m meta_block_size\u001b[38;5;241m=\u001b[39mmeta_block_size,\n\u001b[0;32m 560\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds)\n\u001b[0;32m 561\u001b[0m fcpl \u001b[38;5;241m=\u001b[39m make_fcpl(track_order\u001b[38;5;241m=\u001b[39mtrack_order, fs_strategy\u001b[38;5;241m=\u001b[39mfs_strategy,\n\u001b[0;32m 562\u001b[0m fs_persist\u001b[38;5;241m=\u001b[39mfs_persist, fs_threshold\u001b[38;5;241m=\u001b[39mfs_threshold,\n\u001b[0;32m 563\u001b[0m fs_page_size\u001b[38;5;241m=\u001b[39mfs_page_size)\n\u001b[1;32m--> 564\u001b[0m fid \u001b[38;5;241m=\u001b[39m \u001b[43mmake_fid\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmode\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43muserblock_size\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfapl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfcpl\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mswmr\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mswmr\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 566\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(libver, \u001b[38;5;28mtuple\u001b[39m):\n\u001b[0;32m 567\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_libver \u001b[38;5;241m=\u001b[39m libver\n",
|
19 |
+
"File \u001b[1;32mc:\\Users\\PC\\anaconda3\\envs\\main-gpu\\lib\\site-packages\\h5py\\_hl\\files.py:238\u001b[0m, in \u001b[0;36mmake_fid\u001b[1;34m(name, mode, userblock_size, fapl, fcpl, swmr)\u001b[0m\n\u001b[0;32m 236\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m swmr \u001b[38;5;129;01mand\u001b[39;00m swmr_support:\n\u001b[0;32m 237\u001b[0m flags \u001b[38;5;241m|\u001b[39m\u001b[38;5;241m=\u001b[39m h5f\u001b[38;5;241m.\u001b[39mACC_SWMR_READ\n\u001b[1;32m--> 238\u001b[0m fid \u001b[38;5;241m=\u001b[39m \u001b[43mh5f\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mflags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfapl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfapl\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 239\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m mode \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mr+\u001b[39m\u001b[38;5;124m'\u001b[39m:\n\u001b[0;32m 240\u001b[0m fid \u001b[38;5;241m=\u001b[39m h5f\u001b[38;5;241m.\u001b[39mopen(name, h5f\u001b[38;5;241m.\u001b[39mACC_RDWR, fapl\u001b[38;5;241m=\u001b[39mfapl)\n",
|
20 |
+
"File \u001b[1;32mh5py\\\\_objects.pyx:54\u001b[0m, in \u001b[0;36mh5py._objects.with_phil.wrapper\u001b[1;34m()\u001b[0m\n",
|
21 |
+
"File \u001b[1;32mh5py\\\\_objects.pyx:55\u001b[0m, in \u001b[0;36mh5py._objects.with_phil.wrapper\u001b[1;34m()\u001b[0m\n",
|
22 |
+
"File \u001b[1;32mh5py\\\\h5f.pyx:102\u001b[0m, in \u001b[0;36mh5py.h5f.open\u001b[1;34m()\u001b[0m\n",
|
23 |
+
"\u001b[1;31mOSError\u001b[0m: Unable to synchronously open file (file signature not found)"
|
24 |
+
]
|
25 |
+
}
|
26 |
+
],
|
27 |
+
"source": [
|
28 |
+
"import gradio as gr\n",
|
29 |
+
"import numpy as np\n",
|
30 |
+
"import timm\n",
|
31 |
+
"import torch\n",
|
32 |
+
"import torch.nn as nn\n",
|
33 |
+
"import torch.nn.functional as F\n",
|
34 |
+
"import torchvision.transforms as T\n",
|
35 |
+
"import tensorflow as tf\n",
|
36 |
+
"from PIL import Image\n",
|
37 |
+
"from skimage.transform import resize\n",
|
38 |
+
"\n",
|
39 |
+
"# ----------- Constants -----------\n",
|
40 |
+
"CLASSES = [\"Glioma\", \"Meningioma\", \"No Tumor\", \"Pituitary\"]\n",
|
41 |
+
"IMG_SIZE = (224, 224)\n",
|
42 |
+
"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
|
43 |
+
"\n",
|
44 |
+
"# ----------- Segmentation Model Definition -----------\n",
|
45 |
+
"swin = timm.create_model('swin_base_patch4_window7_224', pretrained = False, features_only = True)\n",
|
46 |
+
"\n",
|
47 |
+
"class UNetDecoder(nn.Module):\n",
|
48 |
+
" def __init__(self):\n",
|
49 |
+
" super().__init__()\n",
|
50 |
+
"\n",
|
51 |
+
" def conv_block(in_c, out_c):\n",
|
52 |
+
" return nn.Sequential(\n",
|
53 |
+
" nn.Conv2d(in_c, out_c, kernel_size=3, padding=1),\n",
|
54 |
+
" nn.ReLU(inplace=True),\n",
|
55 |
+
" nn.Conv2d(out_c, out_c, kernel_size=3, padding=1),\n",
|
56 |
+
" nn.ReLU(inplace=True)\n",
|
57 |
+
" )\n",
|
58 |
+
"\n",
|
59 |
+
" self.up3 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2)\n",
|
60 |
+
" self.dec3 = conv_block(768, 256)\n",
|
61 |
+
"\n",
|
62 |
+
" self.up2 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2)\n",
|
63 |
+
" self.dec2 = conv_block(384, 128)\n",
|
64 |
+
"\n",
|
65 |
+
" self.up1 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2)\n",
|
66 |
+
" self.dec1 = conv_block(192, 64)\n",
|
67 |
+
"\n",
|
68 |
+
" self.final = nn.Conv2d(64, 1, kernel_size=1)\n",
|
69 |
+
"\n",
|
70 |
+
" def forward(self, features):\n",
|
71 |
+
" e1, e2, e3, e4 = features # e4 is reduced 512 channels\n",
|
72 |
+
"\n",
|
73 |
+
" d3 = self.up3(e4)\n",
|
74 |
+
" d3 = self.dec3(torch.cat([d3, e3], dim=1)) # concat 256 + 512 = 768\n",
|
75 |
+
"\n",
|
76 |
+
" d2 = self.up2(d3)\n",
|
77 |
+
" d2 = self.dec2(torch.cat([d2, e2], dim=1)) # concat 128 + 256 = 384\n",
|
78 |
+
"\n",
|
79 |
+
" d1 = self.up1(d2)\n",
|
80 |
+
" d1 = self.dec1(torch.cat([d1, e1], dim=1)) # concat 64 + 128 = 192\n",
|
81 |
+
"\n",
|
82 |
+
" out = F.interpolate(d1, scale_factor=4, mode='bilinear', align_corners=False)\n",
|
83 |
+
" return torch.sigmoid(self.final(out))\n",
|
84 |
+
" \n",
|
85 |
+
"class SwinUNet(nn.Module):\n",
|
86 |
+
" def __init__(self):\n",
|
87 |
+
" super().__init__()\n",
|
88 |
+
" self.encoder = swin\n",
|
89 |
+
" self.channel_reducer = nn.Conv2d(1024, 512, kernel_size=1)\n",
|
90 |
+
" self.decoder = UNetDecoder()\n",
|
91 |
+
"\n",
|
92 |
+
" def forward(self, x):\n",
|
93 |
+
" if x.shape[1] == 1:\n",
|
94 |
+
" x = x.repeat(1, 3, 1, 1)\n",
|
95 |
+
"\n",
|
96 |
+
" features = self.encoder(x)\n",
|
97 |
+
" features = [self._to_channels_first(f) for f in features]\n",
|
98 |
+
"\n",
|
99 |
+
" features[3] = self.channel_reducer(features[3])\n",
|
100 |
+
"\n",
|
101 |
+
" output = self.decoder(features)\n",
|
102 |
+
" return output\n",
|
103 |
+
"\n",
|
104 |
+
" def _to_channels_first(self, feature):\n",
|
105 |
+
" if feature.dim() == 4:\n",
|
106 |
+
" return feature.permute(0, 3, 1, 2).contiguous()\n",
|
107 |
+
" elif feature.dim() == 3:\n",
|
108 |
+
" B, N, C = feature.shape\n",
|
109 |
+
" H = W = int(N ** 0.5)\n",
|
110 |
+
" feature = feature.permute(0, 2, 1).contiguous()\n",
|
111 |
+
" return feature.view(B, C, H, W)\n",
|
112 |
+
" else:\n",
|
113 |
+
" raise ValueError(f\"Unexpected feature shape: {feature.shape}\")\n",
|
114 |
+
"\n",
|
115 |
+
"# ----------- Load Swin-UNet -----------\n",
|
116 |
+
"swinunet_model = SwinUNet()\n",
|
117 |
+
"swinunet_model.load_state_dict(torch.load(\"./swinunet.pth\", map_location = device))\n",
|
118 |
+
"swinunet_model = swinunet_model.to(device)\n",
|
119 |
+
"swinunet_model.eval()\n",
|
120 |
+
"\n",
|
121 |
+
"# ----------- Load Classifier Model -----------\n",
|
122 |
+
"classifier_model = tf.keras.models.load_model(\"./cnn-swinunet.keras\")\n",
|
123 |
+
"\n",
|
124 |
+
"# ----------- Transform -----------\n",
|
125 |
+
"transform = T.Compose([\n",
|
126 |
+
" T.Resize((224, 224)),\n",
|
127 |
+
" T.ToTensor()\n",
|
128 |
+
"])\n",
|
129 |
+
"\n",
|
130 |
+
"# ----------- Segmentation -----------\n",
|
131 |
+
"def segmentation(image: Image.Image) -> np.ndarray:\n",
|
132 |
+
" # Convert to grayscale and tensor\n",
|
133 |
+
" image = image.convert(\"L\")\n",
|
134 |
+
" input_tensor = transform(image).unsqueeze(0).to(device) # [1, 1, 224, 224]\n",
|
135 |
+
"\n",
|
136 |
+
" with torch.no_grad():\n",
|
137 |
+
" mask_pred = swinunet_model(input_tensor)\n",
|
138 |
+
" mask_pred = F.interpolate(mask_pred, size=(224, 224), mode=\"bilinear\", align_corners=False)\n",
|
139 |
+
" mask_pred = (mask_pred > 0.5).float()\n",
|
140 |
+
"\n",
|
141 |
+
" image_np = input_tensor.squeeze().cpu().numpy() # [224, 224]\n",
|
142 |
+
" mask_np = mask_pred.squeeze().cpu().numpy() # [224, 224]\n",
|
143 |
+
" \n",
|
144 |
+
" combined = np.stack([image_np, mask_np], axis=-1) # [224, 224, 2]\n",
|
145 |
+
" return combined\n",
|
146 |
+
"\n",
|
147 |
+
"def predict(image: Image.Image):\n",
|
148 |
+
" combined = segmentation(image)\n",
|
149 |
+
" combined = np.expand_dims(combined, axis=0) # Shape: (1, 224, 224, 2)\n",
|
150 |
+
"\n",
|
151 |
+
" probs = classifier_model.predict(combined)[0]\n",
|
152 |
+
"\n",
|
153 |
+
" return CLASSES[int(np.argmax(probs, axis=1)[0])]\n",
|
154 |
+
"\n",
|
155 |
+
"demo = gr.Interface(\n",
|
156 |
+
" fn = predict,\n",
|
157 |
+
" inputs = gr.Image(type=\"pil\", label=\"Brain MRI\"),\n",
|
158 |
+
" outputs = gr.Label(num_top_classes=4),\n",
|
159 |
+
" title = \"Brain‑Tumor Classifier (.tflite)\",\n",
|
160 |
+
" description = \"Returns: Glioma, Meningioma, No Tumor, Pituitary\"\n",
|
161 |
+
")\n",
|
162 |
+
"\n",
|
163 |
+
"\n",
|
164 |
+
"demo.launch()\n"
|
165 |
+
]
|
166 |
+
}
|
167 |
+
],
|
168 |
+
"metadata": {
|
169 |
+
"kernelspec": {
|
170 |
+
"display_name": "main-gpu",
|
171 |
+
"language": "python",
|
172 |
+
"name": "python3"
|
173 |
+
},
|
174 |
+
"language_info": {
|
175 |
+
"codemirror_mode": {
|
176 |
+
"name": "ipython",
|
177 |
+
"version": 3
|
178 |
+
},
|
179 |
+
"file_extension": ".py",
|
180 |
+
"mimetype": "text/x-python",
|
181 |
+
"name": "python",
|
182 |
+
"nbconvert_exporter": "python",
|
183 |
+
"pygments_lexer": "ipython3",
|
184 |
+
"version": "3.10.16"
|
185 |
+
}
|
186 |
+
},
|
187 |
+
"nbformat": 4,
|
188 |
+
"nbformat_minor": 5
|
189 |
+
}
|
app.py
CHANGED
@@ -1,35 +1,144 @@
|
|
1 |
import gradio as gr
|
2 |
-
import tensorflow as tf
|
3 |
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
from PIL import Image
|
|
|
5 |
|
6 |
-
|
7 |
-
interpreter.allocate_tensors()
|
8 |
-
input_details = interpreter.get_input_details()
|
9 |
-
output_details = interpreter.get_output_details()
|
10 |
-
|
11 |
CLASSES = ["Glioma", "Meningioma", "No Tumor", "Pituitary"]
|
12 |
IMG_SIZE = (224, 224)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
def
|
15 |
-
|
16 |
-
|
17 |
-
return np.expand_dims(arr, 0)
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
demo = gr.Interface(
|
27 |
-
fn=predict,
|
28 |
-
inputs=gr.Image(type="pil", label="Brain MRI"),
|
29 |
-
outputs=gr.Label(num_top_classes=4),
|
30 |
-
title="Brain‑Tumor
|
31 |
-
description="Returns: Glioma, Meningioma, No Tumor, Pituitary"
|
32 |
)
|
33 |
|
34 |
-
|
|
|
|
|
35 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
|
|
2 |
import numpy as np
|
3 |
+
import timm
|
4 |
+
import torch
|
5 |
+
import torch.nn as nn
|
6 |
+
import torch.nn.functional as F
|
7 |
+
import torchvision.transforms as T
|
8 |
+
import keras
|
9 |
+
import traceback
|
10 |
from PIL import Image
|
11 |
+
from skimage.transform import resize
|
12 |
|
13 |
+
# ----------- Constants -----------
|
|
|
|
|
|
|
|
|
14 |
CLASSES = ["Glioma", "Meningioma", "No Tumor", "Pituitary"]
|
15 |
IMG_SIZE = (224, 224)
|
16 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
17 |
+
|
18 |
+
# ----------- Segmentation Model Definition -----------
|
19 |
+
swin = timm.create_model('swin_base_patch4_window7_224', pretrained = False, features_only = True)
|
20 |
+
|
21 |
+
class UNetDecoder(nn.Module):
|
22 |
+
def __init__(self):
|
23 |
+
super().__init__()
|
24 |
+
|
25 |
+
def conv_block(in_c, out_c):
|
26 |
+
return nn.Sequential(
|
27 |
+
nn.Conv2d(in_c, out_c, kernel_size=3, padding=1),
|
28 |
+
nn.ReLU(inplace=True),
|
29 |
+
nn.Conv2d(out_c, out_c, kernel_size=3, padding=1),
|
30 |
+
nn.ReLU(inplace=True)
|
31 |
+
)
|
32 |
+
|
33 |
+
self.up3 = nn.ConvTranspose2d(512, 256, kernel_size=2, stride=2)
|
34 |
+
self.dec3 = conv_block(768, 256)
|
35 |
+
|
36 |
+
self.up2 = nn.ConvTranspose2d(256, 128, kernel_size=2, stride=2)
|
37 |
+
self.dec2 = conv_block(384, 128)
|
38 |
+
|
39 |
+
self.up1 = nn.ConvTranspose2d(128, 64, kernel_size=2, stride=2)
|
40 |
+
self.dec1 = conv_block(192, 64)
|
41 |
+
|
42 |
+
self.final = nn.Conv2d(64, 1, kernel_size=1)
|
43 |
+
|
44 |
+
def forward(self, features):
|
45 |
+
e1, e2, e3, e4 = features # e4 is reduced 512 channels
|
46 |
+
|
47 |
+
d3 = self.up3(e4)
|
48 |
+
d3 = self.dec3(torch.cat([d3, e3], dim=1)) # concat 256 + 512 = 768
|
49 |
+
|
50 |
+
d2 = self.up2(d3)
|
51 |
+
d2 = self.dec2(torch.cat([d2, e2], dim=1)) # concat 128 + 256 = 384
|
52 |
+
|
53 |
+
d1 = self.up1(d2)
|
54 |
+
d1 = self.dec1(torch.cat([d1, e1], dim=1)) # concat 64 + 128 = 192
|
55 |
+
|
56 |
+
out = F.interpolate(d1, scale_factor=4, mode='bilinear', align_corners=False)
|
57 |
+
return torch.sigmoid(self.final(out))
|
58 |
+
|
59 |
+
class SwinUNet(nn.Module):
|
60 |
+
def __init__(self):
|
61 |
+
super().__init__()
|
62 |
+
self.encoder = swin
|
63 |
+
self.channel_reducer = nn.Conv2d(1024, 512, kernel_size=1)
|
64 |
+
self.decoder = UNetDecoder()
|
65 |
|
66 |
+
def forward(self, x):
|
67 |
+
if x.shape[1] == 1:
|
68 |
+
x = x.repeat(1, 3, 1, 1)
|
|
|
69 |
|
70 |
+
features = self.encoder(x)
|
71 |
+
features = [self._to_channels_first(f) for f in features]
|
72 |
+
|
73 |
+
features[3] = self.channel_reducer(features[3])
|
74 |
+
|
75 |
+
output = self.decoder(features)
|
76 |
+
return output
|
77 |
+
|
78 |
+
def _to_channels_first(self, feature):
|
79 |
+
if feature.dim() == 4:
|
80 |
+
return feature.permute(0, 3, 1, 2).contiguous()
|
81 |
+
elif feature.dim() == 3:
|
82 |
+
B, N, C = feature.shape
|
83 |
+
H = W = int(N ** 0.5)
|
84 |
+
feature = feature.permute(0, 2, 1).contiguous()
|
85 |
+
return feature.view(B, C, H, W)
|
86 |
+
else:
|
87 |
+
raise ValueError(f"Unexpected feature shape: {feature.shape}")
|
88 |
+
|
89 |
+
# ----------- Load Swin-UNet -----------
|
90 |
+
swinunet_model = SwinUNet()
|
91 |
+
swinunet_model.load_state_dict(torch.load("swinunet.pth", map_location = device))
|
92 |
+
swinunet_model = swinunet_model.to(device)
|
93 |
+
swinunet_model.eval()
|
94 |
+
|
95 |
+
# ----------- Load Classifier Model -----------
|
96 |
+
classifier_model = keras.models.load_model("cnn-swinunet")
|
97 |
+
|
98 |
+
# ----------- Transform -----------
|
99 |
+
transform = T.Compose([
|
100 |
+
T.Resize((224, 224)),
|
101 |
+
T.ToTensor()
|
102 |
+
])
|
103 |
+
|
104 |
+
# ----------- Segmentation -----------
|
105 |
+
def segmentation(image: Image.Image) -> np.ndarray:
|
106 |
+
# Convert to grayscale and tensor
|
107 |
+
image = image.convert("L")
|
108 |
+
input_tensor = transform(image).unsqueeze(0).to(device) # [1, 1, 224, 224]
|
109 |
+
|
110 |
+
with torch.no_grad():
|
111 |
+
mask_pred = swinunet_model(input_tensor)
|
112 |
+
mask_pred = F.interpolate(mask_pred, size=(224, 224), mode="bilinear", align_corners=False)
|
113 |
+
mask_pred = (mask_pred > 0.5).float()
|
114 |
+
|
115 |
+
image_np = input_tensor.squeeze().cpu().numpy() # [224, 224]
|
116 |
+
mask_np = mask_pred.squeeze().cpu().numpy() # [224, 224]
|
117 |
+
|
118 |
+
combined = np.stack([image_np, mask_np], axis=-1) # [224, 224, 2]
|
119 |
+
return combined
|
120 |
+
|
121 |
+
def predict(image: Image.Image):
|
122 |
+
try:
|
123 |
+
combined = segmentation(image)
|
124 |
+
combined = np.expand_dims(combined, axis=0) # Shape: (1, 224, 224, 2)
|
125 |
+
|
126 |
+
probs = classifier_model.predict(combined)[0]
|
127 |
+
return CLASSES[int(np.argmax(probs))]
|
128 |
+
except Exception as e:
|
129 |
+
traceback_str = traceback.format_exc()
|
130 |
+
print(traceback_str)
|
131 |
+
return traceback_str
|
132 |
|
133 |
demo = gr.Interface(
|
134 |
+
fn = predict,
|
135 |
+
inputs = gr.Image(type = "pil", label = "Brain MRI"),
|
136 |
+
outputs = gr.Label(num_top_classes = 4),
|
137 |
+
title = "Brain‑Tumor Net)",
|
138 |
+
description = "Returns: Glioma, Meningioma, No Tumor, Pituitary"
|
139 |
)
|
140 |
|
141 |
+
demo.launch()
|
142 |
+
|
143 |
+
if __name__ == "main":
|
144 |
demo.launch()
|
cnn-swinunet/config.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"module": "keras", "class_name": "Sequential", "config": {"name": "sequential_2", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "layers": [{"module": "keras.layers", "class_name": "InputLayer", "config": {"batch_shape": [null, 224, 224, 2], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_layer_1"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null}, "filters": 32, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": {"module": "keras.regularizers", "class_name": "L2", "config": {"l2": 5e-05}, "registered_name": null}, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 224, 224, 2]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "axis": -1, "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null, "synchronized": false}, "registered_name": null, "build_config": {"input_shape": [null, 224, 224, 32]}}, {"module": "keras.layers", "class_name": "ReLU", "config": {"name": "re_lu_2", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "registered_name": null}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "filters": 64, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": {"module": "keras.regularizers", "class_name": "L2", "config": {"l2": 5e-05}, "registered_name": null}, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 112, 112, 32]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "axis": -1, "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null, "synchronized": false}, "registered_name": null, "build_config": {"input_shape": [null, 112, 112, 64]}}, {"module": "keras.layers", "class_name": "ReLU", "config": {"name": "re_lu_3", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "registered_name": null}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_3", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_4", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": {"module": "keras.regularizers", "class_name": "L2", "config": {"l2": 5e-05}, "registered_name": null}, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 56, 56, 64]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_4", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "axis": -1, "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null, "synchronized": false}, "registered_name": null, "build_config": {"input_shape": [null, 56, 56, 128]}}, {"module": "keras.layers", "class_name": "ReLU", "config": {"name": "re_lu_4", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "registered_name": null}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_4", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_5", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "linear", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": {"module": "keras.regularizers", "class_name": "L2", "config": {"l2": 5e-05}, "registered_name": null}, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 28, 28, 128]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_5", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "axis": -1, "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null, "synchronized": false}, "registered_name": null, "build_config": {"input_shape": [null, 28, 28, 128]}}, {"module": "keras.layers", "class_name": "ReLU", "config": {"name": "re_lu_5", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "registered_name": null}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_5", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 14, 14, 128]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "units": 128, "activation": "linear", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": {"module": "keras.regularizers", "class_name": "L2", "config": {"l2": 5e-05}, "registered_name": null}, "bias_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 25088]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_6", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "axis": -1, "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null, "synchronized": false}, "registered_name": null, "build_config": {"input_shape": [null, 128]}}, {"module": "keras.layers", "class_name": "ReLU", "config": {"name": "re_lu_6", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "max_value": null, "negative_slope": 0.0, "threshold": 0.0}, "registered_name": null}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "rate": 0.4, "seed": null, "noise_shape": null}, "registered_name": null}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": {"module": "keras", "class_name": "DTypePolicy", "config": {"name": "float32"}, "registered_name": null, "shared_object_id": 2872295962608}, "units": 4, "activation": "softmax", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 128]}}], "build_input_shape": [null, 224, 224, 2]}, "registered_name": null, "build_config": {"input_shape": [null, 224, 224, 2]}, "compile_config": {"optimizer": {"module": "keras.optimizers", "class_name": "Adam", "config": {"name": "adam", "learning_rate": {"module": "keras.optimizers.schedules", "class_name": "ExponentialDecay", "config": {"initial_learning_rate": 0.0001, "decay_steps": 1000, "decay_rate": 0.95, "staircase": false, "name": "ExponentialDecay"}, "registered_name": null}, "weight_decay": null, "clipnorm": null, "global_clipnorm": null, "clipvalue": null, "use_ema": false, "ema_momentum": 0.99, "ema_overwrite_frequency": null, "loss_scale_factor": null, "gradient_accumulation_steps": null, "beta_1": 0.9, "beta_2": 0.999, "epsilon": 1e-07, "amsgrad": false}, "registered_name": null}, "loss": "categorical_crossentropy", "loss_weights": null, "metrics": [{"module": "keras.metrics", "class_name": "Recall", "config": {"name": "recall", "dtype": "float32", "thresholds": null, "top_k": null, "class_id": null}, "registered_name": null}], "weighted_metrics": null, "run_eagerly": false, "steps_per_execution": 1, "jit_compile": false}}
|
cnn-swinunet/metadata.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"keras_version": "3.9.2", "date_saved": "2025-06-01@08:04:02"}
|
cnn.tflite → cnn-swinunet/model.weights.h5
RENAMED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:21a824cb97431d12f42cc1f154ef073566ad84b933b002b97bd0911a8d04f7d1
|
3 |
+
size 41524048
|
requirements.txt
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
-
tensorflow==2.15.0
|
2 |
gradio>=4.31,<5
|
3 |
-
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
gradio>=4.31,<5
|
2 |
+
numpy==1.26.4
|
3 |
+
timm==1.0.15
|
4 |
+
torch==2.6.0
|
5 |
+
torchvision==0.21.0
|
6 |
+
keras==3.9.2
|
7 |
+
pillow==10.4.0
|
8 |
+
scikit-image==0.25.2
|
swinunet.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:043efac3101c1b1ad3d73b4d8f043bb2e8058f1ebe8e860009de418f2d8e07c9
|
3 |
+
size 364350107
|