您的位置:首页 > 理论基础 > 计算机网络

机器学习的大局 4000 :用神经网络和TensorFlow分类文本

2017-12-21 21:26 615 查看
本译文自Déborah Mesquitahttps://medium.freecodecamp.org发表的Big
Picture Machine Learning: Classifying Text with Neural Networks and TensorFlow ,文中版权、图像代码等数据均归作者所有。为了本土化,翻译内容略作修改。

原文: https://cloud.tencent.com/developer/article/1007172
开发人员常说,如果你想开始机器学习,你应该先学习算法是如何工作的。但是我的经验表明并不是这样子。

我说你应该首先能够看到大局:应用程序是如何工作的。一旦你了解了这一点,深入探索和研究算法的内部工作变得更加容易。

那么,你如何发展一种直觉,并对机器学习有一个全面的了解呢?一个好的方法是创建机器学习模型。

假设你还不知道如何从头开始创建所有这些算法,那么你就需要使用一个已经为你实现了所有这些算法的库。那个库就是TensorFlow。

在本文中,我们将创建一个机器学习模型来将文本分类。我们将介绍以下主题:
TensorFlow如何工作
什么是机器学习模型
什么是神经网络?
神经网络如何学习
如何处理数据并将其传递给神经网络输入
如何运行模型并获得预测结果

你可能会学到很多新东西,所以我们开始吧!


TensorFlow

TensorFlow是一个开源的机器学习库,最初由Google创建。图书馆的名字帮助我们理解我们如何使用它:张量是多维数组,流过图的节点。


tf.Graph

TensorFlow中的每个计算都被表示为一个数据流图。这个图有两个元素:
一组
tf.Operation
代表计算单位
一组
tf.Tensor
代表数据的单位

要看到所有这些工作,你将创建这个数据流图:

一个计算x + y的图

你会定义
x = [1,3,6]
y
= [1,1,1]
。如图所示
tf.Tensor
,您可以创建常量张量:
import tensorflow as tf
x = tf.constant([1,3,6])
y = tf.constant([1,1,1])


现在您将定义操作单元:
import tensorflow as tf
x = tf.constant([1,3,6])
y = tf.constant([1,1,1])
op = tf.add(x,y)


你有所有的图形元素。现在你需要建立图表:
import tensorflow as tf
my_graph = tf.Graph()
with my_graph.as_default():
x = tf.constant([1,3,6])
y = tf.constant([1,1,1])
op = tf.add(x,y)


这就是TensorFlow工作流程的工作原理:您首先创建一个图表,然后才能进行计算(真正“运行”具有操作的图形节点)。要运行图形,你需要创建一个
tf.Session


tf.Session

一个
tf.Session
对象封装了
Operation
执行对象的环境,并对
Tensor
对象进行了评估(来自文档)。为此,我们需要定义在会话中使用哪个图表:
import tensorflow as tf
my_graph = tf.Graph()
用tf.Session(graph = my_graph)作为sess:
x = tf.constant([1,3,6])
y = tf.constant([1,1,1])
op = tf.add(x,y)


要执行操作,您将使用该方法
tf.Session.run()
。该方法执行TensorFlow计算的一个“步骤”,通过运行必要的图片段来执行每个
Operation对
象并评估每个
Tensor
传入的参数
fetches
。在你的情况下,你将运行总和操作的一个步骤:
import tensorflow as tf
my_graph = tf.Graph()
用tf.Session(graph = my_graph)作为sess:
x = tf.constant([1,3,6])
y = tf.constant([1,1,1])
op = tf.add(x,y)
result = sess.run(fetches = op)
print(result)
>>> [2 4 7]


预测模型

现在您已经知道TensorFlow是如何工作的,您必须学习如何创建一个预测模型。简而言之,

机器学习算法 +
数据 = 预测模型

构建模型的过程如下所示:

创建预测模型的过程

正如您所看到的,该模型由一个机器学习算法“训练”数据组成。当你有这个模型时,你会得到这样的结果:

预测工作流程

您要创建的模型的目标是按类别对文本进行分类,我们定义:

输入:文本,结果:类别

我们有一个包含所有文本的训练数据集(每个文本都有一个标签,表明它属于哪个类别)。在机器学习中,这种类型的任务被命名为监督学习。

“我们知道正确的答案。该算法迭代地对训练数据进行预测,并由教师纠正。“ -

 Jason Brownlee

