I’m trying to make model for image segmentation of flooded area with 700 training dataset.
Whenever I run the code, the validation loss is increasing after decreasing. Is there any way to adjust variables for solving this overfitting
enter image description here
The code is below.
SIZE = 256
# get data
data_dir =
image_paths, mask_paths = create_data(data_dir)
class EncoderBlock(Layer):
def __init__(self, filters, rate, pooling=True, **kwargs):
super(EncoderBlock, self).__init__(**kwargs)
self.filters = filters
self.rate = rate
self.pooling = pooling
self.c1 = Conv2D(filters, kernel_size=3, strides=1, padding='same', activation='relu', kernel_initializer='he_normal')
self.drop = Dropout(rate)
self.c2 = Conv2D(filters, kernel_size=3, strides=1, padding='same', activation='relu', kernel_initializer='he_normal')
self.pool = MaxPool2D()
def call(self, X):
x = self.c1(X)
x = self.drop(x)
x = self.c2(x)
if self.pooling:
y = self.pool(x)
return y, x
else:
return x
def get_config(self):
base_config = super().get_config()
return {
**base_config,
"filters":self.filters,
'rate':self.rate,
'pooling':self.pooling
}
class DecoderBlock(Layer):
def __init__(self, filters, rate, **kwargs):
super(DecoderBlock, self).__init__(**kwargs)
self.filters = filters
self.rate = rate
self.up = UpSampling2D()
self.net = EncoderBlock(filters, rate, pooling=False)
def call(self, X):
X, skip_X = X
x = self.up(X)
c_ = concatenate([x, skip_X])
x = self.net(c_)
return x
def get_config(self):
base_config = super().get_config()
return {
**base_config,
"filters":self.filters,
'rate':self.rate,
}
class AttentionGate(Layer):
def __init__(self, filters, bn, **kwargs):
super(AttentionGate, self).__init__(**kwargs)
self.filters = filters
self.bn = bn
self.normal = Conv2D(filters, kernel_size=3, padding='same', activation='relu', kernel_initializer='he_normal')
self.down = Conv2D(filters, kernel_size=3, strides=2, padding='same', activation='relu', kernel_initializer='he_normal')
self.learn = Conv2D(1, kernel_size=1, padding='same', activation='sigmoid')
self.resample = UpSampling2D()
self.BN = BatchNormalization()
def call(self, X):
X, skip_X = X
x = self.normal(X)
skip = self.down(skip_X)
x = Add()([x, skip])
x = self.learn(x)
x = self.resample(x)
f = Multiply()([x, skip_X])
if self.bn:
return self.BN(f)
else:
return f
# return f
def get_config(self):
base_config = super().get_config()
return {
**base_config,
"filters":self.filters,
"bn":self.bn
}
# Inputs
input_layer = Input(shape= imgs.shape[-3:])
# Encoder
p1, c1 = EncoderBlock(32, 0.1, name="Encoder1")(input_layer)
p2, c2 = EncoderBlock(64, 0.1, name="Encoder2")(p1)
p3, c3 = EncoderBlock(128, 0.2, name="Encoder3")(p2)
p4, c4 = EncoderBlock(256, 0.2, name="Encoder4")(p3)
# Encoding
encoding = EncoderBlock(512, 0.3, pooling=False, name="Encoding")(p4)
# Attention + Decoder
a1 = AttentionGate(256, bn=True, name="Attention1")([encoding, c4])
d1 = DecoderBlock(256, 0.2, name="Decoder1")([encoding, a1])
a2 = AttentionGate(128, bn=True, name="Attention2")([d1, c3])
d2 = DecoderBlock(128, 0.2, name="Decoder2")([d1, a2])
a3 = AttentionGate(64, bn=True, name="Attention3")([d2, c2])
d3 = DecoderBlock(64, 0.1, name="Decoder3")([d2, a3])
a4 = AttentionGate(32, bn=True, name="Attention4")([d3, c1])
d4 = DecoderBlock(32,0.1, name="Decoder4")([d3, a4])
# Output
output_layer = Conv2D(1, kernel_size=1, activation='sigmoid', padding='same')(d4)
# Model
model = Model(inputs= [input_layer], outputs= [output_layer])
# Compile
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
class MyCallback(Callback):
def __init__(self, model, epochs, ask_epoch):
super(MyCallback, self).__init__()
self.model = model
self.epochs = epochs
self.ask_epoch = ask_epoch
def on_epoch_end(self, epoch, logs=None):
if (epoch + 1) % self.ask_epoch == 0:
user_input = input(f"Epoch {epoch + 1}/{self.epochs} completed. Train more? (yes/no): ")
if user_input.lower() != 'yes':
self.model.stop_training = True
print("Training halted.")
batch_size = 40
epochs = 100
ask_epoch = 5
callbacks = [MyCallback(model= model, epochs= epochs, ask_epoch= ask_epoch)]
# early_stopping
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20, restore_best_weights=True)
# Training
history = model.fit(
imgs, msks,
validation_split=0.3,
epochs=epochs,
verbose=1,
steps_per_epoch=len(imgs)//batch_size,
batch_size=batch_size,
callbacks=[early_stopping]
)
I tried these.
- batch_size : 32 > 16
- validation_split : 0.2 > 0.3
- early_stopping_patience : 30 > 20
New contributor
Hyomin Lee is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.