質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2853閲覧

○○ = self(x) を教えてください。

beggier1

総合スコア7

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

1グッド

0クリップ

投稿2020/06/30 14:08

編集2020/06/30 14:10

https://github.com/YutaroOgawa/Deep-Reinforcement-Learning-Book/blob/master/program/6_5_A2C_Advanced_ActorCritic.ipynb

上記のコードで強化学習を学習しております。
5つ目のセルを以下に抜粋します。

質問1
foward が5つ目のセル以外で使われているところを発見できないのですが、どこで使用しているのでしょうか?
この関数においてニューラルネットワークに学習データを与え、出力していると考えているのですが...
無いのであればなぜこの関数は書かれていて、他のどこでニューラルネットワークに学習データを与えているのでしょうか?

質問2
act関数の中に
value, actor_output = self(x)
が見られるのですが、self(x)とは何ですか?
selfはインスタンス自身という認識で今までこのような使い方をしたことがなく疑問を持っています。
推測としては
ニューラルネットワークに学習データを与え、出てきた出力をvalue, actor_outputに格納していると考えています。
するとself(x)はforward関数を表すのでしょうか?

質問3
また、以下に質問2に対する自分の理解の為に作成したコードとエラー文を載せておきます。
エラー文を見るとself(x)の使い方にエラーが出ていると考えています。
この書き方はPyTorch特有の書き方なのでしょうか?

質問が多く申し訳ありませんが、一つにでも答えていただけると大変ありがたいです。
よろしければご回答の程よろしくお願いします。

最後となりますが、teratailになれていないため質問の仕方等わかりずらい、ルールに基づいていない等あると思います。
その際は是非ご指摘お願いします。

#5つ目 class Net(nn.Module): def __init__(self, n_in, n_mid, n_out): super(Net, self).__init__() self.fc1 = nn.Linear(n_in, n_mid) self.fc2 = nn.Linear(n_mid, n_mid) self.actor = nn.Linear(n_mid, n_out) # 行動を決めるので出力は行動の種類数 self.critic = nn.Linear(n_mid, 1) # 状態価値なので出力は1つ def forward(self, x): '''ネットワークのフォワード計算を定義します''' h1 = F.relu(self.fc1(x)) h2 = F.relu(self.fc2(h1)) critic_output = self.critic(h2) # 状態価値の計算 actor_output = self.actor(h2) # 行動の計算 return critic_output, actor_output def act(self, x): '''状態xから行動を確率的に求めます''' value, actor_output = self(x) # dim=1で行動の種類方向にsoftmaxを計算 action_probs = F.softmax(actor_output, dim=1) action = action_probs.multinomial(num_samples=1) # dim=1で行動の種類方向に確率計算 return action
#自作 class A: def __init__(self,a1): self.unk = a1 def forward(self,x): y = x + 2 z = x*3 print("forwardに入った") return y,z def act(self,x): print("actに入った") y,z = self(x) return y,z a = A(1) print(a.act(5)) #エラー文 TypeError: 'A' object is not callable
jtmk👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問2

self(x)とは何ですか?

self は自身のインスタンスを指します。
Python では、インスタンスに対して、() で関数のように呼び出す (例: myobj()) と関数呼び出しといって特殊メソッド __call__() が呼ばれます。
なので、self() は自身のインスタンスの関数呼び出しになります。

__call__でクラスインスタンスを関数のように呼び出す - Qiita

python

1class Myclass: 2 def __call__(self, x): 3 return x + 1 4 5obj = Myclass() 6print(obj(1)) # 2

質問1

無いのであればなぜこの関数は書かれていて、他のどこでニューラルネットワークに学習データを与えているのでしょうか?

Pytorch では、nn.Module クラスの __call__() 関数内で forward() を呼び出すようになっています。
なので、nn.Module クラスを継承したクラスで forward() 関数を実装しておけば、そのクラスのインスタンスに対して、() で関数呼び出ししたら、実質的に forward() の中身が呼ばれるという仕組みです。

質問3

以下に質問2に対する自分の理解の為に作成したコードとエラー文を載せておきます。

TypeError: 'A' object is not callable
型エラー: オブジェクト A は関数呼び出し可能ではありません。

callable (呼び出し可能) とは、() で関数呼び出しができるという要件を意味しますが、質問のコードだと、__call__() が実装されていないクラス A に対して、関数呼び出ししようとしているので、できないいうエラーです。

「nn.Module を継承したクラスで forward() を実装すると、model() のように呼び出した際に forward() が呼ばれる事」は以下のコードで説明がつきます。

python

1class Myclass: 2 def __call__(self, x): 3 return self.hoge(x) 4 5 def hoge(): 6 pass 7 8 9class MySubClass(Myclass): 10 def hoge(self, x): # 親クラスの関数 hoge() をオーバーライド 11 return x + 1 12 13 14obj = MySubClass() 15print(obj(1)) # 2

投稿2020/06/30 19:11

編集2020/06/30 19:18
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

beggier1

2020/06/30 23:27

ご回答ありがとうございます。 質問2及び3について理解できました。 質問1についてさらに詳しく教えてもらいたいのですが、よろしければご回答お願いします。 forward関数が自動で呼び出される仕組みがあることは理解しました。 しかし、どこでfowarardに引数を渡しているのでしょうか。 記載したURLの8つ目のセルでは actor_critic = Net(n_in, n_mid, n_out) となっており、ここでは初期化メソッドの引数しか与えていないように見えます。
tiitoi

2020/07/01 02:03 編集

actor_critic = Net(n_in, n_mid, n_out) はコンストラクタの呼び出しです。 探すべきなのは作成したオブジェクト actor_critic に対する () による関係呼び出しです。コードを探してみると、 evaluate_actions() 内の Net クラスの関数内に self(x) が3箇所ありますね。
beggier1

2020/07/01 13:18

コメントへの返信ありがとうございます。 nn.Moduleには__call__メソッドがあるため、そのサブクラスNetも__call___メソッドを持っている。 self()によって、__call__メソッドを呼び出すことによって、自動的にfowatdメソッドの呼び出しにつながる仕組みになっていると理解しました。 長々と付き合っていただき感謝しています。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問