- 微软认知工具包(CNTK)教程
- 家
- 介绍
- 入门
- CPU和GPU
- CNTK-序列分类
- CNTK - 逻辑回归模型
- CNTK - 神经网络 (NN) 概念
- CNTK - 创建第一个神经网络
- CNTK - 训练神经网络
- CNTK - 内存中和大型数据集
- CNTK - 测量性能
- 神经网络分类
- 神经网络二元分类
- CNTK - 神经网络回归
- CNTK - 分类模型
- CNTK - 回归模型
- CNTK - 内存不足的数据集
- CNTK - 监控模型
- CNTK - 卷积神经网络
- CNTK - 循环神经网络
- Microsoft 认知工具包资源
- Microsoft 认知工具包 - 快速指南
- Microsoft 认知工具包 - 资源
- Microsoft 认知工具包 - 讨论
CNTK-序列分类
在本章中,我们将详细了解CNTK中的序列及其分类。
张量
CNTK 工作的概念是张量。基本上,CNTK 输入、输出以及参数被组织为张量,通常被认为是广义矩阵。每个张量都有一个等级-
阶为 0 的张量是标量。
1 阶张量是一个向量。
2 阶张量是矩阵。
这里,这些不同的维度被称为轴。
静态轴和动态轴
顾名思义,静态轴在网络的整个生命周期中具有相同的长度。另一方面,动态轴的长度可能因实例而异。事实上,在呈现每个小批量之前,它们的长度通常是未知的。
动态轴与静态轴类似,因为它们还定义了张量中包含的数字的有意义的分组。
例子
为了更清楚地说明这一点,让我们看看 CNTK 中如何表示小批量的短视频剪辑。假设视频片段的分辨率均为640 * 480。并且片段也是彩色拍摄的,通常采用三通道编码。这进一步意味着我们的小批量具有以下内容 -
3 个静态轴,长度分别为 640、480 和 3。
两个动态轴;视频和小批量轴的长度。
这意味着如果一个小批量有 16 个视频,每个视频长 240 帧,则将表示为16*240*3*640*480张量。
在 CNTK 中处理序列
让我们首先了解长短期记忆网络来理解 CNTK 中的序列。
长短期记忆网络 (LSTM)
长短期记忆 (LSTM) 网络由 Hochreiter 和 Schmidhuber 提出。它解决了让基本循环层长期记住事物的问题。LSTM 的架构如上图所示。正如我们所看到的,它有输入神经元、记忆细胞和输出神经元。为了解决梯度消失问题,长期短期记忆网络使用显式记忆单元(存储先前的值)和以下门 -
忘记门- 顾名思义,它告诉存储单元忘记以前的值。存储单元存储这些值,直到门(即“忘记门”)告诉它忘记它们。
输入门- 顾名思义,它向单元添加新的东西。
输出门- 顾名思义,输出门决定何时将向量从单元传递到下一个隐藏状态。
在 CNTK 中使用序列非常容易。让我们借助以下示例来看看它 -
import sys import os from cntk import Trainer, Axis from cntk.io import MinibatchSource, CTFDeserializer, StreamDef, StreamDefs,\ INFINITELY_REPEAT from cntk.learners import sgd, learning_parameter_schedule_per_sample from cntk import input_variable, cross_entropy_with_softmax, \ classification_error, sequence from cntk.logging import ProgressPrinter from cntk.layers import Sequential, Embedding, Recurrence, LSTM, Dense def create_reader(path, is_training, input_dim, label_dim): return MinibatchSource(CTFDeserializer(path, StreamDefs( features=StreamDef(field='x', shape=input_dim, is_sparse=True), labels=StreamDef(field='y', shape=label_dim, is_sparse=False) )), randomize=is_training, max_sweeps=INFINITELY_REPEAT if is_training else 1) def LSTM_sequence_classifier_net(input, num_output_classes, embedding_dim, LSTM_dim, cell_dim): lstm_classifier = Sequential([Embedding(embedding_dim), Recurrence(LSTM(LSTM_dim, cell_dim)), sequence.last, Dense(num_output_classes)]) return lstm_classifier(input) def train_sequence_classifier(): input_dim = 2000 cell_dim = 25 hidden_dim = 25 embedding_dim = 50 num_output_classes = 5 features = sequence.input_variable(shape=input_dim, is_sparse=True) label = input_variable(num_output_classes) classifier_output = LSTM_sequence_classifier_net( features, num_output_classes, embedding_dim, hidden_dim, cell_dim) ce = cross_entropy_with_softmax(classifier_output, label) pe = classification_error(classifier_output, label) rel_path = ("../../../Tests/EndToEndTests/Text/" + "SequenceClassification/Data/Train.ctf") path = os.path.join(os.path.dirname(os.path.abspath(__file__)), rel_path) reader = create_reader(path, True, input_dim, num_output_classes) input_map = { features: reader.streams.features, label: reader.streams.labels } lr_per_sample = learning_parameter_schedule_per_sample(0.0005) progress_printer = ProgressPrinter(0) trainer = Trainer(classifier_output, (ce, pe), sgd(classifier_output.parameters, lr=lr_per_sample),progress_printer) minibatch_size = 200 for i in range(255): mb = reader.next_minibatch(minibatch_size, input_map=input_map) trainer.train_minibatch(mb) evaluation_average = float(trainer.previous_minibatch_evaluation_average) loss_average = float(trainer.previous_minibatch_loss_average) return evaluation_average, loss_average if __name__ == '__main__': error, _ = train_sequence_classifier() print(" error: %f" % error)
average since average since examples loss last metric last ------------------------------------------------------ 1.61 1.61 0.886 0.886 44 1.61 1.6 0.714 0.629 133 1.6 1.59 0.56 0.448 316 1.57 1.55 0.479 0.41 682 1.53 1.5 0.464 0.449 1379 1.46 1.4 0.453 0.441 2813 1.37 1.28 0.45 0.447 5679 1.3 1.23 0.448 0.447 11365 error: 0.333333
上述程序的详细解释将在下一节中介绍,特别是当我们构建循环神经网络时。