训练期间 TensorFlow 2 中多输入图像分类任务中的 AssertionError
AssertionError in multi-input image classification task in TensorFlow 2 during training
我使用 tf.keras 函数 API 构建了以下模型结构,其中整个想法是输入同一项目的不同视图的六张图像并获得单个 classification :
我有两个输出 classes。我在 classification 中使用 softmax 而不是 sigmoid,因为我想稍后分别检查每个 class,如果它们是不同的,它会更容易。
我相信我的输入形状因此应该是 [batch_size, 6, img_width, img_height, num_channels]
,尽管我不是 100% 确定。因为我用的是one-hot labels,所以我的labels的shape应该是[batch_size, num_classes]
吧?
但是,对于输入的 X 和 Y 形状:
Tensor("X:0", shape=(2, 6, 224, 224, 3), dtype=float32)
Tensor("Y:0", shape=(2, 2), dtype=float32)
TensorFlow 抱怨 AssertionError: Could not compute output Tensor("dense_1/Softmax:0", shape=(None, 2), dtype=float32)
追溯这个错误,可以看出是从我的训练函数开始的:
def train_function(X, Y, model, loss, optimizer, metric):
with tf.GradientTape() as tape:
predictions = model(X, training=True) #<- where the traceback occurs
loss_value = loss(Y, predictions)
gradients = tape.gradient(loss_value, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_acc = metric.update_state(Y, predictions)
return loss_value
这个函数本身在训练循环中被调用:
for batch, (X, Y) in train_ds.enumerate():
train_loss = train_function(X, Y, model, loss, optimizer, metric) # do the actual training
train_acc = metric.result().numpy() # get the training accuracy
batch_train_loss.append(train_loss) # save the training loss above
batch_train_acc.append(train_acc) # save the training accuracy above
metric.reset_states() # reset the metric after every batch
其中 train_ds
是使用从 TFRecords
导入的 tf.data.Dataset
构建的。
您有什么可能出错的建议吗?我唯一能想到的是输入的形状不对,但我不知道它应该是什么形状。
这里的正确答案是给每个输入一个名字:
dorsal_image = tf.keras.layers.Input(shape=(None, None, 3), name="dorsal_input")
medial_image = tf.keras.layers.Input(shape=(None, None, 3), name="medial_input")
plantar_image = tf.keras.layers.Input(shape=(None, None, 3), name="plantar_input")
lateral_image = tf.keras.layers.Input(shape=(None, None, 3), name="lateral_input")
proximal_image = tf.keras.layers.Input(shape=(None, None, 3), name="proximal_input")
distal_image = tf.keras.layers.Input(shape=(None, None, 3), name="distal_input")
并在 TFRecord 处理中确保输出是字典而不是列表:
return {'dorsal_input': image_lst[0], 'medial_input': image_lst[1],
'plantar_input': image_lst[2], 'lateral_input': image_lst[3],
'proximal_input': image_lst[4], 'distal_input': image_lst[5]}, label
这实际上是通过查看 samcaetano 在 this github issue 上的回答解决的。
我使用 tf.keras 函数 API 构建了以下模型结构,其中整个想法是输入同一项目的不同视图的六张图像并获得单个 classification :
我有两个输出 classes。我在 classification 中使用 softmax 而不是 sigmoid,因为我想稍后分别检查每个 class,如果它们是不同的,它会更容易。
我相信我的输入形状因此应该是 [batch_size, 6, img_width, img_height, num_channels]
,尽管我不是 100% 确定。因为我用的是one-hot labels,所以我的labels的shape应该是[batch_size, num_classes]
吧?
但是,对于输入的 X 和 Y 形状:
Tensor("X:0", shape=(2, 6, 224, 224, 3), dtype=float32)
Tensor("Y:0", shape=(2, 2), dtype=float32)
TensorFlow 抱怨 AssertionError: Could not compute output Tensor("dense_1/Softmax:0", shape=(None, 2), dtype=float32)
追溯这个错误,可以看出是从我的训练函数开始的:
def train_function(X, Y, model, loss, optimizer, metric):
with tf.GradientTape() as tape:
predictions = model(X, training=True) #<- where the traceback occurs
loss_value = loss(Y, predictions)
gradients = tape.gradient(loss_value, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_acc = metric.update_state(Y, predictions)
return loss_value
这个函数本身在训练循环中被调用:
for batch, (X, Y) in train_ds.enumerate():
train_loss = train_function(X, Y, model, loss, optimizer, metric) # do the actual training
train_acc = metric.result().numpy() # get the training accuracy
batch_train_loss.append(train_loss) # save the training loss above
batch_train_acc.append(train_acc) # save the training accuracy above
metric.reset_states() # reset the metric after every batch
其中 train_ds
是使用从 TFRecords
导入的 tf.data.Dataset
构建的。
您有什么可能出错的建议吗?我唯一能想到的是输入的形状不对,但我不知道它应该是什么形状。
这里的正确答案是给每个输入一个名字:
dorsal_image = tf.keras.layers.Input(shape=(None, None, 3), name="dorsal_input")
medial_image = tf.keras.layers.Input(shape=(None, None, 3), name="medial_input")
plantar_image = tf.keras.layers.Input(shape=(None, None, 3), name="plantar_input")
lateral_image = tf.keras.layers.Input(shape=(None, None, 3), name="lateral_input")
proximal_image = tf.keras.layers.Input(shape=(None, None, 3), name="proximal_input")
distal_image = tf.keras.layers.Input(shape=(None, None, 3), name="distal_input")
并在 TFRecord 处理中确保输出是字典而不是列表:
return {'dorsal_input': image_lst[0], 'medial_input': image_lst[1],
'plantar_input': image_lst[2], 'lateral_input': image_lst[3],
'proximal_input': image_lst[4], 'distal_input': image_lst[5]}, label
这实际上是通过查看 samcaetano 在 this github issue 上的回答解决的。