所以,我遇到了一个臭名昭著的错误(使用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)调用来访问共享模型(已使用两次的层/子模型)的中间层的激活,但是找不到解决方案从人们对错误的大量相关经验中进行工作。
无论如何,由于错误,我似乎根本无法访问激活,因此第一个要解决的问题...
以下是演示此问题的完整的最小脚本:
#!/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"]()]]
答案 0 :(得分: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)