obの関手性

ごさいようじょです。これはMathjaxのテストです。

$\mathcal{C}$を局所小圏、$\textbf{Cat}$を局所小圏とその間の関手の圏とします。
このとき圏論的な対象への対応$\text{ob}$は関手 $\text{ob}: \textbf{Cat} \rightarrow \textbf{Set}$として振る舞います。

具体的には$\text{ob}$を
\begin{align}
&(対象)~\forall \mathcal{A} \in \textbf{Cat}, \\
&~~\text{ob}(\cdot)(\mathcal{A}) = \text{ob}(\mathcal{A})\\
&(射) ~ \mathcal{A} \xrightarrow{\forall F} \mathcal{B}, \forall A \in\mathcal{A},\\
&~~\text{ob}(F)(A) = F(A)
\end{align}
と定義します。

これは$\mathcal{A} \in \textbf{Cat}$の対象を、各々の小圏の対象に関する関手(の二つ組の片割れ)を保存し、その射$\text{ar}(\mathcal{A})=\{A \xrightarrow{f} A' ,~\forall A, A' \in \mathcal{A}\}$の対応を忘却するような感じで$\textbf{Set}$に写す対応になっています。
(忘却関手と言えそうな感じがする)

proof

(恒等射の保存)

$\forall \mathcal{A} \in \textbf{Cat}$に対して恒等関手を$1_\mathcal{A}$とします。
このとき$A \in \text{ob}(\mathcal{A})$に対して
\begin{align}
\text{ob}(1_\mathcal{A})(A) &= 1_\mathcal{A}(A) &\qquad (\text{ob}の定義) \\
&= A&\\
&= 1_{\text{ob}(\mathcal{A})}(A)
\end{align}

より $\text{ob}(1_\mathcal{A}) = 1_{\text{ob}(\mathcal{A})}$ がいえます。

(合成射)

$ \mathcal{A} \xrightarrow{\forall F} \mathcal{B} \xrightarrow{\forall G} \mathcal{C}$とします。
このとき合成関手$G \circ F, ~\forall A \in \mathcal{A}$にたいして

\begin{align}
\text{ob} (G \circ F)(A) &= (G \circ F) (A) &\qquad (\text{ob}の定義)\\
&=(\text{ob}(G) \circ \text{ob}(F))(A) &\qquad(対象に対して\text{ob}(F) = Fなので)
\end{align}

よって$\text{ob} (G \circ F) = \text{ob}(G) \circ \text{ob}(F)$.

なのでobは局所小圏に対して関手$\mathbf{Cat} \rightarrow \mathbf{Set}$を定めることがわかりました*1

自然に出てきた対象への対応$\text{ob}$が実は関手的であったというのはおもしろいですね。
とても童心をくすぐるものだと思います。

*1:これ、局所小圏じゃなくて大きな圏の場合には関手にはならないんですかね。 $\text{ob}: \textbf{CAT} \rightarrow \textbf{Cls}$? $\textbf{Cls}$なんてあるのか…?

日本ディープラーニング協会ジェネラリスト検定 受験記

ごさいようじょです。

2017年12月16日、第一回目の実施となる日本ディープラーニング協会(JDLA)ジェネラリスト検定(G検定)を受験し、
本日26日、無事に合格判定を頂きました。
得点は~~~満点中**点でした。(これは観測され次第状態が定まる不思議な文字列です。しばしお待ちください。)

せっかくなので受験記をここに記したいと思います。

ここで、このエントリの内容は単に個人の感想であり、記載された以上の内容、例えば筆者の気持ちなどを推し量り、見出してはなりません。 ご了承ください。

f:id:tochikuji:20171226220124p:plain

プロフィール

「東大受験記」、「オラクルマスター受験記」的な記事をみる感じ、受験記の最初にはプロフィールを書くらしいのでやります。

  • 名前: ごさいようじょ
  • 年齢: 5
  • 職種: 国立 はなまる幼稚園 年長組
  • 勉強期間: 0時間
  • 受験目的: 記念受験
  • 勉強形態: 独学
  • 実務経験: 未就学児
  • 何度目の挑戦か: 1回目

