使用Keras模型子类时出现问题,输入形状=< unknown>

ux6nzvsh  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(129)

目前我正在学习Keras的子类化。到目前为止,我已经使用函数API构建了我的模型。对于我目前试图重新创建的论文来说,子类化确实会很有帮助。
我的模型是:

class ResidualBlockdown(layers.Layer):
    def __init__(self): 
        super(ResidualBlockdown, self).__init__()
        self.relu = tf.keras.layers.ReLU()
        self.bn = layers.BatchNormalization()
        self.conv1 = layers.Conv3D(128, 1, padding="same")

        self.conv2 = layers.Conv3D(128, 3, padding="same")

       
        self.conv3 = layers.Conv3D(256, 1, padding="same")

        
    def call(self, x, training=True):
        #out = self.bn(x)
        out=x
        out = self.relu(out)
        out = self.conv1(out)
        out = self.bn(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn(out)
        out = self.relu(out)
        out = self.conv3(out)
        out = layers.Add()([out, x])
        
        return out

#Then let's create a single hourglass to later stack them:

class HourglassSingle(layers.Layer): #inp and output of an hourglass should be 96,192,96=3*2^5, #6*2^5
    def __init__(self):
         super(HourglassSingle, self).__init__()
         self.pool=layers.MaxPooling3D(pool_size=(2, 2,2), strides=(2, 2,2), padding='same')
         self.cup =layers.UpSampling3D(size=(2, 2,2), data_format=None)#interpolation="nearest"
         self.res=ResidualBlockdown()
         

    def call(self, x, training=True):
        l1=self.res(x)
        i1=self.res(l1)

        d1=self.pool(l1)
        l2=self.res(d1)
        i2=self.res(l2)

        d2=self.pool(l2)
        l3=self.res(d2)
        i3=self.res(l3)

        d3=self.pool(l3)
        l4=self.res(d3)
        i4=self.res(l4)

        d4=self.pool(l4)
        l5=self.res(d4)
        l6=self.res(l5)

        fi4=self.cup(l6)
        plus4=layers.Add()([fi4, i4])
        plus4prime=self.res(plus4)

        fi3=self.cup(plus4prime)
        plus3=layers.Add()([fi3, i3])
        plus3prime=self.res(plus3)

        fi2=self.cup(plus3prime)
        plus2=layers.Add()([fi2, i2])
        plus2prime=self.res(plus2)

        fi1=self.cup(plus2prime)
        plus1=layers.Add()([fi1, i1])
        plus1prime=self.res(plus1)

        return plus1prime
     

class TestHourGlassSingle(keras.Model):
    def __init__(self):
        super(TestHourGlassSingle, self).__init__()
        self.crop=tf.keras.layers.Cropping3D(cropping=(2, 4, 12))
        self.HG=HourglassSingle()
        self.conv1=layers.Conv3D(50, 1, padding="same")
        self.conv2=layers.Conv3D(1, 1, padding="same")

    def call(self, x,training=True):
        p1=self.crop(x) #96, 192, 96
        p2=self.HG(p1)
        p3=self.conv1(p2)
        p4=self.conv1(p3)
        return p4

model=TestHourGlassSingle()

我用以下方法来安装它:

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=5e-5), loss=custom_loss_function, metrics=["mae", euclidian_distancexpred, euclidian_distancextrue]) #custom_loss_function

reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.4,
                              patience=1500, min_lr=1e-20)


tensorboard_callback = keras.callbacks.TensorBoard(log_dir=log_dir)

model.fit(train_ds,  epochs=20000, validation_data=test_ds,  verbose=2 ,callbacks=[reduce_lr, tensorboard_callback])

训练和测试数据集的形状为(100,200,120,1)。在我裁剪它之后,它得到的形状为(96,192,96)。我的损失函数和指标都与功能编程的UNets一起工作,应该和所有数据集的创建和扩充一样好。
当我运行它时,我得到一个错误消息:

File "C:\Users\lenna\DeepLearning\models\Landmark3_34HG.py", line 565, in call  *
                    out = self.conv1(out)
                File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler  **
                    raise e.with_traceback(filtered_tb) from None
                File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\layers\convolutional\base_conv.py", line 408, in _get_input_channel
                    if input_shape.dims[channel_axis].value is None:

                TypeError: 'NoneType' object is not subscriptable

            Call arguments received by layer "residual_blockdown" "                 f"(type ResidualBlockdown):
              • x=tf.Tensor(shape=<unknown>, dtype=float32)
              • training=True

