이 모듈에서는 내장 Amazon SageMaker Neural Topic Model(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 SDK에는 sagemaker.estimator.Estimator 추정기가 포함되어 있습니다. 이 추정기를 사용하면 Amazon VPC가 아니라 원하는 다른 맞춤형 VPC에서 모델을 훈련할 때 필요한 인프라(Amazon EC2 인스턴스 유형, 인스턴스 수, 하이퍼파라미터, 출력 경로, 보안 관련 설정(선택 사항), Virtual Private Cloud(VPC), 보안 그룹 등)를 지정할 수 있습니다. NTM은 GPU 하드웨어의 이점을 완벽하게 활용하며, 일반적으로 CPU보다 GPU에서 훈련 속도가 약 10배 더 빠릅니다. 다중 GPU 또는 다중 인스턴스 훈련을 활용하면, 컴퓨팅 시간에 비해 통신 오버헤드가 낮을 경우 거의 2배로 훈련 속도를 개선할 수 있습니다.

    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 배치 변환을 사용합니다.

    이 실습에서는 사용 사례에 가장 적합한 방식을 선택할 수 있도록 두 가지 옵션을 모두 제공합니다.

    Amazon SageMaker 호스팅 서비스의 경우, 페이로드를 전달하고 추론 결과를 얻을 수 있는 Amazon EC2 인스턴스에 라이브 HTTP 엔드포인트가 상주합니다.

    모델을 배포할 때 sagemaker.estimator.Estimator 객체의 deploy 메서드를 호출할 수 있습니다. deploy 메서드를 호출할 때는 엔드포인트를 호스팅하는 데 사용할 기계 학습 인스턴스의 수와 유형을 지정합니다.

    다음 코드를 복사하여 붙여 넣고 [실행]을 선택하여 모델을 배포합니다.

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

    deploy 메서드는 배포 가능한 모델을 생성하고 Amazon SageMaker 호스팅 서비스 엔드포인트를 구성하며 모델을 호스팅할 엔드포인트를 시작합니다.

    엔드포인트에 대해 추론을 실행하려면 훈련된 모델이 읽을 수 있는 형식으로 입력 페이로드가 직렬화되어야 하고, 추론 출력은 사람이 읽을 수 있는 형식으로 역직렬화되어야 합니다. 다음 코드에서는 CSV 형식의 데이터를 벡터로서 모델에 전달하여 JSON 출력을 생성하는 csv_serializerjson_deserializer를 사용합니다.

    다음 코드를 복사하여 코드 셀에 붙여 넣고 [실행]을 선택합니다.

    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 객체를 생성합니다. 그런 다음 객체의 transform 메서드를 호출하여 변환 작업을 생성합니다. 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-Distributed Stochastic Neighbor Embedding은 원래 고차원 공간의 최근접 이웃 간 거리가 결과로 생성된 낮은 차원 공간에서 유지되도록 하는 비선형 차원 축소 기법입니다. 차원 수를 2로 설정하면 주제 벡터를 2차원 공간에 시각화하는 시각화 도구로 사용할 수 있습니다.

    다음 코드를 복사하여 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 Neural Topic Model(NTM) 알고리즘을 가져왔습니다. 그런 다음 알고리즘별 하이퍼파라미터를 지정하고 아티팩트를 저장할 Amazon S3 버킷을 제공했습니다. 다음으로, Amazon SageMaker 호스팅 서비스 또는 배치 변환을 사용하여 엔드포인트에 모델을 배포했습니다. 마지막으로, 다양한 주제 수 값을 사용하여 모델을 살펴보았습니다.

다음 모듈에서는 콘텐츠 추천 모델을 훈련시키고 배포합니다.