作用:
当神经网络中上一层的输出直接作为下一层的输入时,每层之间的关系是线性关系,即相当于f(x)=x
,此时神经网络的拟合能力较弱。为了使得神经网络有更好的拟合能力,在每一层网络之间加入了激活函数(非线性)来使得不同层网络之间的关系变为非线性,从而使网络有更好的拟合能力。
常用的激活函数有Sigmoid、tanh,ReLU、leaky ReLU等。除此以外还有线性激活函数如Linear。
激活函数的选取十分重要,不同的激活函数有不同的特点。选取不当可能会导致梯度变得非常小,就是通常所说的梯度消失问题。另外还存在一种相反的问题,就是梯度爆炸(不常见),当梯度值过大时,网络会变得非常不稳定。
包:torch.nn.Sigmoid
特点:
zero-centered
,只有正数输出,所以会导致zigzag
现象包:torch.nn.Tanh
特点:
包:torch.nn.ReLU(inplace=False)
特点:
包:torch.nn.LeakyReLU(negative_slope=0.01, inplace=False)
参数
False
特点:
包:torch.nn.PReLU( num_parameters = 1 , init = 0.25 , device = None , dtype = None )
参数:
特点:
用于度量神经网络的输出的预测值与实际值之间的差距的一种方式。
为卷积核的参数设置梯度,利用梯度下降可以对更新卷积核的参数提供一定的依据(反向传播)。
回归损失函数:
分类损失函数:
LogLoss
CrossEntropyLoss
逻辑回归就是使用对数损失函数来进行二分类任务,
softmax回归是逻辑回归的推广,
softmax回归使用交叉熵损失函数来进行多分类任务。
包:torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean')
特点:(转载于https://www.cnblogs.com/wangguchangqing/p/12021638.html)
# 输入,需要的输入类型是float类型
input = torch.tensor([1, 2, 3], dtype=float)
# 目标
target = torch.tensor([1, 2, 5], dtype=float)
# 损失函数,可选参数有两个:mean, sum
# mean:默认,求差后求和在除以个数
# sum:求差后求和
loss1 = L1Loss(reduction="mean")
loss2 = L1Loss(reduction="sum")
result1 = loss1(input, target)
result2 = loss2(input, target)
print(result1) # tensor(0.6667, dtype=torch.float64) 说明:((1 - 1) + (2 - 2) + (5 - 3)) / 3 = 0.6667
print(result2) # tensor(2., dtype=torch.float64) 说明:((1 - 1) + (2 - 2) + (5 - 3)) = 2.
包:torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')
特点:
总之,MAE作为损失函数更稳定,并且对离群值不敏感,但是其导数不连续,求解效率低。另外,在深度学习中,收敛较慢。MSE导数求解速度高,但是其对离群值敏感,不过可以将离群值的导数设为0(导数值大于某个阈值)来避免这种情况。在某些情况下,上述两种损失函数也可能都不满足需求。
包:torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)
函数:
该函数结合了nn.LogSoftmax()和nn.NLLLoss()函数
1、Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
2、然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性
代码示例:
import torch
import torchvision.datasets
from torch import nn
from torch.nn import L1Loss, Sequential, Conv2d, MaxPool2d, Flatten, Linear
from torch.utils.data import DataLoader
class MyNN(nn.Module):
def __init__(self) -> None:
super().__init__()
self.sequential = Sequential(
Conv2d(3, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, x):
x = self.sequential(x)
return x
dataset = torchvision.datasets.CIFAR10("dataset", transform=torchvision.transforms.ToTensor())
dataLoader = DataLoader(dataset, batch_size=1)
demo_loss = MyNN()
# 交叉商
loss = nn.CrossEntropyLoss()
step = 0
for data in dataLoader:
imgs, targets = data
output = demo_loss(imgs)
print(output)
print(targets)
# 计算实际输出和目标输出之间的差距
result_loss = loss(output, targets)
print(result_loss)
# 反向传播,为更新数据提供一定的依据。会在这一步算出一个梯度
result_loss.backward()
注:本博客只用于人笔记记录,内容来自网络整理