问题描述
在使用TensorFlow进行模型训练或推理时,可能会遇到以下报错信息:
ValueError: Graph disconnected: cannot obtain value for tensor TensorName at layer "LayerName". The tensor has shape (Shape) but there are no sources that provide it.
其中TensorName、LayerName和Shape根据具体情况会有所不同。这个错误信息所表达的意思是:“模型中某些层的输入与输出之间存在不连续的情况,导致无法计算输出结果。”
发生原因
造成“Graph disconnected”这个错误发生的原因可能有多个,下面列出几种常见的情况:
模型中某些层的输入没有被正确地指定。
例如,一个卷积神经网络模型,其第一层(通常为卷积层)的输入应该是一个形如(batch_size, height, width, channels)的Tensor,如果在调用该层时没有正确地指定输入形状,就会出现“Graph disconnected”的错误:
input = tf.keras.Input(shape=(height, width, channels))
conv1 = tf.keras.layers.Conv2D(filters, kernel_size)(input)
这段代码的错误之处在于,卷积层conv1的输入来自于input,但是在定义input时并没有给定batch_size。这样就可能导致batch_size无法在运行时决定,从而无法连接两个层之间的input和conv1。
应该将代码修改为:
input = tf.keras.Input(shape=(height, width, channels,)) # 注意最后的逗号
conv1 = tf.keras.layers.Conv2D(filters, kernel_size)(input)
这样就可以正确地指定输入形状,并且避免了Tensor与输入之间的断开。
模型中某些层的输出没有被作为输入传递到下一个层中。
这种情况通常是由于模型中的某个分支没有被正确地连接到主线上,或者在定义模型时没有明确地指定每个层的输入和输出。(这是因为在TensorFlow 2.x版本中,大多数层都是可以自动推断输入和输出形状的。但是如果输入形状不明确,就有可能无法正确地推断输出形状。)
例如,下面这个代码片段中的Dense层就没有正确地连接到第一个卷积层后面:
input = tf.keras.Input(shape=(height, width, channels,))
conv1 = tf.keras.layers.Conv2D(filters, kernel_size)(input)
dense1 = tf.keras.layers.Dense(units)(conv1) # 这里没有前面的卷积输出conv1作为输入
应该将代码修改为:
input = tf.keras.Input(shape=(height, width, channels,))
conv1 = tf.keras.layers.Conv2D(filters, kernel_size)(input)
dense1 = tf.keras.layers.Dense(units)(tf.keras.layers.Flatten()(conv1))
这样就可以将卷积层conv1的输出展平为一维张量,然后作为Dense层的输入。
模型中某些层的输出并没有被接收或使用。
这种情况通常是由于某些层的输出虽然被计算了,但是由于没有被传递到最终输出或损失函数中,而导致剩下的层无法计算输出结果。
例如,下面这个代码片段中的输出层并没有被正确地指定输入:
input = tf.keras.Input(shape=(height, width, channels,))
x = some_layers(input)
...
output = tf.keras.activations.softmax(x) # 输出层没有明确的输入来源
应该将代码修改为:
input = tf.keras.Input(shape=(height, width, channels,))
x = some_layers(input)
...
output = tf.keras.layers.Dense(num_classes, activation='softmax')(x)
这样就可以将最后一层的输出作为模型的输出并输入到损失函数中。
解决方案
针对上述几种情况,可以分别采取不同的解决方案:
手动为每个层明确指定输入形状
这种方式适合于希望完全掌控模型各层输入输出的情况,但是对于大型模型来说可能比较繁琐。
使用tf.keras.layers.Flatten()将多维张量展平为一维张量。
这种方式可以避免一些输入形状不明确的问题,但是同时会增加模型中的内存和计算负担。
明确指定模型的输出,并将其作为损失函数的输入。
这种方式可以确保模型的输出与损失函数的输入之间是连续的,进而避免“Graph disconnected”错误的发生。
除此之外,还可以通过查看模型的输入输出图来发现并解决“Graph disconnected”错误。在TensorFlow中可以使用tf.keras.utils.plot_model()函数绘制模型的可视化图,通过检查其中的连接关系,可以找到所有不连续的地方并进行修改。
综上所述,避免“Graph disconnected”错误的关键在于充分理解模型各层输入输出之间的关系,并对模型进行充分的测试和调试。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解TensorFlow报”ValueError: Graph disconnected: cannot obtain value for tensor “的原因以及解决办法 - Python技术站