用keras建立模型,然而要插入这个模块CANet(或者改写成层),一直报错报错!!!,报错为 AttributeError: 'NoneType' object has no attribute '_inbound_nodes',解释为由keras建立模型中,插入了非keras的层。但是我尝试将函数或者计算包装成keras层,仍然无用,求教,求教!!!
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
不知道你这个问题是否已经解决, 如果还没有解决的话:(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)])
修改后问题解决,没有报错
参考博客: