import tensorflow as tf
import numpy as np
tf.config.experimental.list_physical_devices('GPU')
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

tf.constant

예비학습: 중첩리스트

- 리스트

lst = [1,2,3,4,5,6]
lst
[1, 2, 3, 4, 5, 6]
lst[0] # 첫번째 원소
1
lst[-1] # 두번째 원소
6

- (2,2) matrix 느낌의 list

  • 아래는 일차원이지만 이차원으로 생각할 수 있다.
lst = [[1,2],[3,4]]
lst[0][1]
2
lst[1][0]
3

원소가 벡터이면 matrix로 생각 가능하다

1 2
3 4
print(lst[0][0]) # (1,1)
print(lst[0][1]) # (1,2)
print(lst[1][0]) # (2,1)
print(lst[1][1]) # (2,2)
1
2
3
4
lst
[[1, 2], [3, 4]]
np.array(lst)
array([[1, 2],
       [3, 4]])

- (4,1) matrix 느낌의 list

lst = [[1],[2],[3],[4]] # (4,1) matrix = 행의 길이가 4인 col-vector
lst
[[1], [2], [3], [4]]
np.array(lst)
array([[1],
       [2],
       [3],
       [4]])

- (1,4) 느낌의 list

lst = [[1,2,3,4]] # (1,4) matrix = 열의 길이가 4인 row-vector
lst
[[1, 2, 3, 4]]
np.array(lst)
array([[1, 2, 3, 4]])

선언

- 스칼라

tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=3.14>
tf.constant(3.14) + tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=6.28>
  • 텐서플로로 꼭 바꿔줘야 함!

- 벡터

type(tf.constant(1)).shape
<property at 0x7fe5625bef70>

타입

이렇게 나오는가 보다~~

type(tf.constant([1,2,3]))
tensorflow.python.framework.ops.EagerTensor
  • 자료형 확인
tf.constant(1)
<tf.Tensor: shape=(), dtype=int32, numpy=1>
tf.constant([1,2,3])
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([1, 2, 3], dtype=int32)>
_vector = tf.constant([1,2,3])
_vector[0]
<tf.Tensor: shape=(), dtype=int32, numpy=1>
_vector[-1]
<tf.Tensor: shape=(), dtype=int32, numpy=3>

- 매트릭스

_matrix = tf.constant([[1,0],[0,1]])
_matrix
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 0],
       [0, 1]], dtype=int32)>

3차원 이상의 배열은 tensor~

- array

np.array([[[0,1,1],[1,2,-1]],[[0,1,2],[1,2,-1]]])
array([[[ 0,  1,  1],
        [ 1,  2, -1]],

       [[ 0,  1,  2],
        [ 1,  2, -1]]])
np.array([[[0,1,1],[1,2,-1]],[[0,1,2],[1,2,-1]]]).shape
(2, 2, 3)
tf.constant(np.array([[[0,1,1],[1,2,-1]],[[0,1,2],[1,2,-1]]]))
<tf.Tensor: shape=(2, 2, 3), dtype=int64, numpy=
array([[[ 0,  1,  1],
        [ 1,  2, -1]],

       [[ 0,  1,  2],
        [ 1,  2, -1]]])>

type이 int64인 tf.constant에서의 np.array

tf.constant([[[0,1,1],[1,2,-1]],[[0,1,2],[1,2,-1]]])
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 0,  1,  1],
        [ 1,  2, -1]],

       [[ 0,  1,  2],
        [ 1,  2, -1]]], dtype=int32)>

type이 int32인tf.constant


Type

type(tf.constant([1]))
tensorflow.python.framework.ops.EagerTensor

텐서플로에서 eager execution 이 가능한가요?

tf.executing_eagerly()
True
  • Eager execution은 명령형 프로그래밍 환경을 의미함
  • Eager execution 기능을 제공하는 tensor의 종류가 EagerTensor

인덱싱

_matrix = tf.constant([[1,2],[3,4]])
_matrix
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 2],
       [3, 4]], dtype=int32)>
_matrix[0][0]
<tf.Tensor: shape=(), dtype=int32, numpy=1>
_matrix[0]
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2], dtype=int32)>
_matrix[0,:]
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2], dtype=int32)>
_matrix[:,0]
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 3], dtype=int32)>
  • list 이기 때문에

tf.constant는 불편하다.

- 불편한 점

  1. 모든 데이터 타입dtype이 다 같아야 한다.
  2. 원소 수정을 일부만 하는 것이 불가능하다
  3. 묵시적 형변환이 불가능하다

- 원소 수정이 불가능함

a = tf.constant([1,22,33])
a
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([ 1, 22, 33], dtype=int32)>
a[0]
<tf.Tensor: shape=(), dtype=int32, numpy=1>
a[0] = 11
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [44], in <cell line: 1>()
----> 1 a[0] = 11

TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment

- 묵시적 형변환이 불가능하다

1 + 3,14
(4, 14)
  • int랑 float이랑 더하면 원래 int가 float으로 자동으로 바뀌어서 4.14로 계산되어야 하는 거 아닌가!
tf.constant(1)
<tf.Tensor: shape=(), dtype=int32, numpy=1>
tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=3.14>
tf.constant(1) + tf.constant(3.14)
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
Input In [47], in <cell line: 1>()
----> 1 tf.constant(1) + tf.constant(3.14)

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/util/traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    151 except Exception as e:
    152   filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153   raise e.with_traceback(filtered_tb) from None
    154 finally:
    155   del filtered_tb

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/framework/ops.py:7107, in raise_from_not_ok_status(e, name)
   7105 def raise_from_not_ok_status(e, name):
   7106   e.message += (" name: " + name if name is not None else "")
-> 7107   raise core._status_to_exception(e) from None

InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was expected to be a int32 tensor but is a float tensor [Op:AddV2]

이건 또 에러가 떠!

  • 왜? int랑 float이랑 더했는데 텐서는 알아서 자료형태 맞춰 계산하지 않거든!
tf.constant(1.0)
<tf.Tensor: shape=(), dtype=float32, numpy=1.0>
tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=3.14>
tf.constant(1.0) + tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=4.1400003>
  • 이제 되네~

- 같은 float도 안 되는 경우가 있음

tf.constant(1.0,dtype=tf.float64)
<tf.Tensor: shape=(), dtype=float64, numpy=1.0>
tf.constant(3.14)
<tf.Tensor: shape=(), dtype=float32, numpy=3.14>
tf.constant(1.0,dtype=tf.float64) + tf.constant(3.14)
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
Input In [54], in <cell line: 1>()
----> 1 tf.constant(1.0,dtype=tf.float64) + tf.constant(3.14)

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/util/traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    151 except Exception as e:
    152   filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153   raise e.with_traceback(filtered_tb) from None
    154 finally:
    155   del filtered_tb

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/framework/ops.py:7107, in raise_from_not_ok_status(e, name)
   7105 def raise_from_not_ok_status(e, name):
   7106   e.message += (" name: " + name if name is not None else "")
-> 7107   raise core._status_to_exception(e) from None

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

안 되는 모습!!

  • 같은 float이지만 float32 , float64로 자료형 다르잖아

float32랑 float 64랑 뭐가 달라?

float 32

  • 32비트를 사용
  • 그러다보니 연산속도도 빠르지

float 64

  • 64비트를 사용
  • 메모리 사용도 flaot32의 두 배~

tf.constant $\to$ 넘파이


np.array([3.14]) + np.array([1.0])
array([4.14])
np.array([3.14,-3.14]) + np.array([1,2])
array([ 4.14, -1.14])
tf.constant(np.array([3.14,-3.14]) + np.array([1,2]))
<tf.Tensor: shape=(2,), dtype=float64, numpy=array([ 4.14, -1.14])>

np.array(tf.constant(1)) # 방법 1
array(1, dtype=int32)
a = tf.constant([3.14,3.14])
type(a)
tensorflow.python.framework.ops.EagerTensor
a.numpy() # 방법2
array([3.14, 3.14], dtype=float32)

연산

- 더하기

a = tf.constant([1,2]) 
b = tf.constant([3,4])
a + b
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([4, 6], dtype=int32)>
tf.add(a,b)
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([4, 6], dtype=int32)>

- 곱하기

  • elements 곱
a = tf.constant([[1,2],[3,4]])
b = tf.constant([[5,6],[7,8]])
a * b
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[ 5, 12],
       [21, 32]], dtype=int32)>
tf.multiply(a,b)
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[ 5, 12],
       [21, 32]], dtype=int32)>

- 매트릭스의 곱

a = tf.constant([[1,0],[0,1]]) # (2,2)
b = tf.constant([[5],[7]]) # (2,1)
a @ b
<tf.Tensor: shape=(2, 1), dtype=int32, numpy=
array([[5],
       [7]], dtype=int32)>
tf.matmul(a,b)
<tf.Tensor: shape=(2, 1), dtype=int32, numpy=
array([[5],
       [7]], dtype=int32)>

다 넘파이 가능한 옵션인듯


Warning: error 확인

- 역행렬

a = tf.constant([[1,0],[0,2]])
a
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 0],
       [0, 2]], dtype=int32)>

자료형이 float이 아닌 int라서 에러가 떠~

tf.linalg.inv(a)
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
Input In [67], in <cell line: 1>()
----> 1 tf.linalg.inv(a)

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/ops/gen_linalg_ops.py:1506, in matrix_inverse(input, adjoint, name)
   1504   return _result
   1505 except _core._NotOkStatusException as e:
-> 1506   _ops.raise_from_not_ok_status(e, name)
   1507 except _core._FallbackException:
   1508   pass

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/framework/ops.py:7107, in raise_from_not_ok_status(e, name)
   7105 def raise_from_not_ok_status(e, name):
   7106   e.message += (" name: " + name if name is not None else "")
-> 7107   raise core._status_to_exception(e) from None

InvalidArgumentError: Value for attr 'T' of int32 is not in the list of allowed values: double, float, half, complex64, complex128
	; NodeDef: {{node MatrixInverse}}; Op<name=MatrixInverse; signature=input:T -> output:T; attr=adjoint:bool,default=false; attr=T:type,allowed=[DT_DOUBLE, DT_FLOAT, DT_HALF, DT_COMPLEX64, DT_COMPLEX128]> [Op:MatrixInverse]
a = tf.constant([[1.0,0.0],[0.0,2.0]])
a
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[1., 0.],
       [0., 2.]], dtype=float32)>
tf.linalg.inv(a) # 이제 됐다!
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[1. , 0. ],
       [0. , 0.5]], dtype=float32)>

- tf.linalg. + tab 에서 응용해봐~

a = tf.constant([[1.0,2.0],[3.0,4.0]])
print(a)
tf.linalg.det(a)
tf.Tensor(
[[1. 2.]
 [3. 4.]], shape=(2, 2), dtype=float32)
<tf.Tensor: shape=(), dtype=float32, numpy=-2.0>
tf.linalg.trace(a) # 대각선 원소들의 합
<tf.Tensor: shape=(), dtype=float32, numpy=5.0>
tf.linalg.eig(a)
(<tf.Tensor: shape=(2,), dtype=complex64, numpy=array([-0.37228122+0.j,  5.372281  +0.j], dtype=complex64)>,
 <tf.Tensor: shape=(2, 2), dtype=complex64, numpy=
 array([[-0.8245648 +0.j, -0.41597357+0.j],
        [ 0.56576747+0.j, -0.90937674+0.j]], dtype=complex64)>)
tf.linalg.matrix_rank(a)
<tf.Tensor: shape=(), dtype=int32, numpy=2>

ref: https://www.tensorflow.org/api_docs/python/tf/linalg

  • tf.linalg를 응용해봅시다

형태변환

- 기본: tf.reshape() 를 이용

a = tf.constant([1,2,3,4])
a
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([1, 2, 3, 4], dtype=int32)>

shape바꿔주기 (1,4)에서 (4,1) 로~

tf.reshape(a,(4,1))
<tf.Tensor: shape=(4, 1), dtype=int32, numpy=
array([[1],
       [2],
       [3],
       [4]], dtype=int32)>
tf.reshape(a,(2,2))
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 2],
       [3, 4]], dtype=int32)>
tf.reshape(a,(2,2,1))
<tf.Tensor: shape=(2, 2, 1), dtype=int32, numpy=
array([[[1],
        [2]],

       [[3],
        [4]]], dtype=int32)>

- 다차원

a = tf.constant([1,2,3,4,5,6,7,8,9,10,11,12])
a
<tf.Tensor: shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int32)>
tf.reshape(a,(2,2,3))
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]], dtype=int32)>
tf.reshape(a,(4,3))
<tf.Tensor: shape=(4, 3), dtype=int32, numpy=
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]], dtype=int32)>

- tf.reshape

a = tf.constant([1,2,3,4,5,6,7,8,9,10,11,12])
a
<tf.Tensor: shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int32)>

잠깐, 왜 다 수를 행 * 열 수에 맞게 써줘야 하지? 아래 해결법.

-1을 쓰면 남은 차원을 알아서 계산을 해준다.

  • 아래의 경우 4 쓰고 -1 쓰면 3으로 자동 계산되는 것~
tf.reshape(a,(4,-1))
<tf.Tensor: shape=(4, 3), dtype=int32, numpy=
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]], dtype=int32)>

아래의 경우 2,2,-1 쓰면 -1이 알아서 계산~

tf.reshape(a,(2,2,-1))
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]], dtype=int32)>
b = tf.reshape(a,(2,2,-1))
b
<tf.Tensor: shape=(2, 2, 3), dtype=int32, numpy=
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[ 7,  8,  9],
        [10, 11, 12]]], dtype=int32)>

심지어 -1로 array 변경도 가능~

tf.reshape(b,-1)
<tf.Tensor: shape=(12,), dtype=int32, numpy=array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int32)>

선언고급

- 다른 자료형 (리스트나 넘파이)로 만들고 바꾸는 것도 좋다.

np.diag([1,2,3,4]) # 대각행렬 만들어
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])
tf.constant(np.diag([1,2,3,4])) # 텐서로도 만들어
<tf.Tensor: shape=(4, 4), dtype=int64, numpy=
array([[1, 0, 0, 0],
       [0, 2, 0, 0],
       [0, 0, 3, 0],
       [0, 0, 0, 4]])>

- tf.ones, tf.zeros

tf.ones([3,3])
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]], dtype=float32)>
tf.zeros([3,3])
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]], dtype=float32)>

아래는 int로 나오고 위에는 float으로 나왔다~

tf.reshape(tf.constant([0]*9),(3,-1))
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]], dtype=int32)>

float으로 나오게~!

tf.reshape(tf.constant([0.0]*9),(3,-1))
<tf.Tensor: shape=(3, 3), dtype=float32, numpy=
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]], dtype=float32)>

- range(10)

a = range(0,12) # generator야 range는
print(a)
range(0, 12)
a?
Type:        range
String form: range(0, 12)
Length:      12
Docstring:  
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
list(a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

array가 만들어진 모습

tf.constant(a)
<tf.Tensor: shape=(12,), dtype=int32, numpy=array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11], dtype=int32)>
list(range(0,5)) # 0,1,2,3,4
[0, 1, 2, 3, 4]
list(range(0,50,3)) # 3씩 건너서 만들어줘!
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

- tf.linspace

tf.linspace(0,1,10) # 0에서 1 사이의 10개 만들어줘!
<tf.Tensor: shape=(10,), dtype=float64, numpy=
array([0.        , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
       0.55555556, 0.66666667, 0.77777778, 0.88888889, 1.        ])>

tf.concat

a = tf.constant([[1],[2]])
b = tf.constant([[3],[4]])
a,b
(<tf.Tensor: shape=(2, 1), dtype=int32, numpy=
 array([[1],
        [2]], dtype=int32)>,
 <tf.Tensor: shape=(2, 1), dtype=int32, numpy=
 array([[3],
        [4]], dtype=int32)>)

- (2,1) concat (2,1) -> (4,1)

  • 첫번째 축이 바뀌었다. -> axis = 0
tf.concat([a,b], axis = 0) # axis = 0은 
<tf.Tensor: shape=(4, 1), dtype=int32, numpy=
array([[1],
       [2],
       [3],
       [4]], dtype=int32)>

- (2,1) concat (2,1) -> (2,2)

  • 두번째 축이 바뀌었다. -> axis = 1
tf.concat([a,b], axis = 1) # axis = 0은 
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 3],
       [2, 4]], dtype=int32)>

- (1,2) concat (1,2) -> (2,2)

  • 첫번째 // axis = 0
a = tf.constant([[1,2]])
b = tf.constant([[3,4]])
tf.concat([a,b], axis = 0)
<tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[1, 2],
       [3, 4]], dtype=int32)>

- (1,2) concat (1,2) -> (1,4)

  • 두번째 // axis = 1
a = tf.constant([[1,2]])
b = tf.constant([[1,2]])
tf.concat([a,b],axis = 1)
<tf.Tensor: shape=(1, 4), dtype=int32, numpy=array([[1, 2, 1, 2]], dtype=int32)>

- (2,3,4,5) concat (2,3,4,5) -> (4,3,4,5)

  • 첫번째 // axis = 0
a = tf.reshape(tf.constant(range(120)),(2,3,4,5))
b = -a
tf.concat([a,b],axis = 0).shape # tf.concat([a,b],axis = -4)
TensorShape([4, 3, 4, 5])

- (2,3,4,5) concat (2,3,4,5) -> (2,6,4,5)

  • 두번째 // axis = 1
a = tf.reshape(tf.constant(range(120)),(2,3,4,5))
b = -a
tf.concat([a,b],axis = 1).shape # tf.concat([a,b],axis = -3)
TensorShape([2, 6, 4, 5])

- (2,3,4,5) concat (2,3,4,5) -> (2,3,8,5)

  • 세번째 // axis = 2
a = tf.reshape(tf.constant(range(120)),(2,3,4,5))
b = -a
tf.concat([a,b],axis = 2).shape # tf.concat([a,b],axis = -2)
TensorShape([2, 3, 8, 5])

- (2,3,4,5) concat (2,3,4,5) -> (2,3,4,10)

  • 네번째 // axis = 3 # 0,1,2,3 # -4,-3,-2,-1
a = tf.reshape(tf.constant(range(120)),(2,3,4,5))
b = -a
tf.concat([a,b],axis = 3).shape # tf.concat([a,b],axis = -1)
TensorShape([2, 3, 4, 10])

- (4,) concat (4,) -> (8,)

  • 첫번째 축? // axis = 0
a = tf.constant([1,2,3,4])
b = -a
a,b
(<tf.Tensor: shape=(4,), dtype=int32, numpy=array([1, 2, 3, 4], dtype=int32)>,
 <tf.Tensor: shape=(4,), dtype=int32, numpy=array([-1, -2, -3, -4], dtype=int32)>)
tf.concat([a,b],axis=0)
<tf.Tensor: shape=(8,), dtype=int32, numpy=array([ 1,  2,  3,  4, -1, -2, -3, -4], dtype=int32)>

- (4,) concat (4,) -> (4,2)

  • 두번째 축? // axis = 1
a = tf.constant([1,2,3,4])
b = -a
a,b
(<tf.Tensor: shape=(4,), dtype=int32, numpy=array([1, 2, 3, 4], dtype=int32)>,
 <tf.Tensor: shape=(4,), dtype=int32, numpy=array([-1, -2, -3, -4], dtype=int32)>)
tf.concat([a,b],axis=1)
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
Input In [121], in <cell line: 1>()
----> 1 tf.concat([a,b],axis=1)

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/util/traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    151 except Exception as e:
    152   filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153   raise e.with_traceback(filtered_tb) from None
    154 finally:
    155   del filtered_tb

File ~/anaconda3/envs/stbda2022/lib/python3.10/site-packages/tensorflow/python/framework/ops.py:7107, in raise_from_not_ok_status(e, name)
   7105 def raise_from_not_ok_status(e, name):
   7106   e.message += (" name: " + name if name is not None else "")
-> 7107   raise core._status_to_exception(e) from None

InvalidArgumentError: ConcatOp : Expected concatenating dimensions in the range [-1, 1), but got 1 [Op:ConcatV2] name: concat

$\star$ 에러 뜨는 이유? -> (4,)는 그냥 (4) 야 concat으로 못 바꿔, 명심해, 하고 싶으면 reshape 하세요~

tf.stack

위의 에러를 해결 가능한 stack~

a = tf.constant([1,2,3,4])
b = -a
a,b
(<tf.Tensor: shape=(4,), dtype=int32, numpy=array([1, 2, 3, 4], dtype=int32)>,
 <tf.Tensor: shape=(4,), dtype=int32, numpy=array([-1, -2, -3, -4], dtype=int32)>)

왜 4,2 아니고 2,4 행렬 만들어?

  • stack이 쌓다는 의미 a랑 b랑 쌓아버린 거
  • 기본으로 axis = 0으로 되어 있기도 하고!
tf.stack([a,b]) # axis = 0 이 기본~
<tf.Tensor: shape=(2, 4), dtype=int32, numpy=
array([[ 1,  2,  3,  4],
       [-1, -2, -3, -4]], dtype=int32)>
tf.stack([a,b], axis = 1)
<tf.Tensor: shape=(4, 2), dtype=int32, numpy=
array([[ 1, -1],
       [ 2, -2],
       [ 3, -3],
       [ 4, -4]], dtype=int32)>

차원을 올리면서 행렬을 만들고 싶을 때 stack을 사용하자!

tnp

텐서플로우를 넘파이로 쓰는 방법!

- 텐서만들기가 너무 힘들다

원래 아래처럼 대각 행렬 만드는 것도 되지 않았다..

np.diag([1,2,3]).reshape(-1)
array([1, 0, 0, 0, 2, 0, 0, 0, 3])

tnp 사용방법 (불만해결방법)

import tensorflow.experimental.numpy as tnp
tnp.experimental_enable_numpy_behavior()

- int와 float을 더할 수 있음

텐서때와는 다르지?

tnp.array([1,2,3]) + tnp.array([1.0,2.0,3.0])
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 4., 6.])>

차원이 다르지만 더해지기도 함!


위에서 되지 않았지만 tnp를 import해주면 tf.constant도 numpy처럼 동작한다!

  • 가령 아래와 같은 거
tf.constant([1,2,3]) + tf.constant([1.0,2.0,3.0])
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 4., 6.])>

tnp.array([1]) + tnp.array([1.0,2.0,3.0])
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 3., 4.])>
tf.constant([1]) + tf.constant([1.0,2.0,3.0])
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 3., 4.])>
tnp.array(1) + tnp.array([1.0,2.0,3.0])
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 3., 4.])>
tnp.diag([1,2,3])
<tf.Tensor: shape=(3, 3), dtype=int64, numpy=
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])>
a = tnp.diag([1,2,3])
type(a)
tensorflow.python.framework.ops.EagerTensor

위와 달리 할 수 있는 기능이 풍부해졌다!

a = tf.constant([1,2,3])
a.reshape(3,1)
<tf.Tensor: shape=(3, 1), dtype=int32, numpy=
array([[1],
       [2],
       [3]], dtype=int32)>

선언고급

tf.constant(np.diag([1,2,3]))
<tf.Tensor: shape=(3, 3), dtype=int64, numpy=
array([[1, 0, 0],
       [0, 2, 0],
       [0, 0, 3]])>
np.random.randn(5)
array([0.04918584, 0.3668472 , 0.2532084 , 0.76346774, 2.21527317])
tnp.random.randn(5)
<tf.Tensor: shape=(5,), dtype=float64, numpy=array([ 1.02154736, -0.08452754, -0.21204739,  0.45301064, -0.17636086])>

타입

type(tnp.random.randn(5))
tensorflow.python.framework.ops.EagerTensor

type은 그대로인 모습!!

- 묵시적 변환이 가능하다는 점이 핵심 point!

tf.constant([1,1]) + tf.constant([2.2,3.3])
<tf.Tensor: shape=(2,), dtype=float64, numpy=array([3.20000005, 4.29999995])>

- 장점은 쓸 수 있는 method가 많아졌다는 점!

  • min 등
a = tnp.array([[1,2,3,4]])
a.T
<tf.Tensor: shape=(4, 1), dtype=int64, numpy=
array([[1],
       [2],
       [3],
       [4]])>

해결

a.shape
TensorShape([1, 4])

이렇게 i 로 표시된 것은 ()없어도 실행 가능, 함수 아니기 때문데

a.min()
<tf.Tensor: shape=(), dtype=int64, numpy=1>

함수이기 때문에 f라고 뜸 min만 치면 에러뜨고, ( ) 같이 입력해줘야 한다.

a.mean()
<tf.Tensor: shape=(), dtype=float64, numpy=2.5>
min(a.reshape(-1))
<tf.Tensor: shape=(), dtype=int64, numpy=1>
max(a.reshape(-1))
<tf.Tensor: shape=(), dtype=int64, numpy=4>
a.max()
<tf.Tensor: shape=(), dtype=int64, numpy=4>

tf.contant로 만들어도 마치 넘파이인듯 쓰는 기능들

그렇지만 np.array는 아님

-

a = tf.constant([1,2,3])
a.reshape((3,1))
<tf.Tensor: shape=(3, 1), dtype=int32, numpy=
array([[1],
       [2],
       [3]], dtype=int32)>

이건 잘 돼

- 원소 할당은 불가능

a = tf.constant([1,2,3])
a[0] = 11
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [153], in <cell line: 1>()
----> 1 a[0] = 11

TypeError: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment

이거까진 안 되네...

  • 배열의 일부를 바꾸는 거..