Модель Keras перестала работать после возврата назад изменений - PullRequest
0 голосов
/ 02 мая 2020

Первоначально я делал описанные здесь изменения, которые я буду здесь Keras UNET реализация прогнозирует очень плохие

После того, как я внес изменения (убрал деление на 255 для слоя Lambda), я увидел значительное улучшение Модель прогнозов (Изменение 1). Итак, рабочая версия кода выглядела так:

Обучение

import tensorflow as tf
import os
import random
import numpy as np
from tqdm import tqdm
import cv2
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau

from skimage.io import imread, imshow
from skimage.transform import resize
import matplotlib.pyplot as plt

os.environ['KERAS_BACKEND'] = 'tensorflow'

seed = 42
np.random.seed = seed

IMAGE_HEIGHT = 256
IMAGE_WIDTH = 256
IMAGE_CHANELS = 1

trainImageFolderPath = os.path.join(os.path.dirname(__file__), 'Bright Dunes Groups')

train_ids = next(os.walk(trainImageFolderPath))[1]

X_train = np.zeros((len(train_ids), IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_CHANELS), dtype=np.uint8)
Y_train = np.zeros((len(train_ids), IMAGE_HEIGHT, IMAGE_WIDTH, 1), dtype=np.bool)

print('Building training set...')

for n, id_ in tqdm(enumerate(train_ids), total=len(train_ids)):
    path = os.path.join(trainImageFolderPath, id_)
    imagePath = os.path.join(path, id_ + '.jpg')
    img = imread(imagePath)
    img = resize(img, (IMAGE_HEIGHT, IMAGE_WIDTH), mode='constant', preserve_range=True)

    img = np.expand_dims(img, axis=-1)

    X_train[n] = img

    mask = np.zeros((IMAGE_HEIGHT, IMAGE_WIDTH, 1), dtype=np.bool)

    for mask_file in next(os.walk(os.path.join(path, 'masks')))[2]:
        maskPath = os.path.join(path, 'masks', mask_file)
        mask_ = imread(maskPath)
        mask_ = resize(mask_, (IMAGE_HEIGHT, IMAGE_WIDTH), mode='constant', preserve_range=True)

        mask_ = np.expand_dims(mask_, axis=-1)
        mask = np.maximum(mask, mask_)

    Y_train[n] = mask

inputs = tf.keras.layers.Input((IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_CHANELS))

s = tf.keras.layers.Lambda(lambda x: x)(inputs)

