赞
踩
点击关注我哦
欢迎关注 “小白玩转Python”,发现更多 “有趣”
“The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.”
― Edsger W. Dijkstra
在本文章中,我们将使用 PyTorch 从头开始实现一个简单的神经网络。
注:阅读本文之前,最好可以了解神经网络的工作原理。
虽然有很多库可以用于深度学习,但我最喜欢 PyTorch。作为一名 python 程序员,我喜欢 PyTorch 的 python 行为是原因之一。它主要使用了 python 的风格和能力,这是很容易理解和使用。
在其核心,PyTorch 提供两个主要特性:
1. 一个类似于 numpy 的 n 维张量,但可以在 gpu 上运行;
2. 自动区分建立和训练神经网络。
什么是神经网络?
神经网络是一组可以模仿人类大脑,并被设计用来识别模式的算法。这些网络是由接近神经元的单个部分构成的,通常称为单元或简称为“神经元”每个单元有一定数量的加权输入。这些加权的输入总和在一起(一个线性组合) ,然后通过一个激活函数来得到单位输出。
神经网络中的节点类型:
1. 输入单元ーー把外界的资讯输入网络,统称为「输入层」。这些节点不执行任何计算,它们只是将信息传递给隐藏节点;
2. 隐藏单元ーー这些节点与外界没有任何直接联系。它们执行计算并将信息从 Input 节点传输到 Output 节点。一个隐藏节点的集合形成了一个“隐藏层”。虽然前馈网络只有一个输入层和一个输出层,但是它可以有零个或多个隐藏层;
3. 输出单元ーー输出节点统称为「输出层」 ,负责计算及将网络上的资讯传送到外界。
每一层包含一个或多个节点。
建立神经网络
PyTorch 提供了一个模块 nn,使得构建网络更加简单。我们将看到如何建立一个有784个输入,256个隐藏单元,10个输出单元和一个softmax 输出单元的神经网络。
- from torch import nnclass Network(nn.Module):
- def __init__(self):
- super().__init__()
-
- # Inputs to hidden layer linear transformation
- self.hidden = nn.Linear(784, 256)
- # Output layer, 10 units - one for each digit
- self.output = nn.Linear(256, 10)
-
- # Define sigmoid activation and softmax output
- self.sigmoid = nn.Sigmoid()
- self.softmax = nn.Softmax(dim=1)
-
- def forward(self, x):
- # Pass the input tensor through each of our operations
- x = self.hidden(x)
- x = self.sigmoid(x)
- x = self.output(x)
- x = self.softmax(x)
-
- return x
注: Softmax 激活函数函数,也称为 softargmax 或 normalizd exponential 函数,可以讲一个含任意实数的K维向量z“压缩”至另一个K维实向量f(z)中,使得每一个元素的范围都在(0, 1)之间,且所有元素的和为1。
让我们把这一行一行地过一遍。
class Network(nn.Module):
这里我们继承了 nn.Module。与 super ().__init__()结合将创建一个可以提供许多有用的方法和属性的类。当你为你的网络创建一个类的时候通常都会从nn.Module进行继承。类的名称可以自定义。
self.hidden = nn.Linear(784, 256)
这一行创建了一个线性映射模块,xW + b,包含784个输入和256个输出,并将其赋值给 self.hidden。该模块自动创建的权重和偏差,我们将在forward函数中使用,并且可以通过 net.hidden.weight 和 net.hidden.bias 从创建的网络中访问权重和偏差。
self.output = nn.Linear(256, 10)
同样地,这也创建了另一个有256个输入和10个输出的线性映射。
- self.sigmoid = nn.Sigmoid()
- self.softmax = nn.Softmax(dim=1)
这里我定义了用于 sigmoid 激活和 softmax 输出的操作。并设置 dim = 1 在 nnSoftmax (dim = 1)对某一维度的列进行softmax运算。
def forward(self, x):
用 nn.Module 创建的 PyTorch 网络必须定义了一个forward方法,它接受一个张量 x,并将其传递给在 __init__ 方法中定义的操作。
- x = self.hidden(x)
- x = self.sigmoid(x)
- x = self.output(x)
- x = self.softmax(x)
这里输入张量 x 通过每个操作重新赋值给 x。我们可以看到,输入张量通过隐藏层,然后是 Sigmod 函数,然后是输出层,最后是Softmax函数。您在这里将变量命名为什么并不重要,只要操作的输入和输出符合您想要构建的网络体系结构即可。在 __init__ 方法中定义事物的顺序并不重要,但是您需要在 forward 方法中正确排列操作的顺序。
- # Create the network and look at it's text representation
- model = Network()
- model
利用神经网络建立神经网络
PyTorch 提供了一种构建类似于张量按顺序通过操作的方便方法——nn.Sequential。我们也可以使用这个来建立等价的网络:
- # Hyperparameters for our network
- input_size = 784
- hidden_sizes = [128, 64]
- output_size = 10
- # Build a feed-forward network
- model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
- nn.ReLU(),
- nn.Linear(hidden_sizes[0], hidden_sizes[1]),
- nn.ReLU(),
- nn.Linear(hidden_sizes[1], output_size),
- nn.Softmax(dim=1))
- print(model)
这里我们的模型是一样的,784个输入单元,一个有128个单元的隐藏层,ReLU 激活函数,64个单元的隐藏层,另一个 ReLU函数,然后带有10个单元的输出层,Softmax层。
您还可以传入 OrderedDict 来命名各个层和操作,而不是使用增量整数。注意,字典键必须是唯一的,因此每个操作必须有不同的名称。
- from collections import OrderedDict
- model = nn.Sequential(OrderedDict([
- ('fc1', nn.Linear(input_size, hidden_sizes[0])),
- ('relu1', nn.ReLU()),
- ('fc2', nn.Linear(hidden_sizes[0], hidden_sizes[1])),
- ('relu2', nn.ReLU()),
- ('output', nn.Linear(hidden_sizes[1], output_size)),
- ('softmax', nn.Softmax(dim=1))]))
-
-
- model
现在,您可以通过整数或名称访问层,如下所示:
- print(model[0])
- print(model.fc1)
· END ·
HAPPY LIFE
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。