CyberAgent秋葉原ラボでインターンしてきました
はじめに
2月初旬〜2月末の約1ヶ月間、CyberAgentの秋葉原ラボでインターンしてきました。その感想を書きたいと思います。
秋葉原ラボってどういうところ?
秋葉原ラボは大規模データ処理やデータ分析、機械学習などを専門とするエンジニアが在籍する研究開発組織です。サイバーエージェントのメディアサービスから得られるデータを活用することで、メディアサービスと会社の発展に寄与することを目的として2011年4月、秋葉原にオフィスを開設しました。
サービスから日々生成されるユーザーのアクセスログや行動ログなどを大規模に集積、処理する基盤を整備し、その基盤上のデータを機械学習や自然言語処理技術などを用いてサービスに活かせるシステムを構築、提供しています。
また、基盤上のデータを分析、マイニングすることによりサービスやユーザーの状況を把握し、サービス拡大および健全化を図る基礎を担っています。
僕はこの開発組織の中でも自然言語処理を担当する班に所属させて頂きました。
秋葉原ラボでしていたことは?
僕は面接の時からやりたいことを伝えていて、希望通りのことをやらせて頂きました。具体的には、AbemaTVのコメントの雰囲気を良くするために、以下のようなタスクを行いました。
・通報されたコメントからNGワード・フレーズの抽出
・通報されてもおかしくないユーザーの抽出
本当はもっと色々なことをやりたかったのですが、時間が足りなかったです。
僕はB3で、自然言語処理は専門ではないのですが、希望したことをさせて頂きました(しかも院進するので、21卒じゃない)。基本的には一人で作業を進めることが求められると思います。でも、メンターさんが具体的な手法や方向性を一緒に考えてくれるので、なんとかなりました。
最後には、最終成果発表(20~30分)があり、スライドを70枚ぐらい作成しました。こんなにスライドを作るのが大変とは知らなかった…
他にどういったイベントがあった?
オフィス見学
渋谷にあるアベマタワーズ内を見学できました。
絵を描いている人の仕事姿にカッコいいなぁと思いました。
懇親会
希望者だけで、懇親会がありました。この時に、人事の方に質問したり、他のインターン生がどういったことをやっているのか知れたりしました。なんかアニメの話をしていたことを一番鮮明に覚えています。
メンター面談
進路の相談や質問ができました。中々フィードバックが貰えない、自分を面接した時にどう感じたかを質問するのがオススメです。また、インターンシップでもっとして欲しいことを伝えることができました。
人事面談
最初の面談で設定した目標(例えば、会社のことをもっと知りたい)が達成できているかを確認しました。この時にも、インターンシップでもっとして欲しいことを伝えることができました。
所属している班のミーティングに参加
同じ班の社員の方々が、どんなお仕事をされているか詳しく知ることができました。
シャッフルランチや同じ部署の方とのお昼ご飯
同じ部署や他の部署で働いている社員の方と一緒にお昼ご飯を食べることができました。色々な方に質問できてありがたかったです。
スマブラ大会
仕事終わりに、社員の方々とスマブラをやりました。社員の方とは10歳以上離れていると思うのですが、友人と一緒にスマブラとやっているのと変わりませんでした。
他にも様々なイベントがありました。
お仕事を通じてどう感じた?
- やっぱりデータの前処理がとても大事だなと感じました。もっとPandasや内包記法を使いこなすことができるようになりたいと思いました。
- タスク「通報されたコメントからNGワード・フレーズの抽出」をやっていく中で、考察がとても大事だなと感じました。考察を通じて、一つ一つ問題を解決していくことで、少しずつNGワード・フレーズが抽出されるようになっていきました(フレーズとなるとかなり難しくなることもよく感じました)。また、考察をして、問題を解決するには、先行研究を調べることや専門性の高い知識が大切だなと感じました。
- わかりやすい発表をするには、練習することが大事だということがわかりました。スライドには喋ることを全部書くわけではないので、伝えたいことを事前に決めて、何回か練習するのが大切だなと感じました。
- 作ったモデルやシステムを評価することは難しいことだと感じました。アノテーションで評価をするとどうしても主観的かつ作業が大変になることを感じました。なので、アノテーションをする時は、アノテーションをする際の定義をしっかりすることとできるだけ複数人でやることが大事だと感じました。
色々な方に質問してどう感じた?
- 基本と専門性が大事だなぁと感じました。自分はB3で専門性がないので、研究室で専門性を身に付けたいと思いました。また、基本を身に付けるためのオススメの本・方法を色々と教えて頂きました。
- 自分はデータサイエンスとバックエンドのどちらもできる人材になりたいと思っていました。しかし、今回のインターンを通じて、データサイエンスとバックエンドのどちらを専門にするかをちゃんと決められていなかったと感じました。バックエンド側の勉強をよりしてみて、ちゃんと専門を決めたいです。
今後はどうする?
- とりあえずは就活の時に何が専門かを言えるようにしたいです。なので、今後やっていく卒論を通じて、専門を決めたいです。
- 研究室のサーバの環境構築や管理を積極的にやりたいと思いました。メンターさんも大学生の頃にこれをやっていたおかげで色々な知識を得られたと仰いていたので、自分もその知識を得たいです。
- 今まではデータサイエンスの勉強をメインにしてきたので、バックエンドの知識を増やしていきたいです。春休みの間は以下の本を読むつもりです。
東京での思い出
休日は観光していました。
しばらく二郎ラーメンはいいです(サイバーエージェントでこのネタを何回やったかわからない)
サイバーエージェントの皆様、特にメンターさんお世話になりました。ありがとうございました。楽しかったです。
Transformerを勉強する
はじめに
私は「ゼロから作るDeep Learning ❷ ―自然言語処理編 斎藤 康毅」を読んだのですが、Transformerについてもっと知りたかったので、論文を読んでみることにしました。論文を読むにあたって、[1]、[2]、[3]、[4]、[5]、[8]を参考にさせて頂きました。間違っているところがあれば、教えていただけると幸いです。
Attention Is All You Need
以下に出てくる図表は論文からの転載です。
Abstract
- 現在、encoderとdecoderを含むRNN、CNNに基づいたモデルが有力とされている
- 本論文ではRNN、CNNを使用せず、Attentionに基づいたTransformerを提案
Introduction
- t番目の状態tを求めるために、RNNはt-1番目の状態ht-1とt番目の単語を使うため並列化が難しい
- TranformerはRNNを使用せず、Attentionに基づいているので、大幅に並列化ができる
- 入力と出力の間のグローバルな依存関係の構築はAttentionに頼る
Background
- 逐次計算を減らすという目標はCNNを使ったモデルで達成されてきた
- しかし、CNNを使ったモデルでは位置間の距離が増加する毎に必要な操作の数が増える。これによって、遠い距離の依存関係を学習するのが難しかった。Transformerではこれを一定数の操作に削減する。
- Transformerは入力と出力の表現をself-attentionに頼る最初のtransductionモデル
Model Architecture
- encoder、decoder共にN = 6。灰色のブロックをそれぞれ6個スタック
- 各層のアウトプットはdmodel = 512次元(単語の次元)
- リークを防ぐためにdecoderの最初のsub-layerでは2種類のMaskをかける
- Maskには2つある。
MASK
ここでMaskについて見る。Maskは特定のkeyに対して、attention_weightを0にするためにある。attention_weightを0にするのはAttentionがかかるのがおかしい部分にAttentionがかからないようにするためである。2つあるMaskはそれぞれ以下の通りである。
- PADを無視する(ある文章が最大長より短い場合、PADで埋め合わせられる)
- decoderでのリークを防ぐ
encoderでは1のみを使用する。decoderでは1と2を使用する。
[5]がとてもわかりやすかったです。
Layer normalization
各sub-layerの後に配置。residual connection(図でのaddに対応していると思われる)とlayer normalizatonを行う。まとめると以下のようになる。
LayerNorm(x + Sublayer(x))
以下では、sub-layerを一つずつ見ていく。
Attention
左側
- 左側のモデルは「ゼロから作るDeep Learning ❷ ―自然言語処理編 斎藤 康毅」に出てくるAttentionとほとんど同じ(内積注意)。
- 内積を使って2つのベクトルの類似度を測っている。
- で除算するところが異なる
- dkが大きい時、softmaxでの勾配がとても小さくなる。対策として、で除算する
数式で表すと以下のようになる
右側
- h = 8
- 単一の内積注意を計算するよりも、異なる重み行列で線形写像をh回計算し、h個の内積注意を計算する方が有益だとわかった。
- dk = dv = dmodel / h = 64
- そして、連結してまた線形写像する
Position-wise-Feed-Forward-Networks
Attention層からの出力を受け取る2層の全結合ニューラルネットワーク。活性化関数はReLU。
Positional Encoding
- TransformerはRNNやCNNを利用していないため、Positional Encodingにて単語の相対的位置または絶対的位置に関する情報を加える
- 下にあるembeddingsの出力と同じ次元を持つため、加算できる
- embeddingsの出力と加算する際、embeddingsの出力の方が小さいので、embeddingsの出力にを掛ける
- posはその単語が何番目か
- iは単語の分散ベクトルの何次元目か
Why Self-Attention
- Layer毎の計算複雑度
- どれぐらい並列化できるか(必要な順次操作の回数で測定)
- 最大パスの長さ(短いほど長距離依存について学びやすい)
- Self-Attentionと他のネットワークを比較
- Self-Attention(restricted)は出力位置を中心として、サイズrの近傍に位置する入力単語のみ考慮する
- 大抵の場合n < d なので、Self-AttentionはRecurrentより高速
Training
- データはWMT 2014 English-GermanとWMT 2014 English-French
- 評価軸はBLEUスコアとTraining Cost
- Adam optimizerを使用
- 3種類の正規化を使用
参考
実装
実装は[6]、[7]、[8]が参考になります(PyTorch)。
[6]の実装は以下のようになっています。
各sub-layerをクラスで実装
⬇︎
EncoderLayer、DecoderLayerにまとめる。
⬇︎
Mask + Embedding + Positional Encoding + Encoder or Decoder LayerをN(=6)回生成したものをEncoder、Decoderクラスにまとめる
⬇︎
Encoder、Decoder、LinearをTransformerクラスにまとめる。
torch.nn.CrossEntropyLossの中にsoftmaxの計算があるので、softmaxは書かれていないことに注意。
[7]はPyTorchの公式チュートリアル
[8]ではレビュー文章のネガポジ分類にTransformerのEncoderを使用している。
- TransformerのEncoderをクラス分類に使用するにはどうすればいいのかがわかる。
- モデルがネガポジ分類をする際にどのような単語を着目したのかをある程度把握するために、Self-Attentionを可視化させている。
次に読む論文
BERT
TransformerのEncoderを使用するらしい。
A Structured Self-attentive Sentence Embedding
Self-Attentionの起源
参考文献
- http://deeplearning.hatenablog.com/entry/transformer
- https://www.slideshare.net/DeepLearningJP2016/dlattention-is-all-you-need
- https://qiita.com/nishiba/items/1c99bc7ddcb2d62667c6
- https://qiita.com/FuwaraMiyasaki/items/239f3528053889847825
- https://qiita.com/halhorn/items/c91497522be27bde17ce
- https://github.com/graykode/nlp-tutorial/tree/master/5-1.Transformer
- https://pytorch.org/tutorials/beginner/transformer_tutorial.html
- https://github.com/YutaroOgawa/pytorch_advanced
CA Tech Challenge AbemaTV Hack –データコンペ編に参加してきました
はじめに
こんにちは、大阪にある私立大学に通っている者です。僕は先日、CyberAgentさんで開催されたCA Tech Challenge AbemaTV Hack –データコンペ編に参加しました。この記事では参加した感想を記します。
インターンシップの内容
AbemaTVのデータを使い、配信される広告がどれぐらい閲覧されるかを予測するモデルを作成し、その精度を競うイベントでした。1日目は個人戦で、2日目はチーム戦でした。学習用データが3600万データ、予測用データが820万データでとても驚きました。自分が持っているノートパソコンのスペックが高くないので、モデルを作成できるか不安でしたが、CyberAgentさんが前もって用意してくれたサーバーで解析・モデル作成を行うので公平で助かりました。
1日目
午前は競技内容の説明と環境構築がありました。それが終わったら昼休憩でした。昼休憩では、社員さんと一緒にお弁当を食べながら、質問することができました。
午後から競技開始でした。僕は3600万もの大規模データを扱ったことがなく、苦労していました。前処理結果がなかなか返ってこなく、処理を一旦止めて作戦をもう一度練るべきか、もう少し粘るべきかで迷っていました。この心境を社員さんに伝えると、大規模データだとあるあるらしくて一緒に笑っていました。あまり試行回数を稼ぐことができず、1日目の競技は終了になってしまいました。大規模データだと以下のことをやることが重要だと学びました。
- 学習データを少なくして、良い特徴量を探す
- for文など重いプログラムをできるだけ書かない
- 少量の学習データで掛かる時間を計測し、学習データを増やした時にどれぐらい時間が掛かるかを簡単に見積もる
僕は大規模データに対してとても苦労していましたが、1日目から周りの方との意見交換が自由で雰囲気はとても良かったです。カーネルが落ちて阿鼻叫喚な叫びが聞こえたりしましたw(2日目にはメモリの増量があり、約2倍の250GBになりました)。
2日目
2日目はチーム戦でした。僕たちは1日目の結果を踏まえて、特徴量をいっぱい作ることにしました。どんな特徴量を作ると良いかをチームメイトと議論する時間はとても楽しかったです。またこの時にチームメイトの方に前処理を速く終わらすことができるプログラムを教えて頂きました。実際に走らせてみると、かなり速く終わり、そういった技術を勉強することはとても重要だと思いました。
競技終了後には各チームの手法の発表とAbemaTVで現在動いているモデルの解説があり、とても勉強になりました。結果発表では入賞はできませんでしたが、ベンチマークになっているAutoMLに勝つことができ、良かったです。ちなみにAutoMLを走らせるのに数万円かかったみたいです。
最後には懇親会がありました。インターン生の中にDataRobotを使用したことがある方がいらっしゃり、DataRobotがある中で、自分たちができることは何かといった話題で盛り上がりました。また、内定者アルバイトしている方にも色々なことが聞けました。
おわりに
大規模データに苦労しましたが、学びがありとても楽しいインターンでした。CyberAgentさんありがとうございました。来年は内容が変わるかもしれませんが、興味がある方はテーブルコンペ(回帰)に参加して練習されると良いと思いました。例えば、SIGNATEの[練習問題] お弁当の需要予測などがあります。
最後にインターンでお世話になった梅田さんがインタビュー記事で僕がインターンでも感じたことを仰っていられました。ぜひ読んでみてください。
https://www.wantedly.com/companies/abema/post_articles/169993