ValueError: График отключен: невозможно получить значение для тензора KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3)
Я работаю над подходом MetaLearning к решению проблемы сегментации изображения. Я обучил 7 разных моделей на разных классах, связанных с набором данных о глазах, предоставленным Oculus SBVPI (радужная оболочка, зрачок, склера, кантус, периокуляр, сосуды, ресницы). Я хочу соединить эти несколько моделей вместе, имея семь входных головок, соответствующих семи предварительно обученным моделям, а затем объединить их выходные данные, чтобы получить окончательный результат.
Я хочу создать архитектуру модели с 7 входными головками, каждая входная головка соединяется со своим собственным блоком кодировщика, а затем в конце блока кодировщика вывод объединяется и передается в один блок декодера для получения вывода.
Я не могу понять проблему, любые предложения вообще будут очень полезны.
Я пробовал другие подобные подходы, приведенные здесь и здесь.
Мой код:
import tensorflow as tf
# Assume all libraries are imported
class PretrainedMetaUNet:
def __init__(self, config, save_model=True, show_summary=True, sigmoid=True, **kwargs):
super(PretrainedMetaUNet, self).__init__(**kwargs)
self.configuration = config
self.x_size = config["dataset"]["width"] # 128
self.y_size = config["dataset"]["height"] # 128
self.channels = config["dataset"]["img_channels"] # 3
self.save_model = save_model
self.add_sigmoid = sigmoid
self.meta_classes = config["dataset"]["meta_channels"] # 1
self.show_summary = show_summary
self.model_img = config["Network"]["modelpath"]
self.dropout_factor = config["Network"]['dropout']
self.maxpool = tf.keras.layers.MaxPooling2D()
def ConvolutionBN(self, input_tensor, filters):
x = tf.keras.layers.Conv2D(filters, 3, padding='same', kernel_initializer='he_normal')(input_tensor)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU()(x)
if self.dropout_factor != 0.0:
x = tf.keras.layers.Dropout(self.dropout_factor)(x)
x = tf.keras.layers.Conv2D(filters, 3, padding='same', kernel_initializer='he_normal')(x)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.ReLU()(x)
if self.dropout_factor != 0.0:
x = tf.keras.layers.Dropout(self.dropout_factor)(x)
return x
def return_pretrained_model_encoder_weights(self):
root_path = self.configuration['train']['Output']['weight']
path = glob.glob(os.path.join(root_path, '*_weights'), recursive=True)
# path variable has absolute address of all the seven models ['/path to sclera model', '/path to iris model', ...]
# Every model is trained on the input images of spatial dimension 128x128x3 predicting a segmentation mask of 128x128x1.
encoder_weights = []
for idx, model_path in enumerate(path):
model = tf.keras.models.load_model(filepath=model_path, compile=False)
class_name = model_path.split('/')[-1].split('_')[0] # takes class name like iris, sclera etc..
for layer in model.layers:
layer._name = layer.name + str('_' + class_name)
# I used segmentation_models library ==> sm.UNet('resnet34', encoder_weights='imagenet')
# Accessing different encoding stages of the model. Every model is Unet pretrained with resnet34 weights.
s1 = model.get_layer(name='data'+str('_' + class_name)).output
s2 = model.get_layer(name='relu0'+str('_' + class_name)).output
s3 = model.get_layer(name='stage2_unit1_relu1'+str('_' + class_name)).output
s4 = model.get_layer(name='stage3_unit1_relu1'+str('_' + class_name)).output
b1 = model.get_layer(name='stage4_unit1_relu1'+str('_' + class_name)).output
encoder_weights.append([b1, s1, s2, s3, s4])
del model
return encoder_weights
def DecoderBlock(self, input_tensor, skip_features, filters, name=None):
if name is None:
x = tf.keras.layers.Conv2DTranspose(filters, kernel_size=2, strides=2,
padding='SAME', kernel_initializer='he_normal')(input_tensor)
else:
x = tf.keras.layers.Conv2DTranspose(filters, kernel_size=2, strides=2, name=name,
padding='SAME', kernel_initializer='he_normal')(input_tensor)
x = tf.keras.layers.Concatenate()([x, skip_features])
x = self.ConvolutionBN(x, filters)
return x
def return_model(self):
input_1 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_2 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_3 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_4 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_5 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_6 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
input_7 = tf.keras.layers.Input(shape=(self.x_size, self.y_size, self.channels)) # (128,128,3)
inputs = [input_1, input_2, input_3, input_4, input_5, input_6, input_7]
encoder_weights = self.return_pretrained_model_encoder_weights()
# Concatenating all the relative weights together
full_b = [layer[0] for layer in encoder_weights]
full_s1 = [layer[1] for layer in encoder_weights]
full_s2 = [layer[2] for layer in encoder_weights]
full_s3 = [layer[3] for layer in encoder_weights]
full_s4 = [layer[4] for layer in encoder_weights]
concatenated_b = tf.keras.layers.Concatenate(axis=-1)(full_b)
concatenated_s1 = tf.keras.layers.Concatenate(axis=-1)(full_s1)
concatenated_s2 = tf.keras.layers.Concatenate(axis=-1)(full_s2)
concatenated_s3 = tf.keras.layers.Concatenate(axis=-1)(full_s3)
concatenated_s4 = tf.keras.layers.Concatenate(axis=-1)(full_s4)
# Creating final decoder block
d1 = self.DecoderBlock(concatenated_b, concatenated_s4, 512, name='decoder_start')
d2 = self.DecoderBlock(d1, concatenated_s3, 256, name='block2')
d3 = self.DecoderBlock(d2, concatenated_s2, 128, name='block3')
d4 = self.DecoderBlock(d3, concatenated_s1, 64, name='block4')
""" Output """
if self.add_sigmoid:
activation = 'sigmoid'
else:
activation = None
output = tf.keras.layers.Conv2D(self.meta_classes, 1, padding='same', activation=activation)(d4)
model = tf.keras.Model(inputs=inputs, outputs=output)
if self.show_summary:
print(model.summary())
if self.save_model:
tf.keras.utils.plot_model(model, show_dtype=True, show_layer_names=True, show_shapes=True,
to_file=self.model_img)
return model
if __name__ == '__main__':
# Loaded Configuration file...
pretrained_unet = PretrainedMetaUNet(config=configuration)
model = pretrained_unet.return_model()
Ошибка:
ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, None, None, 3), dtype=tf.float32, name='data'), name='data', description="created by layer 'data_pupil'") at layer "bn_data_pupil". The following previous layers were accessed without issue: []