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)