完整的错误日志将显示在下面,如果需要的话。我已经搜索了多个论坛的解决方案,所有的子类化在相同的方式。谁能告诉我为什么形状是可以的裁剪层,但没有得到传递到我的自定义部分?有人知道我的错误在于?
完整错误日志:

Epoch 1/20000
Traceback (most recent call last):
  File "C:\Users\lenna\DeepLearning\models\Landmark3_34HG.py", line 813, in <module>
    model.fit(train_ds,  epochs=20000, validation_data=test_ds,  verbose=2 ,callbacks=[reduce_lr, tensorboard_callback]) #validation_data=test_ds
  File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filexk8zl7ue.py", line 15, in tf__train_function
    retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
  File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filewlmonkim.py", line 11, in tf__call
    p2 = ag__.converted_call(ag__.ld(self).HG, (ag__.ld(p1),), None, fscope)
  File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filemam9ops1.py", line 10, in tf__call
    l1 = ag__.converted_call(ag__.ld(self).res, (ag__.ld(x),), None, fscope)
  File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filed_9dqc_p.py", line 12, in tf__call
    out = ag__.converted_call(ag__.ld(self).conv1, (ag__.ld(out),), None, fscope)
TypeError: in user code:

    File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\engine\training.py", line 1160, in train_function  *
        return step_function(self, iterator)
    File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\engine\training.py", line 1146, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\engine\training.py", line 1135, in run_step  **
        outputs = model.train_step(data)
    File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\engine\training.py", line 993, in train_step
        y_pred = self(x, training=True)
    File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
        raise e.with_traceback(filtered_tb) from None
    File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filewlmonkim.py", line 11, in tf__call
        p2 = ag__.converted_call(ag__.ld(self).HG, (ag__.ld(p1),), None, fscope)
    File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filemam9ops1.py", line 10, in tf__call
        l1 = ag__.converted_call(ag__.ld(self).res, (ag__.ld(x),), None, fscope)
    File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filed_9dqc_p.py", line 12, in tf__call
        out = ag__.converted_call(ag__.ld(self).conv1, (ag__.ld(out),), None, fscope)

    TypeError: Exception encountered when calling layer "test_hour_glass_single" "                 f"(type TestHourGlassSingle).

    in user code:

        File "C:\Users\lenna\DeepLearning\models\Landmark3_34HG.py", line 637, in call  *
            p2=self.HG(p1)
        File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler  **
            raise e.with_traceback(filtered_tb) from None
        File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filemam9ops1.py", line 10, in tf__call
            l1 = ag__.converted_call(ag__.ld(self).res, (ag__.ld(x),), None, fscope)
        File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filed_9dqc_p.py", line 12, in tf__call
            out = ag__.converted_call(ag__.ld(self).conv1, (ag__.ld(out),), None, fscope)

        TypeError: Exception encountered when calling layer "hourglass_single" "                 f"(type HourglassSingle).

        in user code:

            File "C:\Users\lenna\DeepLearning\models\Landmark3_34HG.py", line 589, in call  *
                l1=self.res(x)
            File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler  **
                raise e.with_traceback(filtered_tb) from None
            File "C:\Users\lenna\AppData\Local\Temp\__autograph_generated_filed_9dqc_p.py", line 12, in tf__call
                out = ag__.converted_call(ag__.ld(self).conv1, (ag__.ld(out),), None, fscope)

            TypeError: Exception encountered when calling layer "residual_blockdown" "                 f"(type ResidualBlockdown).

            in user code:

                File "C:\Users\lenna\DeepLearning\models\Landmark3_34HG.py", line 565, in call  *
                    out = self.conv1(out)
                File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler  **
                    raise e.with_traceback(filtered_tb) from None
                File "C:\Users\lenna\DeepLearning\ImReg\lib\site-packages\keras\layers\convolutional\base_conv.py", line 408, in _get_input_channel
                    if input_shape.dims[channel_axis].value is None:

                TypeError: 'NoneType' object is not subscriptable

            Call arguments received by layer "residual_blockdown" "                 f"(type ResidualBlockdown):
              • x=tf.Tensor(shape=<unknown>, dtype=float32)
              • training=True

        Call arguments received by layer "hourglass_single" "                 f"(type HourglassSingle):
          • x=tf.Tensor(shape=<unknown>, dtype=float32)
          • training=True

    Call arguments received by layer "test_hour_glass_single" "                 f"(type TestHourGlassSingle):
      • x=tf.Tensor(shape=<unknown>, dtype=float32)
      • training=True
