これは、Kerasでカスタム損失関数を定義するためのものです。コードは次のとおりです。
_from keras import backend as K
from keras.models import Sequential
from keras.layers import Dense
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam
def custom_loss_function(y_true, y_pred):
a_numpy_y_true_array = K.eval(y_true)
a_numpy_y_pred_array = K.eval(y_pred)
# some million dollar worth custom loss that needs numpy arrays to be added here...
return K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)
def build_model():
model= Sequential()
model.add(Dense(16, input_shape=(701, ), activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss=custom_loss_function, optimizer=Adam(lr=0.005), metrics=['accuracy'])
return model
model = build_model()
early_stop = EarlyStopping(monitor="val_loss", patience=1)
model.fit(kpca_X, y, epochs=50, validation_split=0.2, callbacks=[early_stop], verbose=False)
_
上記のコードは次のエラーを返します:
_---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _do_call(self, fn, *args)
1326 try:
-> 1327 return fn(*args)
1328 except errors.OpError as e:
D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in _run_fn(session, feed_dict, fetch_list, target_list, options, run_metadata)
1305 feed_dict, fetch_list, target_list,
-> 1306 status, run_metadata)
1307
D:\milind.dalvi\personal\_python\Anaconda3\lib\contextlib.py in __exit__(self, type, value, traceback)
88 try:
---> 89 next(self.gen)
90 except StopIteration:
D:\milind.dalvi\personal\_python\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py in raise_exception_on_not_ok_status()
465 compat.as_text(pywrap_tensorflow.TF_Message(status)),
--> 466 pywrap_tensorflow.TF_GetCode(status))
467 finally:
InvalidArgumentError: You must feed a value for placeholder tensor 'dense_84_target' with dtype float and shape [?,?]
[[Node: dense_84_target = Placeholder[dtype=DT_FLOAT, shape=[?,?], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]
_
したがって、_y_true
_と_y_pred
_(Tensor("dense_84_target:0", shape=(?, ?), dtype=float32)
)をnumpy配列に変換する方法は誰でも知っています。
編集:------------------------------------- -------------------
基本的に、損失関数に書き込むことを期待しているのは次のとおりです。
_def custom_loss_function(y_true, y_pred):
classifieds = []
for actual, predicted in Zip(y_true, y_pred):
if predicted == 1:
classifieds.append(actual)
classification_score = abs(classifieds.count(0) - classifieds.count(1))
return SOME_MAGIC_FUNCTION_TO_CONVERT_INT_TO_TENSOR(classification_score)
_
損失関数はモデルとともにコンパイルされます。コンパイル時には、y_true
とy_pred
は単なるプレースホルダーテンソルであるため、まだ値がないため、評価できません。これがエラーメッセージが表示される理由です。
損失関数は、評価対象のnumpy配列ではなく、Kerasテンソルを使用する必要があります。追加のnumpy配列を使用する必要がある場合は、keras.backend
のvariable
メソッドを使用してそれらをテンソルに変換します( Keras Backend Documentation )。
編集:
損失を機能させるには、Keras関数空間内にとどまる必要があります。これが実装したい具体的な損失関数であり、値が{0,1}にあると仮定すると、次のようなことを試すことができます。
import keras.backend as K
def custom_loss_function(y_true, y_pred):
y_true = y_true*2 - K.ones_like(y_true) # re-codes values of y_true from {0,1} to {-1,+1}
y_true = y_true*y_pred # makes the values that you are not interested in equal to zero
classification_score = K.abs(K.sum(y_true))
したがって、Tensor( "dense_84_target:0"、shape =(?、?)、dtype = float32)であるy_trueとy_predをnumpy配列に変換する方法を誰もが知っています。
the_tensor = K.arange(5)
// >>> Tensor("arange:0", shape=(5,), dtype=int32)
the_np = the_tensor.eval(session=K.get_session())
// >>> [0 1 2 3 4]