keras构建模型,层异常 AttributeError: 'NoneType' object has no attribute '_inbound_nodes'

用keras建立模型,然而要插入这个模块CANet(或者改写成层),一直报错报错!!!,报错为 AttributeError: 'NoneType' object has no attribute '_inbound_nodes',解释为由keras建立模型中,插入了非keras的层。但是我尝试将函数或者计算包装成keras层,仍然无用,求教,求教!!!

img

def model6(data_in, data_out,):  # 输入(b,c,h,w)
    spec_start = Input(shape=(data_in[-3], data_in[-2], data_in[-1]))
    spec_cnn = spec_start 
    spec_cnn = Conv2D(nb_cnn2d_filt, 3, padding='same')(spec_cnn)
    spec_cnn = BatchNormalization()(spec_cnn)
### 以下就是我要插入的模块(改写成层了)
    input = spec_cnn
    # h = _tensor_shape(input)[2]
    # w = _tensor_shape(input)[3]
    # [n, c, h, w] = input.shape
    x_h = AveragePooling2D(pool_size=(300, 1), strides=1, padding='valid', data_format="channels_first")(input)
    x_w = AveragePooling2D(pool_size=(1, 64), strides=1, padding='valid', data_format="channels_first")(input)
    x_w = Permute((1, 3, 2))(x_w)

    y = Concatenate(axis=3)([x_h, x_w], )
    y = Conv2D(filters=8, kernel_size=1,strides=1, padding="valid")(y)
    y = BatchNormalization()(y)
    y = Activation('relu')(y)

    x_h, x_w = Lambda(tf.split, arguments={"axis": 3, "num_or_size_splits": [64, 300]})(y)   # 分层
    x_w = Permute((1, 3, 2))(y[:, :, :, 64:])

    a_h = Conv2D(filters=64, kernel_size=1,
                 strides=1, padding="valid", activation="sigmoid")(x_h)
    a_w = Conv2D(filters=64, kernel_size=1,
                 strides=1, padding="valid", activation="sigmoid")(x_w)
    spec_cnn = multiply([spec_cnn, a_h, a_w])

################## 模块化
def ca(input):
    identity = input
    # h = _tensor_shape(input)[2]
    # w = _tensor_shape(input)[3]
    # [n, c, h, w] = input.shape
    x_h = AveragePooling2D(pool_size=(300, 1),strides=1,padding='valid',data_format="channels_first")(input)
    x_w = AveragePooling2D(pool_size=(1, 64),strides=1,padding='valid',data_format="channels_first")(input)
    x_w = Permute((1, 3, 2))(x_w)
    y = Concatenate(axis=3)([x_h, x_w],)
    y = Conv2D(filters=8, kernel_size=1,
               strides=1, padding="valid")(y)
    y = BatchNormalization()(y)
    y = Activation('relu')(y)

    x_h, x_w = Lambda(tf.split, arguments={"axis": 3, "num_or_size_splits": [64, 300]})(y) # 分层

    x_w = Permute((1, 3, 2))(y[:,:,:,64:])
    a_h = Conv2D(filters=64, kernel_size=1,
                 strides=1, padding="valid", activation="sigmoid")(x_h)
    a_w = Conv2D(filters=64, kernel_size=1,
                 strides=1, padding="valid", activation="sigmoid")(x_w)
    out = multiply([identity, a_h, a_w])
    return out

你看看这个解决方法:

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你看下这篇博客吧, 应该有用👉 :Keras AttributeError: 'NoneType' object has no attribute '_inbound_nodes'报错
  • 除此之外, 这篇博客: keras模型训练报错AttributeError: ‘NoneType‘ object has no attribute ‘_inbound_nodes‘中的 解决方案 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    (1)由于代码中使用了concatenate以及reshape这两个方法,具体使用例如:

    from keras import backend as K
    from keras.layers import Dense, Input
    
    inpt = Input(shape=(224, 224, 3))
    x = Conv2d(63, (3,3), padding='same', activation='relu')
    ...
    x = K.concatenate([branch1, branch2, branch3], axis=3)
    x = K.reshpe(x, (1000,))
    # 上面两行代码并不是连续出现,这里写出来,主要描述使用了“连接”“reshape”两种操作;
    

    将其修改为:

    from keras.layers import Concatenate, Resahpe
    x = Concatenate(axis=3)([branch1, branch2, branch3])
    x = Resahpe((1000,))(x)
    

    可以想到,直接使用concatenate或者reshape不是作为一层,而Concatenate或者Reshape是一个layer;
    我按照上述方法修改后仍然报错
    (2)将自定义层的输出变为keras layer类型,实现也很简单,就是调用keras中的Lambda函数。举例如下:

    from tensorflow import squeeze
    from keras.layers import Lambda
    def squeeze_dim(input):
        output = squeeze(input, axis = [1,2])
    def my_model(inputs):
        x = Conv2d(inputs)
        ...
        # 只需要使用Lambda调用预定义好的函数即可
        x = Lambda(squeeze_dim, name='sqe_dim')(x)
        model = Model(input = inputs, output = x)
        ...
    

    (3)激活函数的使用**(我的代码报错的原因)**

        left = Multiply()([left1,keras.activations.sigmoid(right1)])
        right = Multiply()([left2,keras.activations.sigmoid(right2)])
    

    将其修改为:

        left = Multiply()([left1, Activation('sigmoid')(right1)])
        right = Multiply()([left2, Activation('sigmoid')(right2)])
    

    修改后问题解决,没有报错
    参考博客:

    https://www.cnblogs.com/chenzhen0530/p/10893803.html
    https://blog.csdn.net/jorg_zhao/article/details/89929230
    https://blog.csdn.net/wdh315172/article/details/105437494
    https://blog.csdn.net/weixin_43786241/article/details/106834761

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^