当前位置:   article > 正文

深度学习 | 神经网络_神经网络的基本原理

神经网络的基本原理

 

一、神经网络原理

 

1、神经元模型

        虽然叫个神经元,但骨子里还是线性模型。

        

2、神经网络结构

        顾名思义就是由很多个神经元结点前后相连组成的一个网络。虽然长相上是个网络,但是本质上是多个线性模型的模块化组合。

        在早期也被称为 多层感知机 Multi-Layer Perceptron(MLP)。

        

        输入层是特征向量,如果输入的是一张32x32的灰度图像,那么输入层的维度就是32x32,为了处理方便,我们通常会将其reshape成列向量表示。

        

        一系列线性方程的运算最后都可以用一个线性方程来表示。如此一来,神经网络就失去了意义,发生了“退化”。也就是说随着网络层数的增加,进行分类的准确率没有发生明显的变化,甚至可能下降。因此注入灵魂——激活层,用来进行非线性变换。

        

        需要注意的是,每个隐藏层的计算之后都需要加一层激活层。

        

        为什么线性计算和激活函数是分离的,不能用一个函数来替代呢?

        —— 这样可以极大地简化学习的步骤,后续反向传播中就可以看到。

        那么现在的神经网络就变成下图这样的形式:

        

        我们都知道整个神经网络都是分为两个步骤的,训练和测试。

        如果是在测试(预测)阶段,输出中数值最大的就代表了当前的分类。但是对于用于训练的网络,还远远不够,因为当前的输出y还不够漂亮,他的取值范围是随意的,算出来是什么就是什么,我们想让最终输出是一个概率的形式 —— softmax层 进行归一化。

        

        神经网络输出的结果并不一定是真实的情况。

        

        最后反向传播,优化参数 w1 w2 b等。

        不同神经网络算法之间的差异主要体现在:

        1、网络模型的结构

        2、损失函数

        3、动态求解损失函数的过程

        4、过程中出现问题(如过拟合)的解决方式

 


 

 二、多层感知机

 

1、线性网络的局限

        

 2、怎么引入非线性

          

 3、多层感知机 MLP

        

         多隐藏层

        

4、激活函数

        

         Sigmoid函数

                在输出值不是0或1的情况下,具有非常好的非线性。

                适用于二元分类问题。逻辑回归中常用。

                光滑投影到(0,1)。

                容易导致梯度消失。输出以0.5为中心。

                

                

        Tanh函数

                Sigmoid改进版,输出值压缩到(-1,1)。

                输出以0为中心。

                更快的收敛速度。

                

                

        ReLU函数

                多数情况下第一选择。

                解决梯度消失问题。

                计算上比Sigmoid和tanh函数快。

                Dying ReLU问题,输入为负数时函数值为0,导致网络某些权重不能更新,难以训练。

                

                

        Softmax函数

                

 


 

三、多层感知机代码实现

 

        PyTorch搭建神经网络步骤:

        

  1. # 导包
  2. import torch
  3. from torchvision import datasets
  4. from torchvision import transforms
  5. import torch.nn as nn
  6. import torch.optim as optim

data

  1. train_data = datasets.MNIST(root="data/mnist",train=True,transform=transforms.ToTensor(),download=True)
  2. test_data = datasets.MNIST(root="data/mnist",train=False,transform=transforms.ToTensor(),download=True)
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to data/mnist/MNIST/raw/train-images-idx3-ubyte.gz
  0%|          | 0/9912422 [00:00<?, ?it/s]
Extracting data/mnist/MNIST/raw/train-images-idx3-ubyte.gz to data/mnist/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to data/mnist/MNIST/raw/train-labels-idx1-ubyte.gz
  0%|          | 0/28881 [00:00<?, ?it/s]
Extracting data/mnist/MNIST/raw/train-labels-idx1-ubyte.gz to data/mnist/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to data/mnist/MNIST/raw/t10k-images-idx3-ubyte.gz
  0%|          | 0/1648877 [00:00<?, ?it/s]
