深層学習を使用したメモリ外のテキスト データの分類
この例では、変換されたデータストアを使用して深層学習ネットワークでメモリ外のテキスト データを分類する方法を説明します。
変換されたデータストアは、基となるデータストアから読み取ったデータを変換または処理します。変換されたデータストアは、深層学習アプリケーションの学習データ セット、検証データ セット、テスト データ セット、および予測データ セットのソースとして使用できます。変換されたデータストアを使用して、メモリ外のデータを読み取るか、データのバッチを読み取る際に特定の前処理演算を実行します。
ネットワークの学習時に、入力データのパディング、切り捨て、または分割が行われ、同じ長さのシーケンスのミニバッチが作成されます。関数 trainingOptions
には、入力シーケンスのパディングと切り捨てを自動的に行うオプションが用意されていますが、これらのオプションは、単語ベクトルのシーケンスにはあまり適していません。さらに、この関数はカスタム データストアにあるデータのパディングをサポートしていません。代わりに、シーケンスのパディングと切り捨てを手動で行わなければなりません。単語ベクトルのシーケンスの "左パディング" と切り捨てを行うと、学習が改善される可能性があります。
深層学習を使用したテキスト データの分類 (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
オブジェクトから読み取ったデータを取り、予測子と応答の表を返します。予測子は numFeatures
行 lenSequence
列の単語ベクトルの配列で、単語埋め込み emb
により与えられます。ここで、numFeatures
は埋め込み次元、lenSequence
はシーケンス長です。応答は、クラスのカテゴリカル ラベルです。
クラス名を取得するために、この例の最後にリストされている関数 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: UnderlyingDatastores: {matlab.io.datastore.TabularTextDatastore} SupportedOutputFormats: ["txt" "csv" "dat" "asc" "xlsx" "xls" "parquet" "parq" "png" "jpg" "jpeg" "tif" "tiff" "wav" "flac" "ogg" "opus" "mp3" "mp4" "m4a"] Transforms: {@(data)transformText(data,emb,classNames)} IncludeInfo: 0
変換されたデータストアをプレビューします。予測子は numFeatures
行 lenSequence
列の配列です。ここで、lenSequence
はシーケンス長、numFeatures
は特徴 (埋め込み次元) の数です。応答はカテゴリカル ラベルです。
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];
学習オプションを指定します。オプションの中から選択するには、経験的解析が必要です。実験を実行してさまざまな学習オプションの構成を調べるには、実験マネージャーアプリを使用できます。
Adam オプティマイザーを使用して学習させます。
入力データの形式を 'CTB' (チャネル、時間、バッチ) に設定します。
ミニバッチのサイズを指定します。
勾配しきい値を
2
に設定します。データストアはシャッフルをサポートしていないため、
'Shuffle'
を'never'
に設定します。学習の進行状況をプロットで表示し、精度を監視します。
詳細出力を無効にします。
既定では、trainnet
は利用可能な GPU がある場合にそれを使用します。実行環境を手動で指定するには、trainingOptions
の名前と値のペアの引数 'ExecutionEnvironment'
を使用します。CPU での学習にかかる時間は、GPU での学習よりも大幅に長くなる可能性があります。GPU を使用して学習させるには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。
numIterationsPerEpoch = floor(numObservations / miniBatchSize); options = trainingOptions('adam', ... 'MaxEpochs',15, ... 'InputDataFormats','CTB', ... 'MiniBatchSize',miniBatchSize, ... 'GradientThreshold',2, ... 'Shuffle','never', ... 'Plots','training-progress', ... 'Metrics','accuracy', ... 'Verbose',false);
関数 trainnet
を使用してニューラル ネットワークに学習させます。分類には、クロスエントロピー損失を使用します。
net = trainnet(tdsTrain,layers,"crossentropy",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 ネットワークを使用して新しいシーケンスを分類します。
scores = minibatchpredict(net,XNew,InputDataFormats="CTB");
Y = scores2label(scores,classNames)
Y = 3×1 categorical
Leak
Electronic Failure
Mechanical Failure
テキスト変換関数
関数 transformText
は、tabularTextDatastore
オブジェクトから読み取ったデータを取り、予測子と応答の表を返します。予測子は numFeatures
行 lenSequence
列の単語ベクトルの配列で、単語埋め込み emb
により与えられます。ここで、numFeatures
は埋め込み次元、lenSequence
はシーケンス長です。応答は、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
は以下のステップを実行します。
tokenizedDocument
を使用してテキストをトークン化する。lower
を使用してテキストを小文字に変換する。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
参考
trainnet
| trainingOptions
| dlnetwork
| fastTextWordEmbedding
(Text Analytics Toolbox) | wordEmbeddingLayer
(Text Analytics Toolbox) | doc2sequence
(Text Analytics Toolbox) | tokenizedDocument
(Text Analytics Toolbox) | lstmLayer
| sequenceInputLayer
| transform