提交 427774fc 编写于 作者: wnma3mz's avatar wnma3mz

finsh 14th

上级 f6366ca1
## BUILDING A NEURAL NET FROM SCRATCH IN GO
## 用Go建立神经网络
原文链接:[BUILDING A NEURAL NET FROM SCRATCH IN GO](https://www.datadan.io/building-a-neural-net-from-scratch-in-go/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com)
I'm super pumped that my new book [Machine Learning with Go](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-go) is now available! Writing the book allowed me to get a complete view of the current state of machine learning in Go, and let's just say that I'm pretty excited to see how the community growing!
我很高兴我的新书[Machine Learning with Go](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-go)现已推出!写这本书让我可以全面了解Go中机器学习的现状,我很高兴看到社区如何成长!
[![img](https://www.datadan.io/content/images/2017/10/book_wide.png)](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-go)
In the book (and for my own edification), I decided that I would build a neural network from scratch in Go. Turns out, this is fairly easy, and I thought it would be great to share my little neural net here.
在书中(包含我自己的启发),我决定用Go从零开始构建一个神经网络。事实证明,这很容易,我认为在这里分享我的小神经网络是一件很棒的事。
All the code and data shown below is available [on GitHub](https://github.com/dwhitena/gophernet).
下面显示的所有代码和数据都可以在[GitHub](https://github.com/dwhitena/gophernet)上找到。
(If you are interested in leveraging pre-existing Go packaging for machine learning, check out [all the great existing packages](https://github.com/gopherdata/resources/tree/master/tooling), and be sure to watch [Chris Benson's recent talk](https://youtu.be/CHzMEamGZDA) at GolangUK about Deep Learning in Go)
(如果您有兴趣利用已有的Go包装进行机器学习,请查看[所有优秀的现有软件包](https://github.com/gopherdata/resources/tree/master/tooling),并观看Chris Benson最近在GolangUK关于Go中深度学习的[演讲](https://youtu.be/CHzMEamGZDA))
## Goals
## 目标
There are a whole variety of ways to accomplish this task of building a neural net in Go, but I wanted to adhere to the following guidelines:
在Go中完成构建神经网络的任务有多种方法,但我想遵循以下准则:
- **No cgo** - I want my little neural net to compile nicely to a statically linked binary, and I also want to highlight the numerical functionality that is available natively in Go.
- **gonum matrix input** - I want supply matrices to my neural network for training, similar to how you would supply `numpy` arrays to most Python machine learning functions.
- **Variable numbers of nodes** - Although I will only illustrate one architecture here, I wanted my code to be flexible, such that I could tweak the numbers of nodes in each layer for other scenarios.
- **没有cgo** - 我希望我的小神经网络可以很好地编译为静态链接的二进制文件,我还想强调Go中本机可用的数字功能。
- **gonum矩阵输入** - 我希望为我的神经网络提供供应矩阵进行训练,类似于如何为大多数Python机器学习功能提供`numpy`数组。
- **可变数量的节点** - 虽然我只在这里说明一个架构,但我希望我的代码是灵活的,这样我就可以调整每层中的节点数量以用于其他场景。
## Network Architecture
## 网络架构
The basic network architecture that we will utilize in this example includes an input layer, a single hidden layer, and an output layer:
我们将在此示例中使用的基本网络体系结构包括输入层,单个隐藏层和输出层:
![img](https://www.datadan.io/content/images/2017/09/B05151_Chapter_08_05-1.png)
This type of single layer neural net might not be very "deep," but it has proven to be very useful for a huge majority of simple classification tasks. In our case, we will be training our model to classify iris flowers based on the [famous iris flower dataset](https://en.wikipedia.org/wiki/Iris_flower_data_set). This should be more than enough to solve that problem with a high degree of accuracy.
这种类型的单层神经网络可能不是很“深”,但它已被证明对绝大多数简单的分类任务非常有用。在我们的例子中,我们将根据着名的鸢尾花数据集训练我们的模型来对[著名的鸢尾花数据集合](https://en.wikipedia.org/wiki/Iris_flower_data_set)进行分类。这应该足以以高精度解决该问题。
Each of the **nodes** in the network will take in one or more inputs, combine those together linearly (using **weights** and a **bias**), and then apply a non-linear **activation function**. By optimizing the weights and the biases, with a process called [**backpropagation**](https://en.wikipedia.org/wiki/Backpropagation), we will be able to mimic the relationships between our inputs (measurements of flowers) and what we are trying to predict (species of flowers). We will then be able to feed new inputs through the optimized network (i.e., we will **feed** them **forward**) to predict the corresponding output.
网络中的每个**节点**将接收一个或多个输入,将它们线性地组合在一起(使用**权重****偏差**),然后应用非线性激活函数。通过优化权重和偏差,通过称为[**反向传播**](https://en.wikipedia.org/wiki/Backpropagation)的过程,我们将能够模仿我们的输入(花的测量)和我们想要预测的(花的种类)之间的关系。然后,我们将能够通过优化网络提供新输入(即,我们将**向前**它们**传播**)以预测相应的输出。
(If you are new to neural nets, you might also check out [this great intro](https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/), or, of course, you can read the relevant section in [Machine Learning with Go](https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-go).)
(如果你是神经网络的新手,你也可以查看[这个很棒的介绍](https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/),当然你还可以阅读[机器学习与Go]中的相关部分(https://www.packtpub.com/big-data-and-business-intelligence/machine-learning-go)。)
## Defining Useful Functions and Types
## 定义有用的函数和类型
Before diving into the backpropagation and feeding forward, let's define a couple types that will help us as we work with our model:
在深入反向传播和前向传播之前,让我们定义一些类型,这将有助于我们使用我们的模型:
```go
// neuralNet contains all of the information
......@@ -63,7 +63,7 @@ func newNetwork(config neuralNetConfig) *neuralNet {
}
```
We also need to define our activation function and it's derivative, which we will utilize during backpropagation. There are many choices for activation functions, but here we are going to use the [sigmoid function](http://mathworld.wolfram.com/SigmoidFunction.html). This function has various advantages, including probabilistic interpretations and a convenient expression for it's derivative.
我们还需要定义我们的激活函数及其衍生函数,我们将在反向传播过程中使用它。激活函数有很多,但在这里我们将使用[sigmoid函数](http://mathworld.wolfram.com/SigmoidFunction.html)。该函数具有各种优点,包括概率解释和对其衍生的方便表达。
```go
// sigmoid implements the sigmoid function
......@@ -79,22 +79,22 @@ func sigmoidPrime(x float64) float64 {
}
```
## Implementing Backpropagation for Training
## 为训练实施反向传播
With the definitions above taken care of, we can write an implementation of the [backpropagation method](https://en.wikipedia.org/wiki/Backpropagation) for training, or optimizing, the weights and biases of our network. The backpropagation method involves:
通过上面的定义,我们可以编写[backpropagation方法](https://en.wikipedia.org/wiki/Backpropagation)的实现来训练或优化我们网络的权重和偏差。反向传播方法包括:
1. Initializing our weights and biases (e.g., randomly).
2. Feeding training data through the neural net forward to produce output.
3. Comparing the output to the correct output to get errors.
4. Calculating changes to our weights and biases based on the errors.
5. Propagating the changes back through the network.
6. Repeating steps 2-5 for a given number of **epochs** or until a stopping criteria is satisfied.
1. 初始化我们的权重和偏差(例如,随机)。
2. 通过神经网络向前馈送训练数据以产生输出。
3. 将输出与正确的输出进行比较以获得错误。
4. 根据错误计算我们的权重和偏差的变化。
5. 通过网络传播更改。
6. 对于给定数量的**批次**重复步骤2-5或直到满足停止标准。
In steps 3-5, we will utilize [**stochastic gradient descent**](https://en.wikipedia.org/wiki/Stochastic_gradient_descent) (SGD) to determine the updates for our weights and biases.
在步骤3-5中,我们将利用[**随机梯度下降**](https://en.wikipedia.org/wiki/Stochastic_gradient_descent)(SGD)来确定我们的权重和偏差的更新。
To implement this network training, I created a method on `neuralNet` that would take pointers to two matrices as input, `x` and `y`. `x` will be the features of our data set (i.e., the independent variables) and `y` will represent what we are trying to predict (i.e., the dependent variable). I will show an example of these later in the article, but for now, let's assume that they take this form.
为了实现这种网络训练,我在`neuralNet`上创建了一个方法,它将用两个矩阵作为输入,`x``y``x`将是我们数据集的特征(即独立变量),而'y`将代表我们试图预测的内容(即因变量)。我将在本文后面展示一些这样的例子,但是现在,让我们假设它们采用这种形式。
In this function, we first initialize our weights and biases randomly and then use backpropagation to optimize the weights and the biases:
在这个函数中,我们首先随机初始化我们的权重和偏差,然后使用反向传播来优化权重和偏差:
```go
// train trains a neural network using backpropagation.
......@@ -143,7 +143,7 @@ func (nn *neuralNet) train(x, y *mat.Dense) error {
}
```
The actual implementation of backpropagation is shown below. **Note/Warning**, for clarity and simplicity, I'm going to create a handful of matrices as I carry out the backpropagation. For large data sets, you would likely want to optimize this to reduce the number of matrices in memory.
反向传播的实际实现如下所示。**注意/警告**,为了表现地清晰和简单,我将在执行反向传播时创建一些矩阵。对于大型数据集,您可能希望对其进行优化以减少内存中的矩阵数。
```go
// backpropagate completes the backpropagation method.
......@@ -217,7 +217,7 @@ func (nn *neuralNet) backpropagate(x, y, wHidden, bHidden, wOut, bOut, output *m
}
```
Here we have utilized a helper function that allows us to sum values along one dimension of a matrix, keeping the other dimension intact:
在这里,我们使用了一个辅助函数,它允许我们沿着矩阵的一个维度对值求和,保持其他维度的完整性:
```go
// sumAlongAxis sums a matrix along a particular dimension,
......@@ -251,9 +251,9 @@ func sumAlongAxis(axis int, m *mat.Dense) (*mat.Dense, error) {
}
```
## Implementing Feed Forward for Prediction
## 实现前向预测
After training our neural net, we are going to want to use it to make predictions. To do this, we just need to feed some given `x` values forward through the network to produce an output. This looks similar to the first part of backpropagation. Except, here we are going to return the generated output.
在训练我们的神经网络之后,我们将要用它来进行预测。为此,我们只需要通过网络向前提供一些给定的“x”值以产生输出。这看起来类似于反向传播的第一部分。除此之外,我们将返回生成的输出。
```go
// predict makes a prediction based on a trained
......@@ -292,11 +292,11 @@ func (nn *neuralNet) predict(x *mat.Dense) (*mat.Dense, error) {
}
```
## The Data
## 数据
Ok, we now have the building blocks that we will need to train and test our neural network. However, before we go off and try to run this, let's take a brief look at the data that I will be using to experiment with this neural net.
好的,我们现在拥有训练和测试神经网络所需的构建模块。然而,在我们开始试图运行之前,让我们简要地看一下我将用来试验这个神经网络的数据。
The data I'm going to use is a slightly transformed version of the popular [iris data set](https://archive.ics.uci.edu/ml/datasets/iris). This data set includes sets of four iris flower measurements (what will become our `x` values) along with a corresponding indication of iris species (what will become our `y` values). To utilize this data set with our neural net, I have slightly transformed the data set, such that the species values are represented by three binary columns (1 if the row corresponds to that species, 0 otherwise). I have also added a little bit of random noise to the measurement to try and confuse the neural net (because this problem is pretty easy to solve otherwise):
我将要使用的数据是流行的[鸢尾花数据集](https://archive.ics.uci.edu/ml/datasets/iris)的略微转换版本。该数据集包括四组虹膜花测量(将成为我们的`x`值)以及鸢尾花种类的相应指示(将成为我们的`y`值)。为了利用我们的神经网络利用这个数据集,我稍微改变了数据集,使得物种值由三个二进制列表示(如果行对应于该物种,则为1,否则为0)。我还在测量中添加了一点随机噪声,试图混淆神经网络(因为这个问题很容易解决):
```
$ head train.csv
......@@ -312,11 +312,11 @@ sepal_length,sepal_width,petal_length,petal_width,setosa,virginica,versicolor
0.416666666667,0.291666666667,0.525423728814,0.375,0.0,0.0,1.0
```
I also split the data set up for training and testing (via an 80/20 split) into `train.csv` and `test.csv` respectively.
我还将用于训练和测试的数据(通过80/20比例分割)分别分为`train.csv`和`test.csv`。
## Putting It All Together
## 全部放在一起
Let's put this neural net to work. To do this, we first need to read our training data, initialize a `neuralNet` value, and call the `train()` method:
让我们把这个神经网络运用起来。为此,我们首先需要读取我们的训练数据,初始化`neuralNet`值,并调用`train()`方法:
```go
package main
......@@ -425,7 +425,7 @@ func main() {
}
```
That gives us a trained neural net. We can then parse the test data into matrices `testInputs` and `testLabels` (I'll spare you these details as they are the same as above), use our `predict()`method to make predictions for the flower species, and then compare the predictions to the actual species. Calculating the predictions and accuracy looks like the following:
这给了我们一个已经训练好的神经网络。然后我们可以将测试数据解析为矩阵`testInputs`和`testLabels`(我将略过这些细节,因为它们与上面相同),使用我们的`predict()`方法来预测花种,以及将预测情况与实际物种进行比较。计算预测和准确性如下所示:
```go
func main() {
......@@ -475,9 +475,9 @@ func main() {
}
```
## Results
## 结果
Compiling and running the full program results in something similar to:
编译并运行完整的程序会产生类似于:
```
$ go build
......@@ -485,11 +485,10 @@ $ ./gophernet
Accuracy = 0.97
```
哇噢!对于我们从头开始的神经网络,97%的准确度并不算太糟糕! 当然,这个数字会因模型中的随机性而有所不同,但它通常表现得非常好。
Woohoo! 97% accuracy isn't too shabby for our little from scratch neural net! Of course this number will vary due to the randomness in the model, but it does generally perform very nicely.
我希望这对你来说是有益的和有趣的。所有的代码和数据都是[可在这里](https://github.com/dwhitena/gophernet),所以自己试试吧! 此外,如果您对Go for ML / AI和Data Science感兴趣,我强烈建议:
I hope this was informative and interesting for you. All of the code and data is [available here](https://github.com/dwhitena/gophernet), so try it out yourself! Also, if you are interested in Go for ML/AI and Data Science in general, I highly recommend:
- Joining [Gophers Slack](https://invite.slack.golangbridge.org/), and participating in the #data-science channel (I'm @dwhitena there)
- Checking out all the great Go ML/AI/data tooling [here](https://github.com/gopherdata/resources/tree/master/tooling)
- Following the [GopherData blog/website](http://gopherdata.io/) for more interesting articles and community information
\ No newline at end of file
- 加入[Gophers Slack](https://invite.slack.golangbridge.org/),并参与#data-science频道(我在那里@dwhitena)
- 检查所有伟大的Go ML / AI /数据工具[这里](https://github.com/gopherdata/resources/tree/master/tooling)
- 关注[GopherData博客/网站](http://gopherdata.io/)获取更多有趣的文章和社区信息
\ No newline at end of file
| 标题 | 简介 |
| ------------------------------------------------------------ | ---- |
| [BUILDING A NEURAL NET FROM SCRATCH IN GO](https://www.datadan.io/building-a-neural-net-from-scratch-in-go/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | |
| [A Quick Introduction to Neural Networks](https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | |
| [Practical Data Science in Python](https://radimrehurek.com/data_science_python/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | |
\ No newline at end of file
| [BUILDING A NEURAL NET FROM SCRATCH IN GO](https://www.datadan.io/building-a-neural-net-from-scratch-in-go/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | 介绍用Go构建一个简单的神经网络 |
| [A Quick Introduction to Neural Networks](https://ujjwalkarn.me/2016/08/09/quick-intro-neural-networks/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | 神经网络的快速入门 |
| [Practical Data Science in Python](https://radimrehurek.com/data_science_python/?from=hackcv&hmsr=hackcv.com&utm_medium=hackcv.com&utm_source=hackcv.com) | 用垃圾邮件分类完整的介绍了建立机器学习模型过程(Python2) |
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册