I cannot stack a classifier model on top of a (partly) pre-trained VGG16 model in Model Class API. There are several threads with people having the same problem Google Groups and StackoverFlow. I have tried all variants, but I keep getting a Graph disconnect error:
Exception: Graph disconnected: cannot obtain value for tensor input_2 at layer "
My last attempt:
from keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense, Input
img_width, img_height = 150, 150
input_1 = Input(shape=(3, img_width, img_height))
vgg16_model = VGG16(include_top=False, weights='imagenet', input_tensor=input_1)
input_2 = Input(shape=vgg16_model.output_shape[1:])
x = GlobalAveragePooling2D()(input_2)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
predict = Dense(1, activation='sigmoid')(x)
top_model = Model(input=input_2, output=predict)
# load the best saved weights
#top_model.load_weights(os.path.join(data_path, 'VGG16Classifier.hdf5'))
# add the model on top of the convolutional base
model = Model(input=input_1, output=top_model.output)
For info I am trying to re-create this Keras Blog , but with the Model Class API in order to later modify the VGG16 model.
Is there a bug that is preventing this from working? Thanks, Jan
Oh, and I am totally thrilled about Keras!!! Really impressive!
@farizrahman4u I also reported this same issue along with a few others. How can we help get this fixed?
The issue is exactly what the error message says. There is no path from input_1 to top_model.output. So nothing to fix on keras side.
@farizrahman4u This is rude comment. This is actually an error that @fchollet fixed, #4477.
@farizrahman4u You've made me irritated with your comment so I will carefully show you the path from input_t to top_model.output.
input_1 feeds into vgg16_model, vgg_model.output feeds into input_2. Input_2 goes to x via the functional API. x goes into predict and then predict goes into top_model = Model(input=input_2, output=predict).
You've made me irritated with your comment
You irritate me with your existence.
vgg_model.output feeds into input_2
No it doesn't. If it does, kindly comment the particular line, Sir.
Here is the original code by OP. You will still get the error, with latest version of Keras; because it is supposed to.
from keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.layers import Convolution2D, MaxPooling2D, ZeroPadding2D, GlobalAveragePooling2D
from keras.layers import Dropout, Flatten, Dense, Input
img_width, img_height = 150, 150
input_1 = Input(shape=(3, img_width, img_height))
vgg16_model = VGG16(include_top=False, weights='imagenet', input_tensor=input_1)
input_2 = Input(shape=vgg16_model.output_shape[1:])
x = GlobalAveragePooling2D()(input_2)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
predict = Dense(1, activation='sigmoid')(x)
top_model = Model(input=input_2, output=predict)
# load the best saved weights
#top_model.load_weights(os.path.join(data_path, 'VGG16Classifier.hdf5'))
# add the model on top of the convolutional base
model = Model(input=input_1, output=top_model.output)
Maybe next time ask someone less rude?
Hi Farirz and Isaac, thank you both for trying to help me get unstuck! Fariz, as you can see I do not see how I can make this work. The code above is just one of many configs I've tried. So may I ask you politely to show me how you think this would work? Isaac and I have given it our best, but so far we have not been able to crack it. Thank you very much! Jan
@jdelange Its pretty straight forward:
img_width, img_height = 150, 150
input = Input(shape=(3, img_width, img_height))
vgg16_model = VGG16(include_top=False, weights='imagenet')
x = vgg16_model(input)
x = GlobalAveragePooling2D()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
predict = Dense(1, activation='sigmoid')(x)
model = Model(input=input, output=predict)
P.S Not tested.
Just split the model:
img_width, img_height = 150, 150
vgg16_model = VGG16(include_top=False, weights='imagenet')
input = Input(batch_shape=vgg16_model.output_shape)
x = GlobalAveragePooling2D()(input)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
predict = Dense(1, activation='sigmoid')(x)
top_model = Model(input, predict)
top_model.load_weights(os.path.join(data_path, 'VGG16Classifier.hdf5'))
input = Input(shape=(3, img_width, img_height))
x = vgg16_model(input)
predict = top_model(x)
model = Model(input, predict)
Looks good. I will try to compile and run this. If it works I will share and close the issue.
The good news: the above code compiles and runs. To replicate the Keras tutorial however, I need a Flatten()
as first layer in the top_model. GlobalAveragePooling2D does not converge. Replacing the GlobalAveragePooling2D()
layer with a Flatten()
layer generates the following error:
File "C:\Program Files\Anaconda2lib\site-packages\keras\layers\core.py", lin 433, in get_output_shape_for '(got ' + str(input_shape[1:]) + '. '
Exception: The shape of the input to "Flatten" is not fully defined (got (512,
None, None). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.
Addinginput_shape=(3, img_width, img_height)
to the VVG16 model raised the 3-channel error I mentioned here #4477. I fixed this by creating a stripped version of the VGG16 model taking out all Tensorflow stuff. It then runs and converges. I realize I would do better by figuring out what causes the issue, but I am not experienced enough.
Perhaps there is a better / more logical way to fully define the input shape?
Since I am now able to proceed, I will close this issue and thank you very much for helping me out. I will copy these findings to the Keras Google group for the benefit of others.
You irritate me with your existence.
@farizrahman4u Boo hoo buddy, get over it
Babies are the ones who delete their comments.
@isaacgerg
You are the one who called me for help, and I did help you with the issue. You called me rude and irritating for pointing out a mistake in your code? (assuming @jdelange is in your team), What did you expect? Also, you do realize that I don't get paid for any of this right? Hope you don't find all the free work we do here for you rude or irritating. "Get over it"? Get over what? You are just an internet troll, who can't even get a trivial VGG to compile. And ping "(@)fchollet" ? You gonna tell on me? Who is the baby now?
Everyone, please be professional.
@farizrahman4u @fchollet
This is it for me. I am moving to tensorflow.
Most helpful comment
Everyone, please be professional.