自然言語処理について

1,105 views
Skip to first unread message

Sumi

unread,
Dec 5, 2017, 8:25:19 AM12/5/17
to Neural Network Console Users (JP)
初めまして。私は、最近NNCで機械学習の勉強を始めた初心者です。
私は、NNCで自然言語処理をしたいと考えております。
そこでまずword2vecを実装したいのですが以下のことが分からないので教えていただきたいです。

1,word2vecのネットワークの構造について

2,データセットについて
 学習に使用する文章コーパスをどのような形でcsvファイルに書き込むのか。
分かち書きしたものに整数値でインデックスをつけるところまでは分かるのですが、
 作成した膨大な単語を横に列で書き込むのか、縦に行で書き込むのか、1つのテキストファイルを1つのcsvファイルにするのかが分かりません。
 また、評価データも必要でしょうか。

3,ヘッダー部について
 海外のフォーラムでは横1列にされていましたがその際ヘッダー部がx_1,x_2...となっていたのですが
 これは出した結果を別のプログラムを作って対応する単語に変換するということでしょうか。直接日本語に変換はできないのでしょうか。
 また、海外のフォーラムではx_1,x_2...の後、yの値が1になっていたのですがこれは何を意味するのでしょうか。

非常に初歩的な質問だと思いますがお答えいただけると幸いです。よろしくお願いいたします。

Sumi

unread,
Dec 11, 2017, 12:01:59 PM12/11/17
to Neural Network Console Users (JP)
すいませんがseq2seqの実装についても教えていただけると幸いです。

BOKU

unread,
Dec 15, 2017, 11:06:27 AM12/15/17
to Neural Network Console Users (JP)
こんにちは。

BOKUといいます。

質問の直接の答えにはならないかもしれませんが、コメントさせていただきます。

実は、自分もword2vecをNNCでやろうとした事があります。
でも、結論から言えば、かなり厳しいです。
NNCだと、inputデータをCSVで渡す場合、数字しかだめですから。

Word2Vecを手軽に試すなら、NNCの裏で動いている「Neural Network Libraries」のサンプルをおすすめします。
exsamplesに「word_embedding.py」(最近名前が変わったのですが、前はWord2Vec.pyという名前でした)という名前であります。

自分はこれで、日本語のテキストを処理するのを一度やったことがあります。
その時のやり方は、ブログに書いてます。
参考にしてもらえたら、うれしいです。


小林由幸

unread,
Dec 18, 2017, 1:14:22 AM12/18/17
to Neural Network Console Users (JP)
自然言語系については今後サンプルやチュートリアルの拡充を検討させていただきます。

Word2vecを含めNeural Network Consoleで文章を扱う場合、
現状では基本的にデータセットを単語Index系列として与えることになります。
また、認識結果を文章で確認するためには、やはり現状認識結果を外部のプログラムで
文章の形に変換する必要があります。

データセットのフォーマットについては、
文章が短いケースではデータセットCSVファイルにベクトルとして(x__0,x__1…)
Index系列を書いてもよいですし、1つの文章を1つのCSVファイルとして
各行に1単語のIndexを書いていくこともできます。

海外のフォーラムは以下のポストかと推察しますが、
こちらはClassificationタスクに関するご質問でしたので、識別対象のカテゴリIndexとして
y列を用意しております。
https://groups.google.com/forum/#!topic/neural_network_console_users/upKeAJoU-J0


Word2vecに関しては適切なデータのシャッフル等が必要になり、
現状ですと実装効率、学習処理の実行効率などを考慮すると、
BOKUさんが書かれているとおりNeural Network Librariesなどの利用を
お薦めしたいところです。

Sumi

unread,
Dec 19, 2017, 10:19:49 AM12/19/17
to Neural Network Console Users (JP)
BOKU様、回答ありがとうございます。
ブログ拝見させていただきました。実際にブログ記載の方法を試したところ、動作しましたのでNNCでのword2vecは諦め、nnablaでの実装を検討しようと思います。

Sumi

unread,
Dec 19, 2017, 10:22:36 AM12/19/17
to Neural Network Console Users (JP)
小林様、回答ありがとうございます。
NNCでの文章に入力する際にcsvには単語indexを与えることということなので早速単語index化のプログラムを作成しました。

