PyTorch新手求助:将Keras Sequential深度模型转为PyTorch函数式模型
将Keras Sequential三层DNN转换为PyTorch模型
核心思路
PyTorch中没有直接对应Keras Sequential的"函数式模型"概念,而是通过继承torch.nn.Module类,自定义模型的初始化(__init__)和前向传播(forward)逻辑来实现。以下是完全匹配你提供的Keras代码的PyTorch实现:
完整代码实现
首先导入必要的库:
import torch import torch.nn as nn import torch.optim as optim
保留原参数配置:
paramDict = { 'epoch': 200, 'batchSize': 32, 'dropOut': 0.2, 'loss': 'binary_crossentropy', 'metrics': ['accuracy'], 'activation1': 'relu', 'activation2': 'sigmoid', 'monitor': 'val_accuracy', 'save_best_only': True, 'mode': 'max' } class_weight = {0: 1.0, 1: 4.0} hl = [128, 256, 512, 1024, 1024, 1024, 1024, 1024, 1024, 1024] optimizerDict = { 'adam': optim.Adam(learning_rate=0.001, betas=(0.9, 0.999)), } numHidden = 3 numberOfClasses = 2 in_feats = 76 # 输入特征数
定义PyTorch模型类:
class DNNModel(nn.Module): def __init__(self, in_feats, numHidden, hl, paramDict, numberOfClasses): super().__init__() # 构建层列表 layers = [] # 第一层隐藏层 layers.append(nn.Linear(in_feats, hl[0])) layers.append(nn.ReLU() if paramDict['activation1'] == 'relu' else nn.Identity()) layers.append(nn.Dropout(paramDict['dropOut'])) # 后续隐藏层 for i in range(1, numHidden): hidden_size = hl[i] if i < len(hl) else 1024 layers.append(nn.Linear(hl[i-1], hidden_size)) layers.append(nn.ReLU() if paramDict['activation1'] == 'relu' else nn.Identity()) layers.append(nn.Dropout(paramDict['dropOut'])) # 输出层 last_hidden_size = hl[numHidden-1] if numHidden-1 < len(hl) else 1024 layers.append(nn.Linear(last_hidden_size, numberOfClasses)) layers.append(nn.Sigmoid() if paramDict['activation2'] == 'sigmoid' else nn.Identity()) # 将层列表转为Sequential容器(类似Keras Sequential) self.model = nn.Sequential(*layers) def forward(self, x): return self.model(x)
实例化模型:
model = DNNModel(in_feats, numHidden, hl, paramDict, numberOfClasses)
训练相关匹配说明
- 损失函数:对应Keras的
binary_crossentropy,由于模型输出用了Sigmoid,使用nn.BCELoss并传入类别权重:
# 将类别权重转为Tensor class_weights = torch.tensor([class_weight[0], class_weight[1]], dtype=torch.float32) criterion = nn.BCELoss(weight=class_weights)
- 优化器:直接使用定义好的Adam优化器:
optimizer = optimizerDict['adam']
- 训练循环示例:
# 假设train_loader是已构建好的DataLoader model.train() # 设置为训练模式(启用Dropout) for epoch in range(paramDict['epoch']): running_loss = 0.0 for inputs, labels in train_loader: optimizer.zero_grad() # 清空梯度 outputs = model(inputs) loss = criterion(outputs, labels.float()) # 确保标签类型匹配 loss.backward() # 反向传播 optimizer.step() # 更新参数 running_loss += loss.item() print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}')
关键细节说明
- PyTorch的
nn.Sequential和Keras Sequential逻辑一致,按顺序堆叠层即可。 - Dropout在训练模式下自动生效,验证/测试时需调用
model.eval()关闭Dropout。 - 输入数据需转为
torch.Tensor类型,且形状为(batch_size, in_feats),和Keras输入格式一致。
内容的提问来源于stack exchange,提问作者Sahar Mrad
相关产品推荐
相关产品推荐

