Main Content

深層学習を使用したメモリ外のテキスト データの分類

この例では、変換されたデータストアを使用して深層学習ネットワークでメモリ外のテキスト データを分類する方法を説明します。

変換されたデータストアは、基となるデータストアから読み取ったデータを変換または処理します。変換されたデータストアは、深層学習アプリケーションの学習データセット、検証データセット、テスト データセット、および予測データセットのソースとして使用できます。変換されたデータストアを使用して、メモリ外のデータを読み取るか、データのバッチを読み取る際に特定の前処理演算を実行します。

ネットワークの学習時に、入力データのパディング、切り捨て、または分割が行われ、同じ長さのシーケンスのミニバッチが作成されます。関数 trainingOptions には、入力シーケンスのパディングと切り捨てを自動的に行うオプションが用意されていますが、これらのオプションは、単語ベクトルのシーケンスにはあまり適していません。さらに、この関数はカスタム データストアにあるデータのパディングをサポートしていません。代わりに、シーケンスのパディングと切り捨てを手動で行わなければなりません。単語ベクトルのシーケンスの "左パディング" と切り捨てを行うと、学習が改善される可能性があります。

Classify Text Data Using Deep Learning (Text Analytics Toolbox)の例では、すべてのドキュメントが同じ長さになるように切り捨てとパディングを手動で行っています。このプロセスでは、非常に短いドキュメントに多数のパディングが追加され、非常に長いドキュメントから多数のデータが破棄されます。

別の方法として、大量のパディングの追加や大量のデータの破棄を避けるため、ミニバッチをネットワークに入力する変換されたデータストアを作成します。この例で作成されたデータストアは、ドキュメントのミニバッチをシーケンスまたは単語インデックスに変換し、ミニバッチ内にある最長のドキュメントの長さになるように各ミニバッチの左パディングを行います。

事前学習済みの単語埋め込みの読み込み

データストアでは、ドキュメントをベクトルのシーケンスに変換するために単語埋め込みが必要です。fastTextWordEmbedding を使用して、事前学習済みの単語埋め込みを読み込みます。この関数には、Text Analytics Toolbox™ Model for fastText English 16 Billion Token Word Embedding サポート パッケージが必要です。このサポート パッケージがインストールされていない場合、関数によってダウンロード用リンクが表示されます。

emb = fastTextWordEmbedding;

データの読み込み

factoryReports.csv 内のデータから表形式のテキスト データストアを作成します。"Description" 列および "Category" 列からのみデータを読み取るよう指定します。

filenameTrain = "factoryReports.csv";
textName = "Description";
labelName = "Category";
ttdsTrain = tabularTextDatastore(filenameTrain,'SelectedVariableNames',[textName labelName]);

データストアのプレビューを表示します。

preview(ttdsTrain)
ans=8×2 table
                                  Description                                         Category       
    _______________________________________________________________________    ______________________

    {'Items are occasionally getting stuck in the scanner spools.'        }    {'Mechanical Failure'}
    {'Loud rattling and banging sounds are coming from assembler pistons.'}    {'Mechanical Failure'}
    {'There are cuts to the power when starting the plant.'               }    {'Electronic Failure'}
    {'Fried capacitors in the assembler.'                                 }    {'Electronic Failure'}
    {'Mixer tripped the fuses.'                                           }    {'Electronic Failure'}
    {'Burst pipe in the constructing agent is spraying coolant.'          }    {'Leak'              }
    {'A fuse is blown in the mixer.'                                      }    {'Electronic Failure'}
    {'Things continue to tumble off of the belt.'                         }    {'Mechanical Failure'}

データストアの変換

データストアから読み取ったデータを予測子と応答を含む表に変換する、カスタム変換関数を作成します。関数 transformText は、tabularTextDatastore オブジェクトから読み取ったデータを取り、予測子と応答の表を返します。予測子は CS 列の単語ベクトルの配列で、単語埋め込み emb により与えられます。ここで、C は埋め込み次元、S はシーケンス長です。応答は、クラスのカテゴリカル ラベルです。

クラス名を取得するために、この例の最後にリストされている関数 readLabels を使用して学習データからラベルを読み取り、一意なクラス名を検索します。

labels = readLabels(ttdsTrain,labelName);
classNames = unique(labels);
numObservations = numel(labels);

表形式のテキスト データストアは 1 回の読み取りで複数のデータ行を読み取れるため、この変換関数でデータのミニバッチ全体を処理できます。変換関数によってデータのミニバッチ全体が確実に処理されるように、表形式のテキスト データストアの読み取りサイズを学習で使用するミニバッチ サイズに設定します。

miniBatchSize = 64;
ttdsTrain.ReadSize = miniBatchSize;

表形式のテキスト データを学習用のシーケンスに変換するために、関数 transform を使用してデータストアを変換します。

tdsTrain = transform(ttdsTrain, @(data) transformText(data,emb,classNames))
tdsTrain = 
  TransformedDatastore with properties:

       UnderlyingDatastore: [1×1 matlab.io.datastore.TabularTextDatastore]
    SupportedOutputFormats: ["txt"    "csv"    "xlsx"    "xls"    "parquet"    "parq"    "png"    "jpg"    "jpeg"    "tif"    "tiff"    "wav"    "flac"    "ogg"    "mp4"    "m4a"]
                Transforms: {@(data)transformText(data,emb,classNames)}
               IncludeInfo: 0

