尝试使用Keras Functional API构建CNN模型时图形断开连接

时间:2019-02-21 00:06:18

标签: tensorflow machine-learning keras conv-neural-network

我正在尝试使用Keras Functional API构建CNN模型,但是每当我尝试执行以下代码行:model = CNN(settings, np.expand_dims(x_train, axis = 3)).build_network()时,我都会遇到以下问题:

  

ValueError:图形已断开:无法获得张量的值   Tensor(“ input_11:0”,shape =(?, 28,28,1),dtype = float32)   “ input_11”。可以顺利访问以下先前的层:   []

这是我的代码:

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

这是我作为类构造函数的参数提供的设置:

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]
}

1 个答案:

答案 0 :(得分:0)

问题是inputs变量具有第一个Dense层的输出张量,而不是实际输入。