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

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

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

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

Q&A

解決済

1回答

1037閲覧

pythonの関数がわからない

kyokio

総合スコア560

Python 3.x

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

0グッド

0クリップ

投稿2020/08/11 08:53

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

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

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

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

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

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

guest

回答1

0

ベストアンサー

すでに同内容の質問がTeratailにありましたほぼ回答になっていると思います。

ゼロから学ぶDeepLearning 4章についての質問

投稿2020/08/11 09:03

aokikenichi

総合スコア2218

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問