在本單元中,您將使用內建的 Amazon SageMaker 神經主題建模 (NTM) 演算法來訓練主題模型。

Amazon SageMaker NTM 是未受監督的學習演算法,用於將文件語料庫整理成主題,這些主題根據其統計分佈包含字詞分組。例如,包含頻繁出現字詞 (例如「自行車」、「汽車」、「火車」、「里程」和「速度」) 的文件可能會共享「運輸」主題。主題建模可用於根據偵測到的主題,對文件進行分類或彙總,或者根據主題相似性來擷取資訊或推薦內容。NTM 從文件中學習的主題被表徵為潛在的表示形式,因為這些主題根據觀察到的語料庫中的字詞分佈來推斷。通常,透過查看主題中包含的最熱門字詞來推斷主題的語義。由於該方法不受監督,因此僅預先指定主題數,而非主題本身。此外,無法保證這些主題與人們可自然對文件分類的方式保持一致。

在以下步驟中,對訓練任務指定 NTM 演算法,為模型指定基礎架構,設定超參數值以調整模型,然後執行模型。然後,將模型部署至由 Amazon SageMaker 管理的端點以進行預測。

完成單元的時間︰20 分鐘


  • 步驟 1.建立並執行訓練任務

    內建的 Amazon SageMaker 演算法作為 Docker 容器存放在 Amazon Elastic Container Registry (Amazon ECR) 中。對於模型訓練,首先需要指定 NTM 容器在 Amazon ECR 中最接近您所在區域的位置。

    在您的筆記本執行個體中,複製以下程式碼並將其貼到新的程式碼儲存格,然後選擇執行

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

    Amazon SageMaker Python SDK 包括 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 SDK 預設會對所有資料通道使用 FullyReplicated 模式。當您使用多個工作程式時,該模式適合用於驗證 (測試) 通道,但對於訓練通道卻不那麼有效。

    在這種情況下,您要讓每個工作程式瀏覽整個資料集的不同部分,以在 epoch 內提供不同的梯度。您可以如下所示,將訓練資料通道的分發指定為 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 Batch Transform

    本實驗室為您提供了兩種選項,您可以選擇適用於您使用案例的最佳方法。

    若選擇 Amazon SageMaker 託管服務,即時 HTTP 端點位於 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 託管服務或批次轉換將模型部署至端點。最後,使用不同的主題數值來探索模型。

在下一個單元中,您將訓練和部署內容推薦模型。