上は適当なこと書いてありますが、実際のところ私は情報系の人間ではないものの、ここ2~3年ほど流行りに乗ってディープラーニングやら、その周辺領域の研究をしている女児です。
ただ専門的にはILSVRCでAccuracy勝負をするようなガチガチのディープラーニング屋ではなく、どちらかと言えばトラディショナルなニューロ屋とか横断領域の人間といったほうがおそらく適切かと思います。
少なくともDeep Learningという言葉を多用する世界線には居ません。
deep neural networks, recently known as deep learning ですかね。

推薦図書

よく知らなかったのですが、検定には推薦図書とやらがあったそうです。
読了状況は以下になります。

AI白書 2017

AI白書 2017

AI白書 2017

IPAからこんな本出てたんですね。知らなかったです。
後述しますがよくわからなかった問題はこの本から出てたのかな、と思います。

人工知能は人間を超えるか ディープラーニングの先にあるもの

松尾先生が書かれた本らしいです。キャッチーなタイトルですね。
Kindle版が500円しないらしいので今度暇なときに読んでみます。

深層学習 機械学習プロフェッショナルシリーズ

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)

読みました。当然です。俗に言う青本/岡谷本ですね。言うまでもなく良書です。

ちなみに青本というと、もう一冊の深層学習に関する良書も、人工知能学会誌の特集を集めたやつも「青本」なので紛らわしいところです。

深層学習 Deep Learning

深層学習 Deep Learning

蛇足ですが、深層学習にとっつくのは最初は下のJSAIの青本のほうが網羅的で、歴史的なところとかそういうのもきちんと書いてあって個人的にはオススメです。
ただ簡潔かつ密度高く書かれていて少々わかりにくいところもあるので、そこは軽く読み飛ばして、岡谷先生の本を読んでもう一回戻ってくるのがよいと思います。

まあ最初に「よく知らなかったのですが」とか言ってる時点でそういうことです。舐めプはやめましょう。

ちなみにこういう書評みたいの、「あふぃりえいと」っていうのをやるとすごく儲かるって聞いたんですけど誰か教えてください。

勉強方法

試験対策的な勉強は一切していませんが、(国語の)作文とか(お遊戯会の)発表をするときに必要になるので、AIの歴史的側面みたいなものはなんとなく抑えています。
研究のスコープ的にはコンピュータビジョン屋なので、CV系の話についてはある程度は最近の研究なんかも追えているつもりです。
一方で強化学習周りや、特に自然言語処理の周辺はからっきし(小耳に挟む程度)なので、そのへんは素直に勉強が足りなかったな、どう考えたってやるべきだったよなと思います。
いえ普通に舐めプでしたすみません許してください何でもしますから

所感など

まず試験の難易度について、舐めプしといてなんですが普通に高かったと思います。
合格率は60%を切っており、休日のオンライン受験で受験率は高いであろうことを鑑みると、まあなかなかといったところですね。

受験形式は多岐選択式で、出題数は当初の予告は100問とのことでしたが、実際は 中問が 100問で小問は230問とかそのくらいあってびっくりしました。

内容としては、 あんまり言うと怒られそうなのでぼかしますが、出題範囲は

例えば

とかとか、いや書いてみて思いましたが、本当に多岐にわたっていました。
法律とかそういうよくわかんないのはAI白書に書いてあるっぽいですね。
設問内容に関して特に、2017年の [1706.00712] Convolutional Neural Networks for Medical Image Analysis: Full Training or Fine Tuning? で触れられている内容について問う問題があって、結構おおっと思いました。 なかなかナウいですね。イケてますよ。

個人的な出来としては、その辺のテクノロジ的な所はよいとしても、 それ以外のジェネラリストっぽい「人工知能」然としたところ(シンギュラリティーについてこんな有名人が〜〜と言ったとか 知らねえよ)とか、AIに関する法律みたいなところは本当にボロボロでchance levelくらいの正答率しかないと思います。
それでも一応合格はいただくことができたので、合格ラインはまあ普通に6~7割のあたりではないかな、と推測します。

