Я получаю сообщение об ошибке при попытке настроить функцию потери - PullRequest
0 голосов
/ 27 июня 2019

Я пытаюсь создать пользовательскую функцию потерь для моей модели глубокого обучения, и я сталкиваюсь с ошибкой.

Я приведу здесь пример кода, который не то, что я хочу использовать, ноесли я пойму, как заставить работать эту маленькую функцию потерь, то я думаю, что смогу заставить мою функцию длинной потери работать.Поэтому я довольно сильно прошу помощи, чтобы эта следующая функция работала, вот она.

    model.compile(optimizer='rmsprop',loss=try_loss(pic_try), metrics= 
    ['accuracy'])
    def try_loss(pic):
    def try_2_loss(y_true,y_pred):
     return tf.py_function(func=try_3_loss,inp=[y_pred,pic], Tout=tf.float32)
    return try_2_loss
    def try_3_loss(y_pred,pic):
     return tf.reduce_mean(pic)

Теперь я хочу знать следующее: 1. Есть ли картинка, на которой я изображен?входящий в мою линию model.compile должен быть тензором?Это может быть массив numpy?2. В моей функции try_3_loss я могу заменить tf.reduce_mean на np.mean?3. Могу ли я использовать в своей функции try_3_loss обычные команды numpy для y_pred, например np.mean (y_pred)?

Главное, чтобы я хотел использовать как можно больше команд numpy.

Я пытался использовать всевозможные вещи, я пытался, чтобы мой рис был массивом, я пытался использовать с этим np.mean (рис) в моей функции try_3_loss, я пытался сделать мой рис тензорнымобъект и затем используйте tf.reduce_mean в моем try_3_project, и я попытался сделать sess.run (рис.) перед запуском строки model.compile, и во всех вышеперечисленных ситуациях я получил следующую ошибку:


TypeError                                 Traceback (most recent call 
last)
<ipython-input-75-ff45de7120bc> in <module>()
----> 1 model.compile(optimizer='rmsprop',loss=try_loss(pic_try), 
metrics=['accuracy'])

1 frames
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in 
compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, 
weighted_metrics, target_tensors, **kwargs)
    340                 with K.name_scope(self.output_names[i] + 
'_loss'):
    341                     output_loss = weighted_loss(y_true, y_pred,
--> 342                                                 sample_weight, 
mask)
    343                 if len(self.outputs) > 1:
    344                     self.metrics_tensors.append(output_loss)

/usr/local/lib/python3.6/dist-packages/keras/engine/training_utils.py in 
weighted(y_true, y_pred, weights, mask)
    418             weight_ndim = K.ndim(weights)
    419             score_array = K.mean(score_array,
    --> 420                                  axis=list(range(weight_ndim, 
    ndim)))
    421             score_array *= weights
    422             score_array /= K.mean(K.cast(K.not_equal(weights, 0), 
K.floatx()))

TypeError: 'NoneType' object cannot be interpreted as an integer

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Большое спасибо за вашу помощь!Я на самом деле решил перейти на tf 2.0, и написание функций там НАМНОГО проще, хотя это немного дороже с точки зрения эффективности, я всегда могу очень легко переключаться с массивов np на тензоры и обратно, поэтому я просто написал все это в формате numpy arrayи переключил его обратно.Таким образом, входы и выходы для всех моих функций являются тензорами, но внутри функций я переключаю их на пустые массивы и, прежде чем вернуть их обратно, переключаю обратно на тензоры, но у меня все еще есть ошибка.Код выглядит так:

    model.compile(optimizer='rmsprop',loss=custom_loss(pic), 
    loss_weights=[None],metrics=['accuracy'])

    def my_loss(y_true, y_pred):
    return loss(y_pred,pic)

    def custom_loss(pic):
    return my_loss

И когда я на самом деле пытаюсь запустить функции потерь (не в файле model.com) следующим образом:

    my_loss(x0,x0)

