実現したいこと
AttributeError: 'SymbolicTensor' object has no attribute 'numpy'を解決したい
発生している問題・分からないこと
Pythonでkerasを使ったMLPモデルで予測をしています。
評価関数はF1マクロ平均でカスタム関数を作っています。
使用環境はGoogle Colabです。
目的変数は保険料の価格帯で、[0,1,2]から構成される多クラス分類です。
エラーメッセージ
error
1--------------------------------------------------------------------------- 2AttributeError Traceback (most recent call last) 3<ipython-input-9-61406dba8cad> in <cell line: 70>() 4 68 5 69 # モデルのトレーニング 6---> 70 history = model.fit(X_train_split, y_train_split, validation_data=(X_val, y_val), epochs=50, batch_size=32, verbose=1) 7 71 8 72 # バリデーションデータで予測 9 102 frames 11/tmp/__autograph_generated_filevx5nsktk.py in tf__update_state(self, y_true, y_pred, sample_weight) 12 10 y_true_labels = ag__.converted_call(ag__.ld(tf).argmax, (ag__.ld(y_true),), dict(axis=1), fscope) 13 11 y_pred_labels = ag__.converted_call(ag__.ld(tf).argmax, (ag__.ld(y_pred),), dict(axis=1), fscope) 14---> 12 y_true_np = ag__.converted_call(ag__.ld(y_true).numpy, (), None, fscope) 15 13 y_pred_np = ag__.converted_call(ag__.ld(y_pred).numpy, (), None, fscope) 16 14 f1 = ag__.converted_call(ag__.ld(tf).py_function, (), dict(func=ag__.ld(custom_f1_score), inp=[ag__.ld(y_true_np), ag__.ld(y_pred_np)], Tout=ag__.ld(tf).float32, name='f1_score'), fscope) 17 18AttributeError: 'SymbolicTensor' object has no attribute 'numpy'
該当のソースコード
Python
1# 必要なライブラリのインストール 2!pip install tensorflow 3 4import pandas as pd 5import numpy as np 6import tensorflow as tf 7from tensorflow.keras.models import Sequential 8from tensorflow.keras.layers import Dense, Dropout 9from sklearn.model_selection import train_test_split 10from sklearn.metrics import classification_report, confusion_matrix, f1_score 11 12# カスタムF1スコアメトリックの定義 13class F1ScoreMacro(tf.keras.metrics.Metric): 14 def __init__(self, name='f1_score_macro', **kwargs): 15 super(F1ScoreMacro, self).__init__(name=name, **kwargs) 16 self.f1 = self.add_weight(name='f1', initializer='zeros', dtype=tf.float32) 17 18 def update_state(self, y_true, y_pred, sample_weight=None): 19 y_true = tf.argmax(y_true, axis=1, output_type=tf.int32) 20 y_pred = tf.argmax(y_pred, axis=1, output_type=tf.int32) 21 22 # Extract class labels from one-hot encoded tensors 23 y_true_labels = tf.argmax(y_true, axis=1) 24 y_pred_labels = tf.argmax(y_pred, axis=1) 25 26 y_true_np = y_true.numpy() 27 y_pred_np = y_pred.numpy() 28 29 f1 = tf.py_function(func=custom_f1_score, inp=[y_true_np, y_pred_np], Tout=tf.float32, name='f1_score') 30 self.f1.assign_add(f1) 31 32 def result(self): 33 return self.f1 34 35 def reset_states(self): 36 self.f1.assign(0.0) 37 38# 39,,, 40(dataの読込、分割) 41,,, 42 43# モデルの構築 44model = Sequential() 45model.add(Dense(64, input_dim=X_train_split.shape[1], activation='relu')) 46model.add(Dropout(0.5)) 47model.add(Dense(32, activation='relu')) 48model.add(Dropout(0.5)) 49model.add(Dense(3, activation='softmax')) # 出力層、クラス数は3 50 51# モデルのコンパイル 52model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=[F1ScoreMacro()]) 53 54# モデルのトレーニング 55history = model.fit(X_train_split, y_train_split, validation_data=(X_val, y_val), epochs=50, batch_size=32, verbose=1)
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
カスタム関数である、F1ScoreMacro()の内容を、historyへ渡すときにエラーが起きてる認識です。
具体的には、カスタム関数内のTensor型のデータをNumpy型へ変換できずに、矛盾が起きていると考えています。
kerasはgraph executionで動くので、eager excutionに直すための"run_eagerly=True"を入れたり、
F1ScoreMacro()にNumpyに変換するためのコードを入れたりしましたが、改善されないので、質問しました。
(以下、そのコードです)
Python
1class F1ScoreMacro(tf.keras.metrics.Metric): 2 def __init__(self, name='f1_score_macro', **kwargs): 3 super(F1ScoreMacro, self).__init__(name=name, **kwargs) 4 self.f1 = self.add_weight(name='f1', initializer='zeros', dtype=tf.float32) 5 6 def update_state(self, y_true, y_pred, sample_weight=None): 7 y_true = tf.argmax(y_true, axis=1) 8 y_pred = tf.argmax(y_pred, axis=1) 9 10 def f1_score_np(y_true, y_pred): 11 return f1_score(y_true, y_pred, average='macro') 12 13 f1 = tf.numpy_function(f1_score_np, [y_true, y_pred], tf.float32) 14 self.f1.assign_add(f1) 15 16 def result(self): 17 return self.f1 18 19 def reset_states(self): 20 self.f1.assign(0.0)
補足
かなり雑多な質問になってしまいましたが、どなたか改善方法などわかる方いましたら、ぜひご教授いただきたいです。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー