재형이의 성장통 일지
  • 텐서플로우 개요, 텐서 형변환, 연산, 함수
    2024년 02월 12일 19시 48분 48초에 업로드 된 글입니다.
    작성자: 재형이
    반응형
     
     
    • 요즘 딥러닝 강의만 듣고 정리하고 올린다는 것 자체에 너무 의미를 부여하고 있는게 아닌가 싶다
    • 사실 잘 이해가 안되서 강의를 듣고 나온 내용들을 올리는 수준에 불과한데 말이다
    • 딥러닝에 익숙해지는 것은 좋지만 지금 우선순위는 이것보다 클라우드 쪽에 좀 더 중점을 둬야하지 않을까 싶다
    • 이번 설연휴에는 핑계지만 딥러닝만 올리고 다른건 거의 안한 것 같다
    • 우선순위를 생각하면서 행동하자

     

     

     


     

     

     

     

     

     

    1. 텐서플로우(Tensorflow) 개요

    • 보시면 아시겠지만 파이토치와 텐서플로우는 상당히 유사한 부분이 많습니다
    • 원래는 텐서플로우를 많이 사용하다가 파이토치가 등장하면서 파이토치로 많이 넘어갔었는데, 텐서플로우 2.0부터 파이토치와 유사한 부분들이 많아졌습니다
    • 텐서플로우로 작성된 내용들도 많이 볼 수 있기 때문에 파이토치 뿐만 아니라 텐서플로우도 알고 있어야 합니다
    import tensorflow as tf

    1-1. GPU 사용 여부 체크하기

    # 각 텐서와 연산이 어떠한 장치에 할당되었는지 출력하기
    tf.debugging.set_log_device_placement(True)
    
    # 텐서 생성
    a = tf.constant([
        [1, 1],
        [2, 2]
    ])
    b = tf.constant([
        [5, 6],
        [7, 8]
    ])
    
    c = tf.matmul(a, b)
    print(c)
    
    tf.debugging.set_log_device_placement(False)

    from tensorflow.python.client import device_lib
    
    # 구체적으로 사용 중인 장치(device) 정보 출력
    device_lib.list_local_devices()

    2. 텐서플로우에서의 텐서 초기화

    • 텐서플로우의 텐서는 파이토치와 마찬가지로 다음과 같은 속성을 가지고 있습니다
      • 모양(shape)
      • 자료형(data type)
      • 저장된 장치
    # 기본적인 모양(shape), 자료형(data type) 출력
    data = [
        [1, 2],
        [3, 4]
    ]
    x = tf.constant(data)
    
    print(x)
    print(tf.rank(x)) # 차원 출력

    • 텐서를 초기화하는 방식도 파이토치와 유사합니다
    • 리스트 데이터에서 직접 텐서를 초기화하기
    data = [
        [1, 2],
        [3, 4]
    ]
    x = tf.constant(data)
    print(x)
    print(tf.rank(x)) # 축(axis)의 개수 출력 = 차원의 개수 출력
    
    data = tf.constant("String")
    print(data)

    • NumPy 배열에서 텐서를 초기화하기
    a = tf.constant([5])
    b = tf.constant([7])
    
    c = (a + b).numpy()
    print(c)
    print(type(c))
    
    result = c * 10
    tensor = tf.convert_to_tensor(result)
    print(tensor)
    print(type(tensor))

    • 다른 텐서로부터 텐서 초기화하기
    x = tf.constant([
        [5, 7],
        [1, 2]
    ])
    
    # x와 같은 모양과 자료형을 가지지만, 값이 1인 텐서 생성
    x_ones = tf.ones_like(x)
    print(x_ones)
    # x와 같은 모양을 가지되, 자료형은 float으로 덮어쓰고, 값은 랜덤으로 채우기
    x_rand = tf.random.uniform(shape=x.shape, dtype=tf.float32) # uniform distribution [0, 1)
    print(x_rand)

    3. 텐서플로우에서의 텐서의 형변환 및 차원 조작

    3-1. 텐서의 특정 차원 접근하기

    tensor = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12]
    ])
    
    print(tensor[0]) # first row
    print(tensor[:, 0]) # first column
    print(tensor[..., -1]) # last column

    3-2. 텐서 이어붙이기(Concatenate)

    tensor = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8],
        [9, 10, 11, 12]
    ])
    
    # axis: 텐서를 이어 붙이기 위한 축
    # 0번 축(행)을 기준으로 이어 붙이기
    result = tf.concat([tensor, tensor, tensor], axis=0)
    print(result)
    
    # 1번 축(열)을 기준으로 이어 붙이기
    result = tf.concat([tensor, tensor, tensor], axis=1)
    print(result)

    3-3. 텐서 형변환(Type Casting)

    • 텐서의 자료형(정수, 실수 등)을 변환할 수 있다
    a = tf.constant([2])
    b = tf.constant([5.0])
    
    print(a.dtype)
    print(b.dtype)
    
    # 텐서 a를 float32 형식으로 변경한 뒤에 더하기 수행
    print(tf.cast(a, tf.float32) + b)

    3-4. 텐서의 모양 변경

    • reshape()는 텐서의 모양을 변경할 때 사용한다
    • 이때, 텐서(tensor)의 순서는 변경되지 않는다
    a = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8])
    b = tf.reshape(a, (4, 2))
    print(b)
    
    # a와 b는 서로 다른 객체
    a.assign_add([1, 1, 1, 1, 1, 1, 1, 1])
    print(a)
    print(b)

    3-5. 텐서의 차원 교환

    • 하나의 텐서에서 특정한 차원끼리 순서를 교체할 수 있다
    a = tf.random.uniform((64, 32, 3))
    print(a.shape)
    
    b = tf.transpose(a, perm=[2, 1, 0]) # 차원 자체를 교환
    # (2번째 축, 1번째 축, 0번째 축)의 형태가 되도록 한다.
    print(b.shape)

    4. 텐서플로우에서의 텐서의 연산과 함수

    4-1. 텐서의 연산

    • 텐서에 대하여 사칙연산 등 기본적인 연산을 수행할 수 있다
    # 같은 크기를 가진 두 개의 텐서에 대하여 사칙연산 가능
    # 기본적으로 요소별(element-wise) 연산
    a = tf.constant([
        [1, 2],
        [3, 4]
    ])
    b = tf.constant([
        [5, 6],
        [7, 8]
    ])
    print(a + b)
    print(a - b)
    print(a * b)
    print(a / b)

    • 행렬 곱을 수행할 수 있다
    a = tf.constant([
        [1, 2],
        [3, 4]
    ])
    b = tf.constant([
        [5, 6],
        [7, 8]
    ])
    # 행렬 곱(matrix multiplication) 수행
    print(tf.matmul(a, b))

    4-2. 텐서의 평균 함수

    • 텐서의 평균(mean)을 계산할 수 있다
    • 텐서플로우(tensorflow)에서는 차원이 감소한다는 의미로 reduce라는 용어를 사용한다
    a = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8]
    ])
    print(a)
    print(tf.reduce_mean(a)) # 전체 원소에 대한 평균
    print(tf.reduce_mean(a, axis=0)) # 각 열에 대하여 평균 계산
    print(tf.reduce_mean(a, axis=1)) # 각 행에 대하여 평균 계산

    4-3. 텐서의 합계 함수

    a = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8]
    ])
    print(a)
    print(tf.reduce_sum(a)) # 전체 원소에 대한 합계
    print(tf.reduce_sum(a, axis=0)) # 각 열에 대하여 합계 계산
    print(tf.reduce_sum(a, axis=1)) # 각 행에 대하여 합계 계산

    4-4. 텐서의 최대 함수

    • max() 함수는 원소의 최댓값을 반환한다
    • argmax() 함수는 가장 큰 원소(최댓값)의 인덱스를 반환한다
    a = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8]
    ])
    print(a)
    print(tf.reduce_max(a)) # 전체 원소에 대한 최댓값
    print(tf.reduce_max(a, axis=0)) # 각 열에 대하여 최댓값 계산
    print(tf.reduce_max(a, axis=1)) # 각 행에 대하여 최댓값 계산

    a = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8]
    ])
    print(a)
    print(tf.argmax(a, axis=0)) # 각 열에 대하여 최댓값의 인덱스 계산
    print(tf.argmax(a, axis=1)) # 각 행에 대하여 최댓값의 인덱스 계산

    4-5. 텐서의 차원 줄이기 혹은 늘리기

    • unsqueeze() 함수는 크기가 1인 차원을 추가한다
      • 배치(batch) 차원을 추가하기 위한 목적으로 흔히 사용된다
    • squeeze() 함수는 크기가 1인 차원을 제거한다
    a = tf.constant([
        [1, 2, 3, 4],
        [5, 6, 7, 8]
    ])
    print(a.shape)
    
    # 첫 번째 축에 차원 추가
    a = tf.expand_dims(a, 0)
    print(a)
    print(a.shape)
    
    # 네 번째 축에 차원 추가
    a = tf.expand_dims(a, 3)
    print(a)
    print(a.shape)

    # 크기가 1인 차원 제거
    a = tf.squeeze(a)
    print(a)
    print(a.shape)

     

     

     

     

     

     

     


     

     

     

     

     

     

    반응형
    댓글