Sumi

unread,
Dec 19, 2017, 11:09:53 AM12/19/17
to Neural Network Console Users (JP)
自分は現在seq2seqの実装を試みているのですが何点か分からないことがあるので再度質問します。

1、Encoder側とDecoder側の重みの共有について
他のライブラリを参考に下記のようなネットワークを作成しているのですが、2つのLSTMの間で状態を共有するにはどうすればいいのでしょうか。パラメータスコープを左側(Encoderのつもり)のものと同一にするのかと思い、それは実行済みです。2つのネットワークをつなげればいけないのならば、どのようにつなげればいいのでしょうか。

2、Embeddingについて
他のライブラリでは入力語をone-hotベクトルでindex化した後Embed層で埋め込みベクトルにしているとのことなのでNNCで実装しようとしました。index化は、既に実行しているものとし(csv入力時点で語彙数の辞書データを作成後、入力文書を辞書に基づきindexに置換したとみなしたため)Embedにかけたのですが、一連の学習の後softmax-cross-entropyにかけようと全結合でベクトルから元のindexの値に戻そうと試みたのですがどうしても1以下の数値になってしまいます。どのようにして埋め込みベクトルから元のindexの整数値に直せばいいのでしょうか。

3、上記のEmbedが使用不可の場合の対処について
Embedが使用不可ならばやはり外部でword2vecなどを使用し、ベクトル表現した後に活性化関数を使わずに出力したベクトルをSquaredErrorで損失を算出するという方法になるのでしょうか。

4、seq2seqの他のモデルはNNCで実装可能でしょうか。

すいませんが、これらの質問にお答えいただけると幸いです。よろしくお願いいたします。

現在の環境
csvデータ>発話をx、応答をyの入力とし各行に1単語のindexを入力。文章長を合わせるために、最長の文章長との差を{0:EOS}で埋める処理を施した。
csvの画像は左から文章の生データ、index化データ、100次元のベクトル化データ

ネットワーク>Encoder・Decoderモデルを実装中。
画像左側がEncoder(xの値入力)、右側がDecoder(yの値の入力、生成)のつもりで作成。
2017-12-20.png
2017-12-20 (2).png

小林由幸

unread,
Dec 20, 2017, 3:03:36 AM12/20/17
to Neural Network Console Users (JP)

> 1、Encoder側とDecoder側の重みの共有について
> 他のライブラリを参考に下記のようなネットワークを作成しているのですが、2つのLSTMの間で状態を共有するにはどうすればいいのでしょうか。パラメータスコープを左側(Encoderのつもり)のものと同一にするのかと思い、それは実行済みです。2つのネットワークをつなげればいけないのならば、どのようにつなげればいいのでしょうか。


EncoderとDecoderのEmbedレイヤーの重みを共有したいということでよろしかったでしょうか。
書かれている通り、ParameterScopeプロパティを同じにすることで、2つのレイヤーのパラメータを共有可能です。
Decode側にEncodeのLSTMの中間層の値を引き継ぐには、

* 本来のLSTMの出力と中間層の値をConcatenateしてRecurrentOutputに接続することで、RecurrentOutput出力されるようにする
* RecurrentOutputから出力された中間層の値をSliceレイヤーで取り出し、DecderのDelayレイヤーのサイドコネクタに接続して入力する

という方法を用います。

> 2、Embeddingについて
> 他のライブラリでは入力語をone-hotベクトルでindex化した後Embed層で埋め込みベクトルにしているとのことなのでNNCで実装しようとしました。index化は、既に実行しているものとし(csv入力時点で語彙数の辞書データを作成後、入力文書を辞書に基づきindexに置換したとみなしたため)Embedにかけたのですが、一連の学習の後softmax-cross-entropyにかけようと全結合でベクトルから元のindexの値に戻そうと試みたのですがどうしても1以下の数値になってしまいます。どのようにして埋め込みベクトルから元のindexの整数値に直せばいいのでしょうか。

Softmax-cross-entropyを用いることにより、時刻ごとの単語Indexのスコア(単語数次元)が得られるかと思います。
各時刻において、もっとも値の大きい次元が、Decoderの予測した単語ととらえることができます。


