{"id":343576,"date":"2023-01-06T15:02:22","date_gmt":"2023-01-06T15:02:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=343576"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=343576","title":{"rendered":"<span>UNet++: \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b UNet++ \u043d\u0430 TensorFlow \u0434\u043b\u044f \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u044f\u0434\u0435\u0440 \u043a\u043b\u0435\u0442\u043e\u043a<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/h3>\n<ol>\n<li>\n<p><a href=\"#1\" rel=\"noopener noreferrer nofollow\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 UNet++?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\" rel=\"noopener noreferrer nofollow\">\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\" rel=\"noopener noreferrer nofollow\">\u0410\u0443\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438\u043e\u0437\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043f\u0443\u0441\u043a \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#8\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/a><\/p>\n<\/li>\n<\/ol>\n<h3>1. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 UNet++?<\/h3>\n<p>\u041c\u043e\u0449\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0441\u043a\u0438\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u042d\u0442\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u0435\u0442\u044c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a-\u0434\u0435\u043a\u043e\u0434\u0435\u0440 \u0441 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0441\u0435\u0442\u0438 \u043a\u043e\u0434\u0435\u0440\u0430 \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441\u0435\u0440\u0438\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u043e\u0435\u0432. \u041f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u0440\u044b\u0432\u0430 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0440\u0442\u0430\u043c\u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u0432 \u043f\u043e\u0434\u0441\u0435\u0442\u0435\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9d1\/32d\/bae\/9d132dbae864c871b6a3e607f580e1c0.png\" width=\"2051\" height=\"1264\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9d1\/32d\/bae\/9d132dbae864c871b6a3e607f580e1c0.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c U-Net++ \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/arxiv.org\/pdf\/1807.10165.pdf\" rel=\"noopener noreferrer nofollow\">UNet++: A Nested U-Net Architecture for Medical Image Segmentation<\/a> <\/p>\n<p><strong>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043a\u043b\u0435\u0442\u043e\u0447\u043d\u044b\u0445 \u044f\u0434\u0435\u0440.<\/strong><\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f\u0434\u0440\u0430?<\/p>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043b\u0435\u0442\u043e\u0447\u043d\u044b\u0445 \u044f\u0434\u0435\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u0432, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 30 \u0442\u0440\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043a\u043b\u0435\u0442\u043e\u043a \u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043c\u0435 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u044f\u0434\u0440\u043e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0414\u041d\u041a \u0433\u0435\u043d\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443. \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u044f\u0434\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443 \u0432 \u043e\u0431\u0440\u0430\u0437\u0446\u0435. \u0410 \u0438\u0437\u043c\u0435\u0440\u044f\u044f, \u043a\u0430\u043a \u043a\u043b\u0435\u0442\u043a\u0438 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044e\u0442 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0438\u0434\u044b \u043b\u0435\u0447\u0435\u043d\u0438\u044f, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0431\u0438\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b.<\/p>\n<h3>2. \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 UNet++ \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f: \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Tensorflow (\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435), NumPy (\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f) \u0438 skimage (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439). \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u043f\u0430\u043b\u0438\u0442\u0440\u0443 matplotlib.<\/p>\n<pre><code class=\"python\">import pandas as pd import numpy as np import zipfile import os import glob import random import sys  import skimage.io                           #Used for imshow function import skimage.transform                    #Used for resize function from skimage.morphology import label        #Used for Run-Length-Encoding RLE to create final submission import matplotlib.pyplot as plt  import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Model from tensorflow.keras import backend as K from tensorflow.keras.callbacks import LearningRateScheduler, ModelCheckpoint, EarlyStopping, ReduceLROnPlateau from tensorflow.keras.preprocessing.image import ImageDataGenerator from sklearn.model_selection import train_test_split    # Custom IoU metric def mean_iou(y_true, y_pred):     prec = []     for t in np.arange(0.5, 1.0, 0.05):         y_pred_ = tf.to_int32(y_pred > t)         score, up_opt = tf.metrics.mean_iou(y_true, y_pred_, 2)         K.get_session().run(tf.local_variables_initializer())         with tf.control_dependencies([up_opt]):             score = tf.identity(score)         prec.append(score)     return K.mean(K.stack(prec), axis=0)  IMG_WIDTH       = 256 IMG_HEIGHT      = 256 IMG_CHANNELS    = 3  print('Python       :', sys.version.split('\\n')[0]) print('Numpy        :', np.__version__) print('Skimage      :', skimage.__version__) print('Tensorflow   :', tf.__version__)<\/code><\/pre>\n<h3>3. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f UNet++.<\/p>\n<pre><code class=\"python\"># learning rate LR = 0.001 # Custom loss function def dice_coef(y_true, y_pred):     smooth = 1.     y_true_f = K.flatten(y_true)     y_pred_f = K.flatten(y_pred)     intersection = K.sum(y_true_f * y_pred_f)     return (2. * intersection + smooth) \/ (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)  def bce_dice_loss(y_true, y_pred):     return 0.5 * tf.keras.losses.binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)  NUM_EPOCHS=25<\/code><\/pre>\n<h3>4. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/h3>\n<p>\u0420\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 path\/{id}\/masks\/{id}.png \u0432 \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c.<\/p>\n<pre><code class=\"python\"># unpack the data import zipfile for name_data in ['test', 'train']:     tmp_zip = zipfile.ZipFile('..\/input\/sf-dl-nucleus-detection\/'+name_data+'.zip')     tmp_zip.extractall(name_data)     tmp_zip.close()  # to load the data, we will use the convenient skimage lib def get_X_data(path, output_shape=(None, None)):     '''     Loads images from path\/{id}\/images\/{id}.png into a numpy array     '''     img_paths = ['{0}\/{1}\/images\/{1}.png'.format(path, id) for id in os.listdir(path)]     X_data = np.array([skimage.transform.resize(skimage.io.imread(path)[:,:,:3],                                                  output_shape=output_shape,                                                  mode='constant',                                                  preserve_range=True) for path in img_paths], dtype=np.uint8)  #take only 3 channels\/bands          return X_data  def get_Y_data(path, output_shape=(None, None)):     '''     Loads and concatenates images from path\/{id}\/masks\/{id}.png into a numpy array     '''     img_paths = [glob.glob('{0}\/{1}\/masks\/*.png'.format(path, id)) for id in os.listdir(path)]          Y_data = []     for i, img_masks in enumerate(img_paths):  #loop through each individual nuclei for an image and combine them together         masks = skimage.io.imread_collection(img_masks).concatenate()  #masks.shape = (num_masks, img_height, img_width)         mask = np.max(masks, axis=0)                                   #mask.shape = (img_height, img_width)         mask = skimage.transform.resize(mask, output_shape=output_shape+(1,), mode='constant', preserve_range=True)  #need to add an extra dimension so mask.shape = (img_height, img_width, 1)         Y_data.append(mask)     Y_data = np.array(Y_data, dtype=np.bool_)          return Y_data  # Get training data X_train = get_X_data('train', output_shape=(IMG_HEIGHT,IMG_WIDTH)) # Get training data labels Y_train = get_Y_data('train', output_shape=(IMG_HEIGHT,IMG_WIDTH))  X_test = get_X_data('test', output_shape=(IMG_HEIGHT,IMG_WIDTH))  TRAIN_PATH = 'train\/'  # Check training data train_ids = next(os.walk(TRAIN_PATH))  f, axarr = plt.subplots(2,4) f.set_size_inches(20,10) ix = random.randint(0, len(train_ids[1])) axarr[0,0].imshow(X_train[ix]) axarr[0,1].imshow(np.squeeze(Y_train[ix]))  axarr[0,2].imshow(X_train[ix]) axarr[0,3].imshow(np.squeeze(Y_train[ix]))  axarr[1,0].imshow(X_train[ix]) axarr[1,1].imshow(np.squeeze(Y_train[ix]))  axarr[1,2].imshow(X_train[ix]) axarr[1,3].imshow(np.squeeze(Y_train[ix]))  plt.show()<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f30\/3b2\/298\/f303b2298105c1d2867a73ab35be3b46.png\" width=\"1160\" height=\"574\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f30\/3b2\/298\/f303b2298105c1d2867a73ab35be3b46.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>5. \u0410\u0443\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/h3>\n<pre><code class=\"python\">x_train, x_test, y_train, y_test = train_test_split(X_train, Y_train, test_size=0.1, random_state=13)  data_gen_args = dict(rotation_range=45.,                          width_shift_range=0.1,                          height_shift_range=0.1,                          shear_range=0.2,                          zoom_range=0.2,                          horizontal_flip=True,                          vertical_flip=True,                          fill_mode='reflect')  X_datagen = ImageDataGenerator(**data_gen_args) Y_datagen = ImageDataGenerator(**data_gen_args) test_datagen = ImageDataGenerator() X_datagen_val = ImageDataGenerator() Y_datagen_val = ImageDataGenerator()  X_datagen.fit(x_train, augment=True, seed=13) Y_datagen.fit(y_train, augment=True, seed=13) test_datagen.fit(X_test, augment=True, seed=13) X_datagen_val.fit(x_test, augment=True, seed=13) Y_datagen_val.fit(y_test, augment=True, seed=13)  X_train_augmented = X_datagen.flow(x_train,  batch_size=15, shuffle=True, seed=13) Y_train_augmented = Y_datagen.flow(y_train,  batch_size=15, shuffle=True, seed=13) test_augmented = test_datagen.flow(X_test, shuffle=False, seed=13) X_train_augmented_val = X_datagen_val.flow(x_test,  batch_size=15, shuffle=True, seed=13) Y_train_augmented_val = Y_datagen_val.flow(y_test,  batch_size=15, shuffle=True, seed=13)  train_generator = zip(X_train_augmented, Y_train_augmented) val_generator = zip(X_train_augmented_val, Y_train_augmented_val)<\/code><\/pre>\n<h3>6. \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 Tensorflow<\/p>\n<pre><code class=\"python\">tf.keras.backend.clear_session() nb_filter = [32,64,128,256,512] # Build U-Net++ model inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS)) s = Lambda(lambda x: x \/ 255) (inputs)   c1 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (s) c1 = Dropout(0.5) (c1) c1 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c1) c1 = Dropout(0.5) (c1) p1 = MaxPooling2D((2, 2), strides=(2, 2)) (c1)  c2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p1) c2 = Dropout(0.5) (c2) c2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c2) c2 = Dropout(0.5) (c2) p2 = MaxPooling2D((2, 2), strides=(2, 2)) (c2)  up1_2 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up12', padding='same')(c2) conv1_2 = concatenate([up1_2, c1], name='merge12', axis=3) c3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_2) c3 = Dropout(0.5) (c3) c3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c3) c3 = Dropout(0.5) (c3)  conv3_1 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p2) conv3_1 = Dropout(0.5) (conv3_1) conv3_1 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_1) conv3_1 = Dropout(0.5) (conv3_1) pool3 = MaxPooling2D((2, 2), strides=(2, 2), name='pool3')(conv3_1)  up2_2 = Conv2DTranspose(nb_filter[1], (2, 2), strides=(2, 2), name='up22', padding='same')(conv3_1) conv2_2 = concatenate([up2_2, c2], name='merge22', axis=3) #x10 conv2_2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_2) conv2_2 = Dropout(0.5) (conv2_2) conv2_2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_2) conv2_2 = Dropout(0.5) (conv2_2)  up1_3 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up13', padding='same')(conv2_2) conv1_3 = concatenate([up1_3, c1, c3], name='merge13', axis=3) conv1_3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_3) conv1_3 = Dropout(0.5) (conv1_3) conv1_3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_3) conv1_3 = Dropout(0.5) (conv1_3)  conv4_1 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (pool3) conv4_1 = Dropout(0.5) (conv4_1) conv4_1 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv4_1) conv4_1 = Dropout(0.5) (conv4_1) pool4 = MaxPooling2D((2, 2), strides=(2, 2), name='pool4')(conv4_1)  up3_2 = Conv2DTranspose(nb_filter[2], (2, 2), strides=(2, 2), name='up32', padding='same')(conv4_1) conv3_2 = concatenate([up3_2, conv3_1], name='merge32', axis=3) #x20 conv3_2 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_2) conv3_2 = Dropout(0.5) (conv3_2) conv3_2 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_2) conv3_2 = Dropout(0.5) (conv3_2)  up2_3 = Conv2DTranspose(nb_filter[1], (2, 2), strides=(2, 2), name='up23', padding='same')(conv3_2) conv2_3 = concatenate([up2_3, c2, conv2_2], name='merge23', axis=3) conv2_3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_3) conv2_3 = Dropout(0.5) (conv2_3) conv2_3 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_3) conv2_3 = Dropout(0.5) (conv2_3)  up1_4 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up14', padding='same')(conv2_3) conv1_4 = concatenate([up1_4, c1, c3, conv1_3], name='merge14', axis=3) conv1_4 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_4) conv1_4 = Dropout(0.5) (conv1_4) conv1_4 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_4) conv1_4 = Dropout(0.5) (conv1_4)  conv5_1 = Conv2D(512, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (pool4) conv5_1 = Dropout(0.5) (conv5_1) conv5_1 = Conv2D(512, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv5_1) conv5_1 = Dropout(0.5) (conv5_1)  up4_2 = Conv2DTranspose(nb_filter[3], (2, 2), strides=(2, 2), name='up42', padding='same')(conv5_1) conv4_2 = concatenate([up4_2, conv4_1], name='merge42', axis=3) #x30 conv4_2 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv4_2) conv4_2 = Dropout(0.5) (conv4_2) conv4_2 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv4_2) conv4_2 = Dropout(0.5) (conv4_2)  up3_3 = Conv2DTranspose(nb_filter[2], (2, 2), strides=(2, 2), name='up33', padding='same')(conv4_2) conv3_3 = concatenate([up3_3, conv3_1, conv3_2], name='merge33', axis=3) conv3_3 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_3) conv3_3 = Dropout(0.5) (conv3_3) conv3_3 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_3) conv3_3 = Dropout(0.5) (conv3_3)  up2_4 = Conv2DTranspose(nb_filter[1], (2, 2), strides=(2, 2), name='up24', padding='same')(conv3_3) conv2_4 = concatenate([up2_4, c2, conv2_2, conv2_3], name='merge24', axis=3) conv2_4 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_4) conv2_4 = Dropout(0.5) (conv2_4) conv2_4 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_4) conv2_4 = Dropout(0.5) (conv2_4)  up1_5 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up15', padding='same')(conv2_4) conv1_5 = concatenate([up1_5, c1, c3, conv1_3, conv1_4], name='merge15', axis=3) conv1_5 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_5) conv1_5 = Dropout(0.5) (conv1_5) conv1_5 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_5) conv1_5 = Dropout(0.5) (conv1_5)  nestnet_output_4 = Conv2D(1, (1, 1), activation='sigmoid', kernel_initializer = 'he_normal',  name='output_4', padding='same')(conv1_5)  model = Model([inputs], [nestnet_output_4]) model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=LR), loss=bce_dice_loss)<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eea\/5a5\/771\/eea5a577132c2aa5f69a464401bb8d91.png\" width=\"781\" height=\"2361\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eea\/5a5\/771\/eea5a577132c2aa5f69a464401bb8d91.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>7. \u0417\u0430\u043f\u0443\u0441\u043a \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c.<\/p>\n<pre><code class=\"python\">checkpoint = ModelCheckpoint('best_model.hdf5' ,                               monitor = 'val_loss',                               verbose = 1,                               save_best_only=True,                              mode = 'min',                              save_weights_only=True,                              save_freq='epoch'                             ) reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.3,                               patience=5, min_lr=0.00005)  callbacks_list = [checkpoint, reduce_lr]  # Fit model history = model.fit(train_generator,                       validation_data=val_generator,                     steps_per_epoch=len(X_train)\/(6),                     validation_steps=10,                     callbacks=callbacks_list,                     epochs=NUM_EPOCHS,                      verbose=1,)<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2af\/bcb\/0eb\/2afbcb0eb85faa2608cfca4c8cd9674c.png\" width=\"384\" height=\"264\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2af\/bcb\/0eb\/2afbcb0eb85faa2608cfca4c8cd9674c.png\"\/><figcaption><\/figcaption><\/figure>\n<h3>8. \u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<pre><code class=\"python\">Y_predict = model.predict(X_train, verbose=1) train_ids = next(os.walk('train')) test_ids = next(os.walk('test')) # Check predict data f, axarr = plt.subplots(2,3) f.set_size_inches(20,10) ix = random.randint(0, len(train_ids[1])) axarr[0,0].imshow(X_train[ix]) axarr[0,0].set_title('Microscope') axarr[0,1].imshow(np.squeeze(Y_predict[ix])) axarr[0,1].set_title('\"Predicted\" Masks') axarr[0,2].imshow(np.squeeze(Y_train[ix])) axarr[0,2].set_title('\"GroundTruth\" Masks')  axarr[1,0].imshow(X_train[ix]) axarr[1,0].set_title('Microscope') axarr[1,1].imshow(np.squeeze(Y_predict[ix])) axarr[1,1].set_title('\"Predicted\" Masks') axarr[1,2].imshow(np.squeeze(Y_train[ix])) axarr[1,2].set_title('\"GroundTruth\" Masks')  plt.show()  # Use model to predict test labels Y_hat = model.predict(X_test, verbose=1) Y_hat.shape idx = random.randint(0, len(test_ids[1])) print(X_test[idx].shape) skimage.io.imshow(X_test[idx]) plt.show(); skimage.io.imshow(Y_hat[idx][:,:,0]) plt.show();<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8b7\/a16\/28f\/8b7a1628fd002edef407f497dc9f471f.png\" width=\"1079\" height=\"590\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8b7\/a16\/28f\/8b7a1628fd002edef407f497dc9f471f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0441\u044f \u043d\u0435\u043f\u043b\u043e\u0445\u043e.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f3f\/dcd\/9d8\/f3fdcd9d84f3baf8cd174f96a61a134f.png\" width=\"434\" height=\"854\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f3f\/dcd\/9d8\/f3fdcd9d84f3baf8cd174f96a61a134f.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/www.kaggle.com\/code\/abdualimov\/unet-a-nested-u-net-tensorflow-architecture\" rel=\"noopener noreferrer nofollow\">Kaggle<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/709276\/\"> https:\/\/habr.com\/ru\/post\/709276\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/h3>\n<ol>\n<li>\n<p><a href=\"#1\" rel=\"noopener noreferrer nofollow\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 UNet++?<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\" rel=\"noopener noreferrer nofollow\">\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\" rel=\"noopener noreferrer nofollow\">\u0410\u0443\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438\u043e\u0437\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\" rel=\"noopener noreferrer nofollow\">\u0417\u0430\u043f\u0443\u0441\u043a \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#8\" rel=\"noopener noreferrer nofollow\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/a><\/p>\n<\/li>\n<\/ol>\n<h3>1. \u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 UNet++?<\/h3>\n<p>\u041c\u043e\u0449\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0441\u043a\u0438\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u042d\u0442\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u0435\u0442\u044c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a-\u0434\u0435\u043a\u043e\u0434\u0435\u0440 \u0441 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u043c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0434\u0441\u0435\u0442\u0438 \u043a\u043e\u0434\u0435\u0440\u0430 \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441\u0435\u0440\u0438\u0435\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u043b\u043e\u0435\u0432. \u041f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0437\u0440\u044b\u0432\u0430 \u043c\u0435\u0436\u0434\u0443 \u043a\u0430\u0440\u0442\u0430\u043c\u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u0432 \u043f\u043e\u0434\u0441\u0435\u0442\u0435\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430. <\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c U-Net++ \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/arxiv.org\/pdf\/1807.10165.pdf\" rel=\"noopener noreferrer nofollow\">UNet++: A Nested U-Net Architecture for Medical Image Segmentation<\/a> <\/p>\n<p><strong>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043a\u043b\u0435\u0442\u043e\u0447\u043d\u044b\u0445 \u044f\u0434\u0435\u0440.<\/strong><\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f\u0434\u0440\u0430?<\/p>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043b\u0435\u0442\u043e\u0447\u043d\u044b\u0445 \u044f\u0434\u0435\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u0432, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 30 \u0442\u0440\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u043a\u043b\u0435\u0442\u043e\u043a \u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043c\u0435 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u044f\u0434\u0440\u043e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0414\u041d\u041a \u0433\u0435\u043d\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443. \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u044f\u0434\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043a\u043b\u0435\u0442\u043a\u0443 \u0432 \u043e\u0431\u0440\u0430\u0437\u0446\u0435. \u0410 \u0438\u0437\u043c\u0435\u0440\u044f\u044f, \u043a\u0430\u043a \u043a\u043b\u0435\u0442\u043a\u0438 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u044e\u0442 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0438\u0434\u044b \u043b\u0435\u0447\u0435\u043d\u0438\u044f, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0431\u0438\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b.<\/p>\n<h3>2. \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 UNet++ \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f: \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Tensorflow (\u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435), NumPy (\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f) \u0438 skimage (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439). \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u043f\u0430\u043b\u0438\u0442\u0440\u0443 matplotlib.<\/p>\n<pre><code class=\"python\">import pandas as pd import numpy as np import zipfile import os import glob import random import sys  import skimage.io                           #Used for imshow function import skimage.transform                    #Used for resize function from skimage.morphology import label        #Used for Run-Length-Encoding RLE to create final submission import matplotlib.pyplot as plt  import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Model from tensorflow.keras import backend as K from tensorflow.keras.callbacks import LearningRateScheduler, ModelCheckpoint, EarlyStopping, ReduceLROnPlateau from tensorflow.keras.preprocessing.image import ImageDataGenerator from sklearn.model_selection import train_test_split    # Custom IoU metric def mean_iou(y_true, y_pred):     prec = []     for t in np.arange(0.5, 1.0, 0.05):         y_pred_ = tf.to_int32(y_pred > t)         score, up_opt = tf.metrics.mean_iou(y_true, y_pred_, 2)         K.get_session().run(tf.local_variables_initializer())         with tf.control_dependencies([up_opt]):             score = tf.identity(score)         prec.append(score)     return K.mean(K.stack(prec), axis=0)  IMG_WIDTH       = 256 IMG_HEIGHT      = 256 IMG_CHANNELS    = 3  print('Python       :', sys.version.split('\\n')[0]) print('Numpy        :', np.__version__) print('Skimage      :', skimage.__version__) print('Tensorflow   :', tf.__version__)<\/code><\/pre>\n<h3>3. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f UNet++.<\/p>\n<pre><code class=\"python\"># learning rate LR = 0.001 # Custom loss function def dice_coef(y_true, y_pred):     smooth = 1.     y_true_f = K.flatten(y_true)     y_pred_f = K.flatten(y_pred)     intersection = K.sum(y_true_f * y_pred_f)     return (2. * intersection + smooth) \/ (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)  def bce_dice_loss(y_true, y_pred):     return 0.5 * tf.keras.losses.binary_crossentropy(y_true, y_pred) - dice_coef(y_true, y_pred)  NUM_EPOCHS=25<\/code><\/pre>\n<h3>4. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/h3>\n<p>\u0420\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u0437 path\/{id}\/masks\/{id}.png \u0432 \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c.<\/p>\n<pre><code class=\"python\"># unpack the data import zipfile for name_data in ['test', 'train']:     tmp_zip = zipfile.ZipFile('..\/input\/sf-dl-nucleus-detection\/'+name_data+'.zip')     tmp_zip.extractall(name_data)     tmp_zip.close()  # to load the data, we will use the convenient skimage lib def get_X_data(path, output_shape=(None, None)):     '''     Loads images from path\/{id}\/images\/{id}.png into a numpy array     '''     img_paths = ['{0}\/{1}\/images\/{1}.png'.format(path, id) for id in os.listdir(path)]     X_data = np.array([skimage.transform.resize(skimage.io.imread(path)[:,:,:3],                                                  output_shape=output_shape,                                                  mode='constant',                                                  preserve_range=True) for path in img_paths], dtype=np.uint8)  #take only 3 channels\/bands          return X_data  def get_Y_data(path, output_shape=(None, None)):     '''     Loads and concatenates images from path\/{id}\/masks\/{id}.png into a numpy array     '''     img_paths = [glob.glob('{0}\/{1}\/masks\/*.png'.format(path, id)) for id in os.listdir(path)]          Y_data = []     for i, img_masks in enumerate(img_paths):  #loop through each individual nuclei for an image and combine them together         masks = skimage.io.imread_collection(img_masks).concatenate()  #masks.shape = (num_masks, img_height, img_width)         mask = np.max(masks, axis=0)                                   #mask.shape = (img_height, img_width)         mask = skimage.transform.resize(mask, output_shape=output_shape+(1,), mode='constant', preserve_range=True)  #need to add an extra dimension so mask.shape = (img_height, img_width, 1)         Y_data.append(mask)     Y_data = np.array(Y_data, dtype=np.bool_)          return Y_data  # Get training data X_train = get_X_data('train', output_shape=(IMG_HEIGHT,IMG_WIDTH)) # Get training data labels Y_train = get_Y_data('train', output_shape=(IMG_HEIGHT,IMG_WIDTH))  X_test = get_X_data('test', output_shape=(IMG_HEIGHT,IMG_WIDTH))  TRAIN_PATH = 'train\/'  # Check training data train_ids = next(os.walk(TRAIN_PATH))  f, axarr = plt.subplots(2,4) f.set_size_inches(20,10) ix = random.randint(0, len(train_ids[1])) axarr[0,0].imshow(X_train[ix]) axarr[0,1].imshow(np.squeeze(Y_train[ix]))  axarr[0,2].imshow(X_train[ix]) axarr[0,3].imshow(np.squeeze(Y_train[ix]))  axarr[1,0].imshow(X_train[ix]) axarr[1,1].imshow(np.squeeze(Y_train[ix]))  axarr[1,2].imshow(X_train[ix]) axarr[1,3].imshow(np.squeeze(Y_train[ix]))  plt.show()<\/code><\/pre>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h3>5. \u0410\u0443\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/h3>\n<pre><code class=\"python\">x_train, x_test, y_train, y_test = train_test_split(X_train, Y_train, test_size=0.1, random_state=13)  data_gen_args = dict(rotation_range=45.,                          width_shift_range=0.1,                          height_shift_range=0.1,                          shear_range=0.2,                          zoom_range=0.2,                          horizontal_flip=True,                          vertical_flip=True,                          fill_mode='reflect')  X_datagen = ImageDataGenerator(**data_gen_args) Y_datagen = ImageDataGenerator(**data_gen_args) test_datagen = ImageDataGenerator() X_datagen_val = ImageDataGenerator() Y_datagen_val = ImageDataGenerator()  X_datagen.fit(x_train, augment=True, seed=13) Y_datagen.fit(y_train, augment=True, seed=13) test_datagen.fit(X_test, augment=True, seed=13) X_datagen_val.fit(x_test, augment=True, seed=13) Y_datagen_val.fit(y_test, augment=True, seed=13)  X_train_augmented = X_datagen.flow(x_train,  batch_size=15, shuffle=True, seed=13) Y_train_augmented = Y_datagen.flow(y_train,  batch_size=15, shuffle=True, seed=13) test_augmented = test_datagen.flow(X_test, shuffle=False, seed=13) X_train_augmented_val = X_datagen_val.flow(x_test,  batch_size=15, shuffle=True, seed=13) Y_train_augmented_val = Y_datagen_val.flow(y_test,  batch_size=15, shuffle=True, seed=13)  train_generator = zip(X_train_augmented, Y_train_augmented) val_generator = zip(X_train_augmented_val, Y_train_augmented_val)<\/code><\/pre>\n<h3>6. \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u041f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0430 Tensorflow<\/p>\n<pre><code class=\"python\">tf.keras.backend.clear_session() nb_filter = [32,64,128,256,512] # Build U-Net++ model inputs = Input((IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS)) s = Lambda(lambda x: x \/ 255) (inputs)   c1 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (s) c1 = Dropout(0.5) (c1) c1 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c1) c1 = Dropout(0.5) (c1) p1 = MaxPooling2D((2, 2), strides=(2, 2)) (c1)  c2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p1) c2 = Dropout(0.5) (c2) c2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c2) c2 = Dropout(0.5) (c2) p2 = MaxPooling2D((2, 2), strides=(2, 2)) (c2)  up1_2 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up12', padding='same')(c2) conv1_2 = concatenate([up1_2, c1], name='merge12', axis=3) c3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_2) c3 = Dropout(0.5) (c3) c3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (c3) c3 = Dropout(0.5) (c3)  conv3_1 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (p2) conv3_1 = Dropout(0.5) (conv3_1) conv3_1 = Conv2D(128, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv3_1) conv3_1 = Dropout(0.5) (conv3_1) pool3 = MaxPooling2D((2, 2), strides=(2, 2), name='pool3')(conv3_1)  up2_2 = Conv2DTranspose(nb_filter[1], (2, 2), strides=(2, 2), name='up22', padding='same')(conv3_1) conv2_2 = concatenate([up2_2, c2], name='merge22', axis=3) #x10 conv2_2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_2) conv2_2 = Dropout(0.5) (conv2_2) conv2_2 = Conv2D(64, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv2_2) conv2_2 = Dropout(0.5) (conv2_2)  up1_3 = Conv2DTranspose(nb_filter[0], (2, 2), strides=(2, 2), name='up13', padding='same')(conv2_2) conv1_3 = concatenate([up1_3, c1, c3], name='merge13', axis=3) conv1_3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_3) conv1_3 = Dropout(0.5) (conv1_3) conv1_3 = Conv2D(32, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (conv1_3) conv1_3 = Dropout(0.5) (conv1_3)  conv4_1 = Conv2D(256, (3, 3), activation='elu', kernel_initializer='he_normal', padding='same') (pool3) conv4_1 = Dropout(0.5) (conv4_1)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-343576","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=343576"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/343576\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}