TensorFlow 2.3训练音乐生成VAE遇Sequential层名重复错误求助
VAE音乐生成模型层名重复错误的解决方法
错误信息
All layers added to a Sequential model should have unique names. Name "" is already the name of a layer in this model. Update the
nameargument to pass a unique name.
问题根源
你给自定义Resnet1DBlock内部的卷积、归一化层都加了唯一前缀,但忽略了**Resnet1DBlock本身作为Keras模型(继承自tf.keras.Model)的名称设置**:初始化时你传入了name=''(空字符串),导致每个Resnet1DBlock实例的层名都是空字符串。当Sequential模型中添加多个该Block实例时,就会出现重复的空名称层,触发报错。
修复方案
修改Resnet1DBlock的初始化逻辑,利用传入的prefix参数给每个Block实例设置唯一名称,避免重复。同时建议把call方法中重复创建的LeakyReLU层移到初始化中,减少冗余创建。
修改后的完整代码
class Resnet1DBlock(tf.keras.Model): def __init__(self, kernel_size, filters, type='encode', prefix=''): # 用prefix生成唯一的Block名称,避免空名称重复 super(Resnet1DBlock, self).__init__(name=prefix + 'block') self.leaky_relu = layers.LeakyReLU(0.4) if type == 'encode': self.conv1a = layers.Conv1D(filters, kernel_size, 2, padding="same", name=prefix + 'conv1a') self.conv1b = layers.Conv1D(filters, kernel_size, 1, padding="same", name=prefix + 'conv1b') self.norm1a = tfa.layers.InstanceNormalization(name=prefix + 'norm1a') self.norm1b = tfa.layers.InstanceNormalization(name=prefix + 'norm1b') elif type == 'decode': self.conv1a = layers.Conv1DTranspose(filters, kernel_size, 1, padding="same", name=prefix + 'conv1a') self.conv1b = layers.Conv1DTranspose(filters, kernel_size, 1, padding="same", name=prefix + 'conv1b') self.norm1a = tf.keras.layers.BatchNormalization(name=prefix + 'norm1a') self.norm1b = tf.keras.layers.BatchNormalization(name=prefix + 'norm1b') else: return None def call(self, input_tensor): x = tf.nn.relu(input_tensor) x = self.conv1a(x) x = self.norm1a(x) x = self.leaky_relu(x) x = self.conv1b(x) x = self.norm1b(x) x = self.leaky_relu(x) x += input_tensor return tf.nn.relu(x) class CVAE(tf.keras.Model): def __init__(self, latent_dim): super(CVAE, self).__init__() self.latent_dim = latent_dim self.encoder = tf.keras.Sequential( [ tf.keras.layers.InputLayer(input_shape=(1, 90001), name='input_encoder'), layers.Conv1D(64, 1, 2, name='conv1_layer1'), Resnet1DBlock(64, 1, 'encode', prefix='res1_'), layers.Conv1D(128, 1, 2, name='conv1_layer2'), Resnet1DBlock(128, 1, 'encode', prefix='res2_'), layers.Conv1D(128, 1, 2, name='conv1_layer3'), Resnet1DBlock(128, 1, 'encode', prefix='res3_'), layers.Conv1D(256, 1, 2, name='conv1_layer4'), Resnet1DBlock(256, 1, 'encode', prefix='res4_'), layers.Flatten(name='flatten'), layers.Dense(latent_dim + latent_dim, name='dense'), ] ) self.decoder = tf.keras.Sequential( [ tf.keras.layers.InputLayer(input_shape=(latent_dim,), name='input_decoder'), layers.Reshape(target_shape=(1, latent_dim)), Resnet1DBlock(512, 1, 'decode', prefix='res1_'), layers.Conv1DTranspose(512, 1, 1, name='Conv1Trans_Layer1'), Resnet1DBlock(256, 1, 'decode', prefix='res2_'), layers.Conv1DTranspose(256, 1, 1, name='Conv1Trans_Layer2'), Resnet1DBlock(128, 1, 'decode', prefix='res3_'), layers.Conv1DTranspose(128, 1, 1, name='Conv1Trans_Layer3'), Resnet1DBlock(64, 1, 'decode', prefix='res4_'), layers.Conv1DTranspose(64, 1, 1, name='Conv1Trans_Layer4'), layers.Conv1DTranspose(90001, 1, 1, name='Conv1Trans_Layer5') ] ) optimizer = tf.keras.optimizers.Adam(0.0003, beta_1=0.9, beta_2=0.999, epsilon=1e-08) random_vector_for_generation = tf.random.normal(shape=[num_examples_to_generate, latent_dim]) model = CVAE(latent_dim)
关键修改点
- 将
Resnet1DBlock初始化中的name=''改为name=prefix + 'block',确保每个Block实例有唯一名称(如res1_block、res2_block)。 - 把
call方法中每次调用都创建的LeakyReLU层移到__init__中作为实例属性,避免重复创建层,提升效率。
内容的提问来源于stack exchange,提问作者Wanderer
相关产品推荐
相关产品推荐

