Ribbon.ruのスタイルで偽のニュースヘッドラインを生成します

ニューラルネットワークを使用してテキストを生成する2つのアプローチを比較してください:Char-RNN対Word埋め込み+最後に楽しい例。



読むものがまったくないときは、本を開きたくない、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個の前の文字に基づいて次の文字を予測することを学習することです。 つまり、ネットワークは入力として一部のソーステキストを受け取り、さらにテキストが文字ごとに生成されます。 したがって、比較的読みやすいテキストの書き方を学ぶために、ネットワークは次のことを行う必要があります。



  1. 文字のシーケンス(擬似単語)をスペースで区切ることを学び、時にはそれを終わらせます。
  2. 実際の単語に似た文字のシーケンスを生成することを学ぶ。
  3. 以前のほぼ実際の単語を考慮に入れて、実際の単語に類似したものを生成する方法を学びます。


限定されたヘッダーセット(<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に比べていくつかの重要な利点があります。



  1. ネットワークは単語を生成する方法を学ぶ必要はありません-それら自体はそれぞれ原子的な要素であり、生成されたフレーズは最初にコーパスからの単語のみで構成され、偽の単語はありません。
  2. フレーズ内の単語は相互に一貫性があります。一連の単語{"in"、 "on"、 "went"、 "car"、 "car"}のシーケンス["went"、 "on"は合計確率が高いためです。 「車」] [[運転]、[中]、[車]]
  3. より高い学習速度、 同じ場合、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」という単語への変貌によって正規化されました-コーパス全体にとって深刻な損失です。



結論





デザート



まあ、最終的に、手動修正後のいくつかの真珠は、かなりLenta.ruの精神にあるようです:





Githubに投稿されたラップトップとコメントを使用したコード。 また、事前に訓練されたネットワーク、テキストを生成するためのスクリプト(lenta_ai.py)および使用手順もあります。 99%のケースでは、意味のない単語のセットを受け取りますが、興味深いものはたまにしか出てきません。 さて、「見た目だけ」にしたい場合は、herokuで小さなWebアプリケーションを起動しました 。このアプリケーションでは、マシンでコードを実行せずにヘッダーを生成できます。



All Articles