変換されたデータストアをプレビューします。予測子は CS 列の配列です。ここで、S はシーケンス長、C は特徴 (埋め込み次元) の数です。応答はカテゴリカル ラベルです。

preview(tdsTrain)
ans=8×2 table
      predictors           responses     
    _______________    __________________

    {300×11 single}    Mechanical Failure
    {300×11 single}    Mechanical Failure
    {300×11 single}    Electronic Failure
    {300×11 single}    Electronic Failure
    {300×11 single}    Electronic Failure
    {300×11 single}    Leak              
    {300×11 single}    Electronic Failure
    {300×11 single}    Mechanical Failure

LSTM ネットワークの作成と学習

LSTM ネットワーク アーキテクチャを定義します。シーケンス データをネットワークに入力するために、シーケンス入力層を含め、入力サイズを埋め込み次元に設定します。次に、180 個の隠れユニットを持つ LSTM 層を含めます。sequence-to-label 分類問題に LSTM 層を使用するには、出力モードを 'last' に設定します。最後に、出力サイズがクラスの数に等しい全結合層や、ソフトマックス層と分類層を追加します。

numFeatures = emb.Dimension;
numHiddenUnits = 180;
numClasses = numel(classNames);
layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits,'OutputMode','last')
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];

学習オプションを指定します。ソルバーを 'adam' に設定し、勾配しきい値を 2 に設定します。データストアはシャッフルをサポートしていないため、'Shuffle''never' に設定します。エポックごとに 1 回ネットワークを検証します。学習の進行状況を監視するには、'Plots' オプションを 'training-progress' に設定します。詳細出力を表示しないようにするには、'Verbose'false に設定します。

既定では、使用可能な GPU がある場合、trainNetwork は GPU を使用します。実行環境を手動で指定するには、trainingOptions の名前と値のペアの引数 'ExecutionEnvironment' を使用します。CPU での学習にかかる時間は、GPU での学習よりも大幅に長くなる可能性があります。GPU を使用して学習させるには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスについては、リリース別の GPU サポート (Parallel Computing Toolbox)を参照してください。

numIterationsPerEpoch = floor(numObservations / miniBatchSize);

options = trainingOptions('adam', ...
    'MaxEpochs',15, ...
    'MiniBatchSize',miniBatchSize, ...
    'GradientThreshold',2, ...
    'Shuffle','never', ...
    'Plots','training-progress', ...
    'Verbose',false);

関数 trainNetwork を使用して LSTM ネットワークに学習させます。

net = trainNetwork(tdsTrain,layers,options);

新しいデータを使用した予測

3 つの新しいレポートの事象タイプを分類します。新しいレポートを含む string 配列を作成します。

reportsNew = [ ...
    "Coolant is pooling underneath sorter."
    "Sorter blows fuses at start up."
    "There are some very loud rattling sounds coming from the assembler."];

学習ドキュメントと同じ前処理手順を使用してテキスト データを前処理します。

documentsNew = preprocessText(reportsNew);

doc2sequence を使用して、テキスト データを埋め込みベクトルのシーケンスに変換します。

XNew = doc2sequence(emb,documentsNew);

学習済みの LSTM ネットワークを使用して新しいシーケンスを分類します。

labelsNew = classify(net,XNew)
labelsNew = 3×1 categorical
     Leak 
     Electronic Failure 
     Mechanical Failure 

テキスト変換関数

関数 transformText は、tabularTextDatastore オブジェクトから読み取ったデータを取り、予測子と応答の表を返します。予測子は CS 列の単語ベクトルの配列で、単語埋め込み emb により与えられます。ここで、C は埋め込み次元、S はシーケンス長です。応答は、classNames 内のクラスのカテゴリカル ラベルです。

function dataTransformed = transformText(data,emb,classNames)

% Preprocess documents.
textData = data{:,1};
documents = preprocessText(textData);

% Convert to sequences.
predictors = doc2sequence(emb,documents);

% Read labels.
labels = data{:,2};
responses = categorical(labels,classNames);

% Convert data to table.
dataTransformed = table(predictors,responses);

end

前処理関数

関数 preprocessText は以下のステップを実行します。

  1. tokenizedDocument を使用してテキストをトークン化する。

  2. lower を使用してテキストを小文字に変換する。

  3. erasePunctuation を使用して句読点を消去する。

function documents = preprocessText(textData)

documents = tokenizedDocument(textData);
documents = lower(documents);
documents = erasePunctuation(documents);

end

ラベル読み取り関数

関数 readLabels は、tabularTextDatastore オブジェクトのコピー ttds を作成して labelName 列からラベルを読み取ります。

function labels = readLabels(ttds,labelName)

ttdsNew = copy(ttds);
ttdsNew.SelectedVariableNames = labelName;
tbl = readall(ttdsNew);
labels = tbl.(labelName);

end

参考

(Text Analytics Toolbox) | (Text Analytics Toolbox) | (Text Analytics Toolbox) | (Text Analytics Toolbox) | | | | |

関連するトピック