多层全连接神经网络随记

在MNIST手写数字识别任务中,训练神经网络时涉及到几个关键参数和概念。

batch_size

- **定义**:`batch_size`是指在每次迭代中用于训练的样本数量。
- **作用**:它决定了每次更新网络权重时使用的样本数。较大的`batch_size`可以加快训练速度,但可能需要更多的内存。较小的`batch_size`可以提供更精确的梯度估计,但训练过程可能更慢且更容易陷入局部最小值。

### epoch

- **定义**:`epoch`是指在整个数据集上完成一次完整的前向和反向传播过程。
- **作用**:一个`epoch`表示网络已经看到了数据集中的每一个样本恰好一次。训练多个`epoch`可以增强模型的泛化能力,但也增加了过拟合的风险。

### loss(损失)

- **定义**:`loss`是一个衡量模型预测值与真实值之间差异的指标。
- **计算**:在训练过程中,每个`batch`的损失是通过对批次中所有样本的损失函数值求平均来计算的。对于分类任务,常用的损失函数是交叉熵损失(cross-entropy loss)。
- **变化**:随着训练的进行,我们通常希望看到损失逐渐降低,这表明模型在学习如何更好地拟合数据。

### 准确率

- **定义**:准确率是指模型正确预测的样本数占总样本数的比例。
- **计算**:在每个`epoch`结束时,通常会计算模型在该`epoch`上的准确率,这涉及将模型对验证集或测试集中每个样本的预测与真实标签进行比较,并统计正确预测的数量。

### 总结

- `batch_size`控制每次权重更新使用的样本数,影响训练速度和内存需求。
- `epoch`表示整个数据集上完成一次完整的训练迭代,影响模型的泛化和过拟合。
- `loss`通过损失函数计算,反映了模型预测与真实值之间的差异,通常随着训练的进行而降低。
- 准确率是通过比较模型预测和真实标签来计算的,提供了模型性能的直观度量。

在训练过程中,监控这些指标可以帮助调整模型参数和防止过拟合,从而提高模型的性能和泛化能力。

num_epochs = 10
for epoch in range(num_epochs):
    running_loss = 0.0
    for i, data in enumerate(train_loader, 0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print('Epoch %d loss: %.3f' % (epoch + 1, running_loss / len(train_loader)))

`for i, data in enumerate(train_loader, 0):` 这个循环是在训练神经网络时,对训练数据集进行遍历的操作。在这个循环中,每次迭代都会从`train_loader`中获取一个批次(batch)的数据,包括输入数据(inputs)和对应的标签(labels)。

`enumerate()`函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中。在这个例子中,`enumerate(train_loader, 0)`表示从`train_loader`的第一个元素开始遍历,并将当前元素的索引赋值给变量`i`,同时将元素本身赋值给变量`data`。

在这个循环中,权重的修改是通过反向传播(backpropagation)和优化器(optimizer)来实现的。具体来说,首先通过`optimizer.zero_grad()`清除之前梯度的值,然后计算模型的输出(outputs),接着使用损失函数(criterion)计算预测值与真实标签之间的损失(loss)。接下来,通过`loss.backward()`进行反向传播,计算损失关于模型参数的梯度。最后,通过`optimizer.step()`更新模型参数以减小损失。这个过程会在每个批次上重复进行,直到整个训练集被遍历完。

`train_loader`的长度是通过数据集的大小除以批次大小(batch size)计算得到的。在PyTorch中,`DataLoader`对象用于将数据集分成多个批次,以便在训练过程中进行迭代。`train_loader`的长度表示整个训练集被分成了多少个批次。

例如,如果训练集有1000个样本,批次大小为32,那么`train_loader`的长度将是:

```python
len(train_loader) = 1000 // 32 = 31
```

这意味着训练过程将遍历31个批次,最后一个批次可能包含少于32个样本。

在PyTorch中,`DataLoader`默认情况下会在每个epoch开始时重新打乱数据。这意味着每一轮epoch训练的数据都是不同的。如果你希望在每个epoch之间保持数据的一致性,可以在创建`DataLoader`时设置`shuffle=False`参数。

例如:

```python
train_loader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=False)
```

这样,在每个epoch中,数据的顺序将保持不变。但是请注意,通常在训练神经网络时,我们希望在每个epoch之间打乱数据,以便模型可以从不同的数据顺序中学习,这有助于提高泛化能力。

class simpleNet(nn.Module):
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super(simpleNet, self).__init__()
        self.layer1 = nn.Linear(in_dim, n_hidden_1)
        self.layer2 = nn.Linear(n_hidden_1, n_hidden_2)
        self.layer3 = nn.Linear(n_hidden_2, out_dim)

class Activation_Net(nn.Module):
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super(Activation_Net, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Linear(in_dim, n_hidden_1), nn.ReLU(True)
        )
        self.layer2 = nn.Sequential(
            nn.Linear(n_hidden_1, n_hidden_2), nn.ReLU(True)
        )
        self.layer3 = nn.Sequential(
            nn.Linear(n_hidden_2, out_dim)
        )
class Batch_Net(nn.Module):
    def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
        super(Batch_Net, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Linear(in_dim, n_hidden_1),
            nn.BatchNorm1d(n_hidden_1), nn.ReLU(True)
        )
        self.layer2 = nn.Sequential(
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.BatchNorm1d(n_hidden_2), nn.ReLU(True)
        )
        self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim))

