用TensorFlow Estimator实现文本分类

本文探讨了如何使用自定义的 TensorFlow Estimator、嵌入技术及 tf.layers 模块来处理文本分类任务,使用的数据集为 IMDB 评论数据集。通过本文你将学到如何使用 word2vec 词嵌入和迁移学习技术,在有标签数据稀缺时获得更好的模型性能。

本文主要内容如下:

  • 使用 Datasets 装载数据

  • 使用预封装好的评估器(estimator)构建基线

  • 使用词嵌入技术

  • 通过卷积层和 LSTM 层构建定制化的评估器

  • 装载预训练好的词向量

  • 使用 TensorBoard 评估并对比模型

本文选自介绍 TensorFlow 的 Datasets 和 Estimators 模块系列博文的第四部分。读者无需阅读所有之前的内容,如果想重温某些概念,可以查看以下链接:

  • 第一部分重点讨论了预建评估器(https://developers.googleblog.com/2017/09/introducing-tensorflow-datasets.html)

  • 第二部分讨论了特征列(https://developers.googleblog.com/2017/11/introducing-tensorflow-feature-columns.html)

  • 第三部分讲解了如何创建一个自定义的评估器(https://developers.googleblog.com/2017/12/creating-custom-estimators-in-tensorflow.html)。

第四部分的内容将会建立在上述所有章节的基础上,我们将处理一系列不同的自然语言处理(NLP)问题。本文演示了如何使用自定义的 TensorFlow 评估器、嵌入技术及 tf.layers 模块(https://www.tensorflow.org/api_docs/python/tf/layers)来处理文本分类任务。在这篇文章中,我们会学习 word2vec 词嵌入迁移学习技术,在有标签数据稀缺时获得更好的模型性能。

我们将展示相关的代码片段。这里是完整的 Jupyter Notebook 代码,你可以在本地或者 Google Colaboratory 上运行它。清晰的「.py」源文件可以通过以下链接获得:(https://github.com/eisenjulian/nlp_estimator_tutorial/blob/master/nlp_estimators.py)。

有一点需要注意的是,此代码只是为了演示评估器的功能是如何运行的,并没有为了获得最佳的性能进行进一步优化。

本文的任务

我们将使用的数据集是 IMDB 大规模电影评论数据集(http://ai.stanford.edu/~amaas/data/sentiment/),它包含 25,000 篇高度分化的电影评论作为训练数据,另有 25,000 篇作为测试数据。我们将使用这个数据集去训练一个能够预测一条评论是正面还是负面的二分类模型。

举例来说,这里有一条数据集中的负面评论(得到了 222 个赞):

现在我喜欢意大利恐怖电影。越俗越好!然而,这并不是俗气的意大利电影。这是放了一周的有腐烂肉丸的意大利面酱汁。这电影从任何层面看都很业余!没有悬念,没有恐惧感,只有几滴血落在周围提醒你:你实际上在看恐怖电影。

Keras 为导入数据集提供了一个方便的处理程序,这个数据集也可以以一个序列化的 numpy 数组「.npz」文件的形式从这里(https://s3.amazonaws.com/text-datasets/imdb.npz)下载获得。文本分类中的标准做法是限制词汇表的规模以防止数据集变得过于稀疏且维度过高,从而防止过拟合。因此,每条评论由一系列单词索引组成,从「4」(在数据集中出现最频繁的单词「the」)一直到「4999」(代表单词「orange」)。索引「1」代表句子的开头,索引「2」被分配给所有未知的(也被称为「词汇表之外的」,即 OOV)单词。这些索引是通过在一个数据管道中进行预处理之后得到的。这个预处理的步骤包括数据清洗、正则化,并且首先对每个句子进行分词,接着根据频率构建一个字典对每个单词进行索引。

在内存中加载数据后,我们用「0」将每个句子填充到固定的长度进行对齐(这里长度为 200)。这样一来,我们就拥有了两个二维的 25,000*200 的数组分别作为训练和测试数组。

vocab_size = 5000  
sentence_size = 200  
(x_train_variable, y_train), (x_test_variable, y_test) = imdb.load_data(num_words=vocab_size)  
x_train = sequence.pad_sequences(  
    x_train_variable, 
    maxlen=sentence_size, 
    padding='post', 
    value=0)
x_test = sequence.pad_sequences(  
    x_test_variable,
    maxlen=sentence_size, 
    padding='post', 
    value=0)

输入函数

评估器框架使用输入函数将数据管道和模型本身分离。可以使用一些辅助方法来创建他们,无论你的数据是存储在一个「.csv」文件还是「pandas.DataFrame」中,也无论它是否存储在内存中。在我们的例子中,训练集合和测试集合都适用「Dataset.from_tensor_slices」读取数据。

x_len_train = np.array([min(len(x), sentence_size) for x in x_train_variable])  
x\_len\_test = np.array([min(len(x), sentence_size) for x in x_test_variable])

def parser(x, length, y):  
    features = {"x": x, "len": length}
    return features, y

def train_input_fn():  
    dataset = tf.data.Dataset.from_tensor_slices((x_train, x_len_train, y_train))
    dataset = dataset.shuffle(buffer_size=len(x_train_variable))
    dataset = dataset.batch(100)
    dataset = dataset.map(parser)
    dataset = dataset.repeat()
    iterator = dataset.make_one_shot_iterator()
    return iterator.get_next()

def eval_input_fn():  
    dataset = tf.data.Dataset.from_tensor_slices((x_test, x_len_test, y_test))
    dataset = dataset.batch(100)
    dataset = dataset.map(parser)
    iterator = dataset.make_one_shot_iterator()
    return iterator.get_next()

我们通过随机化处理将训练数据打乱,并且没有预定义我们想要训练模型的迭代次数,这里我们仅仅需要对测试数据迭代一次就能进行模型的评估。我们也需要一个额外的「len」关键字去获取原始、未填充的序列的长度,我们将会在后面用到它们。

构建基线

通过尝试一些基础的基线来开始机器学习项目是一种很好的做法。这个基线越简单越好,因为有一个简单、鲁棒的基线至关重要,它可以帮助我们理解通过对模型增添额外的复杂性可以获得多大的性能提升。很有可能,一个简单的解决方案就足以满足我们的要求。

考虑到这一点,让我们首先尝试一个最简单的文本分类模型。这将会是一个稀疏的线性模型,它给每个单词赋予一个权重,并且将所有的结果相加,无论单词顺序如何。由于这个模型并不关心句子中单词的顺序,所以我们通常把它称为词袋方法(BOW)。让我们看看如何通过评估器(Estimator)实现这个模型。

我们从定义用做我们分类器输入的特征列开始。正如我们在第二部分中看到的,「categorical_column_with_identity」是对这个文本输入进行预处理的正确选择。如果我们拿到的是原始文本单词,其它的特征列「feature_columns」可以为我们做很多的预处理工作。我们现在可以使用预制好的「LinearClassifier」评估器了。

column = tf.feature_column.categorical_column_with_identity('x', vocab_size)  
classifier = tf.estimator.LinearClassifier(  
    feature_columns=[column], 
    model_dir=os.path.join(model_dir, 'bow_sparse'))

最终,我们创建了一个简单的函数来训练分类器并且另外创建了一个精确率-召回率曲线。由于我们不打算在这篇博文中取得最优的模型性能,所以我们仅仅对我们的模型训练 25,000 步。

def train_and_evaluate(classifier):  
    classifier.train(input_fn=train_input_fn, steps=25000)
    eval_results = classifier.evaluate(input_fn=eval_input_fn)
    predictions = np.array([p['logistic'][0] for p in classifier.predict(input_fn=eval_input_fn)])
    tf.reset_default_graph() 
    # Add a PR summary in addition to the summaries that the classifier writes
    pr = summary_lib.pr_curve('precision_recall', predictions=predictions, labels=y_test.astype(bool), num_thresholds=21)
    with tf.Session() as sess:
        writer = tf.summary.FileWriter(os.path.join(classifier.model_dir, 'eval'), sess.graph)
        writer.add_summary(sess.run(pr), global_step=0)
        writer.close()

train\_and\_evaluate(classifier) 

选择一个简单模型的好处之一是,它的可解释性要强的多。一个模型越复杂,他就越难被检验,并且更容易像一个黑箱子一样工作。在这个例子中,我们可以从我们模型的上一个检查点装载权重,并且看看哪些单词相应的权重的绝对值最大。结果看起来就像我们所期望的那样。

# Load the tensor with the model weights  
weights = classifier.get_variable_value('linear/linear_model/x/weights').flatten()  
# Find biggest weights in absolute value  
extremes = np.concatenate((sorted_indexes[-8:], sorted_indexes[:8]))  
# word_inverted_index is a dictionary that maps from indexes back to tokens  
extreme_weights = sorted(  
    [(weights[i], word_inverted_index[i - index_offset]) for i in extremes])
# Create plot  
y_pos = np.arange(len(extreme_weights))  
plt.bar(y_pos, [pair[0] for pair in extreme_weights], align='center', alpha=0.5)  
plt.xticks(y_pos, [pair[1] for pair in extreme_weights], rotation=45, ha='right')  
plt.ylabel('Weight')  
plt.title('Most significant tokens')  
plt.show()  

正如我们看到的,像「refreshing」这样的拥有最大的正权值的单词显然与正面的语义相关,而拥有很大的负权重的单词不容置疑地会激发负面的情绪。我们可以对模型做一个简单但强而有力的修改去提升模型的能力,那就是根据单词的 tf-idf 值赋予它们权重

嵌入

增加模型复杂性的下一个步骤是词嵌入。嵌入是稀疏高维数据的密集低维表示。它使得我们的模型能学习到每个单词的更有意义的表示,而不仅仅是一个索引。尽管单一的维度可能没有太大的意义,低维空间(当从一个足够大的语料库中学习时)已经被证实可以捕获诸如时态、复数、性别、关联主题等关系。我们可以通过将我们现有的特征列转换为「embedding_column」来增加词嵌入。模型可见的特征表示是每个单词的词嵌入的平均值(具体对「combiner」的讨论参见本文档:https://www.tensorflow.org/api_docs/python/tf/feature_column/embedding_column)可以将嵌入的特征插入预封装的 DNNClassifier 中。

这里我们要提醒一下那些观察力敏锐的人:一个「embedding_column」仅仅是一个将全连接层应用到稀疏的单词的二值特征向量的一种有效方法,它根据选择的组合器(combiner)乘以一个相应的常数。这样做的一个直接后果是,直接在「LinearClassifier」中使用一个「embedding_column」是没有任何意义的,因为之间没有非线性映射的两个连续的线性层不会给模型增添预测能力,当然,除非词嵌入是预训练好的。

embedding_size = 50  
word\_embedding\_column = tf.feature_column.embedding_column(  
    column, dimension=embedding_size)
classifier = tf.estimator.DNNClassifier(  
    hidden_units=[100],
    feature_columns=[word_embedding_column], 
    model_dir=os.path.join(model_dir, 'bow_embeddings'))
train\_and\_evaluate(classifier)  

我们可以使用 TensorBoard 中的 t-SNE(https://en.wikipedia.org/wiki/T-distributed_stochastic_neighbor_embedding)将我们 50 维的词向量方案可视化为 R^3。我们估计相似的词彼此距离会比较接近。这可以称为一种检验我们的模型权重并且发现意想不到的表现的有效方法。

卷积

在这里,让模型变得更」深」,进一步增添更多的全连接层、并围绕层的规模和训练的函数进行操作,是一种可能的改进方法。然而,通过这样做,我们会增加额外的复杂性,并且忽略句子中的重要结构。实际上,单词并不是存在于真空中的(独立存在),它的意义是由它本身和与其相邻的单词组合而成的。

卷积是一种利用这种结构的方法,这类似于我们如何为图像分类建立显著的像素集合。从直觉上来说,特定的单词序列,或 n-gram,无论在句子中的整体位置如何,通常具有相同的含义。通过卷积操作引入一个结构先验,使我们能够对相邻单词之间的交互建模,从而给我们提供了一个更好的表示这种意义的方法。

下图展示了一个 d×m 维的过滤器矩阵F在每个 3-gram 单词窗口的滑动,去构建一个新的特征映射。此后,池化层通常被用于组合相邻的结果。

来源: Learning to Rank Short Text Pairs with Convolutional Deep Neural Networks,Severyn 等著,[2015]。

让我们看看整个模型的框架。Dropout 层的使用是一种正则化技术,它使模型更不容易发生过拟合

创建一个自定义评估器

正如我们在之前的博文中看到的,「tf.estimator」框架提供了一个训练机器学习模型的高级 API,定义了「train()」,「evaluate()」以及「predict()」操作,能够很方便地处理检查点、加载数据、初始化、服务、构建计算图(graph)和会话(session)。我们有一小部分预制评估器,就像我们之前用到的那些,但是很有可能你需要构建你自己的评估器。

要编写一个自定义的评估器意味着,你需要编写一个「model_fn(features, labels, mode, params)」函数,其返回值为一个 EstimatorSpec。你要做的第一步是将特征映射到我们的嵌入层中:

input_layer = tf.contrib.layers.embed_sequence(  
    features['x'], 
    vocab_size, 
    embedding_size,
    initializer=params['embedding_initializer'])

接着我们使用「tf.layers」按顺序处理每一个输出。

training = (mode == tf.estimator.ModeKeys.TRAIN)  
dropout_emb = tf.layers.dropout(inputs=input_layer,  
                                rate=0.2, 
                                training=training)
conv = tf.layers.conv1d(  
    inputs=dropout_emb,
    filters=32,
    kernel_size=3,
    padding="same",
    activation=tf.nn.relu)
pool = tf.reduce_max(input_tensor=conv, axis=1)  
hidden = tf.layers.dense(inputs=pool, units=250, activation=tf.nn.relu)  
dropout = tf.layers.dropout(inputs=hidden, rate=0.2, training=training)  
logits = tf.layers.dense(inputs=dropout_hidden, units=1)  

最后我们会使用一个模型头「Head」对象去简化「model_fn」最后一个部分的编写。模型头「head」已经知道如何计算预测值、损失、训练操作(train_op)、度量并且导出这些输出,并且可以跨模型重用。这种方法也被用于预制评估器中,并为我们提供一个能够在所有模型上使用的统一的评估函数。我们将使用「binary_classification_head」,这是一个针对单标签二分类模型的头,它使用「sigmoid_cross_entropy_with_logits」作为底层的损失函数

head = tf.contrib.estimator.binary_classification_head()  
optimizer = tf.train.AdamOptimizer()  
def _train_op_fn(loss):  
    tf.summary.scalar('loss', loss)
    return optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())

return head.create_estimator_spec(  
    features=features,
    labels=labels,
    mode=mode,
    logits=logits,
    train_op_fn=_train_op_fn) 

运行这个模型和之前一样简单:

initializer = tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0))  
params = {'embedding_initializer': initializer}  
cnn_classifier = tf.estimator.Estimator(model_fn=model_fn,  
                                        model_dir=os.path.join(model_dir, 'cnn'),
                                        params=params)
train\_and\_evaluate(cnn_classifier)  

LSTM 网络

使用「Estimator」API 和相同的模型头,我们可以创建一个使用长短期记忆(LSTM)神经元而不是卷积神经元的分类器。像这样的递归模型是自然语言处理应用最成功的构建模块。一个 LSTM 按顺序处理整个文档,在其内存中存储当前状态的同时也通过它的神经元对序列进行递归操作。

与 CNN 相比,递归模型的缺点之一是:由于递归的性质,模型会会变得越来越深、越来越复杂,通常会导致训练时间加长,收敛性变差。LSTM(和一般的 RNN)可能会遇到像梯度弥散或梯度爆炸这样的收敛问题,也就是说,只要有足够的调优,他们就能够在许多问题取得目前最好的结果。一般说来,CNN 擅长于特征提取,而 RNN 则擅长依赖整个句子语义的任务,比如问答或机器翻译

每个神经元一次处理一个词嵌入,并且根据依赖于嵌入向量 x_t 和之前的状态 h_t-1 的可微的计算更新它的内部状态。为了更好地理解 LSTM 的工作原理,可以参考 Chris Olah 的博文(https://colah.github.io/posts/2015-08-Understanding-LSTMs/)。

来源:Understanding LSTM Networks by Chris Olah

完整的 LSTM 模型可以表示成下面的简单流程图:

在本文的开头,我们将所有的文档都向上填充到了 200 个单词,这对于构建一个合适的张量是十分必要的。然而,当一个文档包含的单词少于 200 个时,我们不希望 LSTM 继续填充单词的处理,因为这样不会增加信息,还会降低性能。因此,我们还希望在填充之前,为我们的网络提供原始序列长度的信息。接下来,在模型的内部,它会将最后一个状态复制到序列的末尾。我们可以通过在我们的输入函数中添加「len」特征做到这一点。我们现在可以遵循上面的逻辑,用我们的 LSTM 神经元替代卷积池化、平整化层。

lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(100)  
_, final_states = tf.nn.dynamic_rnn(  
        lstm_cell, inputs, sequence_length=features['len'], dtype=tf.float32)
logits = tf.layers.dense(inputs=final_states.h, units=1)  

预训练的向量

我们之前展示过的绝大多数模型都依赖于将词嵌入作为第一层。到目前为止,我们已经随机地初始化了这个嵌入层。然而,许多之前的研究表明,在大量未标记的语料库上使用预训练的嵌入作为初始化是很有帮助的,特别是当只对少量标记示例进行训练时。最流行的预训练词嵌入技术是 word2vec。通过预训练的嵌入来利用未标注数据的知识是迁移学习的一个实例。为此,我们将展示如何在评估器「Estimator」中使用他们。我们将使用来自于另一个流行的模型「GloVe」的预训练向量。

embeddings = {}  
with open('glove.6B.50d.txt', 'r', encoding='utf-8') as f:  
    for line in f:
        values = line.strip().split()
        w = values[0]
        vectors = np.asarray(values[1:], dtype='float32')
        embeddings[w] = vectors

在将向量从文件加载到内存之后,我们将他们使用和我们的词汇表相同的索引存储为一个 numpy 数组。创建的数组的大小为(5000,50)。在每个行索引中,它包含代表和我们的词汇表中索引相同的单词的 50 维向量,

embedding_matrix = np.random.uniform(-1, 1, size=(vocab_size, embedding_size))  
for w, i in word_index.items():  
    v = embeddings.get(w)
    if v is not None and i < vocab_size:
        embedding_matrix[i] = v

最后,我们可以使用一个自定义的初始化函数,并且将结果传给「params」对象,再将这个对象不作任何修改直接用于我们的「cnn_model_fn」。

def my_initializer(shape=None, dtype=tf.float32, partition_info=None):  
    assert dtype is tf.float32
    return embedding_matrix
params = {'embedding_initializer': my_initializer}  
cnn\_pretrained\_classifier = tf.estimator.Estimator(  
    model_fn=cnn_model_fn,
    model_dir=os.path.join(model_dir, 'cnn_pretrained'),
    params=params)
train\_and\_evaluate(cnn_pretrained_classifier) 

运行 TensorBorad

现在,我们可以启动 TensorBoard,将我们训练出来的模型进行比较,观察它们在训练时间和性能方面都有何差异。在终端上运行:

tensorboard --logdir={model_dir} 

我们可以在训练和测试中可视化许多收集到的度量结果,包括每个模型在每一个训练步骤上的损失函数值,以及精确度-召回率曲线。这当然是为我们的用例选择最佳模型的最实用的方法,也是选择分类阈值的最佳方法。

得到预测结果

为了得到在新的句子上的预测结果,我们可以使用「Estimator」实例中的「predict」方法,它能为每个模型加载最新的检查点并且对不可见的示例进行评估。但是在将数据传给模型之前,我们必须进行清理、分词并且将每个单词映射到相应的索引上。具体代码如下:

def text_to_index(sentence):  
    # Remove punctuation characters except for the apostrophe
    translator = str.maketrans('', '', string.punctuation.replace("'", ''))
    tokens = sentence.translate(translator).lower().split()
    return np.array([1] + [word_index[t] + index_offset if t in word_index else 2 for t in tokens])

def print_predictions(sentences, classifier):  
    indexes = [text_to_index(sentence) for sentence in sentences]
    x = sequence.pad_sequences(indexes,
                               maxlen=sentence_size, 
                               padding='post', 
                               value=-1)
    length = np.array([min(len(x), sentence_size) for x in indexes])
    predict_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": x, "len": length}, shuffle=False)
    predictions = [p['logistic'][0] for p in classifier.predict(input_fn=predict_input_fn)]
    print(predictions) 

值得注意的是,检查点本身并不足以作出预测,为了将存储的权重映射到相应的张量(tensor)上,用于构建评估器的实际代码也是必需的。将保存的检查点和创建他们的代码分支关联起来是一种很好的做法。如果有兴趣将模型以一种完全可恢复的方式导出,可以查看「SaveModel」类,这对于通过使用 TensorFlow Serving 提供的 API 构建模型十分有用。

总结

在这篇博文中,我们探索了如何使用评估器(estimator)进行文本分类,特别是针对 IMDB 评论数据集。我们训练并且可视化了我们的词嵌入模型,也加载了预训练的嵌入模型。我们从一个简单的基线开始,成功构建了我们的卷积神经网络和长短期记忆神经网络

更多细节请查看:

  • 能在本地或 Colaboratory 上运行的 Jupyter notebook(https://github.com/eisenjulian/nlp_estimator_tutorial/blob/master/nlp_estimators.ipynb)

  • 本文使用的完整源代码(https://github.com/eisenjulian/nlp_estimator_tutorial/blob/master/nlp_estimators.py)

  • TensorFlow 嵌入技术指南(https://www.tensorflow.org/programmers_guide/embedding)

  • TensorFlow 词向量表示教程(https://www.tensorflow.org/tutorials/word2vec

  • NLTK 的原始文本处理(http://www.nltk.org/book/ch03.html)章节,讲述如何设计语言数据管道

工程文本分类NLPTensorFlow
11
相关数据
池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

Dropout技术

神经网络训练中防止过拟合的一种技术

GloVe技术

Stanford开发的用于词向量表示的一个库/工具

TensorBoard技术

一个信息中心,用于显示在执行一个或多个 TensorFlow 程序期间保存的摘要信息。

词嵌入技术

词嵌入是自然语言处理(NLP)中语言模型与表征学习技术的统称。概念上而言,它是指把一个维数为所有词的数量的高维空间嵌入到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

文本分类技术

该技术可被用于理解、组织和分类结构化或非结构化文本文档。文本挖掘所使用的模型有词袋(BOW)模型、语言模型(ngram)和主题模型。隐马尔可夫模型通常用于词性标注(POS)。其涵盖的主要任务有句法分析、情绪分析和垃圾信息检测。

卷积技术

损失函数技术

在数学优化,统计学,计量经济学,决策理论,机器学习和计算神经科学等领域,损失函数或成本函数是将一或多个变量的一个事件或值映射为可以直观地表示某种与之相关“成本”的实数的函数。

TensorFlow技术

TensorFlow是一个开源软件库,用于各种感知和语言理解任务的机器学习。目前被50个团队用于研究和生产许多Google商业产品,如语音识别、Gmail、Google 相册和搜索,其中许多产品曾使用过其前任软件DistBelief。

张量技术

张量是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数,这些线性关系的基本例子有内积、外积、线性映射以及笛卡儿积。其坐标在 维空间内,有 个分量的一种量,其中每个分量都是坐标的函数,而在坐标变换时,这些分量也依照某些规则作线性变换。称为该张量的秩或阶(与矩阵的秩和阶均无关系)。 在数学里,张量是一种几何实体,或者说广义上的“数量”。张量概念包括标量、矢量和线性算子。张量可以用坐标系统来表达,记作标量的数组,但它是定义为“不依赖于参照系的选择的”。张量在物理和工程学中很重要。例如在扩散张量成像中,表达器官对于水的在各个方向的微分透性的张量可以用来产生大脑的扫描图。工程上最重要的例子可能就是应力张量和应变张量了,它们都是二阶张量,对于一般线性材料他们之间的关系由一个四阶弹性张量来决定。

机器翻译技术

机器翻译(MT)是利用机器的力量「自动将一种自然语言(源语言)的文本翻译成另一种语言(目标语言)」。机器翻译方法通常可分成三大类:基于规则的机器翻译(RBMT)、统计机器翻译(SMT)和神经机器翻译(NMT)。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

映射技术

映射指的是具有某种特殊结构的函数,或泛指类函数思想的范畴论中的态射。 逻辑和图论中也有一些不太常规的用法。其数学定义为:两个非空集合A与B间存在着对应关系f,而且对于A中的每一个元素x,B中总有有唯一的一个元素y与它对应,就这种对应为从A到B的映射,记作f:A→B。其中,y称为元素x在映射f下的象,记作:y=f(x)。x称为y关于映射f的原象*。*集合A中所有元素的象的集合称为映射f的值域,记作f(A)。同样的,在机器学习中,映射就是输入与输出之间的对应关系。

语料库技术

语料库一词在语言学上意指大量的文本,通常经过整理,具有既定格式与标记;事实上,语料库英文 "text corpus" 的涵意即为"body of text"。

逻辑技术

人工智能领域用逻辑来理解智能推理问题;它可以提供用于分析编程语言的技术,也可用作分析、表征知识或编程的工具。目前人们常用的逻辑分支有命题逻辑(Propositional Logic )以及一阶逻辑(FOL)等谓词逻辑。

t分布随机邻嵌入技术

t分布随机邻嵌入(t-SNE)是由Geoffrey Hinton和Laurens van der Maaten 开发的一种降维的机器学习算法。 这是一种非线性降维技术,特别适合将高维数据嵌入到二维或三维空间,然后可以在散点图中将其可视化。 具体来说,它通过二维或三维点对每个高维对象进行建模,使得类似的对象由附近的点建模,不相似的对象由远点建模。

规范化技术

规范化:将属性数据按比例缩放,使之落入一个小的特定区间,如-1.0 到1.0 或0.0 到1.0。 通过将属性数据按比例缩放,使之落入一个小的特定区间,如0.0到1.0,对属性规范化。对于距离度量分类算法,如涉及神经网络或诸如最临近分类和聚类的分类算法,规范化特别有用。如果使用神经网络后向传播算法进行分类挖掘,对于训练样本属性输入值规范化将有助于加快学习阶段的速度。对于基于距离的方法,规范化可以帮助防止具有较大初始值域的属性与具有较小初始值域的属相相比,权重过大。有许多数据规范化的方法,包括最小-最大规范化、z-score规范化和按小数定标规范化。

迁移学习技术

迁移学习是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都是为了解决单个任务而设计的,但是促进迁移学习的算法的开发是机器学习社区持续关注的话题。 迁移学习对人类来说很常见,例如,我们可能会发现学习识别苹果可能有助于识别梨,或者学习弹奏电子琴可能有助于学习钢琴。

过拟合技术

过拟合是指为了得到一致假设而使假设变得过度严格。避免过拟合是分类器设计中的一个核心任务。通常采用增大数据量和测试样本集的方法对分类器性能进行评价。

神经元技术

(人工)神经元是一个类比于生物神经元的数学计算模型,是神经网络的基本组成单元。 对于生物神经网络,每个神经元与其他神经元相连,当它“兴奋”时会向相连的神经元发送化学物质,从而改变这些神经元的电位;神经元的“兴奋”由其电位决定,当它的电位超过一个“阈值”(threshold)便会被激活,亦即“兴奋”。 目前最常见的神经元模型是基于1943年 Warren McCulloch 和 Walter Pitts提出的“M-P 神经元模型”。 在这个模型中,神经元通过带权重的连接接处理来自n个其他神经元的输入信号,其总输入值将与神经元的阈值进行比较,最后通过“激活函数”(activation function)产生神经元的输出。

word2vec技术

Word2vec,为一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。 训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系。该向量为神经网络之隐藏层。 Word2vec依赖skip-grams或连续词袋(CBOW)来建立神经词嵌入。Word2vec为托马斯·米科洛夫(Tomas Mikolov)在Google带领的研究团队创造。该算法渐渐被其他人所分析和解释。

自然语言处理技术

自然语言处理(英语:natural language processing,缩写作 NLP)是人工智能和语言学领域的分支学科。此领域探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的语言。自然语言生成系统把计算机数据转化为自然语言。自然语言理解系统把自然语言转化为计算机程序更易于处理的形式。

优化器技术

优化器基类提供了计算梯度loss的方法,并可以将梯度应用于变量。优化器里包含了实现了经典的优化算法,如梯度下降和Adagrad。 优化器是提供了一个可以使用各种优化算法的接口,可以让用户直接调用一些经典的优化算法,如梯度下降法等等。优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。用户基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer(tensorflow下的优化器包)等等这些算法。

推荐文章
暂无评论
暂无评论~