You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将输入层连接到深度神经网络的每一层?

问题与解决方案

需求描述

现有一个Keras Sequential模型,希望保留原有的Dropout、BatchNormalization、LeakyReLU等层操作,同时修改结构,让每个深层Dense层同时接收前一层输出和原始输入层的输出(即每个深层都直接连接输入层)。

原模型代码如下:

from tensorflow.keras import initializers
INNER_LAYER_SIZE=x.shape[1]
drouout_fraction=.0
#set_seeds(123456)

model = keras.models.Sequential([
    keras.layers.InputLayer(input_shape=[x.shape[1],]),
    keras.layers.Dense(INNER_LAYER_SIZE, kernel_initializer=tf.keras.initializers.RandomUniform()),
    tf.keras.layers.BatchNormalization(),
    keras.layers.LeakyReLU(),
    #tf.keras.layers.Dropout(drouout_fraction),
])

for i in range(15):
    model.add(keras.layers.Dense(int(INNER_LAYER_SIZE/2), kernel_initializer=tf.keras.initializers.RandomUniform()))
    model.add(tf.keras.layers.BatchNormalization())    
    model.add(keras.layers.LeakyReLU())
    model.add(tf.keras.layers.Dropout(drouout_fraction))

model.add(tf.keras.layers.BatchNormalization())
model.add(keras.layers.Dense(y.shape[1], kernel_initializer=tf.keras.initializers.RandomUniform()))
model.add(keras.layers.LeakyReLU())

model.compile(loss="mse", metrics=["mean_absolute_error"], optimizer=tf.keras.optimizers.SGD(
    learning_rate=0.1, momentum=0.25, nesterov=True#, decay=.001#/x.shape[0]
))#

last_loss=1

model.summary()

之前尝试的两种写法均报错:

  • 直接在model.add()里调用层:model.add(keras.layers.Dense(...)(input))
  • 尝试用tf.concat([previous, input], axis=1)拼接输入和前层输出,但未成功

解决方案

Sequential模型只能处理线性层结构,无法实现这种多分支的连接逻辑,必须改用Keras函数式API来构建模型。核心思路是:

  1. 定义输入层并保存其引用
  2. 每一层计算前,先把当前前层的输出和原始输入拼接
  3. 将拼接后的张量作为下一个Dense层的输入
  4. 保留原有的BatchNormalization、LeakyReLU、Dropout等操作

完整实现代码如下:

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

INNER_LAYER_SIZE = x.shape[1]
dropout_fraction = .0

# 1. 定义输入层并保存引用
inputs = layers.Input(shape=[INNER_LAYER_SIZE,])

# 2. 第一层处理(和原逻辑一致)
x = layers.Dense(INNER_LAYER_SIZE, kernel_initializer=initializers.RandomUniform())(inputs)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU()(x)
# x = layers.Dropout(dropout_fraction)(x)  # 原代码注释掉的部分,可按需启用

# 3. 循环构建15层,每层都拼接原始输入和前层输出
for i in range(15):
    # 拼接原始输入和当前前层输出
    concat = layers.concatenate([inputs, x], axis=1)
    # 后续层处理和原逻辑一致
    x = layers.Dense(int(INNER_LAYER_SIZE/2), kernel_initializer=initializers.RandomUniform())(concat)
    x = layers.BatchNormalization()(x)
    x = layers.LeakyReLU()(x)
    x = layers.Dropout(dropout_fraction)(x)

# 4. 最后输出层处理
concat_final = layers.concatenate([inputs, x], axis=1)
x = layers.BatchNormalization()(concat_final)
x = layers.Dense(y.shape[1], kernel_initializer=initializers.RandomUniform())(x)
outputs = layers.LeakyReLU()(x)

# 5. 构建模型并编译
model = tf.keras.Model(inputs=inputs, outputs=outputs)
model.compile(loss="mse", metrics=["mean_absolute_error"], optimizer=tf.keras.optimizers.SGD(
    learning_rate=0.1, momentum=0.25, nesterov=True
))

last_loss = 1
model.summary()

关键说明

  • 使用layers.concatenate()替代tf.concat(),更符合Keras函数式API的使用习惯(两者功能一致,但前者是层对象,便于构建模型图)
  • 每次进入新的Dense层前,先拼接原始输入和前一层的输出,确保深层能同时获取原始特征和前层提取的特征
  • 所有原有的层操作(BatchNormalization、LeakyReLU、Dropout)都完整保留,逻辑和原模型一致

内容的提问来源于stack exchange,提问作者Arsen Zahray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:35:24