細かい部分を問われる問題も多かったですが、設問全体を通して特に強調されていたのが
「AI(DNN)を実応用するにあたって最も重要なのは、AIに何ができて何ができないのかをしっかり認識すること」
ということでした。
これに関しては、本当の本当に、全く以って、心の底から、全力で共感することであり、このことが共通認識となってくれるだけで人工知能技術の実社会応用の推進の助けになると思いますし、何より実際に問題に取り組む理系職が、このブームの中で無茶振りに揉まれて死んでゆくのを止めることができるのではないかな、と思います。

設問の細かなところには首をかしげるところも皆無とは言えなかったのですが、上のメッセージを広く・強く伝えてくださるだけでも十分な価値ある検定試験だと思います。

受験のアドバイス

当該分野についてバリバリ業務で使っていたり、今red oceanの中で絶賛泳ぎ回っている方を除いて、ノー勉は普通に無謀だと思います。
とはいえこの範囲をずぶの素人の方が全部カバーするのもなかなか難しいと思うので、指定図書をざっと読んで、エンジニアの方はモデルの内容とか数理的なバックエンド、 営業とかコンサルの方は歴史、法律、応用事例とかそういうのにフォーカスして 確実に8割取りに行く つもりで臨むのがよいと思います。

合格すると名刺にJDLA Generalistって書いていいらしいのでがんばりましょう。

おわりに

無事合格してよかったです。
門外漢の方が落ちてもまあ、ですが、ようじょの場合ド専門なのでシャレになりません。

続きを読む

Pythonのlist.__mul__

ごさいようじょです。

まずは感じてください。

wandbox.org

これでわかった、とか、知ってるわ、という方は少なくともごさいようじょよりPythonができます。

いま

a = [[]] * 3

[[], [], []]

を作ります。
Pythonicではないとかそういうのは後にしてください。
女児にそういうのを求めるのは野暮というもので、ところで、野暮って言葉の意味知ってますか?

先頭要素の空リストに何かをappendします。

a[0].append(1)

純粋な心を持っているので、ここで

[[1], [], []]

を期待します。

しかし上にあるように実際a

[[1], [1], [1]]

になります。

つまり

[~] * n

で返ってくる

[~, ~, ~]

~の各々は同じ実体、というわけです。

蛇足です。

wandbox.org

さもありなん。

Pythonの「基本は参照」という原則からすると、まあわかりますが気を付けてないとふとした時に踏み抜きます。
(損失は概ね1時間でした)

ここからはもっと蛇足です。

さて、list.__mul__はmethod_wrapperです。
実装は多分これです。

cpython/listobject.c at 3.6 · python/cpython · GitHub

static PyObject *
list_repeat(PyListObject *a, Py_ssize_t n)
{
    Py_ssize_t i, j;
    Py_ssize_t size;
    PyListObject *np;
    PyObject **p, **items;
    PyObject *elem;
    if (n < 0)
        n = 0;
    if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n)
        return PyErr_NoMemory();
    size = Py_SIZE(a) * n;github
    if (size == 0)
        return PyList_New(0);

    np = (PyListObject *) PyList_New(size);
    if (np == NULL)
        return NULL;

    items = np->ob_item;
    if (Py_SIZE(a) == 1) {
        elem = a->ob_item[0];
        for (i = 0; i < n; i++) {
            items[i] = elem;
            Py_INCREF(elem);
        }
        return (PyObject *) np;
    }
    p = np->ob_item;
    items = a->ob_item;
    for (i = 0; i < n; i++) {
        for (j = 0; j < Py_SIZE(a); j++) {
            *p = items[j];
            Py_INCREF(*p);
            p++;
        }
    }
    return (PyObject *) np;
}

(これって行番号つかないんですか?)

528, 537行目からが実際のコピー処理です。
elem, pはそれぞれ格納先の各要素(PyObject**), for中のelemが元要素(上の対応では~)です。

ポインタを渡しているので、参照です。(雑理論)

またPy_INCREFでelemの参照カウンタをインクリメントしているのでここからもコピーっぽくないのが感じられます。(雑推論)

つまりそういうことなので、データサイエンティストの皆様におかれましてはPythonのコードはPythonicに書かれることを推奨いたします。