tensorflow - “InvalidArgumentError: You must feed a value for placeholder tensor ...”的简单演示
问题描述
所以,我遇到了臭名昭著的错误(使用 Keras 和 Tensorflow 作为后端):
tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'conv_in' with dtype float and shape [?,4,4,1]
[[Node: conv_in = Placeholder[dtype=DT_FLOAT, shape=[?,4,4,1], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
[[Node: conv2d_1/BiasAdd/_47 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_19_conv2d_1/BiasAdd", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]
我正在尝试使用 Keras 后端(tensorflow)调用来访问共享模型的中间层(使用两次的层/子模型)的激活,但找不到让它工作的解决方案人们对错误的许多相关经验。
- 背景(和最终目标):实际项目将两个图像输入一个网络,共享一个卷积子网,并将它们的密集编码输出关联起来。我的目标是检查和可视化卷积滤波器激活,以了解如何处理每个图像并改进模型(当然不是下面的最小示例)。不幸的是,我似乎无法找到一种方法将两个输入图像输入到我的主模型中,并访问子模型中间层的一个特定实例的激活。IE。子模型的 conv2d 层只有一个输出,那么如何根据子模型在主网上的第一次或第二次使用来访问子模型的中间激活?
无论如何,由于错误,我似乎根本无法访问激活,因此要解决的第一个问题......
这是一个演示该问题的完整最小脚本:
#!/usr/bin/env python3
from keras.models import Model
from keras.layers import Dense, Reshape, Flatten, Conv2D, MaxPooling2D, \
Input, Activation, Dropout, AveragePooling2D
from keras.layers.merge import concatenate
from keras.optimizers import Adam, SGD
import keras
from keras import backend as K
import numpy as np
import ipdb as pdb
def mod_pairs(indim=(None,None), channels=None, lrate=0.01):
x1 = inp1 = Input(shape=(indim[0], indim[1], channels), name='in1')
x2 = inp2 = Input(shape=(indim[0], indim[1], channels), name='in2')
feat = mod_conv(indim=(indim[0], indim[1]), channels=channels)
x1 = feat(x1)
x2 = feat(x2)
x = concatenate([x1,x2], axis=1, name='paired')
x = Dense(128, name='d_postjoin_1')(x)
y1 = Dense(1, name='densey1')(x)
y2 = Dense(1, name='densey2')(x)
model = Model(inputs=[inp1, inp2], outputs=[y1, y2])
adam=Adam(lr=lrate, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(loss='mae', optimizer=adam)
# print(model.summary())
return model
def mod_conv(indim=(None,None), channels=None):
x=inputs=Input(shape=(indim[0], indim[1], channels), name="conv_in")
x = Conv2D(1, (2,2))(x)
x = Flatten()(x)
x = Dense(5)(x)
feats = x
model = Model(inputs=[inputs], outputs=[feats])
# print("Sub-Model: ConvNet")
# print(model.summary())
return model
def main():
dim=4; ch=1
mod = mod_pairs(indim=(dim,dim), channels=ch)
inx1 = np.random.rand(1, dim, dim, ch)
inx2 = np.random.rand(1, dim, dim, ch)
y = mod.predict([inx1, inx2])
print(y)
cnn = mod.layers[2] # [2] is the mod_conv Model layer
# print(cnn) # <keras.engine.training.Model object ...>
out = mod.layers[2].layers[1]
# print(out) # <keras.layers.convolutional.Conv2D object ...>
# mod.layers[2].layers[1].get_output_at(1)
# The above results in:
# *** ValueError: Asked to get output at node 1, but the layer has only 1 inbound nodes.
fun = K.function(
[mod.input[0], mod.input[1], K.learning_phase()],
[mod.layers[2].layers[1].output])
#pdb.set_trace()
# It's about to fail...
print(fun([inx1, inx2, 0.0]))
# Errors here ^^^
# Attempt assuming graph prunes itself without all outputs
# fails with same error:
# fun = K.function(
# [mod.inputs[0], mod.inputs[1], K.learning_phase()],
# [mod.layers[2].layers[1].output] + mod.output)
# print(fun([inx1, inx2, 0.0]))
main()
# Error output:
#
# Traceback (most recent call last):
# File "./sharedsubnet.py", line 68, in <module>
# main()
# File "./sharedsubnet.py", line 55, in main
# print(fun([inx1, inx2, 0.0]))
# File "path.../keras/backend/tensorflow_backend.py", line 2666, in __call__
# return self._call(inputs)
# File "path.../keras/backend/tensorflow_backend.py", line 2636, in _call
# fetched = self._callable_fn(*array_vals)
# File "path.../tensorflow/python/client/session.py", line 1382, in __call__
# run_metadata_ptr)
# File "path.../tensorflow/python/framework/errors_impl.py", line 519, in __exit__
# c_api.TF_GetCode(self.status.status))
# tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'conv_in' with dtype float and shape [?,4,4,1]
# [[Node: conv_in = Placeholder[dtype=DT_FLOAT, shape=[?,4,4,1], _device="/job:localhost/replica:0/task:0/device:GPU:0"]()]]
解决方案
为什么不向您的 mod_conv() 模型添加一个额外的输出,那么您将更容易访问您的特定激活。
def mod_conv(indim=(None,None), channels=None):
x=inputs=Input(shape=(indim[0], indim[1], channels), name="conv_in")
xconv = Conv2D(1, (2,2))(x)
x = Flatten()(xconv)
x = Dense(5)(x)
feats = x
model = Model(inputs=[inputs], outputs=[feats,xconv])
# print("Sub-Model: ConvNet")
# print(model.summary())
return model
现在您的 cnn 模型有两个输出,希望您可以在您的 K.function() 中使用它们(对不起,我不明白那部分)
cnn.get_output_at(0)
cnn.get_output_at(1)
推荐阅读
- vb.net - 为什么我的 VB.NET WebRequest 会突然停止工作?
- git - JGit 允许 Push 更新签出的分支
- python - 如何使用 Python3.7 中的 python 编译代码运行应用程序?
- python - python排序文件列表
- excel - 有没有办法解决excel中的下拉问题?
- python - Why we add templates path in DIRS in django?
- javascript - 使用 Express 下载图像并使用 AJAX 在 Vue 中显示
- javascript - 如何检查图像是否在 Vue/Nuxt 中加载?
- python - 如何在 Seaborn 图中设置色调顺序
- python - 将动态参数传递给 AWS Glue