> 3、上記のEmbedが使用不可の場合の対処について
> Embedが使用不可ならばやはり外部でword2vecなどを使用し、ベクトル表現した後に活性化関数を使わずに出力したベクトルをSquaredErrorで損失を算出するという方法になるのでしょうか。

上記のようにEmbedレイヤーは利用可能ですが、元の単語Indexに戻すためには
出力されたスコアを元に最大値を取るという処理を別途行う必要がります。

> 4、seq2seqの他のモデルはNNCで実装可能でしょうか。

はい、上記の手法を用いることで実装可能です。

Sumi

unread,
Dec 31, 2017, 11:56:47 PM12/31/17
to Neural Network Console Users (JP)
返信、遅くなりました。
いつも丁寧な返答ありがとうございます。

seq2seqの実装について、データセットの中身をword2vecで200次元のベクトルにしたところ無事に実装できました。

何度も申し訳ないのですが、いくつか単語Indexを入力する方法の実装で疑問があったので質問させてください。

前提条件として、
会話の生成では、
発話データ入力 > Embedで任意の次元の単語ベクトル(埋め込みベクトル)を生成 > エンコーダー側の中間層(RNNやLSTM)に入力、中間ベクトル作成 > デコーダ側の中間層(RNNやLSTM)に入力 > 生成されたベクトルを単語数次元に変換、softmaxで出力 > 交差エントロピーで損失計算
のモデルを適用すると解釈しています。(今回ベクトルを入力した時はベクトルをそのまま出力し、二乗誤差で損失計算しました。)
以下は入力から出力までのNNC上のパラメータ
データセットのinput=21,1のデータ(文章長21、単語indexでの入力)
>Embedで100次元のベクトルに変換=21,100
>中間層サイズを100とする=21,100
ベクトルを単語数次元に変換(単語数は3000とする=
21,3000
>これをsoftmaxにかけて損失計算=1

1、Embedを使う際の入力データについて
Embedは入力が単語Indexとあるのですがこれは
[0:”EOS”,1:”こんにちは”…](pythonの辞書型)と言った1単語につき1つの数字で表したものか、
one-hot表現(次元数は語彙)で表したものか
どちらを使うべきでしょうか。

2、交差エントロピーについて
1の前者の方法で入力する際csvへの記載は発話された単語時系列に沿って上から入力されると理解しています。
ex)私 は “名前” です > 0
0 1 2 3 > 1
2
3 左は1つのcsvの入力
また、各Indexは各単語を表すラベルと捉えられると解釈しています。
つまり、一つのcsv内に複数のラベルが存在している状況になります。ex)文章長21なら21,1のデータ
この複数ラベルが入ったcsvファイルを交差エントロピーのT.Datasetのデータとすることは可能でしょうか。できるならどのように入力すればいいですか。
また、交差エントロピーのAxisは何を表していますか。

3、強化学習の実装はできますか。(DQNなど)

以上、3点をお願いいたします。
また、前提条件で間違っているところがあれば、指摘していただければ幸いです。

Sumi

unread,
Jan 3, 2018, 8:47:33 PM1/3/18
to Neural Network Console Users (JP)

追加で聞きたいのですが現在、lstmの部分をQRNNに置き換えて高速化しようとしているのですが、1次元の畳み込みを行うとき畳み込み層の設定はどのようにすればよろしいですか。
もし、入力値の変更があるのならばそれも教えてください。

小林由幸

unread,
Jan 9, 2018, 12:56:05 AM1/9/18
to Neural Network Console Users (JP)
> Embedは入力が単語Indexとあるのですがこれは
> [0:”EOS”,1:”こんにちは”…](pythonの辞書型)と言った1単語につき1つの数字で表したものか、

はい、Embedレイヤーの入力は、上に書かれているように整数(int)の各値が
単語の種類を表すIndexになります。