Extracting data/mnist/MNIST/raw/t10k-images-idx3-ubyte.gz to data/mnist/MNIST/raw

Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to data/mnist/MNIST/raw/t10k-labels-idx1-ubyte.gz
  0%|          | 0/4542 [00:00<?, ?it/s]
Extracting data/mnist/MNIST/raw/t10k-labels-idx1-ubyte.gz to data/mnist/MNIST/raw

  1. batch_size = 100
  2. train_loader = torch.utils.data.DataLoader(dataset=train_data,batch_size=batch_size,shuffle=True)
  3. test_loader = torch.utils.data.DataLoader(dataset=test_data,batch_size=batch_size,shuffle=False)

net

  1. # 定义 MLP 网络 继承nn.Module
  2. class MLP(nn.Module):
  3. # 初始化方法
  4. # input_size输入数据的维度
  5. # hidden_size 隐藏层的大小
  6. # num_classes 输出分类的数量
  7. def __init__(self, input_size, hidden_size, num_classes):
  8. # 调用父类的初始化方法
  9. super(MLP, self).__init__()
  10. # 定义第1个全连接层
  11. self.fc1 = nn.Linear(input_size, hidden_size)
  12. # 定义激活函数
  13. self.relu = nn.ReLU()
  14. # 定义第2个全连接层
  15. self.fc2 = nn.Linear(hidden_size, hidden_size)
  16. # 定义第3个全连接层
  17. self.fc3 = nn.Linear(hidden_size, num_classes)
  18. # 定义forward函数
  19. # x 输入的数据
  20. def forward(self, x):
  21. # 第一层运算
  22. out = self.fc1(x)
  23. # 将上一步结果送给激活函数
  24. out = self.relu(out)
  25. # 将上一步结果送给fc2
  26. out = self.fc2(out)
  27. # 同样将结果送给激活函数
  28. out = self.relu(out)
  29. # 将上一步结果传递给fc3
  30. out = self.fc3(out)
  31. # 返回结果
  32. return out
  33. # 定义参数
  34. input_size = 28 * 28 # 输入大小
  35. hidden_size = 512 # 隐藏层大小
  36. num_classes = 10 # 输出大小(类别数)
  37. # 初始化MLP
  38. model = MLP(input_size, hidden_size, num_classes)

loss

criterion = nn.CrossEntropyLoss()

optim

  1. learning_rate = 0.001 # 学习率
  2. optimizer = optim.Adam(model.parameters(),lr=learning_rate)

training

  1. # 训练网络
  2. num_epochs = 10 # 训练轮数
  3. for epoch in range(num_epochs):
  4. for i, (images, labels) in enumerate(train_loader):
  5. # 将iamges转成向量
  6. images = images.reshape(-1, 28 * 28)
  7. # 将数据送到网络中
  8. outputs = model(images)
  9. # 计算损失
  10. loss = criterion(outputs, labels)
  11. # 首先将梯度清零
  12. optimizer.zero_grad()
  13. # 反向传播
  14. loss.backward()
  15. # 更新参数
  16. optimizer.step()
  17. if (i + 1) % 100 == 0:
  18. print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