这三个网络都是一个简单的三层全连接神经网络,但它们在结构和激活函数方面有所不同。

1. simpleNet:这是一个基本的三层全连接神经网络,每一层之间没有激活函数。这意味着输入信号直接传递给下一层,没有任何非线性变换。这种简单的线性结构可能在某些情况下表现不佳,因为它不能捕捉复杂的非线性关系。

2. Activation_Net:这个网络在每一层之后添加了ReLU激活函数。ReLU激活函数是一种非线性激活函数,它可以增加网络的表达能力,使其能够学习更复杂的模式。在这个网络中,ReLU激活函数被添加到每个隐藏层之后。

3. Batch_Net:这个网络在每一层之后添加了批量归一化(BatchNorm)层和ReLU激活函数。批量归一化层可以加速训练过程,提高模型的收敛速度,同时还可以降低过拟合的风险。在这个网络中,批量归一化层被添加到每个隐藏层之后,然后是ReLU激活函数。

对于训练网络的影响:

- 使用ReLU激活函数可以提高网络的非线性表达能力,有助于捕捉复杂的数据模式。
- 批量归一化可以加速训练过程,提高模型的收敛速度,同时降低过拟合的风险。
- 不使用激活函数或批量归一化的简单网络可能在训练过程中表现较差,尤其是在处理复杂数据集时。

**提高模型的收敛速度意味着让训练过程更快地接近或达到最优解**。

在机器学习和深度学习中,模型的训练可以看作是一个迭代寻找最优解的过程。在这个过程中,模型不断调整自身的参数以最小化(或最大化)某个损失函数,从而逐步提升预测的准确性。收敛速度就是指模型参数向这个最优解靠近的快慢。

例如,在深度学习中,较快的收敛速度意味着模型经过更少的训练迭代就能找到一组较好的参数配置,这可以在较短的时间内获得较高的性能表现。这不仅节省了计算资源,还使开发者能够在较短时间内进行更多实验,优化模型结构与参数设置,并快速验证不同想法的有效性。

因此,提高模型的收敛速度实际上是通过各种技术手段,如改进优化算法、调整学习率、使用批量归一化等方法,来加速这一寻优过程,使模型在更短的迭代次数内达到理想的性能表现。这对于实际应用中的模型训练尤为重要,因为实际问题的复杂性和数据量的庞大往往要求模型能够高效地学习和适应。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值