├── azureml_script ├── AML_unet_keras.ipynb ├── aml_devops.md ├── aml_script │ ├── data.py │ ├── model.py │ └── trainUnet.py ├── data │ ├── test │ │ ├── 0.png │ │ ├── 0_predict.png │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 10_predict.png │ │ ├── 11.png │ │ ├── 11_predict.png │ │ ├── 12.png │ │ ├── 12_predict.png │ │ ├── 13.png │ │ ├── 13_predict.png │ │ ├── 14.png │ │ ├── 14_predict.png │ │ ├── 15.png │ │ ├── 15_predict.png │ │ ├── 16.png │ │ ├── 16_predict.png │ │ ├── 17.png │ │ ├── 17_predict.png │ │ ├── 18.png │ │ ├── 18_predict.png │ │ ├── 19.png │ │ ├── 19_predict.png │ │ ├── 1_predict.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 20_predict.png │ │ ├── 21.png │ │ ├── 21_predict.png │ │ ├── 22.png │ │ ├── 22_predict.png │ │ ├── 23.png │ │ ├── 23_predict.png │ │ ├── 24.png │ │ ├── 24_predict.png │ │ ├── 25.png │ │ ├── 25_predict.png │ │ ├── 26.png │ │ ├── 26_predict.png │ │ ├── 27.png │ │ ├── 27_predict.png │ │ ├── 28.png │ │ ├── 28_predict.png │ │ ├── 29.png │ │ ├── 29_predict.png │ │ ├── 2_predict.png │ │ ├── 3.png │ │ ├── 3_predict.png │ │ ├── 4.png │ │ ├── 4_predict.png │ │ ├── 5.png │ │ ├── 5_predict.png │ │ ├── 6.png │ │ ├── 6_predict.png │ │ ├── 7.png │ │ ├── 7_predict.png │ │ ├── 8.png │ │ ├── 8_predict.png │ │ ├── 9.png │ │ └── 9_predict.png │ └── train │ │ ├── image │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 28.png │ │ ├── 29.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ │ └── label │ │ ├── 0.png │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 11.png │ │ ├── 12.png │ │ ├── 13.png │ │ ├── 14.png │ │ ├── 15.png │ │ ├── 16.png │ │ ├── 17.png │ │ ├── 18.png │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.png │ │ ├── 21.png │ │ ├── 22.png │ │ ├── 23.png │ │ ├── 24.png │ │ ├── 25.png │ │ ├── 26.png │ │ ├── 27.png │ │ ├── 28.png │ │ ├── 29.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png └── image │ └── aml_architecture.png ├── readme.md └── unet+watershed_research_code ├── cell_extraction.md ├── data.py ├── image ├── cell.jpg ├── folder.jpg ├── isbi.jpg └── polyurethane.jpg ├── model.py └── trainUnet+Watershed.ipynb /azureml_script/AML_unet_keras.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "%matplotlib inline\n", 10 | "import numpy as np\n", 11 | "import os\n", 12 | "import matplotlib.pyplot as plt" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "import azureml\n", 22 | "from azureml.core import Workspace\n", 23 | "\n", 24 | "# check core SDK version number\n", 25 | "print(\"Azure ML SDK Version: \", azureml.core.VERSION)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "## Create AML Workspace" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "from azureml.core import Workspace\n", 42 | "ws = Workspace.create(name='unetworkspace',\n", 43 | " subscription_id='your_sub_id', \n", 44 | " resource_group='unetrg',\n", 45 | " create_resource_group=True,\n", 46 | " location='eastus2' \n", 47 | " )\n", 48 | "ws.write_config(path='.', file_name='aml_config.json')" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "## get workspace by its id\n", 58 | "#from azureml.core import Workspace\n", 59 | "#ws = Workspace.get(name='unetworkspace',subscription_id='your_sub_id')" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "## get workspace from local config\n", 69 | "#ws = Workspace.from_config('aml_config/aml_config.json')\n", 70 | "#print('Workspace name: ' + ws.name, \n", 71 | "# 'Azure region: ' + ws.location, \n", 72 | "# 'Subscription id: ' + ws.subscription_id, \n", 73 | "# 'Resource group: ' + ws.resource_group, sep = '\\n')" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "## Create experiment" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "from azureml.core import Experiment\n", 90 | "script_folder = './aml_script'\n", 91 | "exp = Experiment(workspace=ws, name='aml_script')" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "## Upload data to datastore" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "ds = ws.get_default_datastore()\n", 108 | "ds.upload(src_dir='../data/train', target_path='unet', overwrite=True, show_progress=True)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "## Create compute target" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": null, 121 | "metadata": {}, 122 | "outputs": [], 123 | "source": [ 124 | "from azureml.core.compute import ComputeTarget, AmlCompute\n", 125 | "from azureml.core.compute_target import ComputeTargetException\n", 126 | "\n", 127 | "# choose a name for your cluster\n", 128 | "cluster_name = \"gpucluster\"\n", 129 | "\n", 130 | "try:\n", 131 | " compute_target = ComputeTarget(workspace=ws, name=cluster_name)\n", 132 | " print('Found existing compute target')\n", 133 | "except ComputeTargetException:\n", 134 | " print('Creating a new compute target...')\n", 135 | " compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_NC6', \n", 136 | " max_nodes=2)\n", 137 | "\n", 138 | " # create the cluster\n", 139 | " compute_target = ComputeTarget.create(ws, cluster_name, compute_config)\n", 140 | "\n", 141 | " # can poll for a minimum number of nodes and for a specific timeout. \n", 142 | " # if no min node count is provided it uses the scale settings for the cluster\n", 143 | " compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20)\n", 144 | "\n", 145 | "# use get_status() to get a detailed status for the current cluster. \n", 146 | "print(compute_target.get_status().serialize())" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": {}, 153 | "outputs": [], 154 | "source": [ 155 | "compute_targets = ws.compute_targets\n", 156 | "for name, ct in compute_targets.items():\n", 157 | " print(name, ct.type, ct.provisioning_state)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "## Submit training job to gpucluster" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": null, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "from azureml.train.dnn import TensorFlow\n", 174 | "script_folder = './aml_script'\n", 175 | "script_params = {\n", 176 | " '--data-folder': ds.path('unet').as_mount(),\n", 177 | " '--batch-size': 2 \n", 178 | "}\n", 179 | "\n", 180 | "est = TensorFlow(source_directory=script_folder,\n", 181 | " script_params=script_params,\n", 182 | " compute_target=compute_target, \n", 183 | " pip_packages=['keras', 'scikit-image'],\n", 184 | " entry_script='trainUnet.py', \n", 185 | " use_gpu=True)\n", 186 | "\n", 187 | "#est.run_config.environment.python.user_managed_dependencies = True # Means customized all Python env" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": null, 193 | "metadata": {}, 194 | "outputs": [], 195 | "source": [ 196 | "run = exp.submit(est)" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": null, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "# Show training log\n", 206 | "run.wait_for_completion(show_output=True)" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": null, 212 | "metadata": {}, 213 | "outputs": [], 214 | "source": [ 215 | "# Show result file including log and model\n", 216 | "run.get_file_names()" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "## Download and register model" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": null, 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "for f in run.get_file_names():\n", 233 | " if f.startswith('outputs/model'):\n", 234 | " output_file_path = os.path.join('./model', f.split('/')[-1])\n", 235 | " print('Downloading from {} to {} ...'.format(f, output_file_path))\n", 236 | " run.download_file(name=f, output_file_path=output_file_path)" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "metadata": {}, 243 | "outputs": [], 244 | "source": [ 245 | "# register model to AML from experiment\n", 246 | "model = run.register_model(model_name='unet', model_path='outputs/model/unet_keras.hdf5')" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "## register model from local\n", 256 | "#from azureml.core.model import Model\n", 257 | "#model = Model.register(model_name = 'unet', model_path = 'model/unet_keras.hdf5', workspace = ws)" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "## Write score.py" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "%%writefile score.py\n", 274 | "from __future__ import print_function\n", 275 | "import numpy as np\n", 276 | "import os\n", 277 | "import glob\n", 278 | "import logging\n", 279 | "import json\n", 280 | "from azureml.core.model import Model as Modelaml\n", 281 | "from azure.storage.blob import BlockBlobService, PublicAccess\n", 282 | "\n", 283 | "import skimage.io as io\n", 284 | "import skimage.transform as trans\n", 285 | "from keras.models import *\n", 286 | "from keras.layers import *\n", 287 | "from keras.optimizers import *\n", 288 | "from keras.callbacks import ModelCheckpoint, LearningRateScheduler\n", 289 | "from keras import backend as keras\n", 290 | "from keras.preprocessing.image import ImageDataGenerator\n", 291 | "\n", 292 | "\n", 293 | "\n", 294 | "def init():\n", 295 | " global model\n", 296 | "\n", 297 | " model_root = Modelaml.get_model_path('unet')\n", 298 | " model = unet()\n", 299 | " model.load_weights(model_root)\n", 300 | " print('model_loaded')\n", 301 | "\n", 302 | "def unet(pretrained_weights = None,input_size = (256,256,1)):\n", 303 | " inputs = Input(input_size)\n", 304 | " conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(inputs)\n", 305 | " conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)\n", 306 | " pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n", 307 | " conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)\n", 308 | " conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)\n", 309 | " pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n", 310 | " conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)\n", 311 | " conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3)\n", 312 | " pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n", 313 | " conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)\n", 314 | " conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4)\n", 315 | " drop4 = Dropout(0.5)(conv4)\n", 316 | " pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)\n", 317 | "\n", 318 | " conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4)\n", 319 | " conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5)\n", 320 | " drop5 = Dropout(0.5)(conv5)\n", 321 | "\n", 322 | " up6 = Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5))\n", 323 | " merge6 = concatenate([drop4,up6], axis = 3)\n", 324 | " conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6)\n", 325 | " conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6)\n", 326 | "\n", 327 | " up7 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6))\n", 328 | " merge7 = concatenate([conv3,up7], axis = 3)\n", 329 | " conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7)\n", 330 | " conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7)\n", 331 | "\n", 332 | " up8 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7))\n", 333 | " merge8 = concatenate([conv2,up8], axis = 3)\n", 334 | " conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8)\n", 335 | " conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8)\n", 336 | "\n", 337 | " up9 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))\n", 338 | " merge9 = concatenate([conv1,up9], axis = 3)\n", 339 | " conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9)\n", 340 | " conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)\n", 341 | " conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)\n", 342 | " conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)\n", 343 | "\n", 344 | " model = Model(input = inputs, output = conv10)\n", 345 | "\n", 346 | " model.compile(optimizer = Adam(lr = 1e-4), loss = 'binary_crossentropy', metrics = ['accuracy'])\n", 347 | " \n", 348 | " if(pretrained_weights):\n", 349 | " model.load_weights(pretrained_weights)\n", 350 | " return model\n", 351 | "\n", 352 | "\n", 353 | "def testGenerator(testpath, num_image = 30,target_size = (256,256),flag_multi_class = False,as_gray = True):\n", 354 | " for i in range(num_image):\n", 355 | " img = io.imread(os.path.join(testpath,\"%d.png\"%i),as_gray = as_gray)\n", 356 | " img = img / 255\n", 357 | " img = trans.resize(img,target_size)\n", 358 | " img = np.reshape(img,img.shape+(1,)) if (not flag_multi_class) else img\n", 359 | " img = np.reshape(img,(1,)+img.shape)\n", 360 | " yield img\n", 361 | "\n", 362 | "def saveResult(npyfile,flag_multi_class = False,num_class = 2):\n", 363 | " block_blob_service = BlockBlobService(connection_string = \"AzureStorage ConnectionString\") \n", 364 | " result_url = \"Azure Storage Blob Url\"\n", 365 | " container_name ='unetresult' \n", 366 | " block_blob_service.create_container(container_name) \n", 367 | " block_blob_service.set_container_acl(container_name, public_access=PublicAccess.Container)\n", 368 | " \n", 369 | " Sky = [128,128,128]\n", 370 | " Building = [128,0,0]\n", 371 | " Pole = [192,192,128]\n", 372 | " Road = [128,64,128]\n", 373 | " Pavement = [60,40,222]\n", 374 | " Tree = [128,128,0]\n", 375 | " SignSymbol = [192,128,128]\n", 376 | " Fence = [64,64,128]\n", 377 | " Car = [64,0,128]\n", 378 | " Pedestrian = [64,64,0]\n", 379 | " Bicyclist = [0,128,192]\n", 380 | " Unlabelled = [0,0,0]\n", 381 | " COLOR_DICT = np.array([Sky, Building, Pole, Road, Pavement, Tree, SignSymbol, Fence, Car, Pedestrian, Bicyclist, Unlabelled])\n", 382 | " \n", 383 | " for i,item in enumerate(npyfile):\n", 384 | " img = labelVisualize(num_class,COLOR_DICT,item) if flag_multi_class else item[:,:,0]\n", 385 | " io.imsave(\"predict.png\",img)\n", 386 | " # Upload the created file\n", 387 | " block_blob_service.create_blob_from_path(container_name, \"%d_predict.png\"%i, \"predict.png\")\n", 388 | "\n", 389 | " return result_url + container_name\n", 390 | "\n", 391 | "def labelVisualize(num_class,color_dict,img):\n", 392 | " img = img[:,:,0] if len(img.shape) == 3 else img\n", 393 | " img_out = np.zeros(img.shape + (3,))\n", 394 | " for i in range(num_class):\n", 395 | " img_out[img == i,:] = color_dict[i]\n", 396 | " return img_out / 255\n", 397 | "\n", 398 | "def run(raw_data):\n", 399 | " data_url = json.loads(raw_data)['storage_url']\n", 400 | " data_count = json.loads(raw_data)['count']\n", 401 | "\n", 402 | " # make prediction\n", 403 | " testGene = testGenerator(data_url, num_image = data_count)\n", 404 | " results = model.predict_generator(testGene,data_count,verbose=1)\n", 405 | " result_url = saveResult(results) # result saved container url\n", 406 | " return result_url" 407 | ] 408 | }, 409 | { 410 | "cell_type": "markdown", 411 | "metadata": {}, 412 | "source": [ 413 | "## Write env.yml" 414 | ] 415 | }, 416 | { 417 | "cell_type": "code", 418 | "execution_count": null, 419 | "metadata": {}, 420 | "outputs": [], 421 | "source": [ 422 | "from azureml.core.runconfig import CondaDependencies\n", 423 | "\n", 424 | "#cd = CondaDependencies.create()\n", 425 | "cd = CondaDependencies()\n", 426 | "#cd.add_channel('default')\n", 427 | "#cd.add_channel('conda-forge')\n", 428 | "cd.add_tensorflow_pip_package()\n", 429 | "cd.add_pip_package('keras')\n", 430 | "cd.add_pip_package('scikit-image')\n", 431 | "cd.add_pip_package('azure')\n", 432 | "cd.add_pip_package('azure-storage-blob')\n", 433 | "cd.save_to_file(base_directory='.', conda_file_path='myenv.yml')\n", 434 | "\n", 435 | "print(cd.serialize_to_string())" 436 | ] 437 | }, 438 | { 439 | "cell_type": "markdown", 440 | "metadata": {}, 441 | "source": [ 442 | "## Deploy model to Azure Container Instance" 443 | ] 444 | }, 445 | { 446 | "cell_type": "code", 447 | "execution_count": null, 448 | "metadata": {}, 449 | "outputs": [], 450 | "source": [ 451 | "from azureml.core.webservice import AciWebservice\n", 452 | "\n", 453 | "aciconfig = AciWebservice.deploy_configuration(cpu_cores=1, \n", 454 | " auth_enabled=True, # this flag generates API keys to secure access\n", 455 | " memory_gb=1, \n", 456 | " tags={'name':'unet', 'framework': 'Keras'},\n", 457 | " description='Keras Unet')" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": null, 463 | "metadata": {}, 464 | "outputs": [], 465 | "source": [ 466 | "from azureml.core.image import ContainerImage\n", 467 | "\n", 468 | "imgconfig = ContainerImage.image_configuration(execution_script=\"score.py\", \n", 469 | " runtime=\"python\", \n", 470 | " conda_file=\"myenv.yml\")" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": null, 476 | "metadata": {}, 477 | "outputs": [], 478 | "source": [ 479 | "%%time\n", 480 | "from azureml.core.webservice import Webservice\n", 481 | "\n", 482 | "service = Webservice.deploy_from_model(workspace=ws,\n", 483 | " name='keras-unet',\n", 484 | " deployment_config=aciconfig,\n", 485 | " models=[model],\n", 486 | " image_config=imgconfig)\n", 487 | "\n", 488 | "service.wait_for_deployment(show_output=True)" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": {}, 495 | "outputs": [], 496 | "source": [ 497 | "# print ACI deployment log\n", 498 | "print(service.get_logs())" 499 | ] 500 | }, 501 | { 502 | "cell_type": "markdown", 503 | "metadata": {}, 504 | "source": [ 505 | "## Test published service" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": null, 511 | "metadata": {}, 512 | "outputs": [], 513 | "source": [ 514 | "import json\n", 515 | "# storage_url is the url of Azure storage container url where test images are stored. count is amount of test images.\n", 516 | "result = service.run(input_data=json.dumps({'storage_url': 'Azure storage container url', 'count': 2}))\n", 517 | "print(result) # print test images stored container url" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": null, 523 | "metadata": {}, 524 | "outputs": [], 525 | "source": [ 526 | "# plot the result image\n", 527 | "import matplotlib.pyplot as plt\n", 528 | "import skimage.io as skio\n", 529 | "img = skio.imread(result + \"/0_predict.png\")\n", 530 | "plt.imshow(img, cmap = 'gray')" 531 | ] 532 | }, 533 | { 534 | "cell_type": "code", 535 | "execution_count": null, 536 | "metadata": {}, 537 | "outputs": [], 538 | "source": [] 539 | } 540 | ], 541 | "metadata": { 542 | "kernelspec": { 543 | "display_name": "Python 3.6 - AzureML", 544 | "language": "python", 545 | "name": "python3-azureml" 546 | }, 547 | "language_info": { 548 | "codemirror_mode": { 549 | "name": "ipython", 550 | "version": 3 551 | }, 552 | "file_extension": ".py", 553 | "mimetype": "text/x-python", 554 | "name": "python", 555 | "nbconvert_exporter": "python", 556 | "pygments_lexer": "ipython3", 557 | "version": "3.6.6" 558 | } 559 | }, 560 | "nbformat": 4, 561 | "nbformat_minor": 2 562 | } 563 | -------------------------------------------------------------------------------- /azureml_script/aml_devops.md: -------------------------------------------------------------------------------- 1 | ## Train and deploy Unet on Keras model using Azure Machine Learning Service 2 | 3 | ### Introduction 4 | 5 | In the folder of [unet+watershed_research_code](../unet+watershed_research_code/cell_extraction.md), we described the solution of extracting cell from chemical or biological microscope images. This folder will show how to leverage Azure Machine Learning Service Python SDK to train, and deploy Unet on Keras model in Azure Container Instance. 6 | 7 | ### Azure Machine Learning Service 8 | 9 | [Azure Machine Learning Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/) is a cloud service that you use to train, deploy, automate, and manage machine learning models, all at the broad scale that the cloud provides. Besides portal UI, it also provides Python SDK to improve productivity. 10 | 11 | 12 |

