PyTorch如何指定输入层?是否默认内置未展示的输入层?
问题描述
- 开发环境为基于PyTorch实现的Stable Baselines3(SB3)强化学习框架,当前任务共包含101个输入特征。自定义神经网络架构时首层仅设置64个节点,网络仍可正常运行,模型架构如下:

- 此前一直认为神经网络首层节点数必须与输入特征数量一致,因此产生疑问:PyTorch是否默认内置了未对外展示的输入层?如果存在该默认输入层,如何查看并控制该层的激活函数等相关配置?
附:相关代码
import gym from gym import Env import matplotlib import matplotlib.pyplot as plt import numpy as np import pandas as pd from gym import spaces from gym.utils import seeding from stable_baselines3.common.vec_env import DummyVecEnv, SubprocVecEnv from stable_baselines3.common.utils import set_random_seed from stable_baselines3.common.evaluation import evaluate_policy from stable_baselines3.common.env_util import make_vec_env from stable_baselines3 import PPO import math import random import torch as th from sb3_contrib.common.maskable.policies import MaskableActorCriticPolicy from sb3_contrib.common.wrappers import ActionMasker from sb3_contrib.ppo_mask import MaskablePPO from sb3_contrib.common.envs import InvalidActionEnvDiscrete from sb3_contrib.common.maskable.evaluation import evaluate_policy from sb3_contrib.common.maskable.utils import get_action_masks env = MyCustomEnv(....) env = ActionMasker(env, mask_fn) # 包装环境以支持动作掩码 # 自定义神经网络架构 mynetwork = dict(activation_fn=th.nn.LeakyReLU, net_arch=[dict(pi=[64, 64], vf=[64, 64])]) # 掩码PPO调用逻辑和常规PPO一致 model = MaskablePPO(MaskableActorCriticPolicy, env, verbose=1, learning_rate=0.0005, gamma=0.975, seed=10, batch_size=256, clip_range=0.2, tensorboard_log="./log1/", policy_kwargs=mynetwork) # 打印模型结构得到前述截图 print(model.policy)
解答
不存在所谓“隐藏的默认输入层”,产生这个疑问的核心原因是对全连接层的维度规则、SB3的网络自动构建逻辑不熟悉:
- 全连接层(PyTorch中对应
nn.Linear)本身就不需要输入维度和输出维度(即层节点数)一致,其运算逻辑为output = input @ weight.T + bias,其中权重矩阵weight的形状为(out_features, in_features),只要输入特征维度和in_features匹配即可正常计算,和层本身的节点数out_features没有强制相等的要求。 - 你在配置
net_arch时只写了隐藏层的节点数,SB3在构建策略网络时,会自动读取当前环境观测空间的维度(也就是你的101维输入特征),自动给第一个全连接层设置in_features=101, out_features=64,这就是你首层写64个节点也能正常运行的原因——这个首层本身就是直接对接101维输入的,权重矩阵形状为(64, 101),不需要额外的输入层做维度转换。
可以通过以下代码直接验证层的真实参数:
# 查看策略网络第一层全连接层的定义 print(model.policy.mlp_extractor.policy_net[0]) # 查看第一层权重的形状 print(model.policy.mlp_extractor.policy_net[0].weight.shape)
运行后会输出类似Linear(in_features=101, out_features=64, bias=True),权重形状为torch.Size([64, 101]),完全对应101维输入到64维输出的映射,没有任何未展示的隐藏层。
补充说明:
- 打印
model.policy时没有显示第一层的输入维度,只是SB3打印网络结构时省略了自动推断输入维度的逻辑展示,不是刻意隐藏了层。 - 所有层的激活函数都是你在配置中传入的
th.nn.LeakyReLU,顺着model.policy.mlp_extractor.policy_net打印每一层,就能看到完整的网络结构:第一层为101维输入转64维输出的全连接层,之后接LeakyReLU激活,再依次对接64转64的全连接层、LeakyReLU激活,最后接输出层,所有配置都可直接查看、修改,不存在不可控的默认隐藏层配置。
内容的提问来源于stack exchange,提问作者Vladimir Belik
相关产品推荐
相关产品推荐

