読むものがまったくないときは、本を開きたくない、Habréのすべての記事を読み、電話のすべての通知が処理され、メールボックスのスパムも表示されたら、Lenta.ruを開きます。 私の妻、プロのジャーナリストは、そのような瞬間にアレルギーを持っています、そして、それは明らかです。 古いチームが2014年にテープを離れた後、出版物の黄色が上がり、テキストと編集の品質が下がりました。 時間が経つにつれて、定期的に慣性によって、フィードを読み続けながら、ニュースの見出しモデルが繰り返されていることに気付き始めました。など。 これが最初の紹介です。
2つ目の入門-最近、偶然、面白い国内のアナログ@DeepDrumph (これはTwitter です 。トランプの公式twitterに基づいてニューラルネットワークによって生成されたフレーズがレイアウトされています)- @neuromzanです。 残念ながら、著者は新しいツイートの投稿を停止して非表示にしましたが、アイデアの説明はここに保存されました 。
そして、アイデアが浮上しました、なぜ同じことをしないのですか?Lenta.ruの見出しに基づいていますか? このリソースの本当の見出しのいくつかの不条理のレベルを考えると、それはそれほど面白くないことがわかります。
注 :ここでは、導入テキストに基づいて後続のテキストを生成するタスクを検討します。 たとえば、ニュースアイテムのテキストに基づいて見出しが生成される場合、これはテキスト要約のタスクではありません。 私の場合のニュースのテキストはまったく使用されていません。
データ
リボンのすべてのコンテンツをダウンロードして解析する見込みはまったく私を喜ばせませんでした。だれかが私の前にすでにこれを行っているかどうかを調べ始めました。 そして、私は幸運でした。このアイデアが生まれるほんの数日前、Ildar Gabdrakhmanov ildarcheggは、彼がリボンの内容を奪い、アーカイブ全体を共有する方法を説明する投稿を投稿しました。 最後に、彼は、「誰かがこのデータを興味深く見つけて、それが使用されるのを見つけることができることを願っています。」と付け加えます。 私はすでにアプリケーションを持っています! ありがとう、イルダー! あなたの努力は私を数日救った!
そのため、このアーカイブを使用して、必要な期間(2014年4月1日(古いチームが去ったとき)から現在まで)の記事を取り出します。 データの予備処理については説明しません。 Githubリポジトリには、プロセスを段階的に説明した個別のラップトップがあります。
最初の学習の試み-Char-RNN
上記の記事から判断すると、neuromzanの著者は、Andrej Karpathyの伝説的な記事「 The Rereasonable Effectiveness of Recurrent Neural Networks 」で説明されているChar-RNNアーキテクチャを使用しました。 このアプローチを使用して問題を解決してみましょう。 さまざまな言語とフレームワークのChar-RNNの実装は、インターネットで簡単に見つけることができます。 私はこれを取りました -ケラスでは非常にコンパクトであることがわかりました。 私のニーズに合わせて少し変更して(ハイパーパラメーターを変更し、結果の保存とより有益な結論を追加しました)、トレーニングを開始しました。
そして結果は私を喜ばせませんでした。 Char-RNNの考え方は、ネットワークがN個の前の文字に基づいて次の文字を予測することを学習することです。 つまり、ネットワークは入力として一部のソーステキストを受け取り、さらにテキストが文字ごとに生成されます。 したがって、比較的読みやすいテキストの書き方を学ぶために、ネットワークは次のことを行う必要があります。
- 文字のシーケンス(擬似単語)をスペースで区切ることを学び、時にはそれを終わらせます。
- 実際の単語に似た文字のシーケンスを生成することを学ぶ。
- 以前のほぼ実際の単語を考慮に入れて、実際の単語に類似したものを生成する方法を学びます。
限定されたヘッダーセット(<800)でトレーニングされた64個のLSTMセルを持つ2層ネットワークで何が起こったのかを次に示します。 角括弧-ネットワークの紹介テキストで、次の150文字を生成します。
1 : "[ . ] . "; 2 : "[ ] . . . . . 2 "; 3 : "[ . ] . . . . . . . . "; 4 : "[ . : , ] . . "; 5 : "[ - . ] . . . . . . . . . "; ... 25 : "[ 7,2. ] . -. "; ... 50 : "[ - 2018 ] "
私はそれ以上訓練し始めませんでした。 ある種のナンセンスなことが判明しました。 はい、単語はスペースで区切られ、ドットで終わるフレーズに似ています。 一部の「単語」は、ロシア語の実際の単語ですらあります。 しかし、読むことは不可能であり、それは私にインスピレーションを与えた例にあったそれらの美しくて面白い発言にまったく似ていません。 ハイパーパラメーターを変更しても、品質にはほとんど影響しませんでした。 完全なデータセットでのトレーニングも結果を大きく改善しませんでした。 おそらく、これらの同志たちはネットワークをもっと長く訓練し、より多くの層を追加し、それらをより広くしたかもしれませんが、私は別のアプローチを試してみることにしました。
代替方法-単語の埋め込み
1年ほど前のUdacity Deep Learning Foundationコースでは、シンプソンズ(より具体的にはMoの居酒屋の1つのシーン)のスクリプトを生成するネットワークを作成し、25シーズンの漫画の似たようなシーンのオリジナルスクリプトをトレーニングすることを思い出しました。 この場合、別のアプローチが使用されました-テキストが文字ごとに生成されるのではなく、単語に応じて、特定の単語の出現の確率分布に基づいて、[1..N]前の単語に対して生成される単語埋め込み。
このアプローチには、Char-RNNに比べていくつかの重要な利点があります。
- ネットワークは単語を生成する方法を学ぶ必要はありません-それら自体はそれぞれ原子的な要素であり、生成されたフレーズは最初にコーパスからの単語のみで構成され、偽の単語はありません。
- フレーズ内の単語は相互に一貫性があります。一連の単語{"in"、 "on"、 "went"、 "car"、 "car"}のシーケンス["went"、 "on"は合計確率が高いためです。 「車」] [[運転]、[中]、[車]]
- より高い学習速度、 同じ場合、Char-RNNの場合、トークンは記号になり、Wordの埋め込みの場合、単語になります。 テキスト内の単語数は明らかに文字数よりも少ないですが、マシンの場合は最初の単語であり、2番目の場合はトークンは辞書のインデックスにすぎません。 したがって、1回の反復で、Wordの埋め込みはChar-RNNよりもはるかに少ないトークンを処理する必要があり、ほぼ比例して時間がかかります。
限られたデータセット(同じ2つのレイヤーと64個のLSTMセル、次の100個のトークンを生成)の簡単な仮説検定:
1: "[]...................................................................................................." ... 4: "[]... .. ...... facebook........... .......... ............... .... ...... . ......... . ........... ..." ... 10: "[]. . . . .. iphone8. ... . -. . . . .. . . .. facebook . . . . facebook . android. . . . " ... 20: "[]. . . . . . 12. . .. . . . . . android . . - . . . . "
ここで何が起こっているのか。 最初の時代では、ネットワークは最も一般的なトークンの1つがポイントであると見なします。 「さあ、私はあらゆる場所にポイントを置きます。彼女には非常に高い頻度があるからです」と彼女は考え、大きな間違いを犯します。 その後、彼女は2、3回の反復を疑い、4日目にポイント間に単語を挿入する価値があると判断します。 「すごい! エラーは小さくなり、「ネットワークは喜ぶ」、この精神で続けなければなりません、別の単語を挿入しますが、私はドットが本当に好きなので、今のところそれらを入れ続けます。 そして、彼は点をつけ続け、言葉でそれらを希釈します。 次第に、彼女は点よりも言葉を置くほうが価値があることを認識し、いくつかの言葉は互いに近づけるべきです。例えば、データセットからのいくつかの文章を覚えています:「政府を拡張する」、「合意を達成する」、「二重食い」など。 20世紀までに、彼女は「空からの軍事装備の展開の映像」が発表されたなど、かなり長いフレーズをすでに覚えている。 そして、これは、原則として、アプローチは機能するが、そのような小さなデータセットでは、ネットワークは非常に迅速に(ドロップアウトにもかかわらず)再訓練し、ユニークなフレーズを与える代わりに学習したものを与えることを示しています。
ヘッダーの完全なセットで彼女をトレーニングするとどうなるか見てみましょう。
1: "[] .. . . . . . . . . . . . . 10 " ... 5: "[] . . 59 . . . - forbes . 10 . 300. . 3 . -. . " … 10: “[] . . . tor. . . . 72 . . . . . ”
損失が減少しなくなるには10時代のみで十分でした。 ご覧のとおり、この場合、ネットワークはかなり長い部分も記憶していますが、同時に、比較的独創的なフレーズも多数あります。 たとえば、次のように、ネットワークが他の長いフレーズから長いフレーズを作成する方法をよく見ることができます。 「。
ただし、いずれにしても、ほとんどの場合、フレーズはDeepDrumphやneuromzanのフレーズほど美しくありません。 ここで何が間違っていますか? より長く、より深く、より広く学ぶ必要がありますか? そして、洞察が私に降りかかった。 いいえ、これらの人は美しいテキストを生成する魔法のアーキテクチャを見つけませんでした。 長いテキストを生成し、面白い部分を選択して手動で編集します! 男の最後の言葉は秘密です!
手動で編集した後、かなり受け入れられるオプションを取得できます。
- 「反応しました。 砂販売機会副市長「>>>」砂は副市長の地位を売却する可能性に反応した
- 「副スピーカーは男と見なされた」>>>「副スピーカーは男と見なされた」
- 「レベデフ副議長は不適切な殺害の提案を宣言した」>>>「レベデフ副議長は不適切な殺害の提案を宣言した」
...など。
ロシア語に関連する別の重要なポイントがあります。 ロシア語のフレーズを生成することは、文中の単語とフレーズを調整する必要があるため、はるかに困難です。 もちろん、英語でも、しかしそれよりはるかに少ない程度です。 以下に例を示します。
「車」>>>「車」
「車で」>>>「車で」
「車を見る」>>>「車を見る」
つまり、英語では異なる場合の単語はネットワークの観点からは同じトークンであり、ロシア語では異なる語尾や単語の他の部分のために異なります。 したがって、英語のモデルの結果はロシア語よりも信じられそうです。 もちろん、ロシア語のコーパス内の単語を補題にすることはできますが、生成されたテキストもそのような単語で構成されます。ここでは、確かに手動ドーピングなしではできません。 ちなみに、 pymorphy2モジュールを使用してこれを実行しようとしましたが、正規化後の一意のトークン(単語)の数が2倍以上減少したにもかかわらず、個人的な意見では、結果はさらに悪化しました。 20時代後、結果は次のようになりました。
“[]. . . . . . . . . . . . . . facebook .. . . . .. ”
また、単語の元の意味がしばしば失われることに気付くかもしれません。 たとえば、上記の文章では、「Peskov」という名前は、「sand」という単語への変貌によって正規化されました-コーパス全体にとって深刻な損失です。
結論
- Word Embeddingsは、Char-RNNよりもはるかに優れたテキスト生成を処理します。
- 他のすべての条件が同じである場合、英語のテキストを生成する品質は、言語の特性により、一般的にロシア語の品質よりも高くなります。
- AIが本を書いたと聞いたとき(先日、 アルゴリズムがHarry Potterの本を書いたと発表したとき、アルゴリズムが1つしかできなかったため、このステートメントを1000で除算します)、キャラクターの名前と説明を生成し、または、2)物語の一般的なアウトラインを生成する、または3)半ば不条理なテキストを生成します。このテキストは、人間の編集者によって長くハードに編集および調整されました。 または、これらすべてを一緒に取ります。 しかし、確かにAIは最初から最後まで一冊の本を書いたわけではありません。 そのレベルの開発ではまだ私たちの技術ではありません。
デザート
まあ、最終的に、手動修正後のいくつかの真珠は、かなりLenta.ruの精神にあるようです:
- 財務省はリャザン地域の政党を拒否しました
- オーストラリア人がAndroidでiPhone8を拒否
- イルクーツクは空気なしで去った
- サンクトペテルブルクの世界に対するサンクトペテルブルク警察
- 債務者が中国で販売を開始
- 経済開発省、制裁に対する同性愛者のパートナーシップを発表
- ギリシャは熊を作った
- プーチン大統領は博物館とソルジェニツィンと和解した
- 裸の観光客がブデンノフスクで死亡
- 医者は奴隷貿易の分野での問題を抱えた別れの旅からゴルバチョフを思いとどまらせた
- イギリスでは、コンフェデレーションズカップの準決勝ペア
- MP Lebedevは、タクシーに罰金を科すという提案は不適切であると判断した
- 連邦評議会は、名誉レオポルズの選択を提案しました
- Dumaの副スピーカーは、クーデターを準備する提案を実証しました。
- モスクワのリトアニアの腫瘍医が治療を開始しました
- 中央銀行は、トロルの石陰茎を固定するためにお金を割り当てます
- 映画を撮影することは、新しい主要なモスクワ地域について適切に冗談を言うのが難しい
- 酔った拘留者は州下院を引き起こした
- イスラエルは顔に酸で反応した
- 米国連邦準備制度理事会の長は、クリームの不存在を約束しました
- イジェフスクの兵舎の問題はベッドで解決しました
- ヤマルでは、シロハヤブサが最初にユーロビジョン飛行機から子孫を繁殖させました
- モスクワ地域は1年でブラジルより多くを費やす
- イヴァヌシキからリビアの海岸を離れて
- ラダの観光船のcrash落の犠牲者の数を発表
- キム・カーダシアンは別の化学攻撃の準備で告発された
- 政府はロシアの内政のための資金不足を約束した
- ロシアでの仕事に備えた千人のカウンセラー
- ブレイビクは空爆で領土を砲撃したと不満を述べた
- 米国はジルコフを顔に与えることを要求した
- 統合失調症のピーターズバーグは、電報ブロックの数日前に警告しました
Githubに投稿されたラップトップとコメントを使用したコード。 また、事前に訓練されたネットワーク、テキストを生成するためのスクリプト(lenta_ai.py)および使用手順もあります。 99%のケースでは、意味のない単語のセットを受け取りますが、興味深いものはたまにしか出てきません。 さて、「見た目だけ」にしたい場合は、herokuで小さなWebアプリケーションを起動しました 。このアプリケーションでは、マシンでコードを実行せずにヘッダーを生成できます。