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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2055閲覧

'function' has no attribute 'eval' への対処法

knght

総合スコア14

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/10/22 13:55

編集2018/10/22 14:52

クラスを用いたNNのモデル作りに慣れおらず、
すっきりしたコーディングを身に付けるため、本を読みながら勉強しています。
ですが、詳解ディープラーニングP.171からのDNNのモデルをクラス化するところで躓いてしまいました。
少しコードは変えているのですが、本ではドロップアウトを用いているのをやめただけで、基本忠実に書きました。
大分省略しますが、最後のmodel.evaluate()のところで、
'function' object has no attribute 'eval'
というエラーが出てしまいます。
クラス内のevaluate関数の中で違う関数(accuracy)を呼び出し.evalで値を出すことにエラーが出ているようなのですが、どのようにすれば実現できますでしょうか??

python

1class MLP: 2 def __init__(self, input_n, output_n, hidden_n, func_n): 3 #... 4 def weight_variable(self, shape): 5 #... 6 def bias_variable(self, shape): 7 #... 8 def inference(self, x): 9 #... 10 def loss(self, y, t): 11 #... 12 def accuracy(self, y, t): 13 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1)) 14 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 15 return accuracy 16 def fit(): 17 #...モデル学習 18 def evaluate(self, X_test, Y_test): 19 return self.accuracy.eval(session=self._sess, feed_dict={ 20 self._x : X_test, 21 self._t : Y_test 22 }) 23 24model = MLP(input_n=784, output_n=10, hidden_n=[500, 300, 100], func_n=[0, 0, 0]) 25model.fit(X_train, Y_train, epochs=50, batch_size=200) 26accuracy = model.evaluate(X_test, Y_test) 27print('accuracy:', accuracy)

クラス内のコードの全文です。

Tensorflow

1 2# activation = [0, 1, 0 ,1] 3# 0 : ReLU, 1 : sigmoid 4class MLP(object): 5 def __init__(self, input_n, output_n, hidden_n, func_n): 6 self.input_n = input_n 7 self.output_n = output_n 8 self.hidden_n = hidden_n 9 self.weights = [] 10 self.biases = [] 11 self.func_n = func_n 12 self._x = None 13 self._t = None 14 self._sess = None 15 self._history = { 16 'accuracy' : [], 17 'loss' : [] 18 } 19 20 21 def weight_variable(self, shape): 22 initial = tf.Variable(tf.random_normal(shape, stddev=0.01)) 23 return initial 24 25 def bias_variable(self, shape): 26 initial = tf.Variable(tf.zeros(shape)) 27 return initial 28 29 def function(self, x, func): 30 if func == 0: 31 return tf.nn.relu(x) 32 if func == 1: 33 return tf.nn.sigmoi(x) 34 35 def inference(self, x): 36 # input-layer - hidden-layer, hidden-layer - hidden-layer 37 for i, hidden in enumerate(self.hidden_n): 38 if i == 0: 39 inp = x 40 input_dim = self.input_n 41 else: 42 inp = output 43 input_dim = self.hidden_n[i-1] 44 45 self.weights.append(self.weight_variable([input_dim, hidden])) 46 self.biases.append(self.bias_variable([hidden])) 47 48 h = tf.matmul(inp, self.weights[-1]) + self.biases[-1] 49 output = self.function(h, self.func_n[i]) 50 51 self.weights.append(self.weight_variable([self.hidden_n[-1], self.output_n])) 52 self.biases.append(self.bias_variable([self.output_n])) 53 54 y = tf.nn.softmax(tf.matmul(output, self.weights[-1]) + self.biases[-1]) 55 56 return y 57 58 59 def loss(self, y, t): 60 loss = tf.reduce_mean(-tf.reduce_sum( 61 t * tf.log(tf.clip_by_value(y, 1e-10, 1.0)), reduction_indices=[1])) 62 return loss 63 64 def training(self, loss): 65 optimizer = tf.train.GradientDescentOptimizer(0.01) 66 train_step = optimizer.minimize(loss) 67 return(loss) 68 69 def accuracy(self, y, t): 70 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(t, 1)) 71 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 72 return accuracy 73 74 def fit(self, X_train, Y_train, epochs=100, batch_size=100): 75 x = tf.placeholder(tf.float32, [None, self.input_n]) 76 t = tf.placeholder(tf.float32, [None, self.output_n]) 77 78 # save for evaluate() 79 self._x = x 80 self._t = t 81 82 y = self.inference(x) 83 loss = self.loss(y, t) 84 train_step = self.training(loss) 85 accuracy = self.accuracy(y, t) 86 87 init = tf.global_variables_initializer() 88 sess = tf.Session() 89 sess.run(init) 90 91 # save for evaluate() 92 self._sess = sess 93 94 N_train = len(X_train) 95 n_batches = N_train // batch_size 96 97 for epoch in range(epochs): 98 X_, Y_ = shuffle(X_train, Y_train) 99 100 for i in range(n_batches): 101 start = i * batch_size 102 end = start + batch_size 103 104 sess.run(train_step, feed_dict={ 105 x : X_train[start:end], 106 t : Y_train[start:end] 107 }) 108 loss_ = loss.eval(session=sess, feed_dict={ 109 x : X_train, 110 t : Y_train 111 }) 112 accuracy_ = accuracy.eval(session=sess, feed_dict={ 113 x : X_train, 114 t : Y_train 115 }) 116 117 # save to _history 118 self._history['loss'].append(loss_) 119 self._history['accuracy'].append(accuracy_) 120 121 return self._history 122 123 124 def evaluate(self, X_test, Y_test): 125 return self.accuracy.eval(session=self._sess, feed_dict={ 126 self._x : X_test, 127 self._t : Y_test 128 })

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

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

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

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

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

