deaspo / Unet_MedicalImagingSegmentation

A U-Net deep learning model for Segmentation of CT Images
BSD 3-Clause "New" or "Revised" License
5 stars 2 forks source link

definition mean_iou in metrics_v2.py doesn't work on tensorflow2. #2

Open hanieshojaee opened 4 years ago

hanieshojaee commented 4 years ago

Hi. tf.metrics.mean_iou is deprecated on tensorflow2 and we have to use tf.metrics.MeanIoU. But when I changed tensorflow.metrics.mean_iou to tf.metrics.MeanIoU and run the net , I got this Error:

tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: using a tf.Tensor as a Python bool is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.

" I'm beginner, Could you please help me to fix it? my code is as below:

import tensorflow as tf 
import keras.backend as K
import numpy as np

def mean_iou(y_true, y_pred):
    prec = []
    for t in np.arange(0.5, 1.0, 0.05):
        y_pred_ = tf.cast(y_pred > t, tf.int32)
        score, up_opt = tf.metrics.MeanIoU(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)
deaspo commented 4 years ago

Hi, thanks for pointing this out. There are two options

  1. You can either downgrade
  2. There is miou.py file, import this and replace it in the metric during model.compile. i.e.
from miou import MeanIoU
miou_metric = MeanIoU(num_classes)
metrics=['accuracy', miou_metric.mean_iou]
deaspo commented 4 years ago

If it reso;ves the issue let me know

hanieshojaee commented 4 years ago

If it reso;ves the issue let me know

Thanks for your help. Yes you were right and it worked. but when i ran UNet, accuracy reached to 0.98 but mean_iou is 0.48 and doesn't update. Do you have any idea where is my wrong? my code is below:

import os
import numpy as np
import h5py
import tensorflow.keras as keras
from keras import Input
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.core import Dropout
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.models import Model, load_model
import keras.backend as K
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from miou import MeanIoU

## Read Image and Label from HDFfile
Image_hf = h5py.File(r'E:\Education\MSc\thesis\Data\Image.h5', 'r')
Image = np.array(Image_hf.get('Image'))
# print(Image.shape)

Label_hf = h5py.File(r'E:\Education\MSc\thesis\UrbanExpansion\Data\UrbanExpansion\Drivers\HDF5files\Label.h5', 'r')
Label = np.array(Label_hf.get('Label'))
# print(Label.shape)

## Convert Label to One Hot Vector
Label = keras.utils.to_categorical(Label, num_classes=2)
# print(Label.shape)

# class MeanIoU(tf.keras.metrics.MeanIoU):
#     def __call__(self, y_true, y_pred, sample_weight=None):
#         y_pred = tf.argmax(y_pred, axis=-1)
#         return super().__call__(y_true, y_pred, sample_weight=sample_weight)

# tf.metrics.MeanIoU
## Define 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)
#         y_pred_ = tf.cast(y_pred > t, tf.int32)
#         score, up_opt = tf.metrics.MeanIoU(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)

# ## Define Custom Loss Function
class_weights = np.array([1, 0.0000001])
weights = K.variable(class_weights)
def weighted_categorical_crossentropy(y_true, y_pred):
    # scale predictions so that the class probas of each sample sum to 1
    y_pred /= K.sum(y_pred, axis = -1, keepdims = True)
    # clip to prevent NaN's and Inf's
    y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())
    # calculate loss and weight loss
    loss = y_true * K.log(y_pred) * weights
    loss = -K.sum(loss, -1)
    return loss

## Set parameters
Img_Width    = 256
Img_Height   = 256
Img_Channels = 1
Num_Classes  = 2

## Define Inputs and Targets Dim
inputs  = Input((Img_Height, Img_Width, Img_Channels))
# print(inputs.shape)
targets = Input((Img_Height, Img_Width, Num_Classes))
# print(targets.shape)

## Model Architecture

c1 = Conv2D(16, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (inputs)
c1 = Dropout(0.1)(c1)
c1 = Conv2D(16, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c1)
p1 = MaxPooling2D((2, 2))(c1)

c2 = Conv2D(32, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (p1)
c2 = Dropout(0.1)(c2)
c2 = Conv2D(32, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c2)
p2 = MaxPooling2D((2, 2))(c2)

c3 = Conv2D(64, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (p2)
c3 = Dropout(0.2)(c3)
c3 = Conv2D(64, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c3)
p3 = MaxPooling2D((2, 2))(c3)

c4 = Conv2D(128, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (p3)
c4 = Dropout(0.2)(c4)
c4 = Conv2D(128, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c4)
p4 = MaxPooling2D(pool_size = (2, 2))(c4)

c5 = Conv2D(256, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (p4)
c5 = Dropout(0.3)(c5)
c5 = Conv2D(256, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c5)

u6 = Conv2DTranspose(128, (2, 2), strides = (2, 2), padding = 'same') (c5)
u6 = concatenate([u6, c4])
c6 = Conv2D(128, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (u6)
c6 = Dropout(0.2) (c6)
c6 = Conv2D(128, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c6)

u7 = Conv2DTranspose(64, (2, 2), strides = (2, 2), padding = 'same') (c6)
u7 = concatenate([u7, c3])
c7 = Conv2D(64, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (u7)
c7 = Dropout(0.2) (c7)
c7 = Conv2D(64, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c7)

u8 = Conv2DTranspose(32, (2, 2), strides = (2, 2), padding = 'same') (c7)
u8 = concatenate([u8, c2])
c8 = Conv2D(32, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (u8)
c8 = Dropout(0.1) (c8)
c8 = Conv2D(32, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c8)

u9 = Conv2DTranspose(16, (2, 2), strides = (2, 2), padding = 'same') (c8)
u9 = concatenate([u9, c1], axis = 3)
c9 = Conv2D(16, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (u9)
c9 = Dropout(0.1) (c9)
c9 = Conv2D(16, (3, 3), activation = 'elu', kernel_initializer = 'he_normal', padding = 'same') (c9)

outputs = Conv2D(2, (1, 1), activation = 'softmax') (c9)
# print(outputs.shape)

miou_metric = MeanIoU(2)

model = Model(inputs = [inputs], outputs = [outputs])
model.compile(optimizer='adam', loss=weighted_categorical_crossentropy,   metrics=['accuracy', miou_metric.mean_iou])
model.summary()

##
model_hf = h5py.File(r'E:\Education\MSc\thesis\UrbanExpansion\Data\UrbanExpansion\UnetModel\model_epochs_05.h5', 'w')
model_hf.close()
earlystopper = EarlyStopping(patience = 5, verbose = 1)
checkpointer = ModelCheckpoint(r'E:\Education\MSc\thesis\Data\\model_epochs_05.h5', verbose = 1, save_best_only=True, save_weights_only=False)
results      = model.fit(Image, Label, validation_split = 0.10, batch_size = 8, epochs = 5, callbacks = [earlystopper, checkpointer])
deaspo commented 4 years ago

Hi, looking at the code I have can say the following:

hanieshojaee commented 4 years ago

Hi, looking at the code I have can say the following:

  • Are you sure it is two classes? Are you dealing with grey images? and label maps are binary image?
  • Please check the dropouts, that's a lot being droppped, try dropping 50%
  • If the training seems slow, try adding batch normalization following each convolution exxcept where you do activations
  • I wouldn't rely on accuracy as a metric, try IOU or Dice. You can als vary the learning rate and see how it helps or affect the training.

Hi.

hanieshojaee commented 4 years ago

Hi, I have a question about predicting with trained Unet. As I said, when I downgraded tf, it worked and mean_iou increased to 0.92 but when I used this model for prediction, the output is a blank image with zero values. Could you please help me to know what shall I do? my prediction code is below:

import os
import gdal
import numpy as np
from tqdm import tqdm
import h5py
import keras
from keras import Input
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.core import Dropout
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.models import Model, load_model
import keras.backend as K
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow

## Define 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)

# ## Define Custom Loss Function
class_weights = np.array([0.5, 0.5])
weights = K.variable(class_weights)
#
def weighted_categorical_crossentropy(y_true, y_pred):
    # scale predictions so that the class probas of each sample sum to 1
    y_pred /= K.sum(y_pred, axis = -1, keepdims = True)
    # clip to prevent NaN's and Inf's
    y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())
    # calculate loss and weight loss
    loss = y_true * K.log(y_pred) * weights
    loss = -K.sum(loss, -1)
    return loss

number_of_classes = 2
## Save GeoTIFF Image
def save_image(image_data, path, geo_transform, projection):
    driver = gdal.GetDriverByName('GTiff')

    # Set Info of Image
    height, width = image_data.shape
    dataset = driver.Create(path, width, height, 1, gdal.GDT_Byte)
    dataset.SetGeoTransform(geo_transform)
    dataset.SetProjection(projection)
    dataset.GetRasterBand(1).WriteArray(image_data)

    dataset.FlushCache()

## Apply Model to Image
def eval_image(input_image_path, model, output_image_path):

    input_dataset = gdal.Open(input_image_path)
    input_image   = input_dataset.ReadAsArray().astype(np.float32)
    h, w     = input_image.shape
    n = 1
    # print(input_image.shape)

    model_input_height, model_input_width, model_input_channels    = model.layers[0].input_shape[1:4]
    # print(model_input_height, model_input_width, model_input_channels)
    model_output_height, model_output_width, model_output_channels = model.layers[len(model.layers) - 1].output_shape[1:4]
    # print(model_output_height, model_output_width, model_output_channels)

    padding_y = int((model_input_height - model_output_height)/2)
    padding_x = int((model_input_width - model_output_width)/2)
    assert model_output_channels == number_of_classes

    pred_lc_image = np.zeros((h, w, number_of_classes))
    # print(pred_lc_image.shape)
    mask = np.ones((h, w))
    # print(mask.shape)
    irows, icols = [],[]
    batch_size   = 16
    minibatch    = []
    ibatch       = 0
    mb_array     = np.zeros((batch_size, model_input_width, model_input_height, model_input_channels))
    # print(mb_array.shape)

    n_rows = int(h / model_output_height)
    # print(n_rows)
    n_cols = int(w / model_output_width)
    # print(n_cols)

    for row_idx in tqdm(range(n_rows)):
        for col_idx in range(n_cols):

            subimage = input_image[row_idx*model_output_height:row_idx*model_output_height + model_input_height,
                                   col_idx*model_output_width:col_idx*model_output_width + model_input_width] / 256.0
            # print(subimage.shape)

            if(subimage.shape == model.layers[0].input_shape[1:4]):

                mb_array[ibatch] = subimage
                ibatch += 1
                irows.append((row_idx*model_output_height + padding_y,row_idx*model_output_height + model_input_height - padding_y))
                icols.append((col_idx*model_output_width +  padding_x,col_idx*model_output_width  + model_input_width  - padding_x))

                if (ibatch) == batch_size:

                    outputs = model.predict(mb_array)
                    for i in range(batch_size):
                        r0,r1 = irows[i]
                        c0,c1 = icols[i]

                        pred_lc_image[r0:r1, c0:c1] = outputs[i]
                        mask[r0:r1, c0:c1] = 0

                    ibatch = 0
                    irows,icols = [],[]

    if ibatch > 0:
        outputs = model.predict(mb_array)
        for i in range(ibatch):
            r0,r1 = irows[i]
            c0,c1 = icols[i]

            pred_lc_image[r0:r1, c0:c1, :] = outputs[i]
            mask[r0:r1, c0:c1, :] = 0

    label_image = np.ma.array(pred_lc_image.argmax(axis=-1), mask = mask)
    save_image(label_image, output_image_path, input_dataset.GetGeoTransform(), input_dataset.GetProjection())

## Evaluate Images in Folder¶
def evaluate(input_dir, model_path, output_dir):
    model = load_model(model_path, custom_objects={'mean_iou': mean_iou,'weighted_categorical_crossentropy': weighted_categorical_crossentropy})
    # for root, dirs, files in os.walk(input_dir):
    #     if not files: continue

        # for f in files:
            # pth = os.path.join(root,f)
    out_pth = os.path.join(output_dir+'\Predicted_2004.tif')
    eval_image(input_dir, model, out_pth)
    print('saved result to ' + out_pth)

## Set Parameters
input_image_dir  = r'E:\Education\thesis\Data\Reclass_2004.tif'
model = r'E:\Education\MSc\thesis\Data\model_epochs_05.h5'
output_image_dir = r'E:\Education\MSc\thesis\Data\results_2004'
evaluate(input_image_dir, model, output_image_dir)
deaspo commented 4 years ago

Hi, I have a question about predicting with trained Unet. As I said, when I downgraded tf, it worked and mean_iou increased to 0.92 but when I used this model for prediction, the output is a blank image with zero values. Could you please help me to know what shall I do? my prediction code is below:

import os
import gdal
import numpy as np
from tqdm import tqdm
import h5py
import keras
from keras import Input
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.core import Dropout
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.models import Model, load_model
import keras.backend as K
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow

## Define 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)

# ## Define Custom Loss Function
class_weights = np.array([0.5, 0.5])
weights = K.variable(class_weights)
#
def weighted_categorical_crossentropy(y_true, y_pred):
    # scale predictions so that the class probas of each sample sum to 1
    y_pred /= K.sum(y_pred, axis = -1, keepdims = True)
    # clip to prevent NaN's and Inf's
    y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())
    # calculate loss and weight loss
    loss = y_true * K.log(y_pred) * weights
    loss = -K.sum(loss, -1)
    return loss

number_of_classes = 2
## Save GeoTIFF Image
def save_image(image_data, path, geo_transform, projection):
    driver = gdal.GetDriverByName('GTiff')

    # Set Info of Image
    height, width = image_data.shape
    dataset = driver.Create(path, width, height, 1, gdal.GDT_Byte)
    dataset.SetGeoTransform(geo_transform)
    dataset.SetProjection(projection)
    dataset.GetRasterBand(1).WriteArray(image_data)

    dataset.FlushCache()

## Apply Model to Image
def eval_image(input_image_path, model, output_image_path):

    input_dataset = gdal.Open(input_image_path)
    input_image   = input_dataset.ReadAsArray().astype(np.float32)
    h, w     = input_image.shape
    n = 1
    # print(input_image.shape)

    model_input_height, model_input_width, model_input_channels    = model.layers[0].input_shape[1:4]
    # print(model_input_height, model_input_width, model_input_channels)
    model_output_height, model_output_width, model_output_channels = model.layers[len(model.layers) - 1].output_shape[1:4]
    # print(model_output_height, model_output_width, model_output_channels)

    padding_y = int((model_input_height - model_output_height)/2)
    padding_x = int((model_input_width - model_output_width)/2)
    assert model_output_channels == number_of_classes

    pred_lc_image = np.zeros((h, w, number_of_classes))
    # print(pred_lc_image.shape)
    mask = np.ones((h, w))
    # print(mask.shape)
    irows, icols = [],[]
    batch_size   = 16
    minibatch    = []
    ibatch       = 0
    mb_array     = np.zeros((batch_size, model_input_width, model_input_height, model_input_channels))
    # print(mb_array.shape)

    n_rows = int(h / model_output_height)
    # print(n_rows)
    n_cols = int(w / model_output_width)
    # print(n_cols)

    for row_idx in tqdm(range(n_rows)):
        for col_idx in range(n_cols):

            subimage = input_image[row_idx*model_output_height:row_idx*model_output_height + model_input_height,
                                   col_idx*model_output_width:col_idx*model_output_width + model_input_width] / 256.0
            # print(subimage.shape)

            if(subimage.shape == model.layers[0].input_shape[1:4]):

                mb_array[ibatch] = subimage
                ibatch += 1
                irows.append((row_idx*model_output_height + padding_y,row_idx*model_output_height + model_input_height - padding_y))
                icols.append((col_idx*model_output_width +  padding_x,col_idx*model_output_width  + model_input_width  - padding_x))

                if (ibatch) == batch_size:

                    outputs = model.predict(mb_array)
                    for i in range(batch_size):
                        r0,r1 = irows[i]
                        c0,c1 = icols[i]

                        pred_lc_image[r0:r1, c0:c1] = outputs[i]
                        mask[r0:r1, c0:c1] = 0

                    ibatch = 0
                    irows,icols = [],[]

    if ibatch > 0:
        outputs = model.predict(mb_array)
        for i in range(ibatch):
            r0,r1 = irows[i]
            c0,c1 = icols[i]

            pred_lc_image[r0:r1, c0:c1, :] = outputs[i]
            mask[r0:r1, c0:c1, :] = 0

    label_image = np.ma.array(pred_lc_image.argmax(axis=-1), mask = mask)
    save_image(label_image, output_image_path, input_dataset.GetGeoTransform(), input_dataset.GetProjection())

## Evaluate Images in Folder¶
def evaluate(input_dir, model_path, output_dir):
    model = load_model(model_path, custom_objects={'mean_iou': mean_iou,'weighted_categorical_crossentropy': weighted_categorical_crossentropy})
    # for root, dirs, files in os.walk(input_dir):
    #     if not files: continue

        # for f in files:
            # pth = os.path.join(root,f)
    out_pth = os.path.join(output_dir+'\Predicted_2004.tif')
    eval_image(input_dir, model, out_pth)
    print('saved result to ' + out_pth)

## Set Parameters
input_image_dir  = r'E:\Education\thesis\Data\Reclass_2004.tif'
model = r'E:\Education\MSc\thesis\Data\model_epochs_05.h5'
output_image_dir = r'E:\Education\MSc\thesis\Data\results_2004'
evaluate(input_image_dir, model, output_image_dir)

How have you define your color dictionary?

hanieshojaee commented 4 years ago

Hi, Actually I didn't have defined color dictionary. I added it and made some changes but still the outputs are all blank images. Here's code for prediction with color dictionary .I'll appreciate if you could help me.

import os
import gdal
import numpy as np
from tqdm import tqdm
import h5py
import keras
from keras import Input
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.layers.core import Dropout
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
from keras.models import Model, load_model
import keras.backend as K
from keras.callbacks import EarlyStopping, ModelCheckpoint
import tensorflow as tf
import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from IPython.display import HTML, display
import tabulate

## Land Cover Classes
table = [["Non_Urban", 0], ["Urban", 1]]
display(HTML(tabulate.tabulate(table, tablefmt='html')))

## Number of Land Cover Classes
number_of_classes = 2
color_map = [[52, 52, 52], [100, 100, 100]]

## Define 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)

# ## Define Custom Loss Function
class_weights = np.array([1, 1])
weights = K.variable(class_weights)

def weighted_categorical_crossentropy(y_true, y_pred):
    # scale predictions so that the class probas of each sample sum to 1
    y_pred /= K.sum(y_pred, axis=-1, keepdims=True)
    # clip to prevent NaN's and Inf's
    y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())
    # calculate loss and weight loss
    loss = y_true * K.log(y_pred) * weights
    loss = -K.sum(loss, -1)
    return loss

## Save GeoTIFF Image
def save_image(image_data, path):
    driver = gdal.GetDriverByName('GTiff')

    # Set Info of Image
    height, width = image_data.shape
    dataset = driver.Create(path, width, height, 1, gdal.GDT_Byte)
    # dataset.SetGeoTransform(geo_transform)
    # dataset.SetProjection(projection)
    dataset.GetRasterBand(1).WriteArray(image_data)

    # Create Color Table
    color_table = gdal.ColorTable()

    for i in range(number_of_classes):
        color_table.SetColorEntry(i, tuple(color_map[i]) + (255,))
    dataset.GetRasterBand(1).SetRasterColorTable(color_table)
    dataset.GetRasterBand(1).SetNoDataValue(255)

    dataset.FlushCache()

def eval_image(input_image_path, model, output_image_path):
    input_dataset = gdal.Open(input_image_path)
    input_image = input_dataset.ReadAsArray().astype(np.float32)
    input_image = np.expand_dims(input_image, axis=2)

    # print(input_image.shape)
    # input_image = np.rollaxis(input_image, 0, 3)
    h, w, n = input_image.shape
    # print(input_image.shape)

    model_input_height, model_input_width, model_input_channels = model.layers[0].input_shape[1:4]
    print(model_input_height, model_input_width, model_input_channels)
    model_output_height, model_output_width, model_output_channels = model.layers[len(model.layers) - 1].output_shape[1:4]
    print(model_output_height, model_output_width, model_output_channels)

    padding_y = int((model_input_height - model_output_height) / 2)
    padding_x = int((model_input_width - model_output_width) / 2)
    assert model_output_channels == number_of_classes

    pred_lc_image = np.zeros((h, w, number_of_classes))
    # print(pred_lc_image.shape)
    mask = np.ones((h, w))
    # print(mask.shape)

    irows, icols = [], []
    batch_size = 16
    minibatch = []
    ibatch = 0
    mb_array = np.zeros((batch_size, model_input_width, model_input_height, model_input_channels))
    # print(mb_array.shape)

    n_rows = int(h / model_output_height)
    # print(n_rows)
    n_cols = int(w / model_output_width)
    # print(n_cols)

    for row_idx in tqdm(range(n_rows)):
        for col_idx in range(n_cols):

            subimage = input_image[row_idx * model_output_height:row_idx * model_output_height + model_input_height,
                       col_idx * model_output_width:col_idx * model_output_width + model_input_width, :] / 256.0
            print(subimage.shape)
            print(np.amin(subimage), np.amax(subimage))

            if (subimage.shape == model.layers[0].input_shape[1:4]):

                mb_array[ibatch] = subimage
                ibatch += 1
                irows.append((row_idx * model_output_height + padding_y,
                              row_idx * model_output_height + model_input_height - padding_y))
                icols.append((col_idx * model_output_width + padding_x,
                              col_idx * model_output_width + model_input_width - padding_x))

                if (ibatch) == batch_size:

                    outputs = model.predict(mb_array)
                    for i in range(batch_size):
                        r0, r1 = irows[i]
                        c0, c1 = icols[i]

                        pred_lc_image[r0:r1, c0:c1, :] = outputs[i]
                        mask[r0:r1, c0:c1] = 0

                    ibatch = 0
                    irows, icols = [], []

    if ibatch > 0:
        outputs = model.predict(mb_array)
        for i in range(ibatch):
            r0, r1 = irows[i]
            c0, c1 = icols[i]

            pred_lc_image[r0:r1, c0:c1, :] = outputs[i]
            mask[r0:r1, c0:c1] = 0

    label_image = np.ma.array(pred_lc_image.argmax(axis=-1), mask=mask)
    save_image(label_image.filled(255), output_image_path )

## Evaluate Images in Folder¶
def evaluate(input_dir, model_path, output_dir):
    model = load_model(model_path, custom_objects={'mean_iou': mean_iou, 'weighted_categorical_crossentropy': weighted_categorical_crossentropy})

    for root, dirs, files in os.walk(input_dir):
        if not files: continue
        # print(root, dirs, files )

        for f in files:
            pth = os.path.join(root, f)
            # print(pth)

            out_pth = os.path.join(output_dir, f.split('.')[0] + 'Predicted_2004.tif')
            print(out_pth)
            eval_image(pth, model, out_pth)
            print('saved result to ' + out_pth)

input_image_dir = r'E:\All_Images_Shuffle'
model = r'E:\model_epochs_05.h5'
output_image_dir = r'E:\Predict_2004To2014'
evaluate(input_image_dir, model, output_image_dir)
deaspo commented 4 years ago

Hi, if you check the following lines line 26, Line 118, Line 129, shows how the color_dict was defined and applied when saving the predicted results. Maybe you can try the same, in you dictionary I see you have defined only two keys

ghost commented 4 years ago

I used it and get constant IOU accuracy of 1.0, no change during training. Any idea what's wrong. I don't want to downgrade TensorFlow