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

Posted

技术标签:

【中文标题】尝试使用 Keras 功能 API 构建 CNN 模型时图形断开连接【英文标题】:Graph Disconnected when trying to build CNN model with Keras Functional API 【发布时间】:2019-07-14 18:48:38 【问题描述】:

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

ValueError: Graph disconnected: cannot get value for tensor Tensor("input_11:0", shape=(?, 28, 28, 1), dtype=float32) 在层 “输入_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】:

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

【讨论】:

以上是关于尝试使用 Keras 功能 API 构建 CNN 模型时图形断开连接的主要内容,如果未能解决你的问题,请参考以下文章

在使用 sklearn 和 keras 构建 CNN 时需要帮助理解形状错误吗?

深度学习实战Keras构建CNN神经网络完成CIFAR100类别分类

如果在使用功能 API 构建的多输入/输出 Keras 模型中使用生成器应该返回啥?

使用 Keras 的 CNN 深度学习模型中的 PCA

keras构建1D-CNN模型

从零开始,手把手教你使用Keras和TensorFlow构建自己的CNN模型