13 | 14 | ### Code description 15 | 16 | The data and Unet python script we used for training is from [github](https://github.com/zhixuhao/unet), actually sample dataset is from a [ISBI challenge](http://brainiac2.mit.edu/isbi_challenge/). The script including *trainUnet.py*, *data.py*, *model.py* are in aml_script folder. 17 | 18 | In score script, to enable batch prediction, we accept the input of Azure Storage Container url where stores all the test images, and save the prediction images to another container (you should config its location in the *score.py* file), then return the result container url. So you can download them from the container to local computer. If single input is needed, code in score file must be changed. 19 | -------------------------------------------------------------------------------- /azureml_script/aml_script/data.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from keras.preprocessing.image import ImageDataGenerator 3 | import numpy as np 4 | import os 5 | import glob 6 | import skimage.io as io 7 | import skimage.transform as trans 8 | 9 | Sky = [128,128,128] 10 | Building = [128,0,0] 11 | Pole = [192,192,128] 12 | Road = [128,64,128] 13 | Pavement = [60,40,222] 14 | Tree = [128,128,0] 15 | SignSymbol = [192,128,128] 16 | Fence = [64,64,128] 17 | Car = [64,0,128] 18 | Pedestrian = [64,64,0] 19 | Bicyclist = [0,128,192] 20 | Unlabelled = [0,0,0] 21 | 22 | COLOR_DICT = np.array([Sky, Building, Pole, Road, Pavement, 23 | Tree, SignSymbol, Fence, Car, Pedestrian, Bicyclist, Unlabelled]) 24 | 25 | 26 | def adjustData(img,mask,flag_multi_class,num_class): 27 | if(flag_multi_class): 28 | img = img / 255 29 | mask = mask[:,:,:,0] if(len(mask.shape) == 4) else mask[:,:,0] 30 | new_mask = np.zeros(mask.shape + (num_class,)) 31 | for i in range(num_class): 32 | #for one pixel in the image, find the class in mask and convert it into one-hot vector 33 | #index = np.where(mask == i) 34 | #index_mask = (index[0],index[1],index[2],np.zeros(len(index[0]),dtype = np.int64) + i) if (len(mask.shape) == 4) else (index[0],index[1],np.zeros(len(index[0]),dtype = np.int64) + i) 35 | #new_mask[index_mask] = 1 36 | new_mask[mask == i,i] = 1 37 | new_mask = np.reshape(new_mask,(new_mask.shape[0],new_mask.shape[1]*new_mask.shape[2],new_mask.shape[3])) if flag_multi_class else np.reshape(new_mask,(new_mask.shape[0]*new_mask.shape[1],new_mask.shape[2])) 38 | mask = new_mask 39 | elif(np.max(img) > 1): 40 | img = img / 255 41 | mask = mask /255 42 | mask[mask > 0.5] = 1 43 | mask[mask <= 0.5] = 0 44 | return (img,mask) 45 | 46 | 47 | 48 | def trainGenerator(batch_size,train_path,image_folder,mask_folder,aug_dict,image_color_mode = "grayscale", 49 | mask_color_mode = "grayscale",image_save_prefix = "image",mask_save_prefix = "mask", 50 | flag_multi_class = False,num_class = 2,save_to_dir = None,target_size = (256,256),seed = 1): 51 | ''' 52 | can generate image and mask at the same time 53 | use the same seed for image_datagen and mask_datagen to ensure the transformation for image and mask is the same 54 | if you want to visualize the results of generator, set save_to_dir = "your path" 55 | ''' 56 | image_datagen = ImageDataGenerator(**aug_dict) 57 | mask_datagen = ImageDataGenerator(**aug_dict) 58 | image_generator = image_datagen.flow_from_directory( 59 | train_path, 60 | classes = [image_folder], 61 | class_mode = None, 62 | color_mode = image_color_mode, 63 | target_size = target_size, 64 | batch_size = batch_size, 65 | save_to_dir = save_to_dir, 66 | save_prefix = image_save_prefix, 67 | seed = seed) 68 | mask_generator = mask_datagen.flow_from_directory( 69 | train_path, 70 | classes = [mask_folder], 71 | class_mode = None, 72 | color_mode = mask_color_mode, 73 | target_size = target_size, 74 | batch_size = batch_size, 75 | save_to_dir = save_to_dir, 76 | save_prefix = mask_save_prefix, 77 | seed = seed) 78 | train_generator = zip(image_generator, mask_generator) 79 | for (img,mask) in train_generator: 80 | img,mask = adjustData(img,mask,flag_multi_class,num_class) 81 | yield (img,mask) 82 | 83 | 84 | 85 | def testGenerator(test_path,num_image = 30,target_size = (256,256),flag_multi_class = False,as_gray = True): 86 | for i in range(num_image): 87 | img = io.imread(os.path.join(test_path,"%d.png"%i),as_gray = as_gray) 88 | img = img / 255 89 | img = trans.resize(img,target_size) 90 | img = np.reshape(img,img.shape+(1,)) if (not flag_multi_class) else img 91 | img = np.reshape(img,(1,)+img.shape) 92 | yield img 93 | 94 | 95 | def geneTrainNpy(image_path,mask_path,flag_multi_class = False,num_class = 2,image_prefix = "image",mask_prefix = "mask",image_as_gray = True,mask_as_gray = True): 96 | image_name_arr = glob.glob(os.path.join(image_path,"%s*.png"%image_prefix)) 97 | image_arr = [] 98 | mask_arr = [] 99 | for index,item in enumerate(image_name_arr): 100 | img = io.imread(item,as_gray = image_as_gray) 101 | img = np.reshape(img,img.shape + (1,)) if image_as_gray else img 102 | mask = io.imread(item.replace(image_path,mask_path).replace(image_prefix,mask_prefix),as_gray = mask_as_gray) 103 | mask = np.reshape(mask,mask.shape + (1,)) if mask_as_gray else mask 104 | img,mask = adjustData(img,mask,flag_multi_class,num_class) 105 | image_arr.append(img) 106 | mask_arr.append(mask) 107 | image_arr = np.array(image_arr) 108 | mask_arr = np.array(mask_arr) 109 | return image_arr,mask_arr 110 | 111 | 112 | def labelVisualize(num_class,color_dict,img): 113 | img = img[:,:,0] if len(img.shape) == 3 else img 114 | img_out = np.zeros(img.shape + (3,)) 115 | for i in range(num_class): 116 | img_out[img == i,:] = color_dict[i] 117 | return img_out / 255 118 | 119 | 120 | 121 | def saveResult(save_path,npyfile,flag_multi_class = False,num_class = 2): 122 | for i,item in enumerate(npyfile): 123 | img = labelVisualize(num_class,COLOR_DICT,item) if flag_multi_class else item[:,:,0] 124 | io.imsave(os.path.join(save_path,"%d_predict.png"%i),img) -------------------------------------------------------------------------------- /azureml_script/aml_script/model.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | import skimage.io as io 4 | import skimage.transform as trans 5 | import numpy as np 6 | from keras.models import * 7 | from keras.layers import * 8 | from keras.optimizers import * 9 | from keras.callbacks import ModelCheckpoint, LearningRateScheduler 10 | from keras import backend as keras 11 | 12 | 13 | def unet(pretrained_weights = None,input_size = (256,256,1)): 14 | inputs = Input(input_size) 15 | conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(inputs) 16 | conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1) 17 | pool1 = MaxPooling2D(pool_size=(2, 2))(conv1) 18 | conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1) 19 | conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2) 20 | pool2 = MaxPooling2D(pool_size=(2, 2))(conv2) 21 | conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2) 22 | conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3) 23 | pool3 = MaxPooling2D(pool_size=(2, 2))(conv3) 24 | conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3) 25 | conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4) 26 | drop4 = Dropout(0.5)(conv4) 27 | pool4 = MaxPooling2D(pool_size=(2, 2))(drop4) 28 | 29 | conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4) 30 | conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5) 31 | drop5 = Dropout(0.5)(conv5) 32 | 33 | up6 = Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5)) 34 | merge6 = concatenate([drop4,up6], axis = 3) 35 | conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6) 36 | conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6) 37 | 38 | up7 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6)) 39 | merge7 = concatenate([conv3,up7], axis = 3) 40 | conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7) 41 | conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7) 42 | 43 | up8 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7)) 44 | merge8 = concatenate([conv2,up8], axis = 3) 45 | conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8) 46 | conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8) 47 | 48 | up9 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8)) 49 | merge9 = concatenate([conv1,up9], axis = 3) 50 | conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9) 51 | conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9) 52 | conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9) 53 | conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9) 54 | 55 | model = Model(input = inputs, output = conv10) 56 | 57 | model.compile(optimizer = Adam(lr = 1e-4), loss = 'binary_crossentropy', metrics = ['accuracy']) 58 | 59 | #model.summary() 60 | 61 | if(pretrained_weights): 62 | model.load_weights(pretrained_weights) 63 | 64 | return model 65 | 66 | 67 | -------------------------------------------------------------------------------- /azureml_script/aml_script/trainUnet.py: -------------------------------------------------------------------------------- 1 | from model import * 2 | from data import * 3 | from azureml.core import Run 4 | import numpy as np 5 | import argparse 6 | import os 7 | 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument('--data-folder', type=str, dest='data_folder', help='data folder mounting point') 10 | parser.add_argument('--batch-size', type=int, dest='batch_size', default=50, help='mini batch size for training') 11 | 12 | args = parser.parse_args() 13 | data_folder = args.data_folder 14 | os.makedirs('./outputs/model', exist_ok=True) 15 | 16 | data_gen_args = dict(rotation_range=0.2, 17 | width_shift_range=0.05, 18 | height_shift_range=0.05, 19 | shear_range=0.05, 20 | zoom_range=0.05, 21 | horizontal_flip=True, 22 | fill_mode='nearest') 23 | 24 | myGene = trainGenerator(2, data_folder,'image','label',data_gen_args,save_to_dir = None) 25 | model = unet() 26 | model_checkpoint = ModelCheckpoint('./outputs/model/unet_keras.hdf5', monitor='loss',verbose=1, save_best_only=True) 27 | model.fit_generator(myGene,steps_per_epoch=2000,epochs=2,callbacks=[model_checkpoint]) 28 | 29 | -------------------------------------------------------------------------------- /azureml_script/data/test/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/0.png -------------------------------------------------------------------------------- /azureml_script/data/test/0_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/0_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/1.png -------------------------------------------------------------------------------- /azureml_script/data/test/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/10.png -------------------------------------------------------------------------------- /azureml_script/data/test/10_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/10_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/11.png -------------------------------------------------------------------------------- /azureml_script/data/test/11_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/11_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/12.png -------------------------------------------------------------------------------- /azureml_script/data/test/12_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/12_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/13.png -------------------------------------------------------------------------------- /azureml_script/data/test/13_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/13_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/14.png -------------------------------------------------------------------------------- /azureml_script/data/test/14_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/14_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/15.png -------------------------------------------------------------------------------- /azureml_script/data/test/15_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/15_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/16.png -------------------------------------------------------------------------------- /azureml_script/data/test/16_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/16_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/17.png -------------------------------------------------------------------------------- /azureml_script/data/test/17_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/17_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/18.png -------------------------------------------------------------------------------- /azureml_script/data/test/18_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/18_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/19.png -------------------------------------------------------------------------------- /azureml_script/data/test/19_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/19_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/1_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/1_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/2.png -------------------------------------------------------------------------------- /azureml_script/data/test/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/20.png -------------------------------------------------------------------------------- /azureml_script/data/test/20_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/20_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/21.png -------------------------------------------------------------------------------- /azureml_script/data/test/21_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/21_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/22.png -------------------------------------------------------------------------------- /azureml_script/data/test/22_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/22_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/23.png -------------------------------------------------------------------------------- /azureml_script/data/test/23_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/23_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/24.png -------------------------------------------------------------------------------- /azureml_script/data/test/24_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/24_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/25.png -------------------------------------------------------------------------------- /azureml_script/data/test/25_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/25_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/26.png -------------------------------------------------------------------------------- /azureml_script/data/test/26_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/26_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/27.png -------------------------------------------------------------------------------- /azureml_script/data/test/27_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/27_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/28.png -------------------------------------------------------------------------------- /azureml_script/data/test/28_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/28_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/29.png -------------------------------------------------------------------------------- /azureml_script/data/test/29_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/29_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/2_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/2_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/3.png -------------------------------------------------------------------------------- /azureml_script/data/test/3_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/3_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/4.png -------------------------------------------------------------------------------- /azureml_script/data/test/4_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/4_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/5.png -------------------------------------------------------------------------------- /azureml_script/data/test/5_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/5_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/6.png -------------------------------------------------------------------------------- /azureml_script/data/test/6_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/6_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/7.png -------------------------------------------------------------------------------- /azureml_script/data/test/7_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/7_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/8.png -------------------------------------------------------------------------------- /azureml_script/data/test/8_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/8_predict.png -------------------------------------------------------------------------------- /azureml_script/data/test/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/9.png -------------------------------------------------------------------------------- /azureml_script/data/test/9_predict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/test/9_predict.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/0.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/1.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/10.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/11.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/12.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/13.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/14.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/15.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/16.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/17.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/18.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/19.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/2.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/20.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/21.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/22.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/23.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/24.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/25.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/26.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/27.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/28.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/29.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/3.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/4.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/5.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/6.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/7.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/8.png -------------------------------------------------------------------------------- /azureml_script/data/train/image/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/image/9.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/0.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/1.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/10.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/11.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/12.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/13.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/14.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/15.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/16.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/17.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/18.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/19.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/2.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/20.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/21.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/22.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/23.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/24.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/25.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/26.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/27.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/28.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/29.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/3.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/4.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/5.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/6.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/7.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/8.png -------------------------------------------------------------------------------- /azureml_script/data/train/label/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/data/train/label/9.png -------------------------------------------------------------------------------- /azureml_script/image/aml_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/azureml_script/image/aml_architecture.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Cell extraction in microscope image and deployment with Azure ML service 2 | 3 | In this repo, we'll cover two topics, one is how to use Unet and Watershed algorithm to extract and segment cell from materials or biological tissue microscope image, the other is to use Azure Machine Learning Service to train and deploy the Unet model for productivity. 4 | 5 | # Cell extraction in chemical or biological microscope image 6 | 7 | ## Introduction 8 | 9 | Scientists always use microscope to study the structure of some biological tissue or chemical materials. They also need to seperate the cell from the complete structure, so that they can get the count of the cell and also the centroid and the area of the cell, to check the quality and metric of the tissue or materials. Microscope images are like below, left is polyurethane material and right is cell. 10 | 11 |

