Konwersja tensora TensorFlow na tablicę Numpy

Sep 13 2020

opis problemu

Próbuję napisać niestandardową funkcję utraty w TensorFlow 2.3.0. Aby obliczyć stratę, potrzebuję y_predprzekonwertowania parametru na tablicę numpy. Jednak nie mogę znaleźć sposobu na przekonwertowanie go z <class 'tensorflow.python.framework.ops.Tensor'>tablicy numpy, mimo że wydaje się, że funkcje TensorFlow to robią.

Przykład kodu

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)

wyświetla komunikat o błędzie: AttributeError: 'Tensor' object has no attribute 'make_ndarraypo wypisaniu typu y_predparametru:<class 'tensorflow.python.framework.ops.Tensor'>

Czego próbowałem do tej pory

Szukając rozwiązania, stwierdziłem, że jest to częsty problem i jest kilka sugestii, ale jak dotąd nie zadziałały:

1. „... więc po prostu wywołaj .numpy () na obiekcie Tensor.”: Jak mogę przekształcić tensor w tablicę numpy w TensorFlow?

więc próbowałem:

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

dając mi AttributeError: 'Tensor' object has no attribute 'numpy'

2. „Użyj tensorflow.Tensor.eval (), aby przekonwertować tensor na tablicę”: Jak przekonwertować tensor TensorFlow na tablicę NumPy w Pythonie

więc próbowałem:

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

dając mi jeden z najdłuższych śladów komunikatów o błędach, jakie kiedykolwiek widziałem, a jego rdzeniem jest:

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) ]]

również konieczność wywoływania funkcji zgodności TensorFlow z wersji 1.x nie wydaje się zbyt przyszłościowa, więc i tak nie podoba mi się to podejście.

3. Patrząc na dokumentację TensorFlow, wydawało się, że jest funkcja, której potrzebowałem po prostu czekając: tf.make_ndarray Utwórz numpy ndarray z tensora.

więc próbowałem:

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

dając mi AttributeError: 'Tensor' object has no attribute 'tensor_shape'

Patrząc na przykład w dokumentacji TF, używają tego na proto_tensor, więc najpierw spróbowałem przekonwertować na proto:

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

ale już tf.make_tensor_proto(y_pred)podnosi błąd:TypeError: Expected any non-tensor type, got a tensor instead.

Również próba utworzenia najpierw tensora const daje ten sam błąd:

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)
    ...

Jest o wiele więcej postów na ten temat, ale wydaje się, że wszyscy wracają do tych trzech podstawowych pomysłów. Czekamy na Twoje sugestie!

Odpowiedzi

runDOSrun Sep 13 2020 at 17:11

y_pred.numpy()działa w TF 2, ale AttributeError: 'Tensor' object has no attribute 'make_ndarraywskazuje, że istnieją części twojego kodu, których nie uruchamiasz w trybie Eager, ponieważ w przeciwnym razie nie miałbyś Tensorobiektu, ale plik EagerTensor.

Aby włączyć tryb zachłanności, umieść to na początku kodu, zanim cokolwiek na wykresie zostanie zbudowane:

tf.config.experimental_run_functions_eagerly(True)

Po drugie, kiedy kompilujesz swój model, dodaj ten parametr:

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

Teraz wykonujesz w trybie Eager Mode i wszystkie zmienne faktycznie przechowują wartości, które możesz zarówno drukować, jak i pracować. Należy pamiętać, że przejście do trybu zachłannego może wymagać dodatkowych zmian w kodzie (zobacz tutaj, aby zapoznać się z omówieniem).