Open In Colab   Open in Kaggle

チュートリアル 1: ディープラーニングケーススタディ 2: アーキテクチャとマルチモーダルDL

第3週、第2日目: DLケーススタディ 2

Neuromatch Academyによる

コンテンツ作成者: Konrad Kording, Lyle Ungar

コンテンツレビュアー: Kelson Shilling-Scrivo

コンテンツ編集者: Kelson Shilling-Scrivo

制作編集者: Gagana B, Spiros Chavlis


チュートリアルの目的

このチュートリアルでは、ディープラーニングの実践者の視点で考え、さまざまなシナリオに対してアーキテクチャを設計する方法を練習します。

このチュートリアルの終わりまでには、以下のことがよりよくできるようになります:

また、ドメイン専門家から関連情報を引き出す方法、これはDLにおける中心的なスキルとも言えますが、それを実際のアプローチの論理に変換する方法も引き続き学びます。

# @title Tutorial slides
from IPython.display import IFrame
link_id = "teq6v"
print(f"If you want to download the slides: https://osf.io/download/{link_id}/")
IFrame(src=f"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render", width=854, height=480)

セットアップ

# @title Install and import feedback gadget


from vibecheck import DatatopsContentReviewContainer
def content_review(notebook_section: str):
    return DatatopsContentReviewContainer(
        "",  # No text prompt
        notebook_section,
        {
            "url": "https://pmyvdlilci.execute-api.us-east-1.amazonaws.com/klab",
            "name": "neuromatch_dl",
            "user_key": "f379rz8y",
        },
    ).render()


feedback_prefix = "W3D2_T1"

セクション 1: ディープラーニングケーススタディ 2 のイントロダクション

所要時間の目安: 約4分

# @title Video 1: Intro to DL Case Study 2
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'I0PNDBF0Sxg'), ('Bilibili', 'BV19Y4y1J742')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Intro_to_DL_Case_Study_2_Video")

ディープラーニングケーススタディ 1 と同様に、このチュートリアルは他のものとは少し異なります。コーディングはありません!代わりに、ニューラルネットワークを使いたいさまざまなシナリオについての一連の短い映像を見ます。このチュートリアルは、さまざまなアーキテクチャとマルチモーダルDLに焦点を当てています。

以下の各セクションは、LyleかKonradのどちらかが特定の問題に対してニューラルネットワークをどう設定するかを考えている短い映像から始まります。視聴しながら彼らに質問したいことを考え、LyleやKonradがどんな質問をしているかに注目してください。あなたがしたいと思った質問と同じでしたか?彼らの質問は状況を素早く明確にするのにどう役立っていますか?


セクション 2: もっとデータを集める

所要時間の目安: 約15分

# @title Video 2: Getting More Data Vignette
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'Gswf3m0lAro'), ('Bilibili', 'BV1XY411N7uq')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Getting_More_Vignette_Video")

Konradは、画像内の物体に基づいて画像を分類するニューラルネットワークを作りたいと考えています。正確なネットワークを訓練するためにもっと多くのデータが必要ですが、画像を購入するのはコストがかかります。別の解決策が必要です。

考えてみよう!1: もっとデータを集める戦略の設計

知っていることを踏まえて、Konradが訓練している画像分類ニューラルネットワークのために、画像とそれが何の物体かのラベルのペアのデータをもっと集める戦略をどう設計しますか?具体的に手順を書いてください。

グループで話し合ってください。行き詰まったら、以下のヒントを一つずつ開けてみてください。ただし、次のヒントを開ける前に少し話し合う時間を取ってください!今あなたは本物のディープラーニング科学者です。答えは簡単ではありません。

ヒント 1 を見るにはここをクリック

犬の写真をいくつか見てみましょう(画像検索エンジンを使ってください)。それらはどのように似ていますか?どのように違いますか?何がそれらをすべて犬にしているのでしょうか?

ヒント 2 を見るにはここをクリック

ニューラルネットワークに各物体の例をもっと与えるために、新しい画像を取得する必要はありません。

ヒント 3 を見るにはここをクリック

色、向き、反転、ピクセルノイズ、色ノイズ、せん断、コントラスト、明るさ、スケーリングについて考えてみてください。

ヒント 4 を見るにはここをクリック

これらのアイデアはどこで破綻するでしょうか?良いものもやりすぎると良くないことがありますか?

解答を見るにはここをクリック

新しいデータを集める代わりに、既存の画像それぞれに対して、左右反転、水平・垂直方向へのピクセル単位のシフト、拡大縮小(クロップを含む)、回転、コントラストや明るさの変更などを行い、ニューラルネットワークに複数の例を作成できます。

これはデータ拡張(data augmentation)と呼ばれ、ニューラルネットワークの訓練で非常によく使われる重要な戦略です。

