문제의 코드다.
c는 어떤 스칼라 값이고, 당연히 tf.constant를 통해 배열을 만들어낼 수 있다고 생각했으나 tf.constant 쪽에서 오류가 떴다.
ValueError: Can't convert Python sequence with mixed types to Tensor.
python 배열에 왜 뜬금없이 Tensor가 있냐고 불평한다.
c의 타입은 당연히 EagarTensor이고, 그래프 모드로 가면 그냥 Tensor가 될것이다.
tf.constant를 만들때는 순수 python 배열만 넣어야하는걸까?
[첫번째 가설] 배열에 scalar tensor만 넣는건 어떨까?
ValueError: Can't convert Python sequence with mixed types to Tensor.
에러 메시지를 보면 텐서가 눈치없이 껴있어서 그렇다고 하는걸로 이해할 수 있다.
그렇다고 텐서를 뺄수는 없다. # shape이 다를 때도 코드가 돌아가도록 하는것을 목표로 했다.
따라서 텐서만 들어있는 배열을 넣기로 하자.
c = tf.shape(y[0])[2]
one = tf.ones((1,), tf.int32)
print(tf.constant([one, one, one*c, one]))
Eagar하게 실행할때도 안된다.
TypeError: Scalar tensor has no `len()`
스칼라 텐서는 len 메서드가 없다고 한다.
관련 에러를 검색해봐도 원하는 질문과 대답을 찾을 수 없었다.
[두번째 가설] c를 그냥 float로 만들어버리는건 어떨까?
Eagar 하게 실행하면 되긴 된다.
@tf.function
def test():
c = tf.shape(y[0])[2]
c = float(c)
print(tf.constant([1,1,c,1]))
test()
그래프 모드로 돌려보면 어떻게 될까?
TypeError: Expected any non-tensor type, but got a tensor instead.
Tensor아닐 줄 알았는데, tensor라서 당황스럽다고 한다.
그래프 모드에서는 순수 float로 안 바뀐다 !!
[세번째 가설] tf.constant의 인자로 꼭 python sequence만 되는건가?
tf.constant로 python sequence만 넣어야한다는건 고정관념이 아닐까?
문서를 보자
https://www.tensorflow.org/api_docs/python/tf/constant
[Note]
All eager tf.Tensor values are immutable (in contrast to tf.Variable).
모든 eagar tf.Tensor 값들은 tf.Variable과 다르게 변하지 않는 값들이다.
There is nothing especially constant about the value returned from tf.constant.
tf.constant 메서드가 반환하는 값은 딱히 상수는 아니다.(?)
This function is not fundamentally different from tf.convert_to_tensor.
이 함수는 근본적으로 tf.convert_to_tensor와 다르지 않다.
The name tf.constant comes from the value being embedded in a Const node in the tf.Graph.
tf.constant라는 이름은 tf.Graph의 상수 노드에 포함되는 값으로부터 만들어졌다.
tf.constant is useful for asserting that the value can be embedded that way.
tf.constant는 값을 상수처럼 표현하고싶을때 유용하다.
마지막줄에 나온것처럼 상수처럼 표현하고싶을때 사용하나보다.
즉, 상수처럼 표현하기 위해 tf.constant의 인자로는 순수한 python sequence만 넣도록 했나보다.
그리고 tf.convert_to_tensor 와 근본적으로 다르지 않다는 말이 있다.
이름만 보면, tf.constant가 tf.convert_to_tensor보다 더 좁은 범위를 표현한다고 이해할 수 있다.
따라서 tf.convert_to_tensor를 쓰면 되지 않을까 생각했다.
된다..
그래프 연산으로도 된다...
[결론] tf.convert_to_tensor를 적극 사용하자.
특정 변수가 포함되는 python sequence 형태를 tensor로 만들때는 tf.convert_to_tensor를 사용하자.
tf.constant는 진짜 상수 형태로 표현하고 싶을때만 쓰자.