你会把数据分类到不同的类别,所以它也是一个分类任务。

为了创建模型,我们将使用神经网络。


神经网络

神经网络是一种计算模型(一种用数学语言和数学概念来描述系统的方法)。这些系统是自学和训练的,而不是明确的编程。

神经网络受到我们中枢神经系统的启发。他们连接了与我们的神经元相似的节点。

一个神经网络

感知器是第一个神经网络算法。这篇文章很好地解释了一个感知器的内部工作(“人造神经元内部”动画很棒)。

为了理解神经网络是如何工作的,我们实际上将用TensorFlow建立一个神经网络体系结构。在这个例子中,这个架构被Aymeric
Damien使用。


神经网络架构

神经网络将有2个隐藏层(你必须选择网络将有多少隐藏层,是架构设计的一部分)。每个隐藏层的工作是将输入转换成输出层可以使用的东西

隐藏图层1

输入层和第一个隐藏层

你还需要定义第一个隐藏层有多少个节点。这些节点也被称为特征或神经元,在上面的图像中,它们由每个圆圈表示。

在输入层中,每个节点都对应于数据集中的一个单词(我们将在稍后看到它是如何工作的)。

如所解释这里,每个节点(神经元)被乘以权重。每个节点都有一个权重值,在训练阶段,神经网络调整这些值以产生正确的输出(等待,我们将在一分钟内了解更多)。

除了将每个输入节点乘以权重之外,网络还增加了一个偏差(神经网络中的偏差作用)。

在通过权重乘以输入并将这些值与偏差相加后,在您的体系结构中,数据也通过激活函数传递。这个激活函数定义了每个节点的最终输出。比喻:假设每个节点都是一个灯,激活功能告诉灯是否点亮。

许多类型的激活功能。您将使用整流线性单元(ReLu)。这个函数是这样定义的:

f(x) =
max(0,x) 输出是x或0(零),以较大者为准

例如:如果x
= -1,则f(x)= 0________________________(零); 如果x
= 0.7,则________________________f(x)= 0.7。

隐藏的图层2

第二个隐藏层确实是第一个隐藏层所做的,但是现在第二个隐藏层的输入是第一个隐藏层的输出。

第一和第二隐藏层

输出层

我们终于到了最后一层,即输出层。您将使用单热编码来获取此图层的结果。在这个编码中,只有一位的值是1,其他的都是零值。例如,如果我们想编码三个类别(运动,空间和计算机图形):
+-------------------+-----------+
|    category       |   value   |
+-------------------|-----------+
|      sports       |    001    |
|      space        |    010    |
| computer graphics |    100    |
|-------------------|-----------|


所以输出节点的数量就是输入数据集的类数。

输出层的值也乘以权重,我们也加上偏差,但现在激活函数是不同的。

你想用一个类别来标记每个文本,而这些类别是相互排斥的(一个文本不能同时属于两个类别)。考虑到这一点,而不是使用ReLu激活功能,您将使用Softmax功能。该函数将每个单位的输出转换为0和1之间的值,并确保所有单位的总和等于1.这样,输出将告诉我们每个类别的每个文本的概率。
| 1.2 0.46 |
| 0.9  - > [softmax]  - > 0.34 |
| 0.4 0.20 |


现在你有神经网络的数据流图。将我们目前看到的所有内容翻译成代码,结果是:
# Network Parameters
n_hidden_1 = 10        # 第一层的功能
n_hidden_2 = 5         # 第二层的功能
n_input = total_words  # 词汇中的单词
n_classes = 3          # 分类:图形,空间和棒球
def multilayer_perceptron(input_tensor, weights, biases):
layer_1_multiplication = tf.matmul(input_tensor, weights['h1'])
layer_1_addition = tf.add(layer_1_multiplication, biases['b1'])
layer_1_activation = tf.nn.relu(layer_1_addition)
#RELU激活的隐藏层
layer_2_multiplication = tf.matmul(layer_1_activation, weights['h2'])
layer_2_addition = tf.add(layer_2_multiplication, biases['b2'])
layer_2_activation = tf.nn.relu(layer_2_addition)
#线性激活的输出层
out_layer_multiplication = tf.matmul(layer_2_activation, weights['out'])
out_layer_addition = out_layer_multiplication + biases['out']
return out_layer_addition


