- Microsoft Cognitive Toolkit (CNTK) 教程
- 首页
- 介绍
- 入门
- CPU 和 GPU
- CNTK - 序列分类
- CNTK - 逻辑回归模型
- CNTK - 神经网络 (NN) 概念
- CNTK - 创建第一个神经网络
- CNTK - 训练神经网络
- CNTK - 内存数据集和大型数据集
- CNTK - 性能测量
- 神经网络分类
- 神经网络二元分类
- CNTK - 神经网络回归
- CNTK - 分类模型
- CNTK - 回归模型
- CNTK - 内存不足的数据集
- CNTK - 监控模型
- CNTK - 卷积神经网络
- CNTK - 循环神经网络
- Microsoft Cognitive Toolkit 资源
- Microsoft Cognitive Toolkit - 快速指南
- Microsoft Cognitive Toolkit - 资源
- Microsoft Cognitive Toolkit - 讨论
CNTK - 序列分类
本章将详细讲解 CNTK 中的序列及其分类。
张量
CNTK 工作的基础概念是张量。基本上,CNTK 的输入、输出以及参数都组织为张量,通常被认为是广义矩阵。每个张量都有一个秩 -
秩为 0 的张量是标量。
秩为 1 的张量是向量。
秩为 2 的张量是矩阵。
这里,这些不同的维度被称为轴。
静态轴和动态轴
顾名思义,静态轴在整个网络的生命周期中长度相同。另一方面,动态轴的长度在不同的实例之间可能会有所不同。事实上,在呈现每个小批量之前,通常不知道它们的长度。
动态轴与静态轴类似,因为它们也定义了张量中包含数字的有意义的组合。
示例
为了更清楚地说明,让我们看看如何在 CNTK 中表示短视频剪辑的小批量。假设视频剪辑的分辨率都是 640 * 480。而且,剪辑也是彩色的,通常用三个通道编码。这意味着我们的迷你批次具有以下内容:
长度分别为 640、480 和 3 的 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
上述程序的详细解释将在接下来的章节中介绍,尤其是在构建循环神经网络时。