, я получаю следующее:

    orig shape x:  (1, 2501)
    shape x:  (2501,)
    shape pic:  (100, 100)
    shape a:  ()
    shape ms:  (2500,)
    r_size:  50
    c_size:  50
    <tf.Tensor: id=261, shape=(), dtype=float64, numpy=6.741635588952273>

Таким образом, я получаю вывод тензора с потерей, которую я хотел.(напечатаны вещи, которые помогут понять ошибку) ОДНАКО, когда я пытаюсь запустить команду компиляции, я получаю это:

    orig shape x:  ()

    (...a bunch of unneccessary stuff...)

    ----> 4     x=np.reshape(x,(2501,1))
      5     x=np.reshape(x,(2501,))
      6     pic=np.array(pic)

    /usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py in reshape(a, 
    newshape, order)
    290            [5, 6]])
    291     """
    --> 292     return _wrapfunc(a, 'reshape', newshape, order=order)
    293 
    294 

    /usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py in 
    _wrapfunc(obj, method, *args, **kwds)
     54 def _wrapfunc(obj, method, *args, **kwds):
     55     try:
    ---> 56         return getattr(obj, method)(*args, **kwds)
     57 
     58     # An AttributeError occurs if the object does not have

    ValueError: cannot reshape array of size 1 into shape (2501,1)

Как будто компилятор не понимает, что y_pred будет иметь размервывод моей модели.

Моя модель:

    model = tf.keras.Sequential()
    #add model layers
    model.add(layers.Conv2D(64, kernel_size=3,activation='linear',input_shape= 
    (inputs_shape_0,inputs_shape_1,1)))
    #model.add(LeakyReLU(alpha=0.3))
    model.add(layers.Conv2D(32, kernel_size=3,activation='linear'))
    #model.add(LeakyReLU(alpha=0.3))
    model.add(layers.Flatten())
    model.add(layers.Dense(2501, activation='linear'))

Есть идеи как это исправить?Я также посмотрю тестовый код, который вы мне прислали, чтобы получить представление.

Спасибо!

0 голосов
/ 27 июня 2019

Тестовый код:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K

@tf.custom_gradient
def py_loss_fn(y_true, y_pred):
  """ This function takes eager tensors as inputs which can be explicitly
  converted to np.arrays via EagerTensor.numpy() or implicitly converted
  by applying numpy operations to them.

  However, once tf operations are no longer used it means that the function has to
  implement its own gradient function.
  """
  def grad(dy):
    """ Compute gradients for function inputs.
        Ignore input[0] (y_true) since that is model.targets[0]
    """
    g = np.mean(-dy * np.sign(y_true - y_pred), axis=1)[:, np.newaxis]
    return None, g

  return np.mean(np.abs(y_true - y_pred), axis=1), grad

def eager_loss_fn(y_true, y_pred):
  """ If tf operations are used on eager tensors auto diff works without issues
  """
  return tf.reduce_mean(tf.abs(y_true - y_pred))

def loss_fn(y_true, y_pred, **kw_args):
  """ This function takes tensors as inputs. Numpy operations are not valid.
  """
#   loss = tf.py_function(eager_loss_fn, inp=[y_true, y_pred], Tout=tf.float32)
  loss = tf.py_function(py_loss_fn, inp=[y_true, y_pred], Tout=tf.float32)
  return loss

def make_model():
  """ Linear regression model with custom loss """
  inp = Input(shape=(4,))
  out = Dense(1, use_bias=False)(inp)
  model = Model(inp, out)
  model.compile('adam', loss_fn)
  return model

model = make_model()
model.summary()

Тестовый код для вызова модели:

import numpy as np

FACTORS = np.arange(4) + 1
def test_fn(x):
  return np.dot(x, FACTORS.T)

X = np.random.rand(3, 4)
Y = np.apply_along_axis(test_fn, 1, X)

history = model.fit(X, Y, epochs=1000, verbose=False)
print(history.history['loss'][-1])
...