使用PyTorch构建深度神经网络
立即解锁
发布时间: 2025-09-01 01:16:40 阅读量: 3 订阅数: 12 AIGC 


现代计算机视觉与PyTorch
### 使用 PyTorch 构建深度神经网络
在深度学习中,训练深度神经网络时会遇到各种问题,如输入值范围对训练的影响、过拟合等。本文将介绍如何使用 PyTorch 构建深度神经网络,并探讨批量归一化、Dropout 和正则化等技术如何解决这些问题。
#### 批量归一化的原理与作用
批量归一化(Batch Normalization)是一种在深度学习中常用的技术,它通过减去每个数据点的批次均值,然后除以批次方差,将一个节点上批次的所有数据点归一化到一个固定范围。通过引入 γ 和 β 参数,网络可以找到最佳的归一化参数。
为了理解批量归一化的作用,我们将对比以下两种情况:
1. 没有批量归一化的极小输入值
2. 有批量归一化的极小输入值
##### 没有批量归一化的极小输入值
通常,我们会将输入数据缩放到 0 到 1 之间。在这个实验中,我们将进一步把输入值缩放到 0 到 0.0001 之间,以观察数据缩放的影响。因为小的输入值即使权重值有很大变化,也难以改变 sigmoid 函数的值。
以下是修改后的 `FMNISTDataset` 类,用于将输入值缩放到 0 到 0.0001 之间:
```python
class FMNISTDataset(Dataset):
def __init__(self, x, y):
x = x.float()/(255*10000) # Done only for us to
# understand the impact of Batch normalization
x = x.view(-1,28*28)
self.x, self.y = x, y
def __getitem__(self, ix):
x, y = self.x[ix], self.y[ix]
return x.to(device), y.to(device)
def __len__(self):
return len(self.x)
```
同时,我们需要重新定义 `get_model` 函数,以便获取模型的预测结果和隐藏层的值:
```python
def get_model():
class neuralnet(nn.Module):
def __init__(self):
super().__init__()
self.input_to_hidden_layer = nn.Linear(784,1000)
self.hidden_layer_activation = nn.ReLU()
self.hidden_to_output_layer = nn.Linear(1000,10)
def forward(self, x):
x = self.input_to_hidden_layer(x)
x1 = self.hidden_layer_activation(x)
x2= self.hidden_to_output_layer(x1)
return x2, x1
model = neuralnet().to(device)
loss_fn = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=1e-3)
return model, loss_fn, optimizer
```
由于 `get_model` 函数现在返回两个输出,我们需要修改 `train_batch` 和 `accuracy` 函数,只获取输出层的值:
```python
def train_batch(x, y, model, opt, loss_fn):
model.train()
prediction = model(x)[0]
batch_loss = loss_fn(prediction, y)
batch_loss.backward()
optimizer.step()
optimizer.zero_grad()
return batch_loss.item()
def accuracy(x, y, model):
model.eval()
with torch.no_grad():
prediction = model(x)[0]
max_values, argmaxes = prediction.max(-1)
is_correct = argmaxes == y
return is_correct.cpu().numpy().tolist()
```
运行代码后,我们发现即使经过 100 个 epoch,模型的训练效果也不佳,验证集准确率仅为 ~85%,而之前在 10 个 epoch 内就能达到 ~90% 的准确率。通过观察隐藏层值和参数的分布,我们发现隐藏层值的范围非常小,输入层和隐藏层的值范围都很小,导致连接各层的权重需要有很大的变化。
##### 有批量归一化的极小输入值
在这个场景中,我们只需要在定义模型架构时添加批量归一化层。修改后的 `get_model` 函数如下:
```python
def get_model():
class neuralnet(nn.Module):
def __init__(self):
super().__init__()
self.input_to_hidden_layer = nn.Linear(784,1000)
self.batch_norm = nn.BatchNorm1d(1000)
self.hidden_layer_activation = nn.ReLU()
self.hidden_to_output_layer = nn.Linear(1000,10)
def forward(self, x):
x = self.input_to_hidden_layer(x)
x0 = self.batch_norm(x)
x1 = self.hidden_layer_activation(x0)
x2= self.hidden_to_output_layer(x1)
return x2, x1
model = neuralnet().to(device)
loss_fn = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=1e-3)
return model, loss_fn, optimizer
``
```
0
0
复制全文
相关推荐