> 2、交差エントロピーについて
> 1の前者の方法で入力する際csvへの記載は発話された単語時系列に沿って上から入力されると理解しています。
> ex)私 は “名前” です          >     0
>      0   1       2       3            >     1
>                                                    2
>                                                    3      左は1つのcsvの入力
> また、各Indexは各単語を表すラベルと捉えられると解釈しています。
> つまり、一つのcsv内に複数のラベルが存在している状況になります。ex)文章長21なら21,1のデータ
> この複数ラベルが入ったcsvファイルを交差エントロピーのT.Datasetのデータとすることは可能でしょうか。できるならどのように入力すればいいですか。
> また、交差エントロピーのAxisは何を表していますか。

はい、CategoricalCrossEntropyのT.Datasetとして、単語Index系列データを与えることができます。
このとき、Axisは入力データのどの次元でCrossEntropyを計算するかを指定します
(Axis以外の次元は、単に複数のデータとして扱われます)。
今回の場合、データパスが21,3000に対し、ラベルが21,1とのことですので、
Axisを1とすることで、3000次元の各単語のスコアと、ラベルとして与えられた0~2999の単語Indexを元に
Categorical Cross Entropyを求めることができます。

> 3、強化学習の実装はできますか。(DQNなど)

現状Neural Network Consoleは強化学習での利用を想定していません。
これは、強化学習は通常環境とのインタラクションを通じてデータを収集しながら学習を進めるためです。
強化学習はNeural Network Librariesを用いることで実現することができます。
また、その際に用いるネットワークの設計にはNeural Network Consoleを利用することができます。

> 追加で聞きたいのですが現在、lstmの部分をQRNNに置き換えて高速化しようとしているのですが、1次元の畳み込みを行うとき畳み込み層の設定はどのようにすればよろしいですか。

Transposeレイヤー、Reshapeレイヤーを用いて、データを画像の形に変換することで
Convolutionレイヤーを適用することができます。
例えばEmbed後の21,100のデータに対し、

Transpose(Axes=1,0) # 行と列を入れ替えて、100,21に
Reshape(OutShape=100,1,21) # 100枚の21(w)×1(h)画像の形に変換
Convolution(KernelShape=1,5, BorderMode=same) # 時間方向のカーネル幅が5のConvolutionを行う
Reshape(OutShape=100,21) # 再び行列に戻す
Transpose(Axes=1,0) # 行と列を入れ替えて、100,21に戻す


とすることができます。

Sumi

unread,
Feb 14, 2018, 8:30:39 PM2/14/18
to Neural Network Console Users (JP)

seq2seqの動作がよくわからず再びお尋ねします。
seq2seqの実装については下記のサイトを参考に構築しました。
これらは共通してデコーダ側で隠れ層の値を全結合層に入れ予測単語に変換した後、時点の入力に用いています。
これをnncで実装する場合RecurrentOutput前にaffineを挿入することで対応できるのでしょうか。また、この場合損失計算のレイヤーはどこに置くべきなのでしょうか。
自分はgensimのword2vecを用いて前処理をしたベクトルをnncの入力とし、誤差は教師ベクトルとの二乗誤差を取っています。現在二乗誤差のレイヤーはRecurrentOutputの外に置いています。
参考サイト
https://qiita.com/kenchin110100/items/b34f5106d5a211f4c004
https://fight-tsk.blogspot.jp/2017/03/seq2seq.html
http://tech.mof-mof.co.jp/blog/seq2seq.html
https://qiita.com/takumi_TKHS/items/54d6551c97ef84c4d141
http://d.hatena.ne.jp/higepon/20171210/1512887715

小林由幸

unread,
Feb 15, 2018, 11:25:40 PM2/15/18
to Neural Network Console Users (JP)
RecurrentOutputの出力の予測単語のベクトルへの変換については、
書かれている通りRecurrentOutputの手前にAffineを挿入することで実現可能です。

ロス関数については、RecurrentOutputで各時刻の予測単語のベクトルをまとめた結果の
サイズが(時間数,単語ベクトル次元数)である行列について、
教師ベクトルとの二乗誤差を計算するとよいかと思います。

Sumi

unread,
Feb 22, 2018, 11:21:22 AM2/22/18
to Neural Network Console Users (JP)
お答えいただきありがとうございます。
この実装を試してみました。
精度はそれほど変わらなかったので一旦、学習データに問題があるとして精査していきたいと思います。
Reply all
Reply to author
Forward
0 new messages