深度神经网络中的输出层是否需要激活函数?

人工智能 神经网络 深度学习 激活函数
2021-10-24 03:02:54

我参加了一只使用一个隐藏层的课程,那是唯一具有激活功能的层。该模型可以如下可视化:

在此处输入图像描述

这是一个 PyTorch 实现:

class MnistModel(nn.Module):
    """Feedfoward neural network with 1 hidden layer"""
    def __init__(self, in_size, hidden_size, out_size):
        super().__init__()
        # hidden layer
        self.linear1 = nn.Linear(in_size, hidden_size)
        # output layer
        self.linear2 = nn.Linear(hidden_size, out_size)
        
    def forward(self, xb):
        # Flatten the image tensors
        xb = xb.view(xb.size(0), -1)
        # Get intermediate outputs using hidden layer
        out = self.linear1(xb)
        # Apply activation function
        out = F.relu(out)
        # Get predictions using output layer
        out = self.linear2(out)
        return out

输出层不应该也有激活功能吗?

2个回答

没有激活函数的神经网络层与“线性激活”相同,即f(x)=x

这通常用于回归问题中的输出层,其中 sigmoid、双曲正切或 ReLU 等受约束的输出可能不合适。

对于输出层,这很好,并且不与神经网络背后的任何理论相冲突。它通常与均方误差 (MSE) 损失函数结合使用,使输出层的梯度计算变得简单。

对于隐藏层,跳过激活函数可能是个问题,因为多层网络中间的纯线性层是多余的——它可以被替换甚至移除而没有影响。那是因为两个直接连接的线性层在功能上等同于具有不同参数的单个线性层,并且每个隐藏层都由一个线性分量加上一个激活函数组成。因此,即使隐藏层上缺少一个激活函数,也会直接连接两个线性子组件,从而使其中一个成为冗余。

在分类器的情况下,一些库(尤其包括您正在使用的 PyTorch)要求您拥有神经网络的两个变体 - 一个没有最终 sigmoid 或 softmax 层的可训练版本,以及添加 sigmoid 或顶部的softmax(通常只是一个调用训练网络并添加最后一个激活的函数)。这样做是为了允许您使用基于logits的更稳定的梯度计算,即应用激活函数之前的值。

我想为尼尔的回答添加更多信息。

示例中实现的网络不包括输出激活,因为它将在训练期间应用:

# ...
def training_step(self, batch):
    images, labels = batch 
    out = self(images)
    # apply activation and calculate loss
    loss = F.cross_entropy(out, labels)
    return loss
# ...

示例中考虑的问题是多类分类,通常通过 softmax 激活和交叉熵损失来解决。F.cross_entropylog_softmax和结合nll_loss在一个函数中,它在数值上比 softmax 和 NLL 损失更稳定。有关更多详细信息,请参阅此讨论,这里是有关不同实现的文章。