guest

回答1

0

ベストアンサー

tf.Tensor.eval() でノードの計算を行おうとしているということですよね?

'function' object has no attribute 'eval'

MLP.accuracy という function オブジェクトは eval を持っていないのでエラーになります。

self.accuracy() が返すテンソルの eval() を呼ぶのなら、self.accuracy().eval() とするべきではないでしょうか。

追記

accuracy = self.accuracy(y, t) の部分で精度を計算するノードを作成しています。ただ、これはローカル変数なので、def evaluate() 内で self.accuracy としてもこの変数は参照されません。
そのかわりに accuracy(self, y, t) というメソッドのほうが参照されてしまい、今回の質問のエラーに繋がっています。
なので、evaluate() 内で作成した精度を計算するノード accuracy を参照するために、self.acc = self.accuracy(y, t) のように Attribute として記録しておき、evaluate(self, X_test, Y_test) 内で self.acc.eval(引数) とすれば、目的のことができるでしょう。

self.accuracy = self.accuracy(y, t) のようにしないよう注意してください。
Attribute とメソッドで同じ名前を使用した場合、メソッドのほうが隠蔽されてしまい、self.accuracy() と呼び出すことができなくなってしまいます。
今回のケースに限らず、メソッド名と Attribute 名が重複しないよう注意してください。

投稿2018/10/22 14:07

編集2018/10/22 15:42
tiitoi

総合スコア21956

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

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

knght

2018/10/22 14:40

回答ありがとうございます。 accuracy()の引数はどのようにすればよいですか…?
tiitoi

2018/10/22 14:46

y がモデルの推論した結果 (N, NumClasses) のテンソル (おそらく、inference() の返り値) で、t が one-hot 表現の正解ラベル (N, NumClasses) のテンソルです。 本は持ってないのでどのような内容なのかはわかりませんが、本の通りにすすめていてうまくいかないのでしょうか?
knght

2018/10/22 15:00

その通りなのですが、普通.eval()を使う際は、その関数を計算するためにfeed_dictで値を入れますよね?(知識が浅く間違ってたら申し訳ないのですが…) クラスの中で違うメソッドを呼び出すときにself.accuracy(引数).evalのように何か引数を入れるとなると、その関数も違うところからの値(inferenceの返り値など)を持ってきているので、入れようがないのかと思いまして… 一度本のままにコードを書いてみようと思います。ですが本にはself.accuracy.eval()とありました。 何度もご親切にありがとうございます。
tiitoi

2018/10/22 15:44

追記しました。 本のほうは、self.accuracy.eval() としていたとのことですが、だとしたら、self.accuracy は tf.Tensor オブジェクトのはずです。 def accuracy(self, y, t) は質問者さんが作られた関数でしょうか? attribute とメソッドで同じ名前を使おうとして今回の混乱が生じている気がします。
knght

2018/10/23 07:53

追記のようにコードを修正したところ無事解決しました…! 理由もわかり納得スッキリです。 何度もご丁寧にありがとうございました :)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問