在本模块中,您将使用内置的 Amazon SageMaker 神经主题模型 (NTM) 算法训练主题模型。

Amazon SageMaker NTM 是一个无监督学习算法,可用于根据统计分布将文档语料库组织到包含词组的主题中。包含“自行车”、“汽车”、“火车”、“英里数”和“速度”等频繁出现的单词的文档可能会共享有关“交通”的主题。主题建模可用于根据检测到的主题分类或总结文档,或根据主题相似性检索信息或推荐内容。由于主题是从语料库中的观察单词分布中推断出的,NTM 学习的文档中的主题被描述为潜在表示。主题的语义通常通过检查其中包含的排名靠前的单词推断出。由于方法无监督,只会预先指定主题的数量而非主题本身。此外,不保证这些主题与人类对文档的自然分类方式一致。

在下面的步骤中,您将为训练作业指定 NTM 算法,为模型指定基础设施,设置超参数值来调整模型及运行模型。然后,您可以将模型部署到 Amazon SageMaker 管理的终端节点中,以进行预测。

完成模块所需时间:20 分钟


  • 步骤 1.创建并运行训练作业

    内置的 Amazon SageMaker 算法在 Amazon Elastic Container Registry (Amazon ECR) 中被存储为 Docker 容器。对于模型训练,您首先需要在 Amazon ECR 中指定最靠近您所在区域的 NTM 容器位置。

    在您的笔记本实例中,将以下代码复制并粘贴到新的代码单元格中,然后选择运行

    import boto3
    from sagemaker.amazon.amazon_estimator import get_image_uri
    container = get_image_uri(boto3.Session().region_name, 'ntm')

    Amazon SageMaker Python 开发工具包包含 sagemaker.estimator.Estimator 估算器。如果我们在自己选择的自定义 VPC 而不是 Amazon VPC 中训练模型,此估算器可使您指定可能相关的基础设施(Amazon EC2 实例类型、实例数量、超参数、输出路径,以及可选的任何与安全相关的设置 (Virtual Private Cloud (VPC))、安全组等)。NTM 将充分利用 GPU 硬件,通常情况下,在 GPU 上的训练速度比在 CPU 上快一个数量级。如果通信开销与计算时间相比较低,多 GPU 或多实例训练将进一步提高训练速度,大致呈线性关系。

    要创建 sagemaker.estimator.Estimator 类的实例,将以下代码复制并粘贴到新的代码单元格中,然后选择运行

    sess = sagemaker.Session()
    ntm = sagemaker.estimator.Estimator(container,
                                        role, 
                                        train_instance_count=2, 
                                        train_instance_type='ml.c4.xlarge',
                                        output_path=output_path,
                                        sagemaker_session=sess)
    

    现在,您可以为主题模型设置超参数:

    ntm.set_hyperparameters(num_topics=NUM_TOPICS, feature_dim=vocab_size, mini_batch_size=128, 
                            epochs=100, num_patience_epochs=5, tolerance=0.001)
    

    SageMaker 为数据通道提供两个模式:

    • FullyReplicated:将所有数据文件复制给所有工作线程。
    • ShardedByS3Key:将数据文件分区到不同的工作线程,也就是说,每个工作线程收到完整数据集的不同部分。

    编写时,Amazon SageMaker Python 开发工具包默认将 FullyReplicated 模式用于所有数据通道。此模式适用于验证(测试)通道,但当您使用多个工作线程时,它没有用于训练通道时的效率高。

    在此案例中,您希望每个工作线程都遍历完整数据集的不同部分,以提供纪元格式内的不同梯度。您将训练数据通道的分布指定为 ShardedByS3Key,如下所示。

    from sagemaker.session import s3_input
    s3_train = s3_input(s3_train_data, distribution='ShardedByS3Key') 
    ntm.fit({'train': s3_train, 'test': s3_val_data})
    

    您应该能在终端中看到以下输出:

    Completed - Training job completed

    成功! 您已使用 NTM 算法对主题模型进行了训练。

    在下一步中,您会将模型部署到 Amazon Sagemaker 托管服务中。

  • 第 2 步:部署主题模型

    经过训练的模型本身只是一个 tar 文件,由模型权重组成,本身没有任何作用。要想让模型有用并获取预测,您需要部署模型。

    在 Amazon SageMaker 中部署模型的方式有两种,具体取决于您希望如何生成推理:

    • 要一次获得一个推理,请使用 Amazon SageMaker 托管服务设置永久性终端节点。
    • 要获得整个数据集的推理,请使用 Amazon SageMaker 批量转换

    此实验室同时为您提供两个选项,供您选择最适合您的使用案例的方法。

    在使用 Amazon SageMaker 托管服务的情况下,活动的 HTTPs 终端节点位于 Amazon EC2 实例上,您可以将有效负载传递到其中并获得推理。

    当您部署模型时,您将调用 sagemaker.estimator.Estimator 对象的部署方法。当您调用部署方法时,您将指定希望用于托管终端节点的 ML 实例的数量和类型。

    复制并粘贴以下代码,然后选择运行以部署模型。

    ntm_predictor = ntm.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')

    部署方法可创建可部署的模型、配置 Amazon SageMaker 托管服务终端节点并启动终端节点来托管模型。

    要对终端节点运行推理,您需要确保输入有效负载以训练模型可以读取的格式进行序列化,且推理输出已反序列化为人类可读的格式。在下面的代码中,您使用 csv_serializerjson_deserializer 将 CSV 格式的数据(作为向量)传递到模型中以生成 JSON 输出。

    将以下代码复制并粘贴到代码单元格中,然后选择运行

    from sagemaker.predictor import csv_serializer, json_deserializer
    
    ntm_predictor.content_type = 'text/csv'
    ntm_predictor.serializer = csv_serializer
    ntm_predictor.deserializer = json_deserializer

    接下来,提取训练数据的主题向量,以稍后用于 K-NN 模型中。

    将以下代码复制并粘贴到新的代码单元格中,然后选择运行

    predictions = []
    for item in np.array(vectors.todense()):
        np.shape(item)
        results = ntm_predictor.predict(item)
        predictions.append(np.array([prediction['topic_weights'] for prediction in results['predictions']]))
        
    predictions = np.array([np.ndarray.flatten(x) for x in predictions])
    topicvec = train_labels[newidx]
    topicnames = [categories[x] for x in topicvec]
    

    成功! 现在,您可以探索模型输出。

    使用批量转换,您一次可以对一批数据运行推理。Amazon SageMaker 会创建必要的计算基础设施,并在批量作业完成时将其拆除。

    批量转换代码将从主题模型中创建一个 sagemaker.transformer.Transformer 对象。然后,它将调用该对象的转换方法来创建转换作业。当您创建 sagemaker.transformer.Transformer 对象时,您可以指定将用于执行批量转换作业的实例数量和类型,您希望将推理存储到 Amazon S3 中的位置。 

    要将推理作业批量作业运行,请将以下代码复制并粘贴到代码单元格中,然后选择运行

    np.savetxt('trainvectors.csv',
               vectors.todense(),
               delimiter=',',
               fmt='%i')
    batch_prefix = '20newsgroups/batch'
    
    train_s3 = sess.upload_data('trainvectors.csv', 
                                bucket=bucket, 
                                key_prefix='{}/train'.format(batch_prefix))
    print(train_s3)
    batch_output_path = 's3://{}/{}/test'.format(bucket, batch_prefix)
    
    ntm_transformer = ntm.transformer(instance_count=1,
                                      instance_type ='ml.m4.xlarge',
                                      output_path=batch_output_path
                                     )
    ntm_transformer.transform(train_s3, content_type='text/csv', split_type='Line')
    ntm_transformer.wait()
    

    当转换作业完成后,您可以使用以下代码将输出下载回您的本地笔记本实例进行检查。

    !aws s3 cp --recursive $ntm_transformer.output_path ./
    !head -c 5000 trainvectors.csv.out

    成功! 模型已将每个文档传送到 NUM_TOPICS 维度训练向量中。您现在可以探索主题模型。

  • 第 3 步:探索主题模型

    探索模型输出的一个方法是可视化使用 T-SNE 图生成的主题向量。T-SNE(或 t 分布随机邻近嵌入)是用于降维的一种非线性方法,目的是确保原高维空间中最近的邻居之前的距离保留在产生的较低维度的空间中。通过将维数设置为 2,可以将其用作可视化工具,以在 2D 空间中可视化主题向量。

    在您的 Jupyter 笔记本中,将以下代码复制并粘贴到新的代码单元格中,然后选择运行

    from sklearn.manifold import TSNE
    time_start = time.time()
    tsne = TSNE(n_components=2, verbose=1, perplexity=50, n_iter=5000)
    tsne_results = tsne.fit_transform(predictions)
    print('t-SNE done! Time elapsed: {} seconds'.format(time.time()-time_start))
    tsnedf = pd.DataFrame()
    tsnedf['tsne-2d-one'] = tsne_results[:,0]
    tsnedf['tsne-2d-two'] = tsne_results[:,1]
    tsnedf['Topic']=topicnames
    plt.figure(figsize=(25,25))
    sns.lmplot(
        x="tsne-2d-one", y="tsne-2d-two",
        hue='Topic',
        palette=sns.color_palette("hls", NUM_TOPICS),
        data=tsnedf,
        legend="full",
        fit_reg=False
    )
    plt.axis('Off')
    plt.show()

    TSNE 图应显示一些大型主题集群,如下面的图像。这样的图可用于提取数据集中的不同主题集群数量。目前,NUM_TOPICS 被设置为 30,但 TSNE 图中似乎有很多互相接近的主题,可能会合并到一个主题中。最后,由于主题建模在很大程度上是一个无监督的学习问题,您必须使用诸如此类的可视化工具来确定将数据集分区到的适当主题数量。

    尝试使用不同的主题数量进行实验,以看看可视化是什么样子。


在本模块中,您从 Amazon ECR 中检索了 Amazon SageMaker 神经主题模型 (NTM) 算法。然后,您指定了算法特定的超参数,并提供了 Amazon S3 存储桶进行构件存储。接下来,您使用 Amazon SageMaker 托管服务或批量转换将模型部署到终端节点中。最后,您使用不同的主题数量值探索模型。

在下一个模块中,您将训练并部署内容推荐模型。