2016-10-30 3 views
2

ダニエル・ノウリのtutorialさんにCNNを使った顔認識についてお伝えしていますが、わかりません。これはある意味、中しかし、実際の実装を行いこのクラスの__call__メソッドは、適切な引数なしで呼び出されるとどのように動作しますか?

class EarlyStopping(object): 
    def __init__(self, patience=100): 
     self.patience = patience 
     self.best_valid = np.inf 
     self.best_valid_epoch = 0 
     self.best_weights = None 

    def __call__(self, nn, train_history): 
     current_valid = train_history[-1]['valid_loss'] 
     current_epoch = train_history[-1]['epoch'] 
     if current_valid < self.best_valid: 
      self.best_valid = current_valid 
      self.best_valid_epoch = current_epoch 
      self.best_weights = nn.get_all_params_values() 
     elif self.best_valid_epoch + self.patience < current_epoch: 
      print("Early stopping.") 
      print("Best valid loss was {:.6f} at epoch {}.".format(
       self.best_valid, self.best_valid_epoch)) 
      nn.load_params_from(self.best_weights) 
      raise StopIteration() 

:ダニエルは訓練が早期に停止する必要があるかどうかを決定すること、ネットワークのトレーニング中の各反復の終了時に呼び出されるクラスを定義していますコードは次のようになります。

net8 = NeuralNet(
# ... 
on_epoch_finished=[ 
    AdjustVariable('update_learning_rate', start=0.03, stop=0.0001), 
    AdjustVariable('update_momentum', start=0.9, stop=0.999), 
    EarlyStopping(patience=200), 
    ], 
# ... 
) 

明らかにDanielはクラスを関数として呼び出しています。しかし、私は彼が__call__(args)に示されている引数なしでそれをどのように呼び出すのか理解していません。これは、nolearnのソースコードに実装されるべきものなのでしょうか?私は、ネットワークがnntrain_historyをどのように関数に渡されることなく使用するのかについて混乱しています。

答えて

4

彼はむしろ、彼はの署名で*EarlyStopping.__init__を呼び出すことだ、EarlyStopping(patience=200)__call__を起動されていません。

def __init__(self, patience=100): 

patienceの代替値を提供します。これは__init__の引数と完全に一致します。

EarlyStopping.__call__のインスタンスでが呼び出されます。つまり、一連の呼び出しが:

e = EarlyStopping(patience = 200) 
e(patience=50) # TypeError Raised 

の場合は、適切なエラーが発生します。


* を離れて投げる括弧は、実際にコールを作っています。呼び出しはEarlyStopping.__call__ではなく、type.__call__に、EarlyStoppingの(メタ)クラスが呼び出されます。 type.__call__は、オブジェクトを初期化するときにPythonによって実行される最初のアクションです。渡された引数を受け入れるように呼び出され、次に(他のアクションの後で)__new____init__の順に呼び出されます。本質的には__init__が引数patience=100で間接的に呼び出されます。

+0

これで、初期化されたオブジェクトは、適切な引数を付けてNeuralNetのソースコードのどこかで呼び出されます。この機能を実装するのは奇妙な方法のようです。なぜ関数を渡すだけではないのですか? –

関連する問題