什么是神经网络?

神经网络是由神经元通过层连接形成的,每个神经元是一个小的计算单元,每个神经元接受一个或多个带权重的输入,并通过激活函数(如sigmoid)判断是否产生一个有效输出。
如果我们希望能够控制神经元被激活的容易程度,可以对神经元加一个偏置值。

该神经元的输出结果公式即为下图所示,且由激活函数f(x)判断是否激活该神经元。

神经网络即是由这些神经元通过层连接形成的网络。不同神经元组成了3个层(输入层、隐藏层、输出层),其中隐藏层可以有多层。

建立神经网络

torch.nn提供了自定义神经网络的几乎所有模块,在Pytorch中每个神经网络模型都是nn.Module的子类,神经网络模型在实战往往中通过“层”甚至“子神经网络”来构建。

1
2
3
4
5
6
7
8
9
10
11
# 调包
%matplotlib inline
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

# 指定训练平台
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('Using {} device'.format(device))

先定义一个继承nn.Module的类,通过__init__方法初始化神经网络模型的参数。然后定义一个forward方法,在该方法中定义对数据的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class NeuralNetwork(nn.Module):                 # 继承Module
def __init__(self):
super(NeuralNetwork, self).__init__() # 继承父类的初始化方法
self.flatten = nn.Flatten() # 展平层,用来将输入“压平”,即把多维的输入一维化
self.linear_relu_stack = nn.Sequential( # 神经网络隐藏层部分
nn.Linear(28*28, 512), # 输入为28*28,输出为512个特征
nn.ReLU(), # 激活函数,未被激活的神经元输出为0
nn.Linear(512, 512), # 输入为512个特征,输出为512个特征
nn.ReLU(),
nn.Linear(512, 10), # 输入为512个特征,输出为10个类别
nn.ReLU()
)

def forward(self, x): # 模型的调用方法
x = self.flatten(x)
logits = self.linear_relu_stack(x)
return logits

展平层的作用就是将多维输入一维化,如下图所示:


通过model = NeuralNetwork().to(device)创建一个神经网络的实例,要使用这个实例,应该先将输入数据传递给他。调用实例会返回一个10维的张量,包含每个类别的概率。

1
2
3
4
5
X = torch.rand(5, 28, 28, device=device)
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits) # 将logits转换为概率
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")

这里没有对模型进行训练,原文未指明,此处应该是个聚类模型。


输出模型权重和偏置值:

1
2
3
print(f"First Linear weights: {model.linear_relu_stack[0].weight} \n")

print(f"First Linear weights: {model.linear_relu_stack[0].bias} \n")

输出模型结构和参数:

1
2
3
4
print("Model structure: ", model, "\n\n")

for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")