(稍后我们将讨论输出层激活函数的代码。)


神经网络如何学习

正如我们前面看到的那样,在训练网络的同时更新了权重值。现在我们将在TensorFlow环境中看到这是如何发生的。


tf.Variable

权重和偏差存储在变量(
tf.Variable
)中。这些变量通过调用来维护图形中的状态
run()
。在机器学习中,我们通常通过正态分布开始权重和偏差值。
weights = {
'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))
}
biases = {
'b1': tf.Variable(tf.random_normal([n_hidden_1])),
'b2': tf.Variable(tf.random_normal([n_hidden_2])),
'out': tf.Variable(tf.random_normal([n_classes]))
}


当我们第一次运行网络时(也就是说,权值是正态分布定义的):
input values: x
weights: w
bias: b
output values: z
expected values: expected


要知道网络是否正在学习,您需要将输出值(z)与期望值(预期)进行比较。我们如何计算这种差异(损失)?有很多方法可以做到这一点。因为我们正在处理分类任务,所以损失的最好方法就是交叉熵误差

詹姆斯·D·麦卡弗里(James
D. McCaffrey)写一篇关于为什么这是这种任务最好的方法的精彩解释

使用TensorFlow,您将使用
tf.nn.softmax_cross_entropy_with_logits()
方法(这里是softmax激活函数)计算交叉熵误差并计算平均误差(
tf.reduce_mean()
)。
#构建模型
prediction = multilayer_perceptron(input_tensor, weights, biases)
#定义损失
entropy_loss = tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor)
loss = tf.reduce_mean(entropy_loss)


你想找到权重和偏差的最佳值,以最大限度地减少输出误差(我们得到的价值和正确的价值之间的差异)。要做到这一点,你将使用渐变下降法。更具体地说,你将使用随机梯度下降

梯度下降。来源:https//sebastianraschka.com/faq/docs/closed-form-vs-gd.html

还有很多算法来计算梯度下降,你将使用自适应矩估计(亚当)。要在TensorFlow中使用此算法,您需要传递learning_rate值,该值确定值的增量步骤以找到最佳权重值。

该方法是一个语法糖做两件事情:
tf.train.AdamOptimizer(learning_rate).minimize(loss)

compute_gradients(损失,<变量列表>)
apply_gradients(<变量列表>)

该方法更新所有的
tf.Variables
新值,所以我们不需要传递变量列表。现在你有了训练网络的代码:
learning_rate = 0.001
#构建模型 prediction = multilayer_perceptron(input_tensor, weights, biases) #定义损失 entropy_loss = tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor) loss = tf.reduce_mean(entropy_loss)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)


数据操作

您将使用的数据集有许多英文文本,我们需要操纵这些数据将其传递到神经网络。要做到这一点,你会做两件事情:
为每个单词创建一个索引
为每个文本创建一个矩阵,如果文本中有一个单词,则值为1,否则为0

让我们看看代码来理解这个过程:
import numpy as np    #numpy 是一个从集合导入计算器的科学计算包
from collections import Counter
vocab = Counter()
text = "Hi from Brazil"
#获取所有单词
for word in text.split(' '):
vocab[word]+=1

#将单词转换为索引
def get_word_2_index(vocab):
word2index = {}
for i,word in enumerate(vocab):
word2index[word] = i

return word2index
#Now we have an index
word2index = get_word_2_index(vocab)
total_words = len(vocab)
#This is how we create a numpy array (our matrix)
matrix = np.zeros((total_words),dtype=float)
#Now we fill the values
for word in text.split():
matrix[word2index[word]] += 1
print(matrix)
>>> [ 1.  1.  1.]


在上面的例子中,文字是“Hi from Brazil”,矩阵是1.1.1。如果文本只是“Hi”呢?
matrix = np.zeros((total_words),dtype=float)
text = "Hi"
for word in text.split():
matrix[word2index[word.lower()]] += 1
print(matrix)
>>> [ 1.  0.  0.]


您将与标签(文本的类别)相同,但是现在您将使用单一编码:
y = np.zeros((3),dtype=float)
if category == 0:
y[0] = 1.        # [ 1.  0.  0.]
elif category == 1:
y[1] = 1.        # [ 0.  1.  0.]
else:
y[2] = 1.       # [ 0.  0.  1.]


运行图形并获得结果