c1 = tf.keras.layers.Conv2D(16, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(s)
c1 = tf.keras.layers.Dropout(0.1)(c1)
c1 = tf.keras.layers.Conv2D(16, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(c1)
p1 = tf.keras.layers.MaxPooling2D((2,2))(c1)

c2 = tf.keras.layers.Conv2D(32, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(p1)
c2 = tf.keras.layers.Dropout(0.1)(c2)
c2 = tf.keras.layers.Conv2D(32, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(c2)
p2 = tf.keras.layers.MaxPooling2D((2,2))(c2)

c3 = tf.keras.layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(p2)
c3 = tf.keras.layers.Dropout(0.2)(c3)
c3 = tf.keras.layers.Conv2D(64, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(c3)
p3 = tf.keras.layers.MaxPooling2D((2,2))(c3)

c4 = tf.keras.layers.Conv2D(128, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(p3)
c4 = tf.keras.layers.Dropout(0.2)(c4)
c4 = tf.keras.layers.Conv2D(128, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(c4)
p4 = tf.keras.layers.MaxPooling2D((2,2))(c4)

c5 = tf.keras.layers.Conv2D(256, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(p4)
c5 = tf.keras.layers.Dropout(0.3)(c5)
c5 = tf.keras.layers.Conv2D(256, (3,3), activation='relu', kernel_initializer='he_normal', padding='same')(c5)

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

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

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

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

outputs = tf.keras.layers.Conv2D(1, (1,1), activation='sigmoid')(c9)

model = tf.keras.Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

model.summary()


######################################################################################################
callbacks = [
    EarlyStopping(patience=5, verbose=1),
    ReduceLROnPlateau(factor=0.2, patience=3, min_lr=0.001, verbose=1),
    ModelCheckpoint('bright_Dunes_Groups_model.h5', verbose=1, save_best_only=True)
]
######################################################################################################


results = model.fit(X_train, 
                    Y_train,
                    validation_split=0.25,
                    batch_size=16,
                    epochs=80,
                    callbacks = callbacks)

idx = random.randint(0, len(X_train))

predictions_train = model.predict(X_train[:int(X_train.shape[0]*0.9)], verbose=1)
predictions_value = model.predict(X_train[int(X_train.shape[0]*0.9):], verbose=1)

predictions_train_t = (predictions_train > 0.5).astype(np.uint8)
predictions_value_t = (predictions_value > 0.5).astype(np.uint8)

###### random training sample

ix = random.randint(0, len(predictions_train_t))
###################################################################
imshow(X_train[ix])
###################################################################
plt.show()
imshow(np.squeeze(Y_train[ix]))
plt.show()
imshow(np.squeeze(predictions_train_t[ix]))
plt.show()

###### random validation sample
ix = random.randint(0, len(predictions_value_t))
imshow(X_train[int(X_train.shape[0]*0.9):][ix])
plt.show()
imshow(np.squeeze(Y_train[int(Y_train.shape[0]*0.9):][ix]))
plt.show()
imshow(np.squeeze(predictions_value_t[ix]))
plt.show()

Тестирование

import tensorflow as tf
import os
import random
import numpy as np
from tqdm import tqdm
import cv2

from skimage.io import imread, imshow
from skimage.transform import resize
import matplotlib.pyplot as plt

os.environ['KERAS_BACKEND'] = 'tensorflow'

IMAGE_HEIGHT = 256
IMAGE_WIDTH = 256
IMAGE_CHANELS = 1

modelFilePath = 'bright_Dunes_Groups_model.h5'
model = tf.keras.models.load_model(modelFilePath)

testImageFolderPath = os.path.join(os.path.dirname(__file__), 'TestDunes')

test_ids = next(os.walk(testImageFolderPath))[2]

for n, id_ in tqdm(enumerate(test_ids), total=len(test_ids)):
    imagePath = os.path.join(testImageFolderPath, id_)
    img = imread(imagePath)

    img = resize(img, (IMAGE_HEIGHT, IMAGE_WIDTH), mode='constant', preserve_range=True)

    imshow(img)
    plt.show()

    img = np.expand_dims(img, axis=0)
    img = np.expand_dims(img, axis=-1)

    predictions = model.predict(img, verbose=1)

    predictions_value_t = (predictions > 0.6).astype(np.uint8)
    imshow(np.squeeze(predictions_value_t))
    plt.show()

Все было хорошо.

Тогда я решил изменить размеры изображения кода для изменения размера с 256 * 256 до 512 * 512 (изменение 2).

Итак, я изменил как в обучении, так и в тестировании

IMAGE_HEIGHT = 256
IMAGE_WIDTH = 256

на

IMAGE_HEIGHT = 512
IMAGE_WIDTH = 512

Я попробовал это и увидел, что предсказания стали хуже, поэтому я вернулся к своему изменились размеры до 256 и добавлено около 50 новых изображений в X_train и соответствующие маски для расширения набора обучающих данных.

Затем я попытался снова начать тренировку. И к моему удивлению это снова не работает (предсказания снова плохи). Код точно такой же, как и тогда, когда все было хорошо, но я не вижу ожидаемых результатов. Кто-нибудь может объяснить, что может go не так с этой реализацией Keras UNET? Я уверен, что это не может быть добавлено 50 новых изображений и масок. Они выглядят точно так же, как и другие изображения. Я уверен, что это неправильные предопределения не могут быть, потому что я сначала внес изменения, а затем отменил их обратно, потому что после кода возврата точно такой же, как это было, когда предсказания были в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...