PyTorch搭建BiLSTM处理蛋白质嵌入出现RuntimeError与NameError求助
问题修复方案
错误2:NameError: name 'x_size' is not defined
错误原因
调用张量维度的写法错误,同时存在3个关联问题:
- 张量取指定维度大小的正确写法是
x.size(0)而非x_size(0) - 双向LSTM的隐藏层数量为
2 * num_layers(前后向各有num_layers层),所以h0、c0的第一维需要乘以2 - 不要硬编码
device,直接用PyTorch Lightning提供的self.device自动匹配设备 - 双向LSTM的输出是前后向隐藏态的拼接,所以全连接层输入维度应为
2 * n_neurons
修正代码
def __init__(self, input_shape: int, n_class: int, num_layers, n_neurons: int = 128, lr: float = 1e-3): super(RNN,self).__init__() self.lr = lr self.n_neurons=n_neurons self.num_layers=num_layers self.input_shape = input_shape self.output_shape = 1 if n_class <= 2 else n_class self.activation = nn.Sigmoid() if n_class <= 2 else nn.Softmax(dim=-1) self.lstm = nn.LSTM(self.input_shape, self.n_neurons, num_layers, batch_first=True, bidirectional=True) # 修正全连接层输入维度:双向输出拼接后是2*n_neurons self.fc= nn.Linear(2 * self.n_neurons, self.output_shape) def forward(self, x): # 修正双向LSTM的隐藏层维度、张量尺寸写法、设备获取 h0=torch.zeros(2 * self.num_layers, x.size(0), self.n_neurons).to(self.device) c0=torch.zeros(2 * self.num_layers, x.size(0), self.n_neurons).to(self.device) out, _=self.lstm(x,(h0, c0)) out=self.fc(out[:, -1, :]) # 修正:返回经过LSTM计算+激活后的概率结果 return self.activation(out)
错误1:RuntimeError: all elements of input should be between 0 and 1
错误原因
你在训练、验证步骤中没有调用forward方法,直接调用self.fc(x)跳过了LSTM和激活层,输出的是未归一化的logits,不符合BCELoss要求输入为0~1概率的规则。
修正代码
def training_step(self, batch, batch_idx): x, y = batch # 修正:调用forward走完整网络链路 y_hat = self(x).squeeze() y = y.squeeze() if self.output_shape > 1: y_hat = torch.log(y_hat) loss = self.loss(y_hat, y) self.log("train_loss", loss, on_epoch=True, on_step=False) return {"loss": loss} def validation_step(self, batch, batch_idx): x, y = batch # 修正:调用forward走完整网络链路 y_hat = self(x).squeeze() y = y.squeeze() if self.output_shape > 1: y_hat = torch.log(y_hat) loss = self.loss(y_hat, y) self.log("val_loss", loss, on_epoch=True, on_step=False) return {"val_loss": loss}
其他需要修正的问题
- 你
fit方法定义的validation_data参数是布尔类型,但调用时传入了(embeddings_test, np.array(y_test))元组,需要修改fit方法的参数定义为validation_data: Optional[tuple] = None,对应调整数据划分逻辑。 - 现有
save方法仅保存全连接层的参数,没有保存LSTM层的参数,会导致模型加载后无法正常推理,修正save方法:
def save(self, path: str): torch.save(self.state_dict(), path) log.info("Save complete model parameters in %s", path)
- 对应修改
load_state_dict方法加载整个模型的参数,不要只加载fc层。
内容的提问来源于stack exchange,提问作者KhalilBR
相关产品推荐
相关产品推荐