Epoch [1/10], Step [100/600], Loss: 0.3697
Epoch [1/10], Step [200/600], Loss: 0.1534
Epoch [1/10], Step [300/600], Loss: 0.1699
Epoch [1/10], Step [400/600], Loss: 0.0657
Epoch [1/10], Step [500/600], Loss: 0.1864
Epoch [1/10], Step [600/600], Loss: 0.0878
Epoch [2/10], Step [100/600], Loss: 0.0853
Epoch [2/10], Step [200/600], Loss: 0.0340
Epoch [2/10], Step [300/600], Loss: 0.1702
Epoch [2/10], Step [400/600], Loss: 0.0413
Epoch [2/10], Step [500/600], Loss: 0.0730
Epoch [2/10], Step [600/600], Loss: 0.0986
Epoch [3/10], Step [100/600], Loss: 0.0139
Epoch [3/10], Step [200/600], Loss: 0.0562
Epoch [3/10], Step [300/600], Loss: 0.0235
Epoch [3/10], Step [400/600], Loss: 0.0731
Epoch [3/10], Step [500/600], Loss: 0.0398
Epoch [3/10], Step [600/600], Loss: 0.1915
Epoch [4/10], Step [100/600], Loss: 0.0118
Epoch [4/10], Step [200/600], Loss: 0.0911
Epoch [4/10], Step [300/600], Loss: 0.0256
Epoch [4/10], Step [400/600], Loss: 0.0879
Epoch [4/10], Step [500/600], Loss: 0.0045
Epoch [4/10], Step [600/600], Loss: 0.0191
Epoch [5/10], Step [100/600], Loss: 0.0073
Epoch [5/10], Step [200/600], Loss: 0.0125
Epoch [5/10], Step [300/600], Loss: 0.0421
Epoch [5/10], Step [400/600], Loss: 0.0424
Epoch [5/10], Step [500/600], Loss: 0.0099
Epoch [5/10], Step [600/600], Loss: 0.0043
Epoch [6/10], Step [100/600], Loss: 0.0086
Epoch [6/10], Step [200/600], Loss: 0.0070
Epoch [6/10], Step [300/600], Loss: 0.0092
Epoch [6/10], Step [400/600], Loss: 0.0152
Epoch [6/10], Step [500/600], Loss: 0.0071
Epoch [6/10], Step [600/600], Loss: 0.0038
Epoch [7/10], Step [100/600], Loss: 0.0414
Epoch [7/10], Step [200/600], Loss: 0.0159
Epoch [7/10], Step [300/600], Loss: 0.0332
Epoch [7/10], Step [400/600], Loss: 0.0054
Epoch [7/10], Step [500/600], Loss: 0.0067
Epoch [7/10], Step [600/600], Loss: 0.0072
Epoch [8/10], Step [100/600], Loss: 0.0030
Epoch [8/10], Step [200/600], Loss: 0.0046
Epoch [8/10], Step [300/600], Loss: 0.0492
Epoch [8/10], Step [400/600], Loss: 0.0126
Epoch [8/10], Step [500/600], Loss: 0.0592
Epoch [8/10], Step [600/600], Loss: 0.0073
Epoch [9/10], Step [100/600], Loss: 0.0520
Epoch [9/10], Step [200/600], Loss: 0.0031
Epoch [9/10], Step [300/600], Loss: 0.0036
Epoch [9/10], Step [400/600], Loss: 0.0077
Epoch [9/10], Step [500/600], Loss: 0.0097
Epoch [9/10], Step [600/600], Loss: 0.0029
Epoch [10/10], Step [100/600], Loss: 0.0002
Epoch [10/10], Step [200/600], Loss: 0.0021
Epoch [10/10], Step [300/600], Loss: 0.0235
Epoch [10/10], Step [400/600], Loss: 0.0004
Epoch [10/10], Step [500/600], Loss: 0.0343
Epoch [10/10], Step [600/600], Loss: 0.0249

test

  1. # 测试网络
  2. with torch.no_grad():
  3. correct = 0
  4. total = 0
  5. # 从 test_loader中循环读取测试数据
  6. for images, labels in test_loader:
  7. # 将images转成向量
  8. images = images.reshape(-1, 28 * 28)
  9. # 将数据送给网络
  10. outputs = model(images)
  11. # 取出最大值对应的索引 即预测值
  12. _, predicted = torch.max(outputs.data, 1)
  13. # 累加label数
  14. total += labels.size(0)
  15. # 预测值与labels值比对 获取预测正确的数量
  16. correct += (predicted == labels).sum().item()
  17. # 打印最终的准确率
  18. print(f'Accuracy of the network on the 10000 test images: {100 * correct / total} %')
Accuracy of the network on the 10000 test images: 98.01 %

save

torch.save(model,"mnist_mlp_model.pkl")

 


四、回归问题

 Chapter-04/4-6 线性回归代码实现.ipynb · 梗直哥/Deep-Learning-Code - Gitee.com

 


 

 五、多分类问题

Chapter-04/4-8 多分类问题代码实现.ipynb · 梗直哥/Deep-Learning-Code - Gitee.com 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/990467
推荐阅读
相关标签
  

闽ICP备14008679号