重要なのは、画像の変化量に注意し、まだ有用な訓練画像であることを保つことです。例えば犬の写真を1000倍に拡大して中央を切り取ると、毛皮の一部だけの画像になり、犬の分類に役立つ訓練例とはなりません。したがって、画像の特徴を変えつつも、元の物体として認識可能な範囲に留める必要があります。

# @title Submit your feedback
content_review(f"{feedback_prefix}_Getting_More_Data_Discussion")

まとめ

# @title Video 3: Getting More Data Wrap-up
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'GcGJNF-wIb0'), ('Bilibili', 'BV1X94y1y7nJ')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Getting_More_Data_WrapUp_Video")

上のビデオで紹介された論文をチェックしてください:

  • Balestriero, R., Bottou, L., LeCun, Y. (2022). The Effects of Regularization and Data Augmentation are Class Dependent. arxiv: 2204.03632

(ボーナス)考えてみよう!: クラス別戦略

物体や画像のクラスによってこれらの戦略をどう変えたいか話し合ってみてください。

# @title Submit your feedback
content_review(f"{feedback_prefix}_ClassBased_strategies_Bonus_Discussion")

セクション 3: 腫瘍検出 - それでもデータが足りない場合の対処法

所要時間の目安: 約15分

# @title Video 4: Detecting Tumors Vignette
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'dRRRuiQctXY'), ('Bilibili', 'BV1Fr4y177An')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Detecting_Tumors_Vignette_Video")
# @title Video 5: Detecting Tumors Set-up
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', '0UZ2qia2pG4'), ('Bilibili', 'BV1C3411u74T')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Detecting_Tumors_SetUp_Video")

Konradは病院で働いており、脳スキャン画像から腫瘍を自動検出するニューラルネットワークを訓練したいと考えています。このタイプの腫瘍はかなり稀で、人類にとっては良いことですが、ニューラルネットワークの訓練例は数千例しかありません。これは十分ではありません。

他のタイプの腫瘍画像を追加しても、まだデータは不足しています。ただし、ImageNetには猫や犬など他の多くの画像があります。これを使えるかもしれません。

考えてみよう!2: 腫瘍検出のための戦略設計

知っていることを踏まえて、正確な腫瘍検出ニューラルネットワークを訓練できる戦略をどう設計しますか?具体的に手順を書いてください。

グループで話し合ってください。行き詰まったら、以下のヒントを一つずつ開けてみてください。ただし、次のヒントを開ける前に少し話し合う時間を取ってください!今あなたは本物のディープラーニング科学者です。答えは簡単ではありません。

ヒント 1 を見るにはここをクリック

データ拡張は常に検討すべきことです。

ヒント 2 を見るにはここをクリック

腫瘍を検出する人間は、腫瘍画像だけからゼロから視覚を学習しているわけではありません。

ヒント 3 を見るにはここをクリック

別のデータセットを使うことができます。そのようなデータセットはどんな特性を持つべきでしょうか?

ヒント 4 を見るにはここをクリック

ImageNetの画像は腫瘍ではありませんが、自然画像は腫瘍に似た視覚的特徴(連続性や局所的な滑らかさなど)を含みます。

ImageNetでニューラルネットワークをまず訓練し、一般的な視覚処理や画像の埋め込みを学習させた後、腫瘍画像のデータセットで訓練するときに何を変えたいでしょうか?

解答を見るにはここをクリック

人間は新しい分類タスクを学ぶときに視覚をゼロから学習しません。すでに自然画像を処理し埋め込みを学習する訓練された視覚システムを持っています。

これをニューラルネットワークで再現できます。まずImageNetだけで物体分類を行うようにニューラルネットワークを訓練します。これにより、画像処理と埋め込みを学習したネットワークが得られます。

次に、このネットワークの最終層(ImageNetのクラス確率を出力する層)を切り離し、腫瘍の有無を出力する新しい層を訓練します。

畳み込み層の重みをImageNet訓練後に固定する方法や、微調整(ファインチューニング)する方法の両方があります。どちらの戦略も使われています。

この一連のプロセスは事前学習(pre-training)と呼ばれます。実際のタスクである腫瘍検出の訓練前にImageNetで事前学習を行うわけです。

ここで言及しておくと、これには多くの方法があります。最初のタスクで全ネットワークを訓練後に全体を訓練する方法、下層を訓練後に上層だけを訓練する方法、あるいはその両方を組み合わせる方法などです。事前学習は多様な方法があり、機会として捉えることが重要です。

# @title Submit your feedback
content_review(f"{feedback_prefix}_Detecting_Tumors_Discussion")

まとめ

# @title Video 6: Detecting Tumors Wrap-up
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'fAD2Bo49LgE'), ('Bilibili', 'BV1zS4y1H7TL')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Detecting_Tumors_WrapUp_Video")

上のビデオで紹介された論文をチェックしてください:

  • Tschandl, P., Rinner, C., Apalla, Z. et al. (2020). Human–computer collaboration for skin cancer recognition. Nat Med 26: 1229–1234. doi: 10.1038/s41591-020-0942-0

セクション 4: フォレスト・ガンプの脳