12 | 13 | This repo is to use [Unet deep learning network](https://en.wikipedia.org/wiki/U-Net) and [Watershed](https://en.wikipedia.org/wiki/Watershed_(image_processing)) to extract the edges of the cells and segment them from the microscope images, and also get the centroid and area of each cell. 14 | 15 | ## Procedure 16 | 17 | Take polyurethane microscope image as an example. At first, we used Watershed directly to segment each cell and get its centroid. But the result is not as expected because some cells has the irregular shape and unclear edge. We had to adjust the parameter manually image by image, which is not repeatable work. So we tried to investigate some deep learning algorithm to automatically extract the edge. 18 | 19 | We decided to use Unet to extract the edge of the cell because of a similar scenario: [ISBI Neural Electron Microscope Image Segmentation challenge](http://brainiac2.mit.edu/isbi_challenge/home). A [github sample](https://github.com/zhixuhao/unet) tried to use UNET to extract the edge of neural electron and got very good accuracy after little training steps. The ISBI challenge is as below: 20 |

21 | 22 | So the final step is 23 | 1) transform the original image to contrast gray image 24 | 2) Manually label several typical images as black and white edge image 25 | 3) train the whole UNET model, or with transfer learning 26 | 4) transform the edge extraction result to binary image 27 | 5) Use Watershed to extract all the cells from the edge result and get centroid and area information 28 | 29 | For labeling the edge image, we tried two approaches: 30 | 1) Use [Labelme](https://github.com/wkentaro/labelme) to label the cell by polygon and generate the black and white edge image based on the json file, with white color inside cell and black color filled the edge. 31 | 2) Use default Painting app to draw the edge manually. 32 | 33 | 34 | ## code description 35 | Use UNET implementation from the [github sample from zhixuhao]((https://github.com/zhixuhao/unet)), upload the image folder to */data* folder with a train folder and a test folder, each folder will cover a image folder and a label folder, each includes the .png file named from 0. 36 | 37 |

38 | 39 | The data is used for transfer learning based on a pre-trained Unet model ( like *unet_membrane.hdf5* ). You can leverage the Azure Machine Learning script in the folder of [azureml_script](azureml_script/aml_devops.md) to train the model and download it. 40 | 41 | Last step, use Skimage implemented Watershed algorithm to extract each cell and get its centroid and area. 42 | 43 | 44 | ## Train and deploy Unet on Keras model using Azure Machine Learning Service 45 | 46 | ### Introduction 47 | 48 | In the folder of [unet+watershed_research_code](unet+watershed_research_code/cell_extraction.md), we described the solution of extracting cell from chemical or biological microscope images. This folder will show how to leverage Azure Machine Learning Service Python SDK to train, and deploy Unet on Keras model in Azure Container Instance. 49 | 50 | ### Azure Machine Learning Service 51 | 52 | [Azure Machine Learning Service](https://docs.microsoft.com/en-us/azure/machine-learning/service/) is a cloud service that you use to train, deploy, automate, and manage machine learning models, all at the broad scale that the cloud provides. Besides portal UI, it also provides Python SDK to improve productivity. 53 | 54 |

55 | 56 | ### Code description 57 | 58 | The data and Unet python script we used for training is from [github](https://github.com/zhixuhao/unet), actually sample dataset is from a [ISBI challenge](http://brainiac2.mit.edu/isbi_challenge/). The script including *trainUnet.py*, *data.py*, *model.py* are in aml_script folder. 59 | 60 | In score script, to enable batch prediction, we accept the input of Azure Storage Container url where stores all the test images, and save the prediction images to another container (you should config its location in the *score.py* file), then return the result container url. So you can download them from the container to local computer. If single input is needed, code in score file must be changed. 61 | 62 | -------------------------------------------------------------------------------- /unet+watershed_research_code/cell_extraction.md: -------------------------------------------------------------------------------- 1 | # Cell extraction in chemical or biological microscope image 2 | 3 | ## Introduction 4 | 5 | In chemistry or biology industry, scientists always use microscope to study the structure of some biological tissue or materials. They also need to seperate the cell from the complete structure, so that they can get the count of the cell and also the centroid and the area of the cell, to check the quality and metric of the tissue or materials. Microscope images are like below, left is polyurethane material and right is cell. 6 | 7 |

8 | 9 | This repo is to use [Unet deep learning network](https://en.wikipedia.org/wiki/U-Net) and [Watershed](https://en.wikipedia.org/wiki/Watershed_(image_processing)) to extract the edges of the cells and segment them from the microscope images, and also get the centroid and area of each cell. 10 | 11 | ## Procedure 12 | 13 | Take polyurethane microscope image as an example. At first, we used Watershed directly to segment each cell and get its centroid. But the result is not as expected because some cells has the irregular shape and unclear edge. We had to adjust the parameter manually image by image, which is not repeatable work. So we tried to investigate some deep learning algorithm to automatically extract the edge. 14 | 15 | We decided to use Unet to extract the edge of the cell because of a similar scenario: [ISBI Neural Electron Microscope Image Segmentation challenge](http://brainiac2.mit.edu/isbi_challenge/home). A [github sample](https://github.com/zhixuhao/unet) tried to use UNET to extract the edge of neural electron and got very good accuracy after little training steps. The ISBI challenge is as below: 16 |

17 | 18 | So the final step is 19 | 1) transform the original image to contrast gray image 20 | 2) Manually label several typical images as black and white edge image 21 | 3) train the whole UNET model, or with transfer learning 22 | 4) transform the edge extraction result to binary image 23 | 5) Use Watershed to extract all the cells from the edge result and get centroid and area information 24 | 25 | For labeling the edge image, we tried two approaches: 26 | 1) Use [Labelme](https://github.com/wkentaro/labelme) to label the cell by polygon and generate the black and white edge image based on the json file, with white color inside cell and black color filled the edge. 27 | 2) Use default Painting app to draw the edge manually. 28 | 29 | 30 | ## code description 31 | Use UNET implementation from the [github sample from zhixuhao]((https://github.com/zhixuhao/unet)), upload the image folder to */data* folder with a train folder and a test folder, each folder will cover a image folder and a label folder, each includes the .png file named from 0. 32 | 33 |

34 | 35 | The data is used for transfer learning based on a pre-trained Unet model ( like *unet_membrane.hdf5* ). You can leverage the Azure Machine Learning script in the folder of [azureml_script](../azureml_script/aml_devops.md) to train the model and download it. 36 | 37 | Last step, use Skimage implemented Watershed algorithm to extract each cell and get its centroid and area. 38 | 39 | 40 | -------------------------------------------------------------------------------- /unet+watershed_research_code/data.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from keras.preprocessing.image import ImageDataGenerator 3 | import numpy as np 4 | import os 5 | import glob 6 | import skimage.io as io 7 | import skimage.transform as trans 8 | 9 | Sky = [128,128,128] 10 | Building = [128,0,0] 11 | Pole = [192,192,128] 12 | Road = [128,64,128] 13 | Pavement = [60,40,222] 14 | Tree = [128,128,0] 15 | SignSymbol = [192,128,128] 16 | Fence = [64,64,128] 17 | Car = [64,0,128] 18 | Pedestrian = [64,64,0] 19 | Bicyclist = [0,128,192] 20 | Unlabelled = [0,0,0] 21 | 22 | COLOR_DICT = np.array([Sky, Building, Pole, Road, Pavement, 23 | Tree, SignSymbol, Fence, Car, Pedestrian, Bicyclist, Unlabelled]) 24 | 25 | 26 | def adjustData(img,mask,flag_multi_class,num_class): 27 | if(flag_multi_class): 28 | img = img / 255 29 | mask = mask[:,:,:,0] if(len(mask.shape) == 4) else mask[:,:,0] 30 | new_mask = np.zeros(mask.shape + (num_class,)) 31 | for i in range(num_class): 32 | #for one pixel in the image, find the class in mask and convert it into one-hot vector 33 | #index = np.where(mask == i) 34 | #index_mask = (index[0],index[1],index[2],np.zeros(len(index[0]),dtype = np.int64) + i) if (len(mask.shape) == 4) else (index[0],index[1],np.zeros(len(index[0]),dtype = np.int64) + i) 35 | #new_mask[index_mask] = 1 36 | new_mask[mask == i,i] = 1 37 | new_mask = np.reshape(new_mask,(new_mask.shape[0],new_mask.shape[1]*new_mask.shape[2],new_mask.shape[3])) if flag_multi_class else np.reshape(new_mask,(new_mask.shape[0]*new_mask.shape[1],new_mask.shape[2])) 38 | mask = new_mask 39 | elif(np.max(img) > 1): 40 | img = img / 255 41 | mask = mask /255 42 | mask[mask > 0.5] = 1 43 | mask[mask <= 0.5] = 0 44 | return (img,mask) 45 | 46 | 47 | 48 | def trainGenerator(batch_size,train_path,image_folder,mask_folder,aug_dict,image_color_mode = "grayscale", 49 | mask_color_mode = "grayscale",image_save_prefix = "image",mask_save_prefix = "mask", 50 | flag_multi_class = False,num_class = 2,save_to_dir = None,target_size = (256,256),seed = 1): 51 | ''' 52 | can generate image and mask at the same time 53 | use the same seed for image_datagen and mask_datagen to ensure the transformation for image and mask is the same 54 | if you want to visualize the results of generator, set save_to_dir = "your path" 55 | ''' 56 | image_datagen = ImageDataGenerator(**aug_dict) 57 | mask_datagen = ImageDataGenerator(**aug_dict) 58 | image_generator = image_datagen.flow_from_directory( 59 | train_path, 60 | classes = [image_folder], 61 | class_mode = None, 62 | color_mode = image_color_mode, 63 | target_size = target_size, 64 | batch_size = batch_size, 65 | save_to_dir = save_to_dir, 66 | save_prefix = image_save_prefix, 67 | seed = seed) 68 | mask_generator = mask_datagen.flow_from_directory( 69 | train_path, 70 | classes = [mask_folder], 71 | class_mode = None, 72 | color_mode = mask_color_mode, 73 | target_size = target_size, 74 | batch_size = batch_size, 75 | save_to_dir = save_to_dir, 76 | save_prefix = mask_save_prefix, 77 | seed = seed) 78 | train_generator = zip(image_generator, mask_generator) 79 | for (img,mask) in train_generator: 80 | img,mask = adjustData(img,mask,flag_multi_class,num_class) 81 | yield (img,mask) 82 | 83 | 84 | 85 | def testGenerator(test_path,num_image = 30,target_size = (256,256),flag_multi_class = False,as_gray = True): 86 | for i in range(num_image): 87 | img = io.imread(os.path.join(test_path,"%d.png"%i),as_gray = as_gray) 88 | img = img / 255 89 | img = trans.resize(img,target_size) 90 | img = np.reshape(img,img.shape+(1,)) if (not flag_multi_class) else img 91 | img = np.reshape(img,(1,)+img.shape) 92 | yield img 93 | 94 | 95 | def geneTrainNpy(image_path,mask_path,flag_multi_class = False,num_class = 2,image_prefix = "image",mask_prefix = "mask",image_as_gray = True,mask_as_gray = True): 96 | image_name_arr = glob.glob(os.path.join(image_path,"%s*.png"%image_prefix)) 97 | image_arr = [] 98 | mask_arr = [] 99 | for index,item in enumerate(image_name_arr): 100 | img = io.imread(item,as_gray = image_as_gray) 101 | img = np.reshape(img,img.shape + (1,)) if image_as_gray else img 102 | mask = io.imread(item.replace(image_path,mask_path).replace(image_prefix,mask_prefix),as_gray = mask_as_gray) 103 | mask = np.reshape(mask,mask.shape + (1,)) if mask_as_gray else mask 104 | img,mask = adjustData(img,mask,flag_multi_class,num_class) 105 | image_arr.append(img) 106 | mask_arr.append(mask) 107 | image_arr = np.array(image_arr) 108 | mask_arr = np.array(mask_arr) 109 | return image_arr,mask_arr 110 | 111 | 112 | def labelVisualize(num_class,color_dict,img): 113 | img = img[:,:,0] if len(img.shape) == 3 else img 114 | img_out = np.zeros(img.shape + (3,)) 115 | for i in range(num_class): 116 | img_out[img == i,:] = color_dict[i] 117 | return img_out / 255 118 | 119 | 120 | 121 | def saveResult(save_path,npyfile,flag_multi_class = False,num_class = 2): 122 | for i,item in enumerate(npyfile): 123 | img = labelVisualize(num_class,COLOR_DICT,item) if flag_multi_class else item[:,:,0] 124 | io.imsave(os.path.join(save_path,"%d_predict.png"%i),img) -------------------------------------------------------------------------------- /unet+watershed_research_code/image/cell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/unet+watershed_research_code/image/cell.jpg -------------------------------------------------------------------------------- /unet+watershed_research_code/image/folder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/unet+watershed_research_code/image/folder.jpg -------------------------------------------------------------------------------- /unet+watershed_research_code/image/isbi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/unet+watershed_research_code/image/isbi.jpg -------------------------------------------------------------------------------- /unet+watershed_research_code/image/polyurethane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/THULiusj/Cell-segmentation-microscope-image-Unet-Watershed-AzureMachineLearningService/ae3612028d62ed68ec605710e3451451b30ce354/unet+watershed_research_code/image/polyurethane.jpg -------------------------------------------------------------------------------- /unet+watershed_research_code/model.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import os 3 | import skimage.io as io 4 | import skimage.transform as trans 5 | import numpy as np 6 | from keras.models import * 7 | from keras.layers import * 8 | from keras.optimizers import * 9 | from keras.callbacks import ModelCheckpoint, LearningRateScheduler 10 | from keras import backend as keras 11 | 12 | 13 | def unet(pretrained_weights = None,input_size = (256,256,1)): 14 | inputs = Input(input_size) 15 | conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(inputs) 16 | conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1) 17 | pool1 = MaxPooling2D(pool_size=(2, 2))(conv1) 18 | conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1) 19 | conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2) 20 | pool2 = MaxPooling2D(pool_size=(2, 2))(conv2) 21 | conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2) 22 | conv3 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3) 23 | pool3 = MaxPooling2D(pool_size=(2, 2))(conv3) 24 | conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3) 25 | conv4 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4) 26 | drop4 = Dropout(0.5)(conv4) 27 | pool4 = MaxPooling2D(pool_size=(2, 2))(drop4) 28 | 29 | conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4) 30 | conv5 = Conv2D(1024, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5) 31 | drop5 = Dropout(0.5)(conv5) 32 | 33 | up6 = Conv2D(512, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5)) 34 | merge6 = concatenate([drop4,up6], axis = 3) 35 | conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6) 36 | conv6 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6) 37 | 38 | up7 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6)) 39 | merge7 = concatenate([conv3,up7], axis = 3) 40 | conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7) 41 | conv7 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7) 42 | 43 | up8 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7)) 44 | merge8 = concatenate([conv2,up8], axis = 3) 45 | conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8) 46 | conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8) 47 | 48 | up9 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8)) 49 | merge9 = concatenate([conv1,up9], axis = 3) 50 | conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9) 51 | conv9 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9) 52 | conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9) 53 | conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9) 54 | 55 | model = Model(input = inputs, output = conv10) 56 | 57 | model.compile(optimizer = Adam(lr = 1e-4), loss = 'binary_crossentropy', metrics = ['accuracy']) 58 | 59 | #model.summary() 60 | 61 | if(pretrained_weights): 62 | model.load_weights(pretrained_weights) 63 | 64 | return model 65 | 66 | 67 | -------------------------------------------------------------------------------- /unet+watershed_research_code/trainUnet+Watershed.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stderr", 10 | "output_type": "stream", 11 | "text": [ 12 | "/anaconda/envs/py35/lib/python3.5/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.\n", 13 | " from ._conv import register_converters as _register_converters\n", 14 | "Using TensorFlow backend.\n" 15 | ] 16 | } 17 | ], 18 | "source": [ 19 | "from model import *\n", 20 | "from data import *" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "## Train your Unet with data\n", 28 | "data is in folder /data/your_image_folder/, it is a binary classification task.\n", 29 | "\n", 30 | "```bash\n", 31 | "data/your_image_folder\n", 32 | "├── train\n", 33 | "│ ├── image\n", 34 | "│ │ ├── 0.png\n", 35 | "│ │ ├── 1.png\n", 36 | "│ ├── label\n", 37 | "│ │ ├── 0.png\n", 38 | "│ │ ├── 1.png\n", 39 | "├── test\n", 40 | "│ ├── image\n", 41 | "│ │ ├── 0.png\n", 42 | "│ │ ├── 1.png\n", 43 | "│ ├── label\n", 44 | "│ │ ├── 0.png\n", 45 | "│___│___├── 1.png\n", 46 | "\n", 47 | "```" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "### Train with data generator" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "# transform the training data to contrast gray image\n", 66 | "import cv2\n", 67 | "import matplotlib.pyplot as plt\n", 68 | "image = cv2.imread(\"data/image_folder/train/image/train.JPG\", cv2.IMREAD_GRAYSCALE)\n", 69 | "gray = 255 - image\n", 70 | "cv2.imwrite(\"data/image_folder/train/image/0.png\", gray)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": { 77 | "collapsed": true 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "# train UNET with transfer learning\n", 82 | "data_gen_args = dict(rotation_range=0.2,\n", 83 | " width_shift_range=0.05,\n", 84 | " height_shift_range=0.05,\n", 85 | " shear_range=0.05,\n", 86 | " zoom_range=0.05,\n", 87 | " horizontal_flip=True,\n", 88 | " fill_mode='nearest')\n", 89 | "myGene = trainGenerator(2,'data/image_folder/train','image','label',data_gen_args,save_to_dir = None)\n", 90 | "model = unet('unet_membrane.hdf5') # transfer learning or you can remove the pre-trained model\n", 91 | "model_checkpoint = ModelCheckpoint('unet_transfer_learning_model.hdf5', monitor='loss',verbose=1, save_best_only=True)\n", 92 | "model.fit_generator(myGene,steps_per_epoch=500,epochs=2,callbacks=[model_checkpoint])" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "### test your model and save predicted results" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": { 106 | "collapsed": true 107 | }, 108 | "outputs": [], 109 | "source": [ 110 | "number_of_test_images = 1\n", 111 | "testGene = testGenerator(\"data/image_folder/test\", num_image = number_of_test_images)\n", 112 | "model = unet()\n", 113 | "model.load_weights(\"unet_transfer_learning_model.hdf5\")\n", 114 | "results = model.predict_generator(testGene, number_of_test_images, verbose=1)" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": { 121 | "collapsed": true 122 | }, 123 | "outputs": [], 124 | "source": [ 125 | "saveResult(\"data/image_folder/test/result\",results)" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "# watershed" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 6, 138 | "metadata": { 139 | "collapsed": true 140 | }, 141 | "outputs": [], 142 | "source": [ 143 | "from skimage import io, color\n", 144 | "from skimage import filters\n", 145 | "from scipy import ndimage\n", 146 | "\n", 147 | "from skimage.morphology import watershed\n", 148 | "from skimage.feature import peak_local_max\n", 149 | "from skimage.measure import regionprops, label\n", 150 | "\n", 151 | "import cv2\n", 152 | "import matplotlib.pyplot as plt\n", 153 | "import numpy as np" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": { 160 | "collapsed": true 161 | }, 162 | "outputs": [], 163 | "source": [ 164 | "bin_threshold = 10\n", 165 | "background_threshold = 30\n", 166 | "foreground _threshold = 200\n", 167 | "\n", 168 | "for i in range(0, numter_of_test_images):\n", 169 | " imresult = results[i,:,:,0]\n", 170 | " ret, thresh = cv2.threshold(255 - imresult*255, bin_threshold, 255,cv2.THRESH_BINARY_INV) # transform the unet result to binary image\n", 171 | " thresh=thresh/255 # normalize to 1\n", 172 | " \n", 173 | " edges = ndimage.sobel(thresh) # filter with sobel\n", 174 | " markers = np.zeros_like(thresh)\n", 175 | " foreground, background = 1, 2\n", 176 | " \n", 177 | " # set background and foreground with low and high threshold\n", 178 | " markers[thresh < background_threshold / 255] = background\n", 179 | " markers[thresh > foreground_threshold / 255] = foreground\n", 180 | " \n", 181 | " ws = watershed(edges, markers)\n", 182 | " seg = ndimage.label(ws == foreground)[0]\n", 183 | " \n", 184 | " # get centroids and areas\n", 185 | " regions = regionprops(seg)\n", 186 | " regions = [r for r in regions if r.area > 10]\n", 187 | " print('Number of centroids for image '+str(i) + ': ', len(regions))\n", 188 | " centroids = [r.centroid for r in regions if r.area > 10]\n", 189 | " x = [i[0] for i in centroids]\n", 190 | " y = [i[1] for i in centroids]\n", 191 | " \n", 192 | " #plot centroid on original image\n", 193 | " image = cv2.imread(os.path.join(\"data/image_folder/test\", str(i) + \".png\"))\n", 194 | " im_shape = image.shape\n", 195 | " x_scale = [x_single*im_shape[0]/256 for x_single in x]\n", 196 | " y_scale = [y_single*im_shape[1]/256 for y_single in y]\n", 197 | " image_square = cv2.resize(image, (256,256))\n", 198 | " image_square[markers==0] = (255, 0 , 0)\n", 199 | " image_square = cv2.resize(image_square,im_shape[0:2])\n", 200 | " \n", 201 | " \n", 202 | " plt.figure()\n", 203 | " plt.imshow(image, cmap='gray')\n", 204 | " plt.scatter(y_scale,x_scale, c = 'r',marker = 'o')\n", 205 | " plt.title(\"Number \" + str(i))\n", 206 | " plt.savefig(os.path.join(\"data/image_folder/test/result\", str(i) + \"_dots.png\"))\n" 207 | ] 208 | } 209 | ], 210 | "metadata": { 211 | "kernelspec": { 212 | "display_name": "Python [Anaconda3-4.1.1-Windows-x86_64]", 213 | "language": "python", 214 | "name": "Python [Anaconda3-4.1.1-Windows-x86_64]" 215 | }, 216 | "language_info": { 217 | "codemirror_mode": { 218 | "name": "ipython", 219 | "version": 3 220 | }, 221 | "file_extension": ".py", 222 | "mimetype": "text/x-python", 223 | "name": "python", 224 | "nbconvert_exporter": "python", 225 | "pygments_lexer": "ipython3", 226 | "version": "3.5.2" 227 | } 228 | }, 229 | "nbformat": 4, 230 | "nbformat_minor": 2 231 | } 232 | --------------------------------------------------------------------------------