现在是最好的部分:从模型中获得结果。首先让我们仔细看看输入数据集。


数据集

您将使用20个新闻组,这是一个包含20个主题的18.000个帖子的数据集。加载这个数据集,你将使用scikit学习库。我们将只使用3个类别:comp.graphics,sci.space和rec.sport.baseball。scikit学习有两个子集:一个用于训练,一个用于测试。建议您不要看测试数据,因为这会在创建模型时影响您的选择。你不想创建一个模型来预测这个特定的测试数据,你想创建一个具有良好泛化的模型。

这是你将如何加载数据集:
from sklearn.datasets import fetch_20newsgroups
categories = ["comp.graphics","sci.space","rec.sport.baseball"]
newsgroups_train = fetch_20newsgroups(subset='train', categories=categories)
newsgroups_test = fetch_20newsgroups(subset='test', categories=categories)


培训模型

神经网络术语中,所有训练样例中的一个历元=一个正向传递(获得输出值)和一个反向传递(更新权重)。

记住这个
tf.Session.run()
方法吗?让我们仔细看看它:

tf.Session.run(fetches, feed_dict=None, options=None, run_metadata=None)


在本文开头的数据流图中,您使用了sum操作,但是我们也可以传递一个事件列表来运行。在这个神经网络运行中,您将通过两件事情:损失计算和优化步骤。

feed_dict
参数是我们传递数据每次运行一步。为了传递这些数据,我们需要定义
tf.placeholders
(提供
feed_dict
)。

正如TensorFlow文档所述:

“占位符的存在完全是为了作为Feed的目标。它没有被初始化,也没有数据。“ - 

来源

所以你会这样定义你的占位符:

“如果使用占位符来提供输入,则可以通过使用tf.placeholder(...,shape = [
None,...])创建占位符来指定变量批量维度__。形状的None元素对应于可变尺寸的维度。“ - 

来源

在测试模型时,我们会用更大的批量来填充字典,这就是为什么您需要定义一个变量批量维度的原因。

get_batches()
功能为我们提供了批量大小的文本数量。现在我们可以运行模型:
training_epochs = 10
# 启动图表
with tf.Session() as sess:
sess.run(init) #inits the variables (normal distribution, remember?)
# Training cycle
for epoch in range(training_epochs):
avg_cost = 0.
total_batch = int(len(newsgroups_train.data)/batch_size)
# Loop over all batches
for i in range(total_batch):
batch_x,batch_y = get_batch(newsgroups_train,i,batch_size)
# Run optimization op (backprop) and cost op (to get loss value)
c,_ = sess.run([loss,optimizer], feed_dict={input_tensor: batch_x, output_tensor:batch_y})


现在你已经训练了模型。为了测试它,你还需要创建图形元素。我们将测量模型的准确性,所以您需要得到预测值的索引和正确值的索引(因为我们使用的是单热编码),检查它们是否相等,并计算均值所有的测试数据集:
# 测试模型
index_prediction = tf.argmax(prediction, 1)
index_correct = tf.argmax(output_tensor, 1)
correct_prediction = tf.equal(index_prediction, index_correct)
# 计算准确性
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
total_test_data = len(newsgroups_test.target)
batch_x_test,batch_y_test = get_batch(newsgroups_test,0,total_test_data)
print("Accuracy:", accuracy.eval({input_tensor: batch_x_test, output_tensor: batch_y_test}))
>>> Epoch: 0001 loss= 1133.908114347
Epoch: 0002 loss= 329.093700409
Epoch: 0003 loss= 111.876660109
Epoch: 0004 loss= 72.552971845
Epoch: 0005 loss= 16.673050320
Epoch: 0006 loss= 16.481995190
Epoch: 0007 loss= 4.848220565
Epoch: 0008 loss= 0.759822878
Epoch: 0009 loss= 0.000000000
Epoch: 0010 loss= 0.079848485
Optimization Finished!
Accuracy: 0.75


而就是这样!您使用神经网络创建了一个模型来将文本分类。恭喜!

您可以在这里看到带有最终代码 的笔记本。

提示:修改我们定义的值以查看更改如何影响训练时间和模型精度。

原文链接:https://medium.freecodecamp.org/big-picture-machine-learning-classifying-text-with-neural-networks-and-tensorflow-d94036ac2274

原文作者:Déborah Mesquita
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: