自己搭建的回归神经网络收敛时损失很大怎么办,需要进行超参数调优吗,如何用pytorch做超参数调优,请写出代码
时间: 2023-11-19 10:05:26 浏览: 77
当神经网络的损失很大时,可能是因为模型过于复杂或者数据集不够充分,此时需要进行超参数调优以获得更好的性能。以下是使用PyTorch进行超参数调优的示例代码:
```python
import torch
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
from torchvision.transforms import ToTensor
import torch.nn as nn
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR
from sklearn.model_selection import ParameterGrid
# 加载MNIST数据集
train_dataset = MNIST(root='./data', train=True, transform=ToTensor(), download=True)
test_dataset = MNIST(root='./data', train=False, transform=ToTensor(), download=True)
# 定义超参数
params = {'lr': [0.1, 0.01, 0.001], 'batch_size': [32, 64, 128], 'num_epochs': [10, 20, 30]}
# 定义网格搜索器
param_grid = ParameterGrid(params)
# 定义模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.dropout1 = nn.Dropout2d(0.25)
self.dropout2 = nn.Dropout2d(0.5)
self.fc1 = nn.Linear(9216, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.conv1(x)
x = nn.functional.relu(x)
x = self.conv2(x)
x = nn.functional.relu(x)
x = nn.functional.max_pool2d(x, 2)
x = self.dropout1(x)
x = torch.flatten(x, 1)
x = self.fc1(x)
x = nn.functional.relu(x)
x = self.dropout2(x)
x = self.fc2(x)
output = nn.functional.log_softmax(x, dim=1)
return output
# 定义训练函数
def train(model, train_loader, optimizer, criterion, epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# 定义测试函数
def test(model, test_loader, criterion):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
output = model(data)
test_loss += criterion(output, target).item()
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
# 进行超参数搜索
for params in param_grid:
print(params)
# 定义超参数
lr = params['lr']
batch_size = params['batch_size']
num_epochs = params['num_epochs']
# 定义数据加载器
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True)
# 定义模型、损失函数和优化器
model = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=lr, momentum=0.9)
scheduler = StepLR(optimizer, step_size=1, gamma=0.7)
# 训练模型
for epoch in range(num_epochs):
train(model, train_loader, optimizer, criterion, epoch)
scheduler.step()
# 测试模型
test(model, test_loader, criterion)
```
上述代码中,我们首先定义了一个超参数字典 `params`,其中包含学习率 `lr`、批次大小 `batch_size` 和训练轮数 `num_epochs`。然后,使用 `ParameterGrid` 对象生成所有可能的超参数组合,并依次使用不同的超参数组合训练和测试模型。在训练过程中,我们使用 `StepLR` 调度器来动态调整学习率。在每个超参数组合的训练结束后,我们输出测试集的准确度。通过比较不同超参数组合的测试准确度,我们可以选择最优的超参数组合。
阅读全文