Я пытаюсь обучить нейронную сеть, чтобы она могла находить линии в изображениях, изображения в формате bmp и в оттенках серого. После начала фазы обучения сети программа останавливается и выдает соответствующее сообщение об ошибке.
Этот код полностью основан на «Сегментации изображения с помощью tf.keras» Рэймонда Юаня (https://ej.uz/hk9s) с изменениями в конвейере ввода, но сама модель точно такая же. Я попытался переопределить форму ввода на что-то другое, но каждый раз, когда я что-то меняю, сообщение об ошибке меняется, но всегда происходит в одном и том же месте.
#%%
import numpy as np
import matplotlib as mpl
import tensorflow as tf
from tensorflow.python.keras import layers
from tensorflow.python.keras import losses
from tensorflow.python.keras import models
#%%
#Defining paths to all the images
x_train_filenames = []
y_train_filenames = []
x_eval_filenames = []
y_eval_filenames = []
for x in range(250):
x_train_filenames.append(r'Train/Images/gen_{}_.bmp'.format(x))
y_train_filenames.append(r'Train/Labels/gen_{}_seg_.bmp'.format(x))
x_eval_filenames.append(r'Evaluate/Images/gen_{}_.bmp'.format(x))
y_eval_filenames.append(r'Evaluate/Labels/gen_{}_seg_.bmp'.format(x))
num_train_examples = len(x_train_filenames)
num_eval_examples = len(x_eval_filenames)
#%%
#Creating dataset from all of the pathnames.
img_shape = (3296, 3008, 1)
batch_size = 3
epochs = 5
threads = 5
def _process_pathnames(img_name, lbl_name):
img_str = tf.read_file(img_name)
img = tf.image.decode_bmp(img_str)
lbl_str = tf.read_file(lbl_name)
lbl = tf.image.decode_bmp(lbl_str)
return img, lbl
training_dataset = tf.data.Dataset.from_tensor_slices((x_train_filenames, y_train_filenames))
training_dataset = training_dataset.map(_process_pathnames, num_parallel_calls=threads)
training_dataset = training_dataset.shuffle(num_train_examples)
training_dataset = training_dataset.repeat().batch(batch_size)
evaluation_dataset = tf.data.Dataset.from_tensor_slices(((x_eval_filenames, y_eval_filenames)))
evaluation_dataset = evaluation_dataset.map(_process_pathnames, num_parallel_calls=threads)
evaluation_dataset = evaluation_dataset.shuffle(num_eval_examples)
evaluation_dataset = evaluation_dataset.repeat().batch(batch_size)
#%%
#Deining model
def conv_block(input_tensor, num_filters):
encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(input_tensor)
encoder = layers.BatchNormalization()(encoder)
encoder = layers.Activation('relu')(encoder)
encoder = layers.Conv2D(num_filters, (3, 3), padding='same')(encoder)
encoder = layers.BatchNormalization()(encoder)
encoder = layers.Activation('relu')(encoder)
return encoder
def encoder_block(input_tensor, num_filters):
encoder = conv_block(input_tensor, num_filters)
encoder_pool = layers.MaxPooling2D((2, 2), strides=(2, 2))(encoder)
return encoder_pool, encoder
def decoder_block(input_tensor, concat_tensor, num_filters):
decoder = layers.Conv2DTranspose(num_filters, (2, 2), strides=(2, 2), padding='same')(input_tensor)
decoder = layers.concatenate([concat_tensor, decoder], axis=-1)
decoder = layers.BatchNormalization()(decoder)
decoder = layers.Activation('relu')(decoder)
decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)
decoder = layers.BatchNormalization()(decoder)
decoder = layers.Activation('relu')(decoder)
decoder = layers.Conv2D(num_filters, (3, 3), padding='same')(decoder)
decoder = layers.BatchNormalization()(decoder)
decoder = layers.Activation('relu')(decoder)
return decoder
inputs = layers.Input(shape=img_shape)
encoder0_pool, encoder0 = encoder_block(inputs, 32)
encoder1_pool, encoder1 = encoder_block(encoder0_pool, 64)
encoder2_pool, encoder2 = encoder_block(encoder1_pool, 128)
encoder3_pool, encoder3 = encoder_block(encoder2_pool, 256)
encoder4_pool, encoder4 = encoder_block(encoder3_pool, 512)
center = conv_block(encoder4_pool, 1024)
decoder4 = decoder_block(center, encoder4, 512)
decoder3 = decoder_block(decoder4, encoder3, 256)
decoder2 = decoder_block(decoder3, encoder2, 128)
decoder1 = decoder_block(decoder2, encoder1, 64)
decoder0 = decoder_block(decoder1, encoder0, 32)
outputs = layers.Conv2D(1, (1, 1), activation='sigmoid')(decoder0)
model = models.Model(inputs=[inputs], outputs=[outputs])
#%%
#Defining custom loss functions
def dice_coeff(y_true, y_pred):
smooth = 1.
# Flatten
y_true_f = tf.reshape(y_true, [-1])
y_pred_f = tf.reshape(y_pred, [-1])
intersection = tf.reduce_sum(y_true_f * y_pred_f)
score = (2. * intersection + smooth) / (tf.reduce_sum(y_true_f) + tf.reduce_sum(y_pred_f) + smooth)
return score
def dice_loss(y_true, y_pred):
loss = 1 - dice_coeff(y_true, y_pred)
return loss
def bce_dice_loss(y_true, y_pred):
loss = losses.binary_crossentropy(y_true, y_pred) + dice_loss(y_true, y_pred)
return loss
model.compile(optimizer='adam', loss=bce_dice_loss, metrics=[dice_loss])
save_model_path = '/tmp/weights.hdf5'
cp = tf.keras.callbacks.ModelCheckpoint(filepath=save_model_path, monitor='val_dice_loss', save_best_only=True, verbose=1)
#%%
#Training the model
history = model.fit(training_dataset,
steps_per_epoch=int(np.ceil(num_train_examples / float(batch_size))),
epochs=epochs,
validation_data=evaluation_dataset,
validation_steps=int(np.ceil(num_eval_examples / float(batch_size))),
callbacks=[cp])
Полное сообщение об ошибке:
Traceback (most recent call last):
File "<ipython-input-19-f1dcac0996cd>", line 1, in <module>
runfile('//upb.lv/usr/profiles/Peteris.Zvejnieks/Desktop/Tests/Train data/A thing_retry.py', wdir='//upb.lv/usr/profiles/Peteris.Zvejnieks/Desktop/Tests/Train data')
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 786, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "//upb.lv/usr/profiles/Peteris.Zvejnieks/Desktop/Tests/Train data/A thing_retry.py", line 159, in <module>
callbacks=[cp])
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py", line 880, in fit
validation_steps=validation_steps)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_arrays.py", line 266, in model_iteration
batch_outs = f(actual_inputs)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\backend.py", line 3076, in __call__
run_metadata=self.run_metadata)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 1439, in __call__
run_metadata_ptr)
File "C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 528, in __exit__
c_api.TF_GetCode(self.status.status))
InvalidArgumentError: Number of channels must be 1, 3 or 4, was 0
[[{{node DecodeBmp_1}}]]
[[{{node IteratorGetNext_13}}]]