I am trying to build a CNN model using Keras Functional API but whenever I try to execute this line of code: model = CNN(settings, np.expand_dims(x_train, axis = 3)).build_network()
I keep running into the following issue:
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_11:0", shape=(?, 28, 28, 1), dtype=float32) at layer "input_11". The following previous layers were accessed without issue: []
Here is my code:
class CNN:
def __init__(self, settings, data):
self.flag = False
self.settings = settings
if self.check_network_settings() == False:
self.flag = True
return
self.data = data
if K.image_data_format() == "channels_first":
self.data = self.data.reshape(data.shape[0], data.shape[3], data.shape[2], data.shape[1])
self.build_network()
def show_model_chart(self):
if not os.path.isfile('model.png'):
plot_model(self.model, to_file = 'model.png')
model_pic = cv2.imread('model.png')
plt.imshow(model_pic)
plt.show()
def build_network(self):
print('Bulding Convolutional Neural Network ...')
inputs = Input(shape = (self.data.shape[1], self.data.shape[2], self.data.shape[3]))
final_output = None
for layer_idx in range(self.settings['conv']['layers']):
inputs = Conv2D(
filters = self.settings['conv']['filters'][layer_idx],
kernel_size = self.settings['conv']['kernel_size'][layer_idx],
strides = self.settings['conv']['strides'][layer_idx],
padding = self.settings['conv']['padding']
)(inputs)
if self.settings['pooling']['apply'] == True:
inputs = MaxPooling2D(
pool_size = self.settings['pooling']['pool_size'][layer_idx],
strides = self.settings['pooling']['strides'][layer_idx],
padding = self.settings['pooling']['padding']
)(inputs)
inputs = Activation(
activation = self.settings['detector_stage'][layer_idx]
)(inputs)
inputs = Flatten()(inputs)
for dense_layer_idx in range(self.settings['dense']['layers']):
if self.settings['dense']['activations'][dense_layer_idx] != 'softmax':
inputs = Dense(
units = self.settings['dense']['output_units'][dense_layer_idx],
activation = self.settings['dense']['activations'][dense_layer_idx]
)(inputs)
else:
final_output = Dense(
units = self.settings['dense']['output_units'][dense_layer_idx],
activation = self.settings['dense']['activations'][dense_layer_idx]
)(inputs)
self.model = Model(inputs = inputs, outputs = final_output)
def check_network_settings(self):
for key in self.settings:
if key == 'conv':
if set(self.settings['conv'].keys()) != {'layers', 'filters', 'kernel_size', 'strides', 'padding'}:
print('[INCORRECT SETTINGS]: Convolutional layers ...')
return False
elif key == 'pooling':
if set(self.settings['pooling'].keys()) != {'apply', 'pool_size', 'strides', 'padding'}:
print('[INCORRECT SETTINGS]: Pooling layers ...')
return False
if len(self.settings['pooling']['apply']) != self.settings['conv']['layers']:
print('Please specify wether or not to apply pooling for each convolutional layer')
return False
elif key == 'detector_stage':
if self.settings['conv']['layers'] != len(self.settings['detector_stage']):
print('Number of activation functions you have specified does not match the number of convolutional layers inside the network ...')
return False
elif key == 'dense':
if set(self.settings['dense'].keys()) != {'layers', 'output_units', 'activations'}:
print('[INCORRECT SETTINGS]: Dense layers ...')
return False
if 'softmax' != self.settings['dense']['activations'][len(self.settings['dense']['activations'])-1]:
print('Your network must contain Softmax activation function at the last Dense layer in order to produce class probabilities ...')
return False
print('Network settings have been correctly specified ...')
return True
And here are the settings I provided as an argument to the class constructor:
settings = {
'conv':
{
'layers': 3,
'filters': [32, 64, 128],
'kernel_size':[(3,3), (5,5), (5,5)],
'strides': [1, 1, 1],
'padding': 'same',
},
'pooling':
{
'apply': [True, True, True],
'pool_size': [(2,2), (3,3), (3,3)],
'strides': [1, 1, 1],
'padding': 'same'
},
'detector_stage': ['relu', 'relu', 'relu'],
'dense':
{
'layers': 2,
'output_units': [500, 10],
'activations': ['relu', 'softmax'],
},
'batch_norm': [False, False, False, False]
}