AttributeError: ‘NoneType‘ object has no attribute ‘_inbound_nodes‘解决方法

几周前要用自动编码器模拟一个通信系统,开始学习tensorflow,后来发现Keras对新手更加友好,便入坑Keras,但由于keras集成度很高,很多细节不是很好实现,导致模拟模拟通信系统的过程出现了些小问题,在此记录下来。

常规的自动编码器网络:
在这里插入图片描述
我需要实现的网络:
在这里插入图片描述


出现的问题:


信道可以用矩阵来代替,也就是我需要对编码器的输出乘上一个矩阵,然后将其送入解码器,因为keras搭建网络时操作对象是Layer,不能是变量或tensor,所以这个地方直接将编码器的输出和矩阵相乘赋值给变量,再将变量输入到解码器会报错,利用tensorflow中的tf.matmul()语句将结果赋值给张量后传入给解码器仍然会报错。自动编码器网络结构部分代码如下:

    #编码器
    input_img = Input(shape=(4,))
    encoded = Dense(32, activation='relu')(input_img)  
    encoded = Dense(32, activation='relu')(encoded)  
    encoded = Dense(7, activation='relu')(encoded)
    #信道    
    encoded_output1 = tf.matmul(encoded,h)
    encoded_output2 = keras.layers.noise.GaussianNoise(sigma_2)(encoded_output1)
    #解码器
    decoded = Dense(32, activation='relu')(encoded_output2)  
    decoded = Dense(32, activation='relu')(decoded)  
    decoded = Dense(4, activation='sigmoid')(decoded)  

程序运行后报错如下:
在这里插入图片描述


解决方法:


利用keras中的Lambda层自定义一个层。
Lambda层的作用是自定义层,如果只是对数据进行操作,而网络中的参数没有更新,那么便可以利用Lambda进行自定义层。步骤如下:

1.首先定义一个函数,我需要的是编码器的输出乘上一个矩阵,所以定义一个相乘的函数如下:

    def mul(x):
        return tf.matmul(x,h)
#x表示编码器的输出,h表示矩阵

2.利用Lambda定义一个层

encoded_output1 = Lambda(mul)(encoded)
#mul表示第一步定义的函数,encoded表示编码器的输出

完整代码如下:

    def mul(x):
        return tf.matmul(x,h)
    #编码器
    input_img = Input(shape=(4,))
    encoded = Dense(32, activation='relu')(input_img)  
    encoded = Dense(32, activation='relu')(encoded)  
    encoded = Dense(7, activation='relu')(encoded)
    #信道
    encoded_output1 = Lambda(mul)(encoded)
    encoded_output2 = keras.layers.noise.GaussianNoise(sigma_2)(encoded_output1)
     #解码器
    decoded = Dense(32, activation='relu')(encoded_output2)  
    decoded = Dense(32, activation='relu')(decoded)  
    decoded = Dense(4, activation='sigmoid')(decoded)

再次运行程序,就不会在出现AttributeError: ‘NoneType’ object has no attribute ‘_inbound_nodes’。
123456

你可能感兴趣的:(Keras,通信,tensorflow,神经网络,自动编码器)