(Tensorflow) dtype이 일치하지 않는 문제 #TDP 02-step04_05

  • by
from tensorflow.python.ops.init_ops import deprecated_arg_values
from tensorflow._api.v2 import linalg
import tensorflow as tf

A=tf.constant(((1,4,1),(1,6,-1),(2,-1,2)),dtype=tf.float64)

L_U,p= tf.linalg.lu(A)
print(L_U)
print(p)
print();print()

#making P, L, U
U=tf.linalg.band_part(L_U, 0, -1) #Upper triangular
print(U)
L=tf.linalg.band_part(L_U,-1,0) #Lower triangular
print(L,end="\n\n")

L=tf.linalg.set_diag(L, (1,1,1)) #strictly lower triangular part of LU
print(L)

P=tf.gather(tf.eye(3),p) #tf.eye is unit matrix tf.gatheris https://www.tensorflow.org/api_docs/python/tf/gather
print(P)
print();print()

#check A == PLU under this 2 function is same tool
print(tf.linalg.lu_reconstruct(L_U,p))
print(tf.matmul(P, tf.matmul(L,U))) #It is same with tf.gather(tf.matmul(L,U),p)
print();print()

#solve Ax=b using PLUx=b
print(tf.linalg.lu_solve(L_U, p, b))
y=tf.linalg.triangular_solve(L, tf.matmul(tf.transpose(P),b))
print(y)

x=tf.linalg.triangular_solve(U, y, lower=False)
print(x)
print();print()

#pivot, calculate det and rank
D=tf.linalg.diag_part(L_U) #tf.linalg.diag_part(U)
print(D)
rank=tf.math.count_nonzero(D)
print(rank,end="\n\n\n")

det_U=tf.reduce_prod(tf.linalg.diag_part(U)) #tf.linalg.det(U)
det_L=tf.reduce_prod(tf.linalg.diag_part(L)) #tf.linalg.det(L)
det_P=tf.linalg.det(P)

print(det_U);print(det_L);print(det_P)
det_A=det_P*det_L*det_U
print(det_A)

어제 http://www.yes24.com/Product/Goods/93156986공부하고 발생한 이슈였습니다.

(Problem)

코드만 보면 별 문제는 보이지 않았지만,

tf.matmul(P, tf.matmul(L,U))

InvalidArgumentError Traceback (most recent call last)



InvalidArgumentError: cannot compute MatMul as input #1(zero-based) was expected to be a float tensor but is a double tensor (Op:MatMul)

잡다한 로그는 주워 보면

matmul (행렬 곱)을 실행할 수 없다고 가정합니다.

원인은 분명히

“data_type이 float tensor를 넣었지만 double tensor가 잘못 들어간 것 같습니다.

그렇군요.

이것은 내가 어디에 있는지 데이터 형식을 잘못 지정했습니까? 라는 것은 파이썬입니다.

컴파일러 당신이 지금 지정 이상하게 해두고, 나에게 이것이 니타야.

그럼, 원인을 알았으므로, 대체로 예상대로의 장소로 이동해 봅시다.


이 코드를 수정하고 내 느낌은 그냥했다.

또한 파이썬은 …

그런데, 데이터형이 바뀔 정도의 부분을 찾아내면서 코드에 대해 가볍게 설명해 보면, 에러가 있는 부분까지는 선형 대수의 PLU 분해을 컴퓨터로 구현해 둔 형태입니다.

PLU 분해에 대한 자세한 내용은 내가 작성한 게시물을 참조하십시오.

향후 작성 예정

(Solve)

이 기사를 읽으면 주의 깊게 봐야 할 부분은 이미 알고 있었던 것 같습니다.

PLU가 각각 분해되는 과정입니다.

실제로 설명을 시작하면서 오류의 원인을 발견했습니다.

정말 맨 위에 있었어요. 함께 봐.

L_U,p= tf.linalg.lu(A)
print(L_U)
print(p)

tf.Tensor( ( ( 2. -1. 2. ) ( 0.5 6.5 -2. ) ( 0.5 0.69230769 1.38461538)), shape=(3, 3), dtype=float64)
tf.Tensor((2 1 0), shape=(3,), dtype=int32)

글쎄, 컴파일러가 나에게 다시 한 번 그라를 쳤다.

직관적으로 데이터형이 다른 부분을 확인했으므로 수정을 해야 합니다.

그렇다면 어떻게 해야 하나요?

구글을 또 열심히 찾아 본 결과, 이 함수가 나에게 도움이 되겠지요.

tf.cast(x, dtype, name=None)

x A Tensor or SparseTensor or IndexedSlices of numeric type. It could be uint8, uint16, uint32, uint64, int8, int16, int32, int64, float16, float32, float64, complex64, complex128, bfloat16.
dtype 대상 유형. The list of supported dtypes is the same as x.
이름 A name for the operation (optional).

dtype 캐스트하는 친구입니다.

나는 이 함수 P의 dtype을 float64로 변환했어요.

이제 결과를 확인해 보겠습니다.

P=tf.cast(P, tf.float64) #P is int32 before. So We have to cast P to float64
print(P)

print(tf.matmul(P, tf.matmul(L,U))) #It is same with tf.gather(tf.matmul(L,U),p)

tf.Tensor (
((0.0.1.)
(0.1.0.)
(1. 0. 0.)), shape=(3, 3), dtype=float64)

tf.Tensor (
((1.4.1.)
(1.6.-1.)
( 2. -1. 2.)), shape=(3, 3), dtype=float64)

내가 원하는대로 dtype이 성공적으로 변형되었고 결과의 도출이 잘 작동했습니다.

(Why It caused?)

이제 이 현상이 발생한 원인을 생각해 봅시다.

물론 이 문제의 원인은 파이썬 자체 자동 캐스트입니다.

자동 변환에 대해 간단히 설명하면 다음과 같습니다.

더 보기

컴퓨팅 언어 변수를 지정할 때 데이터 형식을 지정해야 합니다.

라고 하는 매우 *1e+100 중요한 전제를 깔아 가야 합니다.

파이썬에서는 코더와 프로그래머의 편의를 위해 자동로 지정하여 숨겨 두었지만 파이썬은 뿌리가되는 C만큼 많은 데이터 유형을 가지고 있지 않지만, int,float,string등의 데이터형을 엄밀하게 가지고 있어, 이것은 유저의 요구에 응해 컴파일러로 알고 변형시킵니다.

더 자세히 알고 싶은 분은 제가 다시 준비한 문장을 참고해 보세요!

향후 작성 예정

그리고 tensorflow는 Python의 데이터 유형이 아닌 자체 데이터 유형을 사용합니다.

합니다.

(정확하게는 Numpy라는 패키지와의 호완성을 위해 Numpy의 데이터형을 가지고 사용하고 있습니다.

)

상기 내용이 어느 정도 이해되고 있으면, 내려가기 쉽습니다.

미리 정답을 공개하면 컴파일러는 최적화 문제와 여러 문제에 데이터 형식을 가능한 작게 설정합니다.

그 결과 데이터 유형 충돌따라서 연산 오류가 발생했습니다.

만약 프로그래밍과 코딩을 파이썬으로 처음 만지는 분이라면 아마도이 오류를 만지고 부끄러울 수 있습니다.

low language아래로 떨어질수록 흔히 볼 수있는 실수입니다.

이번에 잘 배워서 다른 언어를 배울 때 도움이 되는 것이 좋습니다.