What is a neural network? 什么是神经网络?
A neural network is a collection of neurons that are connected by layers. Each neuron is a small computing unit that performs simple calculations to collectively solve a problem. Neurons are organized in three types of layers: input layer, hidden layer, and output layer. The hidden and output layers contain a number of neurons. Neural networks mimic the way a human brain processes information.
神经网络是一组通过层连接的神经元的集合。每个神经元是一个小型计算单元,执行简单的计算来集体解决问题。神经元被组织成三种类型的层:输入层、隐藏层和输出层。隐藏层和输出层中包含多个神经元。神经网络模拟人脑处理信息的方式。
Components of a neural network 神经网络的组成部分
An activation function determines whether a neuron should be activated or not. The computations that happen in a neural network include applying an activation function. If a neuron activates, then it means the input is important. There are different kinds of activation functions. The choice of which activation function to use depends on what you want the output to be. Another important role of an activation function is to add non-linearity to the model.
激活函数决定了一个神经元是否应该被激活。神经网络中的计算包括应用激活函数。如果一个神经元被激活,这意味着输入是重要的。激活函数有多种类型,选择哪种激活函数取决于你希望输出的结果。激活函数的另一个重要作用是为模型增加非线性特性。
- Binary is used to set an output node to 1 if the function result is positive and 0 if the function result is zero or negative.
Binary (二值)用于将输出节点设置为1(如果函数结果为正),或设置为0(如果函数结果为0或负)。$f(x)= {\small \begin{cases} 0, & \text{if } x < 0\ 1, & \text{if } x\geq 0\ \end{cases}}$
- Sigmoid is used to predict the probability of an output node being between 0 and 1.
Sigmoid(S形函数)用于预测输出节点在0到1之间的概率。$f(x) = {\large \frac{1}{1+e^{-x}}}$
- Tanh is used to predict whether an output node is between 1 and -1, for classification use cases.
Tanh(双曲正切函数)用于预测输出节点在1到-1之间的值,常用于分类场景。$f(x) = {\large \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}}$
- ReLU (rectified linear activation function) is used to set the output node to 0 if the function result is negative and keeps the result value if the result is a positive value.
- ReLU(修正线性激活函数)用于将输出节点设置为0(如果函数结果为负),并保留正值的结果。$f(x)= {\small \begin{cases} 0, & \text{if } x < 0\ x, & \text{if } x\geq 0\ \end{cases}}$
- Weights influence how close our network's output is to the expected output value. As an input enters the neuron, it gets multiplied by a weight value, and the resulting output is either observed or passed to the next layer in the neural network. Weights for all neurons in a layer are organized into one tensor.
权重影响神经网络输出与期望输出的接近程度。当输入进入神经元时,它会被一个权重值所乘,结果要么被观察,要么传递到神经网络的下一层。每一层中所有神经元的权重组织成一个张量。
- Bias makes up the difference between the activation function's output and its intended output. A low bias suggests that the network is making more assumptions about the output's form, whereas a high bias value makes fewer assumptions about the output's form.
- 偏置用于弥补激活函数输出与期望输出之间的差距。较低的偏置意味着网络对输出的形式做了更多假设,而较高的偏置值则对输出的形式假设较少。
We can say that an output of a neural network layer with weights and bias is computed as summation of the inputs multiplied by the weights plus the bias. , where is the activation function.
我们可以说,具有权重$W$和偏置$b$的神经网络层的输出$y$是输入乘以权重再加上偏置的总和。$x = \sum{(weights * inputs) + bias}$,其中$f(x)$是激活函数。
Build a neural network 构建神经网络
Neural networks are comprised of layers and modules that perform operations on data. The torch.nn namespace provides all the building blocks you need to build your own neural network. Every module in PyTorch subclasses nn.Module. A neural network is itself a module that consists of other modules (layers). This nested structure allows for building and managing complex architectures easily.
神经网络由执行数据操作的层和模块组成。torch.nn命名空间提供了构建神经网络所需的所有基础组件。PyTorch 中的每个模块都继承自 nn.Module。神经网络本身也是一个模块,由其他模块(层)组成。这样的嵌套结构可以轻松构建和管理复杂的架构。
In the following sections, we'll build a neural network to classify images in the FashionMNIST dataset.
在接下来的部分中,我们将构建一个神经网络,用于对 FashionMNIST 数据集中的图像进行分类。
Get a hardware device for training 获取用于训练的硬件设备
We want to be able to train our model on a hardware accelerator like a GPU, if one is available. Let's check to see whether
torch.cuda is available; if not, we'll continue to use the CPU.
我们希望能够在硬件加速器(如 GPU)上训练模型,如果可用的话。让我们检查一下 torch.cuda 是否可用;如果不可用,我们将继续使用 CPU。
Define the class 定义类
We define our neural network by subclassing nn.Module, and initialize the neural network layers in __init__. Every nn.Module subclass implements the operations on input data in the forward method.
我们通过继承 nn.Module 来定义神经网络,并在 __init__ 方法中初始化神经网络层。每个 nn.Module 子类都在 forward 方法中实现对输入数据的操作。
Our neural network is composed of the following:
- The input layer with 28x28 or 784 features/pixels.
- The first linear module takes the input 784 features and transforms it to a hidden layer with 512 features.
- The ReLU activation function will be applied in the transformation.
- The second linear module takes 512 features as input from the first hidden layer and transforms it to the next hidden layer with 512 features.
- The ReLU activation function will be applied in the transformation.
- The third linear module take 512 features as input from the second hidden layer and transforms those features to the output layer with 10, which is the number of classes.
- The ReLU activation function will be applied in the transformation.
我们的神经网络由以下部分组成:
- 输入层有 28x28 或 784 个特征/像素。
- 第一个线性模块将 784 个输入特征转换为具有 512 个特征的隐藏层。
- 在转换过程中应用 ReLU 激活函数。
- 第二个线性模块将第一个隐藏层的 512 个特征作为输入,并将其转换为具有 512 个特征的下一个隐藏层。
- 在转换过程中应用 ReLU 激活函数。
- 第三个线性模块将第二个隐藏层的 512 个特征作为输入,并将这些特征转换为输出层,输出层具有 10 个类(即分类数)。
- 在转换过程中应用 ReLU 激活函数。
We create an instance of NeuralNetwork, move it to the device, and print its structure.
我们创建一个 NeuralNetwork 实例,将其移动到 device 上,并打印其结构。
To use the model, we pass it the input data. This executes the model's forward, along with some background operations. However, don't call model.forward() directly! Calling the model on the input returns a 10-dimensional tensor with raw predicted values for each class.
要使用模型,我们将输入数据传递给它。这将执行模型的 forward 方法,并在后台进行一些操作。但不要直接调用 model.forward()!将输入传递给模型会返回一个包含每个类别的原始预测值的 10 维张量。
We get the prediction densities by passing it through an instance of the nn.Softmax.
我们通过将其传递给 nn.Softmax 的实例来获得预测的概率分布。
Weight and Bias 权重和偏置
The nn.Linear module randomly initializes the and for each layer and internally stores the values in Tensors.
nn.Linear 模块会随机初始化每一层的 和 ,并将这些值内部存储在张量中。
First Linear biases: Parameter containing:
Model layers 模型层
Let's break down the layers in the FashionMNIST model. To illustrate it, we take a sample minibatch of three images of size 28x28 and see what happens to it as we pass it through the network.
让我们详细分析 FashionMNIST 模型中的各个层。为了说明这一点,我们取一个包含三张 28x28 尺寸图像的样本小批量,并观察它在通过网络时会发生什么。
nn.Flatten
We initialize the nn.Flatten layer to convert each two-dimensional 28x28 image into a contiguous array of 784 pixel values; that is, the minibatch dimension (at dim=0) is maintained. Each of the pixels are passed to the neural network's input layer.
我们初始化 nn.Flatten 层,以将每张二维的 28x28 图像转换为一个连续的 784 像素值数组;即,保持小批量维度(在 dim=0 处)。每个像素都被传递到神经网络的输入层。
nn.Linear
The linear layer is a module that applies a linear transformation on the input using its stored weights and biases. The grayscale value of each pixel in the input layer is connected to neurons in the hidden layer for calculation. The calculation the transformation uses is .
线性层是一个模块,它使用存储的权重和偏置对输入应用线性变换。输入层中每个像素的灰度值与隐藏层中的神经元连接以进行计算。变换使用的计算公式为 。
nn.ReLU
Nonlinear activations are what create the complex mappings between the model's inputs and outputs. They're applied after linear transformations to introduce nonlinearity, helping neural networks learn a wide variety of phenomena. In this model, we use nn.ReLU between our linear layers, but there's other activations to introduce nonlinearity in your model.
非线性激活函数在模型的输入和输出之间创建复杂的映射。它们在进行线性变换后应用,以引入 非线性,帮助神经网络学习多种现象。在这个模型中,我们在线性层之间使用 nn.ReLU,但还有其他激活函数可以在模型中引入非线性。
The ReLU activation function takes the output from the linear layer calculation and replaces the negative values with zeros.
ReLU 激活函数将线性层计算的输出中的负值替换为零。
Linear output: 线性输出:${ x = {weight * input + bias}} f(x)= \begin{cases}
\end{cases} $
After ReLU: tensor([[0.0000, 0.4203, 0.0824, 0.3017, 0.0000, 0.1329, 0.2476, 0.0000, 0.0000,
nn.Sequential
nn.Sequential is an ordered
container of modules. The data is passed through all the modules in their defined order. You can use
sequential containers to put together a quick network like seq_modules.
nn.Sequential 是一个有序的模块容器。数据按定义的顺序通过所有模块进行传递。您可以使用顺序容器快速组装网络,例如 seq_modules。
nn.Softmax
The last linear layer of the neural network returns logits (the raw values in [-infty, infty]), which are passed to the nn.Softmax module. The Softmax activation function calculates the probability of the output from the neural network. It's only used on a neural network's output layer. The results are scaled to values [0, 1], representing the model's predicted densities for each class. The dim parameter indicates the dimension along which the result values must sum to 1. The node with the highest probability predicts the desired output.
神经网络的最后一个线性层返回 logits(原始值在 [-infty, infty] 范围内),这些值会传递给 nn.Softmax 模块。Softmax 激活函数计算神经网络输出的概率。它仅用于神经网络的输出层。结果被缩放到 [0, 1] 的值,表示模型对每个类别的预测概率。dim 参数指示结果值必须在某个维度上相加为 1。具有最高概率的节点预测所需的输出。
Model parameters 模型参数
Many layers inside a neural network are parameterized; that is, the layers have associated weights
and biases that are optimized during training. Subclassing nn.Module automatically tracks all fields defined inside your model object, and makes all parameters accessible using your model's parameters() or named_parameters() methods.
神经网络中的许多层是 参数化的;也就是说,这些层具有与之关联的权重和偏置,这些权重和偏置在训练过程中被优化。继承 nn.Module 会自动跟踪模型对象中定义的所有字段,并使所有参数可以通过模型的 parameters() 或 named_parameters() 方法访问。
In this example, we iterate over each parameter and print its size and a preview of its values.
在这个示例中,我们遍历每个参数并打印其大小及其值的预览。
Layer: linearrelustack.0.weight | Size: torch.Size([512, 784]) | Values : tensor([[ 0.0016, 0.0144, -0.0148, ..., -0.0311, 0.0349, -0.0070],
Layer: linearrelustack.0.bias | Size: torch.Size([512]) | Values : tensor([ 0.0046, -0.0049], device='privateuseone:0', grad_fn=
Layer: linearrelustack.2.bias | Size: torch.Size([512]) | Values : tensor([0.0118, 0.0111], device='privateuseone:0', grad_fn=
Layer: linearrelustack.4.bias | Size: torch.Size([10]) | Values : tensor([-0.0050, -0.0234], device='privateuseone:0', grad_fn=