TF.Keras中模型子类化API的多输入建模

2024-10-02 00:24:31 发布

您现在位置:Python中文网/ 问答频道 /正文

TF.Keras中使用模型子分类api,我们如何构建一个多输入模型?在我的例子中,输入数据类型不同,一个是图像数据,另一个是表格特征。下面是我们尝试过的:

import tensorflow as tf
import tensorflow.keras.layers as KL
from tensorflow.keras.models import Model
from tensorflow.keras.applications import EfficientNetB0

class Net(tf.keras.Model):
    def __init__(self, idim, gdim):
        super(Net, self).__init__()
        # image input
        self.efnet  = EfficientNetB0(input_shape=(idim), include_top = False, weights = 'imagenet')
        self.gap    = KL.GlobalAveragePooling2D()
        self.bn     = KL.BatchNormalization()
        self.denseA = KL.Dense(784, activation='relu', name = 'denseA')
        
        # meta information input
        self.gender = KL.Input(shape=(gdim), name='gender', dtype='float32')
        self.gmeta  = KL.Dense(100, kernel_regularizer=tf.keras.regularizers.l2(l=0.01), activation='relu')
        
        self.cat    = KL.Concatenate()
        self.out    = KL.Dense(1, activation='linear')
    
    def call(self, inputs, training=False):
        print(inputs[0])
        print(inputs[1])
        
        # image data 
        x     = self.efnet(inputs[0])
        x_gap = self.gap(x)
        bn    = self.bn(x_gap)
        den_A = self.denseA(bn)
        
        # tabular feature 
        x2    = self.gender(inputs[1])
        x3    = self.gmeta(x2)
        
        # cat
        out   = self.cat()([den_A, x3])
        y     = self.out(out)
        return y

idim = (224, 224, 3) # image dimension
gdim = 2 # let's say, we've 2 feature column
model = Net(idim, gdim)
model.build(input_shape=[(None, *idim), (None, gdim)])

但它抛出以下ValueError

Tensor("Placeholder:0", shape=(None, 224, 224, 3), dtype=float32)
Tensor("Placeholder_1:0", shape=(None, 2), dtype=float32)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
c:\users\innat\anaconda3\envs\melanoma\lib\site-packages\tensorflow\python\keras\engine\training.py in build(self, input_shape)
    431         try:
--> 432           self.call(x, **kwargs)
    433         except (errors.InvalidArgumentError, TypeError):

<ipython-input-1-a7757d21ee96> in call(self, inputs, training)
     30 
---> 31         x2    = self.gender(inputs[1])
     32         x3    = self.gmeta(x2)

TypeError: 'Tensor' object is not callable

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-1-a7757d21ee96> in <module>
     46 gdim = 2
     47 model = Net(idim, gdim)
---> 48 model.build(input_shape=[(None, *idim), (None, gdim)])

c:\users\innat\anaconda3\envs\melanoma\lib\site-packages\tensorflow\python\keras\engine\training.py in build(self, input_shape)
    432           self.call(x, **kwargs)
    433         except (errors.InvalidArgumentError, TypeError):
--> 434           raise ValueError('You cannot build your model by calling `build` '
    435                            'if your layers do not support float type inputs. '
    436                            'Instead, in order to instantiate and build your '

ValueError: You cannot build your model by calling `build` if your layers do not support float type inputs. Instead, in order to instantiate and build your model, `call` your model on real tensor data (of the correct dtype).

更新

多亏了安德烈找到了那只愚蠢的虫子。以下是已接受解决方案的模型图:

enter image description here


Tags: inbuildselfnoneinputyourmodeltensorflow
1条回答
网友
1楼 · 发布于 2024-10-02 00:24:31
  1. 您正在调用layer.Input,但它实际上不是layer,无法调用。它是函数API中使用的一个特殊名称

  2. 您对cat层的调用不正确

此代码适用于:

import tensorflow as tf
import tensorflow.keras.layers as KL
from tensorflow.keras.models import Model
from tensorflow.keras.applications import EfficientNetB0

class Net(tf.keras.Model):
    def __init__(self, idim, gdim):
        super(Net, self).__init__()
        # image input
        self.efnet  = EfficientNetB0(input_shape=(idim), include_top = False, weights = 'imagenet')
        self.gap    = KL.GlobalAveragePooling2D()
        self.bn     = KL.BatchNormalization()
        self.denseA = KL.Dense(784, activation='relu', name = 'denseA')
        
        # meta information input
        #self.gender = KL.Input(shape=(gdim), name='gender', dtype='float32')
        self.gmeta  = KL.Dense(100, kernel_regularizer=tf.keras.regularizers.l2(l=0.01), activation='relu')
        
        self.cat    = KL.Concatenate()
        self.out    = KL.Dense(1, activation='linear')
    
    def call(self, inputs, training=False):
        print(inputs[0])
        print(inputs[1])
        
        # image data 
        x     = self.efnet(inputs[0])
        x_gap = self.gap(x)
        bn    = self.bn(x_gap)
        den_A = self.denseA(bn)
        
        # tabular feature 
        #x2    = self.gender(inputs[1])
        x2    = inputs[1]
        x3    = self.gmeta(x2)
        
        # cat
        out   = self.cat([den_A, x3]) # brackets removed
        y     = self.out(out)
        return y

idim = (224, 224, 3) # image dimension
gdim = 2 # let's say, we've 2 feature column
model = Net(idim, gdim)
model.build(input_shape=[(None, *idim), (None, gdim)])

相关问题 更多 >

    热门问题