pythonの関数がわからない
今まではC++をメインに使ってきましたが、大学で機械学習の勉強を始めたのでpython
を書き始めました。
ゼロから作るDeepLearnigという本を読んでいるのですが、コードをみていていまいちすっきりと理解できない部分がありました。
importしている関数と定義している関数名が同じ
下の『該当のソースコード内』の以下の部分で他のファイルからnumerical_gradient
関数をimportしています。
python
1from common.gradient import numerical_gradient
しかし、以下の部分ではimportした関数と全く同じ関数名をclass内で定義しています。
その定義した関数内でimportした numerical_gradient
関数を使用しています。
python
1def numerical_gradient(self, x, t): 2 loss_W = lambda W: self.loss(x, t) 3 4 grads = {} 5 grads['W1'] = numerical_gradient(loss_W, self.params['W1']) 6 grads['b1'] = numerical_gradient(loss_W, self.params['b1']) 7 grads['W2'] = numerical_gradient(loss_W, self.params['W2']) 8 grads['b2'] = numerical_gradient(loss_W, self.params['b2']) 9 10 return grads
これでいいのだろうと納得すればいいのですが、これでは再起関数になってしまはないのか?と疑問に感じてしまいます。
これでなぜ再起関数にならずにimportした同じ名前の関数が優先されるのかを知りたいです。
該当のソースコード
import sys, os sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定 from common.functions import * from common.gradient import numerical_gradient import numpy as np class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): # 重みの初期化 self.params = {} self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size) self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size) self.params['b2'] = np.zeros(output_size) def predict(self, x): W1, W2 = self.params['W1'], self.params['W2'] b1, b2 = self.params['b1'], self.params['b2'] a1 = np.dot(x, W1) + b1 z1 = sigmoid(a1) a2 = np.dot(z1, W2) + b2 y = softmax(a2) return y # x:入力データ, t:教師データ def loss(self, x, t): y = self.predict(x) return cross_entropy_error(y, t) def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) t = np.argmax(t, axis=1) accuracy = np.sum(y == t) / float(x.shape[0]) return accuracy # x:入力データ, t:教師データ def numerical_gradient(self, x, t): loss_W = lambda W: self.loss(x, t) grads = {} grads['W1'] = numerical_gradient(loss_W, self.params['W1']) grads['b1'] = numerical_gradient(loss_W, self.params['b1']) grads['W2'] = numerical_gradient(loss_W, self.params['W2']) grads['b2'] = numerical_gradient(loss_W, self.params['b2']) return grads def gradient(self, x, t): W1, W2 = self.params['W1'], self.params['W2'] b1, b2 = self.params['b1'], self.params['b2'] grads = {} batch_num = x.shape[0] # forward a1 = np.dot(x, W1) + b1 z1 = sigmoid(a1) a2 = np.dot(z1, W2) + b2 y = softmax(a2) # backward dy = (y - t) / batch_num grads['W2'] = np.dot(z1.T, dy) grads['b2'] = np.sum(dy, axis=0) dz1 = np.dot(dy, W2.T) da1 = sigmoid_grad(a1) * dz1 grads['W1'] = np.dot(x.T, da1) grads['b1'] = np.sum(da1, axis=0) return grads
補足情報
importしたnumerical_gradient
関数です。
python
1def numerical_gradient(f, x): 2 h = 1e-4 # 0.0001 3 grad = np.zeros_like(x) 4 5 it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) 6 while not it.finished: 7 idx = it.multi_index 8 tmp_val = x[idx] 9 x[idx] = tmp_val + h 10 fxh1 = f(x) # f(x+h) 11 12 x[idx] = tmp_val - h 13 fxh2 = f(x) # f(x-h) 14 grad[idx] = (fxh1 - fxh2) / (2*h) 15 16 x[idx] = tmp_val # 値を元に戻す 17 it.iternext() 18 19 return grad
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。