qojgxg4l

qojgxg4l1#

这里有一些你可以尝试.虽然它的类似结构,你创建多个通道使用resudial块,所以当你使用多个他们在一行他们的尺寸不匹配,简单的方法是删除和修改他们.但这是与假设,你的模型可以修改,它不是一成不变的:

from tensorflow.keras import layers
import tensorflow as tf
from tensorflow import keras

class ResidualBlockdown(layers.Layer):
    def __init__(self, channels): 
        super(ResidualBlockdown, self).__init__()
        self.relu = tf.keras.layers.ReLU()
        self.bn1 = layers.BatchNormalization()
        self.conv1 = layers.Conv3D(channels // 2, 1, padding="same", input_shape=(None, None, None, None))
        self.bn2 = layers.BatchNormalization()
        self.conv2 = layers.Conv3D(channels // 2, 3, padding="same")
        self.bn3 = layers.BatchNormalization()
        self.conv3 = layers.Conv3D(channels, 1, padding="same")

    def build(self, input_shape):
        super(ResidualBlockdown, self).build(input_shape)

    def call(self, x, training=True):
        out = self.bn1(x)
        out = self.relu(out)
        out = self.conv1(out)
        out = self.bn2(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn3(out)
        out = self.relu(out)
        out = self.conv3(out)
        out = layers.Add()([out, x])
        
        return out
    
#Then let's create a single hourglass to later stack them:

class HourglassSingle(layers.Layer): #inp and output of an hourglass should be 96,192,96=3*2^5, #6*2^5
    def __init__(self, channels=256):
        super(HourglassSingle, self).__init__()
        self.pool=layers.MaxPooling3D(pool_size=(2,2,2), strides=(2, 2,2), padding='same')
        self.cup =layers.UpSampling3D(size=(2,2,2), data_format=None)#interpolation="nearest"
        self.res1=ResidualBlockdown(channels)
        self.res2=ResidualBlockdown(channels)
        self.res3=ResidualBlockdown(channels)
        self.res4=ResidualBlockdown(channels)
        self.res5=ResidualBlockdown(channels)
        self.res6=ResidualBlockdown(channels)

    def call(self, x, training=True):
        l1=self.res1(x)

        d1=self.pool(l1)
        l2=self.res2(d1)

        d2=self.pool(l2)
        l3=self.res3(d2)

        d3=self.pool(l3)
        l4=self.res4(d3)

        d4=self.pool(l4)
        l5=self.res5(d4)

        l6=self.res6(l5)

        fi4=self.cup(l6)
        plus4=layers.Add()([fi4, l4])
        plus4prime=self.res5(plus4)

        fi3=self.cup(plus4prime)
        plus3=layers.Add()([fi3, l3])
        plus3prime=self.res4(plus3)

        fi2=self.cup(plus3prime)
        plus2=layers.Add()([fi2, l2])
        plus2prime=self.res3(plus2)

        fi1=self.cup(plus2prime)
        plus1=layers.Add()([fi1, l1])
        plus1prime=self.res2(plus1)

        return plus1prime
     
class TestHourGlassSingle(keras.Model):
    def __init__(self):
        super(TestHourGlassSingle, self).__init__()
        self.crop=tf.keras.layers.Cropping3D(cropping=(2, 4, 12))
        self.HG = HourglassSingle(channels=256)
        self.conv1=layers.Conv3D(128, 1, padding="same")
        self.conv2=layers.Conv3D(1, 1, padding="same")

    def call(self, x,training=True):
        p1=self.crop(x)
        p2=self.HG(p1)
        p3=self.conv1(p2)
        p4=self.conv2(p3)
        return p4
    
    
model=TestHourGlassSingle()

相关问题