TensorFlow tensörünü Numpy dizisine dönüştürme

Sep 13 2020

Sorun Açıklaması

TensorFlow 2.3.0'da özel bir kayıp işlevi yazmaya çalışıyorum. Kaybı hesaplamak için y_predparametrenin bir numpy dizisine dönüştürülmesine ihtiyacım var . Ancak, bunu <class 'tensorflow.python.framework.ops.Tensor'>yapmak için TensorFlow işlevleri var gibi görünse de, onu numpy dizisinden çevirmenin bir yolunu bulamıyorum .

Kod Örneği

def custom_loss(y_true, y_pred):
    print(type(y_pred))
    npa = y_pred.make_ndarray()
    ...
    

if __name__ == '__main__':
    ...
    model.compile(loss=custom_loss, optimizer="adam")
    model.fit(x=train_data, y=train_data, epochs=10)

hata mesajını verir: parametrenin AttributeError: 'Tensor' object has no attribute 'make_ndarraytürünü yazdırdıktan sonra y_pred:<class 'tensorflow.python.framework.ops.Tensor'>

Şimdiye kadar ne denedim

Bir çözüm arıyorum, bunun yaygın bir sorun gibi göründüğünü ve birkaç öneri olduğunu buldum, ancak şu ana kadar benim için işe yaramadılar:

1. "... öyleyse sadece Tensor nesnesinde .numpy () 'yi çağırın.": TensorFlow'da bir tensörü nemsiz bir diziye nasıl dönüştürebilirim?

bu yüzden denedim:

def custom_loss(y_true, y_pred):
    npa = y_pred.numpy()
    ...

bana veriyor AttributeError: 'Tensor' object has no attribute 'numpy'

2. "Bir tensörü diziye dönüştürmek için tensorflow.Tensor.eval () kullanın": Python'da bir TensorFlow tensörü NumPy dizisine nasıl dönüştürülür

bu yüzden denedim:

def custom_loss(y_true, y_pred):
    npa = y_pred.eval(session=tf.compat.v1.Session())
    ...

bana çekirdek varlıkla gördüğüm en uzun hata mesajlarından birini veriyor:

InvalidArgumentError: 2 root error(s) found.
      (0) Invalid argument: You must feed a value for placeholder tensor 'functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource' with dtype resource
         [[node functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource (defined at main.py:303) ]]
         [[functional_1/cropping2d/strided_slice/_1]]
      (1) Invalid argument: You must feed a value for placeholder tensor 'functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource' with dtype resource
         [[node functional_1/conv2d_2/BiasAdd/ReadVariableOp/resource (defined at main.py:303) ]]

Ayrıca Sürüm 1.x'ten TensorFlow Uyumluluk İşlevlerini çağırmak zorunda kalmak da geleceğe dönük hissettirmiyor, bu yüzden bu yaklaşımı zaten pek sevmiyorum.

3. TensorFlow Docs'a baktığımda, beklemem gereken işlev görünüyordu: tf.make_ndarray Bir tensörden bir ndarray oluşturun.

bu yüzden denedim:

def custom_loss(y_true, y_pred):
    npa = tf.make_ndarray(y_pred)
    ...

bana veriyor AttributeError: 'Tensor' object has no attribute 'tensor_shape'

TF belgelerindeki örneğe bakıldığında, bunu bir proto_tensor üzerinde kullandıklarından, önce bir protokole dönüştürmeyi denedim:

def custom_loss(y_true, y_pred):
    proto_tensor = tf.make_tensor_proto(y_pred)
    npa = tf.make_ndarray(proto_tensor)
    ...

ama zaten tf.make_tensor_proto(y_pred)hatayı artırıyor:TypeError: Expected any non-tensor type, got a tensor instead.

Ayrıca önce bir sabit tensör yapmaya çalışmak aynı hatayı verir:

def custom_loss(y_true, y_pred):
    a = tf.constant(y_pred)
    proto_tensor = tf.make_tensor_proto(a)
    npa = tf.make_ndarray(proto_tensor)
    ...

Bununla ilgili daha birçok gönderi var, ancak hepsi bu üç temel fikre geri dönüyor gibi görünüyor. Önerilerinizi bekliyorum!

Yanıtlar

runDOSrun Sep 13 2020 at 17:11

y_pred.numpy()TF 2'de çalışır, ancak AttributeError: 'Tensor' object has no attribute 'make_ndarraykodunuzun Eager modunda çalışmadığınız kısımları olduğunu belirtir, aksi takdirde bir Tensornesneniz değil, bir EagerTensor.

İstekli Modu etkinleştirmek için, grafikteki herhangi bir şey oluşturulmadan önce bunu kodunuzun başına koyun:

tf.config.experimental_run_functions_eagerly(True)

İkinci olarak, modelinizi derlerken şu parametreyi ekleyin:

model.compile(..., run_eagerly=True, ...)

Şimdi Hevesli Modda çalıştırıyorsunuz ve tüm değişkenler aslında hem yazdırabileceğiniz hem de çalışabileceğiniz değerleri tutuyor. Eager moduna geçmenin kodunuzda ek ayarlamalar gerektirebileceğini unutmayın ( genel bakış için buraya bakın ).