39781

[code]

    class MLP(chainer.Chain):
    
    def __init__(self, n_units, n_out):
        super(MLP, self).__init__()
        with self.init_scope():
            self.l1 = L.Linear(None, n_units)  
            self.l2 = L.Linear(None, n_units)  
            self.l3 = L.Linear(None, n_out)    
    
    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        return self.l3(h2)
    
[/code]

chainerでモデルを作成している上記コードで`super(MLP,
self).__init__`の意味がわかりません。`super()`はサブクラスからスーパークラスを参照して、スーパークラスを利用するという認識だったのですが、ここでは`super`がサブクラス`MLP`のなかで`MLP`を参照しています。どうしてでしょうか。また、`super(MLP,
self).__init__`と`with self.init_scope()`の意味も合わせて教えていただきたいです。


CC BY-SA 3.0
2017-11-22T18:24:08.407
39769
2017-11-23T03:44:08.750
2017-11-23T03:44:08.750
14744
25909
question
python chainer
スーパークラスの参照について


## `super(MLP, self).__init__` について

Python の組み込み関数 `super()` は引数を指定できます。正確性を犠牲にして簡単に説明すると、`super(aa, bb)` で「`bb`
が属するクラス `aa` の親または兄弟クラス」のような意味になります。

今回の場合、`super(MLP, self).__init__` は `super().__init__`
として想像されるものと同じ意味になります。引数を指定することで、`self` の属するクラス `MLP`
のスーパークラスを表していると明示しています。これらの引数は Python 3 だと省略できるのですが、Python 2
だと省略できません。このためたとえば、Python 2 でも 3 でも動くことが意識されたコードでは必ず明示的に引数を書きます。

なお Python は多重継承を許しているため、Python の `super()` は他の多くのプログラミング言語における `super`
とは挙動が異なります。詳細な説明は Python 3
の[ドキュメント](https://docs.python.jp/3/library/functions.html#super)や、本家  
Stack Overflow の投稿 ["Understanding Python super() with __init__()
methods"](https://stackoverflow.com/q/576169/5989200) をご覧下さい。

## `with self.init_scope()` について

Python の [with 文](https://docs.python.jp/3/reference/compound_stmts.html#the-
with-statement)で、`as` が省略された場合の書き方です。with
文は、処理が実行される前後に特定の処理を入れたい場合などに使われます。本家 Stack Overflow の ["Meaning of “with”
statement without “as” keyword"](https://stackoverflow.com/q/26342769/5989200)
などが分かりやすいと思います。


CC BY-SA 3.0
2017-11-23T03:09:05.923
39781
2017-11-23T03:09:05.923
19110
39769
answer