В чем причина ошибки "input image must be of non-zero size"?
Недавно начал изучать сверточные нейронные сети для медицинских сегментированных изображений. Построил простую модель. Вроде бы все работает, но на этапе model.fit выдает ошибку
input image must be of non-zero size [[node model/up_sampling2d/resize/ResizeNearestNeighbor (defined at :1) ]] [Op:__inference_train_function_2038]
Я не представляю с чем это может быть связано, но предполагаю, что либо в загрузке данных, либо в создании массивов. Прилагаю код к ознакомлению с пояснениями. Делаю в colab
Импортирую необходимые библиотеки
import tensorflow as tf
import keras
from tensorflow.keras.layers import concatenate, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from tensorflow.keras import datasets, layers, models
from glob import glob
import skimage.io as io
import matplotlib.pyplot as plt
import numpy as np
path = '/content'
end = '/Study-DCM/*.dcm'
Загружаю файлы
files = glob(path+end, recursive=True)
files
Устанавливаю simpleitk для чтения изображений
!pip install simpleitk
Создаю функцию для преобразования обычных изображений в массив
def to_array(path, end):
files = glob(path+end, recursive=True)
img_list = []
for file in files:
img = io.imread(file, plugin="simpleitk")
img = ((img - img.min())/(img.max() - img.min()))
img.astype("float32")
for slice in range(2, 33):
img_s = img[slice,:,:]
img_s = np.expand_dims(img_s, axis=-1)
img_list.append(img_s)
return np.array(img_list,np.float32)
Создаю функцию для преобразования сегментированных изображений в массив
def seg_to_array(path, end):
files = glob(path+end, recursive=True)
img_list = []
for file in files:
img = io.imread(file, plugin='simpleitk')
img.astype("float32")
for slice in range(2,33):
img_s = img[slice,:,:]
img_s = np.expand_dims(img_s, axis=-1)
img_list.append(img_s)
return np.array(img_list,np.float32)
Создание массивов
lungs = to_array(path=path, end=end)
seg = seg_to_array(path=path, end='/Masks-DCM/*.dcm')
Создание тренировочного набора при помощи срезов
lungs_train = lungs[:1200]
seg_train = seg[:1200]
Создание тестового набора при помощи срезов
lungs_test = lungs[1200:]
seg_test = seg[1200:]
Далее идет структура нейронной сети
def unet_model():
inputs = tf.keras.layers.Input((512, 512, 1))
# -- Encoder -- #
# Block encoder 1
conv1 = Conv2D(2, (3, 3), activation='relu', padding='same') (inputs)
conv1 = Conv2D(2, (3, 3), activation='relu', padding='same') (conv1)
# Block encoder 2
pool1 = MaxPooling2D((2, 2), data_format='channels_last')(conv1)
conv2 = Conv2D(4, (3, 3), activation='relu', padding='same') (pool1)
conv2 = Conv2D(4, (3, 3), activation='relu', padding='same') (conv2)
# Block encoder 3
pool2 = MaxPooling2D((2, 2), data_format='channels_last')(conv2)
conv3 = Conv2D(8, (3, 3), activation='relu', padding='same') (pool2)
conv3 = Conv2D(8, (3, 3), activation='relu', padding='same') (conv3)
# -- Encoder -- #
pool3 = MaxPooling2D((2, 2), data_format='channels_last')(conv3)
conv4 = Conv2D(16, (3, 3), activation='relu', padding='same')(pool3)
conv4 = Conv2D(16, (3, 3), activation='relu', padding='same')(conv4)
# -- Decoder -- #
# Block encoder 1
conv_t_1 = Conv2D(8, 2, activation = 'relu', padding = 'same') (conv4)
up_s_1= UpSampling2D(size = (2, 2),)(conv_t_1)
conc1 = concatenate([conv3, up_s_1], axis=-1)
conv5 = Conv2D(8, (3, 3), activation='relu', padding='same') (conc1)
conv5 = Conv2D(8, (3, 3), activation='relu', padding='same') (conv5)
# Block encoder 2
conv_t_2 = Conv2D(4, 2, activation = 'relu', padding = 'same') (conv5)
up_s_2= UpSampling2D(size = (2, 2))(conv_t_2)
conc2 = concatenate([conv2, up_s_2], axis=-1)
conv6 = Conv2D(4, (3, 3), activation='relu', padding='same') (conc2)
conv6 = Conv2D(4, (3, 3), activation='relu', padding='same') (conv6)
# Block encoder 3
conv_t_3 = Conv2D(2, 2, activation = 'relu', padding = 'same') (conv6)
up_s_3= UpSampling2D(size = (2, 2))(conv_t_3)
conc3 = concatenate([conv1, up_s_3], axis=-1)
conv7 = Conv2D(2, (3, 3), activation='relu', padding='same') (conc3)
conv7 = Conv2D(2, (3, 3), activation='relu', padding='same') (conv7)
conv_final = Conv2D(1, 1, activation='sigmoid')(conv7)
model = Model(inputs=[inputs], outputs=[conv_final])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(),
metrics=['accuracy'])
return model
model = unet_model()
Генерация структуры нейронной сети
tf.keras.utils.plot_model(model, show_shapes=True)
Создание генераторов
def get_gen(data_x: list, data_y: list):
assert len(data_x) == len(data_y), "Ошибка не соответствия данных"
while True:
for i, el in enumerate(data_x):
yield data_x[i], data_y[i]
lungs_tr_gen = get_gen(lungs_train, seg_train)
lungs_ts_gen = get_gen(lungs_test, seg_test)
И место, где происходит ошибка
model.fit(lungs_tr_gen, epochs=10, validation_data=(lungs_ts_gen))