所要時間の目安: 約17分

# @title Video 7: Brains on Forrest Gump Vignette
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'R7H4ybe7gck'), ('Bilibili', 'BV1af4y1f7MR')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Brains_on_Forrest_Gump_Vignette_Video")
# @title Video 8:  Brains on Forrest Gump Set-up
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'TcBNbGez5BY'), ('Bilibili', 'BV1NY411K7f6')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Brains_on_Forrest_Gump_SetUp_Video")

Konradは素晴らしいデータセットを持っています。ある人が映画『フォレスト・ガンプ』を見ている間のMRIデータ(脳画像)を全時間にわたって取得しています。つまり、動画の時間的ストリームと脳データの時間的ストリームがあります。彼はこの二つのデータストリームの共通点を見つけたいのです。言い換えれば、二つの異なるモダリティの共有情報を抽出したいのです。

考えてみよう!3: 脳データとフォレスト・ガンプの共有情報抽出戦略の設計

知っていることを踏まえて、脳データと動画データの共有埋め込みを得る戦略をどう設計しますか?具体的に手順を書いてください。

グループで話し合ってください。行き詰まったら、以下のヒントを一つずつ開けてみてください。ただし、次のヒントを開ける前に少し話し合う時間を取ってください!今あなたは本物のディープラーニング科学者です。答えは簡単ではありません。

ヒント 1 を見るにはここをクリック

二つのデータセットに共通するものを持たせたい。これはどういう意味でしょうか?

ヒント 2 を見るにはここをクリック

ベクトル Xˉ1\bar{X}_1Xˉ2\bar{X}_2 はどこから来るでしょうか?脳データと動画データにどう関連するでしょうか?

ヒント 3 を見るにはここをクリック

複数のニューラルネットワークを使いたいかもしれません!

ヒント 4 を見るにはここをクリック

ここでニューラルネットワークの解決策に何をしてほしいですか?最大化または最小化したいものはありますか?

ヒント 5 を見るにはここをクリック

すべての活動を2倍にしたらどうなりますか?スケールに不変な解決策が必要です。

解答を見るにはここをクリック

まず、脳データ用の埋め込みと動画データ用の埋め込み、二つの埋め込みが必要です。

次に、これらの埋め込みが二つのデータ間の共有情報を捉えることが望まれます。

ポイントは、両方の埋め込みが同じ情報を含んでいれば、それらは相関しているはずだということです。

ピアソン相関の式を見てみましょう:


ρ=cov(X1,X2)var(X1)var(X2)\rho = \frac{\text{cov}(X_1, X_2)}{\text{var}(X_1) \cdot \text{var}(X_2)}

ここで X1X_1X2X_2 は二つの埋め込みです。相関を求めるには共分散を取り、それを二つの分散の積で正規化します。これによりスケール不変な量が得られ、最適化できます。

ノイズがなく両方の埋め込みが同じ情報を抽出している極端な場合を想像してください。両者は完全に相関します。逆に共有情報がなければ相関はほとんどありません。したがって、二つの埋め込み空間の相関を最大化することは、共有情報を最大化することに等しいのです。

別の見方をすると、相関を最大化することで脳データとANNデータの共通埋め込みを得ようとしていることになります。両方のネットワークが同じ情報を抽出すれば可能です。

両方の埋め込みが少し異なる情報を抽出すれば、埋め込みも少し異なります。したがって、埋め込みがより似て(つまり相関が高く)なるほど、抽出される情報もより似ていることになります。

# @title Submit your feedback
content_review(f"{feedback_prefix}_Brains_on_Forrest_Gump_Discussion")

まとめ

# @title Video 9: Brains on Forrest Gump Wrap-up
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', '5rp9utqRvWY'), ('Bilibili', 'BV1fv4y1M7eQ')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_Brains_on_Forrest_Gump_WrapUp_Video")

上のビデオで紹介された論文をチェックしてください:

  • Andrew, G., Arora, R., Bilmes, J., Livescu, K. (2013). Deep Canonical Correlation Analysis. Proceedings of the 30th International Conference on Machine Learning, PMLR 28(3):1247-1255. url: proceedings.mlr.press/v28/andrew13

まとめ

所要時間の目安: 約2分

# @title Video 10: Wrap-up of DL Case Study
from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'p9vQLAfrYJQ'), ('Bilibili', 'BV1nf4y1f7oL')]
tab_contents = display_videos(video_ids, W=854, H=480)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)
# @title Submit your feedback
content_review(f"{feedback_prefix}_WrapUp_of_DL_Case_Study_Video")

このチュートリアルでは、非常に限られたデータしかない場合にうまくやるためのいくつかのトリックを見ました:

  • データ拡張
  • 事前学習
  • 正準相関分析(CCA)

これら3つはすべて、利用可能なデータが限られている場合に使えます。また、関連情報が明確になることや、世界の知見がディープラーニングのアプローチにどう翻訳されるかを教えてくれます。