1. 激活函数如何在两个层之间作用
如果不在两个层之间添加激活函数,模型将无法学习非线性关系,表现出像线性模型一样的局限性。
LeakyReLU(0.2) 是一个激活函数,它的作用是对每一层的输出进行非线性转换。激活函数通常在神经网络中用于增加网络的非线性能力,使得网络能够拟合更复杂的函数。
- LeakyReLU 的定义
LeakyReLU 是一种变种的 ReLU 激活函数。与普通的 ReLU 激活函数不同,LeakyReLU 对负值部分并不会直接输出 0,而是给负值部分留下一点点“泄漏”:
其中,α(通常为 0.01)是负半轴的斜率,LeakyReLU 通过给负值加上一个较小的斜率(通常是 0.01 或其他小值)来避免神经元完全“死亡”的问题(即神经元在训练过程中因为权重更新过小导致输出始终为零)。
在神经网络中,LeakyReLU 会接收上一层的输出并对其进行变换,从而得到下一层的输入。
让我们通过一个简化的例子来说明如何将 LeakyReLU 用在网络中。
model = []
model += block(nROI, int(nROI/2)) + block(int(nROI/2), int(nROI/4))
这里的 block 函数定义了一个标准的网络块,其中包含以下内容:
def block(in_layer, out_layer):layers = [nn.Linear(in_layer, out_layer, bias=False)]layers.append(nn.LeakyReLU(0.2, inplace=True))return layers
block函数的目的是将多个神经网络层组合成一个模块。这个模块返回的是一个列表(layers),其中每个元素都是一个nn.Module对象。nn.Module是PyTorch中所有神经网络层和功能模块的基类,包括激活函数(如nn.ReLU、nn.Sigmoid等)。因此,block函数中的每个元素可以是一个神经网络层,也可以是一个激活函数模块。通过这种方式,block函数能够灵活地组合不同的层和功能模块,形成一个完整的神经网络模块。
假设我们调用了 block(8, 4) 和 block(4, 2)。这些 block 函数会返回一组层(包括线性层以及 LeakyReLU 激活函数)。
比如 block(8, 4)会得到:
[nn.Linear(8, 4, bias=False), nn.LeakyReLU(0.2)]
这个模块先通过 nn.Linear(8, 4, bias=False) 将输入的 8 维数据转换为 4 维数据,然后将结果传递给 LeakyReLU(0.2) 激活函数,进行非线性变换。
假设输入数据为 x = [2, -3, 1, 0.5, …],经过线性层后输出为 4 维数据(假设输出为 [1.0, -0.5, 3.2, 0.1])。然后,经过 LeakyReLU 变换:
1.0 → 1.0(因为大于 0)
-0.5 → -0.5 * 0.2 = -0.1(因为小于 0,乘以 0.2)
3.2 → 3.2(因为大于 0)
0.1 → 0.1(因为大于 0)
最终经过 LeakyReLU 处理后的输出为:[1.0, -0.1, 3.2, 0.1]。
2 多个网络层之间如何连接
网络层是通过每个层的输出作为下一个层的输入来连接的。当一个神经网络的层经过 LeakyReLU 激活后,其输出成为下一层的输入。
在你的代码中,每个 block 函数会返回一个层列表,这些层会依次执行:
model += block(nROI, int(nROI/2)) + block(int(nROI/2), int(nROI/4))
假设输入数据 x 的维度为 nROI=8,那么这个 block 会返回如下的网络结构:
nn.Linear(8, 4):将输入的 8 维数据映射到 4 维。
nn.LeakyReLU(0.2):对 4 维输出应用 LeakyReLU 激活函数。
然后继续使用另一个 block(4, 2):
nn.Linear(4, 2):将 4 维数据映射到 2 维。
nn.LeakyReLU(0.2):对 2 维输出应用 LeakyReLU 激活函数。
block 函数的作用是将一些神经网络层组合成一个列表。你将这些层组合起来,形成一个完整的神经网络结构。通过 model +=,这些层会被加到 model 列表中,从而组成模型的一部分。