Я написал данные генератор для обработки больших изображений, которые загружаются только партиями по 4.
Я использую изображения в оттенках серого размером 512 x 1152 пикселей с 73 каналами. Итак, по сути у меня есть 73 изображения для одного скаляра.
Соответствующие разделы генератора данных выглядят следующим образом:
Код: Выделить всё
def __getitem__(self, index):
"""Generates one batch of data."""
# Get the indices for this batch
batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]
# Load the batch of images from the numpy array file
input, target_scalar = self.__load_batch(batch_indices)
return input, target_scalar
def __load_batch(self, batch_indices):
"""Loads a specific batch of images and their target_scalar."""
# Open the numpy array file each time to load only the needed data
array = np.load(self.images_path, mmap_mode='r')
try:
# Access only the rows in the array corresponding to batch_indices
batch_images = array[batch_indices,:,:,:]
finally:
array._mmap.close()
# Get the corresponding target_scalar for the batch
batch_target_scalar = np.array([self.target_scalar[i] for i in batch_indices])
batch_input_scalar = np.array([self.input_scalar[i] for i in batch_indices])
return (batch_images, batch_input_scalar), batch_target_scalar
Сеть CNN сама по себе имеет структуру:
Код: Выделить всё
class ConvModel(Model):
def __init__(self, image_size, *args, **kwargs):
super(ConvModel, self).__init__()
activation_function = 'relu'
self.conv1 = Conv2D(64, (5, 5), activation=activation_function,data_format='channels_last')
self.maxpool1 = MaxPooling2D((2, 2))
self.conv2 = Conv2D(64, (5, 5), activation=activation_function)
self.flatten = Flatten()
self.dense1 = Dense(256, activation=activation_function)
self.dropout = Dropout(0.5)
self.dense2 = Dense(128, activation=activation_function)
self.dense3 = Dense(1, activation=activation_function)
self.dense4 = Dense(1, activation=activation_function)
self.reshape_scalar_input = tf.keras.layers.Reshape((1,)) # Ensures scalar input has shape (batch_size, 1)
self.output_layer = Dense(1)
def call(self, inputs):
# Unpack the inputs (image and scalar input)
image_input = inputs[0]
scalar_input = inputs[1]
x = self.conv1(image_input)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.flatten(x)
x = self.dense1(x)
x = self.dropout(x)
x = self.dense2(x)
x = self.dense3(x)
y = self.reshape_scalar_input(scalar_input)
combined = tf.keras.layers.concatenate([x, y])
x = self.dense4(combined)
return self.output_layer(x)
Код: Выделить всё
model.fit(train_generator, epochs=10, batch_size=4)
Входное изображение имеет размерность (None, 512, 1152, 73), а scalar_input имеет (None ,), что мне кажется правильным.
Первая эпоха также заканчивается без каких-либо проблем.
Как только начинается вторая эпоха, для некоторых по этой причине форма image_input теперь равна (512,1152,73), а для scalar_input (512,1152,73) также с соответствующим сообщением об ошибке:
Input 0 слоя «conv2d» несовместим со слоем: ожидается min_ndim=4, обнаружено ndim=3. Полная форма получена: (512, 1152, 73)
Поэтому по какой-то причине наборы данных портятся от одной эпохи к другой. Есть идеи, что здесь может произойти?
Я попробовал исключить скалярные входные данные из модели, чтобы получить CNN, работающую исключительно с изображениями. Это сработало нормально. Но как только я ввел этот второй ввод, все стало странно.
Подробнее здесь: https://stackoverflow.com/questions/792 ... irst-epoch
Мобильная версия