自定义激活层问题

时间:2020-08-12 06:37:26

标签: python tensorflow machine-learning keras deep-learning

bioActivatorV2 是我的自定义激活功能,它有两个主要问题,如下所示:

  • self.potential.assign(self.temp)引起Tensor' object has no attribute 'assign'
  • 在我的自定义模型中使用此激活层会给我以下错误:
TypeError: An op outside of the function building code is being passed
a "Graph" tensor. It is possible to have Graph tensors
leak out of the function building context by including a
tf.init_scope in your function building code.
For example, the following function will fail:
  @tf.function
  def has_init_scope():
    my_constant = tf.constant(1.)
    with tf.init_scope():
      added = my_constant * 2
The graph tensor has name: SelectV2:0

代码:

import tensorflow as tf
import numpy as np
import pandas as pd

class bioActivatorV2(tf.keras.layers.Layer):
    def __init__(self, **kwargs):
        super(bioActivatorV2, self).__init__(**kwargs)
        self.action_potential = 5
        self.threshold = 0
        self.initial_potential = -2.0
        ##########################################
        self.constrain_receptor = tf.keras.constraints.MinMaxNorm(min_value=-1.0, max_value=1.0, rate=1.0, axis=0)
        self.constrain_frequency = tf.keras.constraints.NonNeg()
        self.receptor_initilizer = tf.keras.initializers.RandomUniform(minval=0., maxval=1.)
        self.frequency_initializer = tf.keras.initializers.Ones()
        self.potential_initilizer = tf.keras.initializers.Constant(-2.)
        
    
    def build(self,batch_input_shape):
        input_shape_old = batch_input_shape
        input_shape = batch_input_shape[1:]
        ##############################
        self.potential = self.add_weight(shape=(1, 128), initializer=self.potential_initilizer, trainable=False, name='potential')
        self.frequency = self.add_weight(shape=input_shape, initializer= self.frequency_initializer, trainable=True, constraint=self.constrain_frequency, dtype='float32', name='frequency')
        self.receptor = self.add_weight(shape=input_shape, initializer= self.receptor_initilizer, trainable=True, constraint=self.constrain_receptor, dtype='float32', name='receptor')
        ##############################
        self.out = self.potential
        self.temp = self.potential
        ##############################
        super().build(batch_input_shape)
    
    @tf.function    
    def call(self, inputs):
        self.temp.assign(self.potential + inputs, name='new_potential')
        # self.potential = self.temp  ---> sloved : 'Tensor' object has no attribute 'assign' Problem
        self.potential.assign(self.temp)
        self.potential = tf.where(self.potential > 0, self.initial_potential, self.potential)
        self.out = tf.where(self.out > 0, 1.0, 0.0)
        freq = tf.math.multiply(self.frequency , self.action_potential)
        self.out = tf.math.multiply(self.out, freq)
        self.out = tf.math.multiply(self.out, self.receptor)
        return self.out
    
    def compute_output_shape(self, batch_input_shape):
        return tf.TensorShape(batch_input_shape.as_list())

测试:

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(1,28,28), data_format='channels_first'))
model.add(tf.keras.layers.Conv2D(32, 3, activation='relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(bioActivatorV2())
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(10, activation='softmax'))

test = tf.random.uniform((1,1,28, 28), minval=-5, maxval=5, dtype=tf.dtypes.float32)
model(test)

0 个答案:

没有答案