- Notifications
You must be signed in to change notification settings - Fork 5.4k
KO: add site/ko/guide/tensor.md #1070
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
c5f1b71 46bf2fe dcde397 7b9a7f9 85c70c9 e036b41 464b1db e390e1e aa0a2a8 278da5c 7fb88ca ed407b0 dfca1e7 File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,303 @@ | ||
| # 텐서플로 텐서 | ||
| | ||
| 이름에서 알 수 있듯이, 텐서플로는 텐서를 포함한 계산을 정의하고 실행하는 프레임워크입니다. | ||
| *텐서*는 벡터(vector)와 행렬(matrix)을 일반화한 것이고 고차원으로 확장 가능합니다. | ||
| 내부적으로 텐서플로는 텐서를 기본 데이터 타입의 n-차원 배열로 나타냅니다. | ||
| | ||
| 텐서플로 프로그램을 작성할 때, 조작하고 전달하는 중요 객체는 `tf.Tensor` 입니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| `tf.Tensor` 객체는 결과적으로는 값으로 변환될 수 있는 부분적으로 정의된 계산으로 표현됩니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 텐서플로 프로그램은 `tf.Tensor` 객체 그래프를 만드는 것으로 먼저 시작하고, | ||
| 각각의 텐서가 다른 텐서를 기반으로 어떤 식으로 계산될 수 있는지 구체화하고, | ||
| 그 다음 그래프를 실행해서 원하는 결과를 얻게 됩니다. | ||
| | ||
| `tf.Tensor`는 다음과 같은 속성을 가지고 있습니다: | ||
| | ||
| * 데이터 타입(data type) (예를 들어, `float32` 또는 `int32`, `string`) | ||
| * 쉐이프(shape) | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| | ||
| 텐서안의 각각 원소(element)는 동일한 데이터 타입이고 항상 그 데이터 타입을 알 수 있습니다. | ||
| 쉐이프(즉, 차원 수와 각 차원마다 길이(size))는 일부만 알 수 있습니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 대부분 연산은 입력값 쉐이프를 알 수 있다면 모든 정보를 알 수 있는 텐서를 만들지만, | ||
| 일부 경우에서는 그래프를 실행한 이후에 텐서 쉐이프를 알 수 있기도 합니다. | ||
| | ||
| 일부 특별한 텐서는 텐서플로 가이드문서의 다른 부분에서 다뤄질 것입니다. | ||
| 핵심인 텐서는 다음과 같습니다: | ||
| | ||
| * `tf.Variable` | ||
| * `tf.constant` | ||
| * `tf.placeholder` | ||
| * `tf.SparseTensor` | ||
| | ||
| 예외인 `tf.Variable`을 제외한다면, 텐서 값은 변경불가능(immutable)합니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 즉, 텐서를 한번 실행시킨 경우에는 오직 하나의 값만을 가집니다. | ||
| 그러나, 동일한 텐서를 다시 실행시킨다면 다른 값을 가질 수 있습니다; | ||
| 예를 들어 텐서가 디스크로부터 데이터를 읽어들인 결과이거나, | ||
| 무작위 숫자를 생성하는 경우입니다. | ||
| | ||
| ## 랭크(Rank) | ||
wckim marked this conversation as resolved. Show resolved Hide resolved | ||
| | ||
| `tf.Tensor` 객체의 **랭크**는 그 차원의 수입니다. | ||
| 랭크의 동의어는 **order** 또는 **degree**, **n-차원**입니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 텐서플로의 랭크는 수학에서 사용하는 행렬의 랭크와는 다릅니다. | ||
| 다음 표에서 알 수 있는 것처럼, 텐서플로의 각 랭크는 각각 다른 수학 개체(entity)에 해당됩니다. | ||
| | ||
| 랭크 | 수학 개체(entity) | ||
| --- | --- | ||
| 0 | 스칼라(Scalar) (크기(magnitude)만) | ||
| 1 | 벡터(Vector) (크기와 방향(direction)) | ||
| 2 | 행렬(Matrix) (숫자 표) | ||
| 3 | 3-텐서 (숫자 큐브(cube)) | ||
| n | n-텐서 (알 수 있을겁니다(you get the idea)) | ||
| | ||
| | ||
| ### 랭크 0 | ||
| | ||
| 다음은 랭크 0 변수 생성 예의 일부입니다: | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| ```python | ||
| mammal = tf.Variable("코끼리", tf.string) | ||
| ignition = tf.Variable(451, tf.int16) | ||
| floating = tf.Variable(3.14159265359, tf.float64) | ||
| its_complicated = tf.Variable(12.3 - 4.85j, tf.complex64) | ||
| ``` | ||
| | ||
| Note: 문자열은 텐서에서 문자 시퀀스(sequence)가 아니라 단일 객체로 다뤄집니다. | ||
| 객체는 단일 문자열과 문자열 벡터 등 모두 가능합니다. | ||
| | ||
| ### 랭크 1 | ||
| | ||
| 랭크 1 `tf.Tensor` 객체를 생성하기 위해서 초기값으로 리스트를 사용할 수 있습니다. | ||
| 예를 들어: | ||
| | ||
| ```python | ||
| mystr = tf.Variable(["안녕하세요"], tf.string) | ||
| cool_numbers = tf.Variable([3.14159, 2.71828], tf.float32) | ||
| first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32) | ||
| its_very_complicated = tf.Variable([12.3 - 4.85j, 7.5 - 6.23j], tf.complex64) | ||
| ``` | ||
| | ||
| | ||
| ### 고차원 랭크 | ||
| | ||
| 랭크 2 `tf.Tensor` 객체는 최소 한 개 이상의 열(column)과 행(row)으로 구성됩니다: | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| ```python | ||
| mymat = tf.Variable([[7],[11]], tf.int16) | ||
| myxor = tf.Variable([[False, True],[True, False]], tf.bool) | ||
| linear_squares = tf.Variable([[4], [9], [16], [25]], tf.int32) | ||
| squarish_squares = tf.Variable([ [4, 9], [16, 25] ], tf.int32) | ||
| rank_of_squares = tf.rank(squarish_squares) | ||
| mymatC = tf.Variable([[7],[11]], tf.int32) | ||
| ``` | ||
| | ||
| 유사하게, 고차원 랭크 텐서는 n-차원 배열로 구성됩니다. | ||
| 예를 들어, 이미지 처리에서는 각각 배치 수와 이미지 높이, 이미지 너비, 색상 채널에 해당하는 4차원 랭크 텐서가 사용됩니다. | ||
| | ||
| ``` python | ||
| my_image = tf.zeros([10, 299, 299, 3]) # 배치 x 높이 x 너비 x 색상 | ||
| ``` | ||
| | ||
| ### `tf.Tensor` 객체 랭크 구하기 | ||
| | ||
| `tf.Tensor` 객체의 랭크를 알기 위해서는 `tf.rank` 메서드를 호출합니다. | ||
| 예를 들어, 다음 메서드는 프로그램적으로 이전 섹션에서 정의된 `tf.Tensor`의 랭크를 알려줍니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| ```python | ||
| r = tf.rank(my_image) | ||
| # 그래프가 실행된 후 r은 4라는 값을 가지게 됩니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| ``` | ||
| | ||
| ### `tf.Tensor` 일부분(slice) 참조하기 | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| `tf.Tensor`는 n-차원 배열로 구성된 셀이기 때문에, | ||
| `tf.Tensor`의 셀 하나에 접근하기 위해서는 n개의 인덱스가 필요합니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| 랭크 0 텐서(스칼라)인 경우 그것이 이미 하나의 숫자이기 때문에 인덱스가 필요없습니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| 랭크 1 텐서(벡터)인 경우 숫자 하나에 접근하기 위해서는 인덱스 한 개를 전달해야 합니다: | ||
| | ||
| ```python | ||
| my_scalar = my_vector[2] | ||
| ``` | ||
| | ||
| 벡터로부터 원소 한 개를 동적으로 선택하기 위해서 | ||
| `[]`안에 스칼라형 `tf.Tensor`를 인덱스로 사용할 수 있습니다. | ||
| | ||
| 랭크 2이상의 고차원 텐서인 경우에는 좀 더 흥미롭습니다. | ||
| 예상한 것처럼 랭크 2인 `tf.Tensor`를 위해 인덱스로 2개를 전달해야 스칼라 한 개를 반환합니다: | ||
| | ||
| | ||
| ```python | ||
| my_scalar = my_matrix[1, 2] | ||
| ``` | ||
| | ||
| | ||
| 그러나, 한 개만 전달한다면 다음과 같이 행렬의 부분 벡터를 반환합니다: | ||
| | ||
| | ||
| ```python | ||
| my_row_vector = my_matrix[2] | ||
| my_column_vector = my_matrix[:, 3] | ||
| ``` | ||
| | ||
| `:` 표기는 "해당 차원를 남겨라"라는 파이썬 슬라이싱(slicing) 문법입니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 이러한 표기법은 고차원 텐서에서 부분 벡터와 부분 행렬, 다른 부분 텐서들까지도 접근할 수 있도록 만들어 주기 때문에 유용합니다. | ||
| | ||
| | ||
| ## 쉐이프(Shape) | ||
| | ||
| 텐서의 **쉐이프**는 각 차원에 있는 원소 개수입니다. | ||
| 텐서플로는 그래프 계산 과정에서 자동으로 쉐이프를 추론합니다. | ||
| 이렇게 추론된 쉐이프는 랭크를 알고 있는 경우도 있고 그렇지 않는 경우도 있습니다. | ||
| 만약에 랭크를 알고 있는 경우라도 각 차원의 개수를 알고 경우도 있고 그렇지 않는 경우도 있습니다. | ||
| | ||
| 텐서플로 문서에서 텐서 차원을 표현하기 위해서 3가지 용어를 사용합니다: 랭크, 쉐이프, 차원수. | ||
| 다음 표는 각 용어가 다른 용어와 연관되어 있는지를 보여줍니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| 랭크 | 쉐이프 | 차원수 | 예제 | ||
| --- | --- | --- | --- | ||
| 0 | [] | 0-차원 | 스칼라인 0-차원 텐서. | ||
| 1 | [D0] | 1-차원 | 쉐이프 [5]인 1-차원 텐서. | ||
| 2 | [D0, D1] | 2-차원 | 쉐이프 [3, 4]인 2-차원 텐서. | ||
| 3 | [D0, D1, D2] | 3-차원 | 쉐이프 [1, 4, 3]인 3-차원 텐서. | ||
| n | [D0, D1, ... Dn-1] | n-차원 | 쉐이프 [D0, D1, ... Dn-1]인 텐서. | ||
| | ||
| 쉐이프는 파이썬 리스트 / 정수형 튜플 또는 `tf.TensorShape`으로 표현될 수 있습니다. | ||
| | ||
| ### `tf.Tensor` 객체 쉐이프 얻기 | ||
| | ||
| `tf.Tensor`의 쉐이프를 알기 위한 2가지 방법이 있습니다. | ||
| 그래프를 생성하는 동안 텐서의 쉐이프를 알 수 있는 것은 종종 유용합니다. | ||
| 쉐이프는 `tf.Tensor`객체의 `shape` 속성으로 알 수 있습니다. | ||
| 이 메서드는 `TensorShape`를 반환하고, 이러한 방식은 전체가 알려지지 않는 쉐이프를 표현하는데 편리한 방법입니다 | ||
| (그래프를 생성할 때 모든 쉐이프를 알 수 없기 때문에). | ||
| | ||
| `tf.Tensor`를 얻는 것은 실행 시점에 쉐이프를 알고 있는 다른 `tf.Tensor`로 표현할 수 있습니다. | ||
| 이것은 `tf.shape` 연산을 통해서 확인할 수 있습니다. | ||
| 이를 통해, 입력 `tf.Tensor`의 동적인 쉐이프에 연동된 다른 텐서를 생성함으로써 | ||
| 텐서 쉐이프를 변경하는 그래프를 생성할 수 있습니다. | ||
| | ||
| 예를 들어 다음은 주어진 행렬의 열 개수와 동일한 크기의 0으로 구성된 벡터를 만드는 예입니다. | ||
| | ||
| ``` python | ||
| zeros = tf.zeros(my_matrix.shape[1]) | ||
| ``` | ||
| | ||
| ### `tf.Tensor` 쉐이프 변경 | ||
| | ||
| 텐서의 **원소 개수**는 모든 쉐이프의 크기를 곱한 것입니다. | ||
| 스칼라의 원소 개수는 항상 `1`입니다. | ||
| 원소 개수가 같은 경우라도 쉐이프는 다양할 수 있기 때문에, | ||
| 그 원소 개수를 유지하면서 `tf.Tensor`의 쉐이프를 변경할 수 있는 것은 유용합니다. | ||
| 이것은 `tf.reshape`으로 처리할 수 있습니다. | ||
| | ||
| 다음은 텐서 쉐이프를 변경하는 예입니다: | ||
| | ||
| ```python | ||
| rank_three_tensor = tf.ones([3, 4, 5]) | ||
| matrix = tf.reshape(rank_three_tensor, [6, 10]) # 기존 내용을 6x10 행렬로 | ||
| # 쉐이프 변경 | ||
| matrixB = tf.reshape(matrix, [3, -1]) # 기존 내용을 3x20 행렬로 쉐이프 변경 | ||
| # -1은 차원 크기를 계산한 후에 | ||
| # 쉐이프를 변경하라는 의미 | ||
| matrixAlt = tf.reshape(matrixB, [4, 3, -1]) # 기존 내용을 4x3x5 텐서로 | ||
| # 쉐이프 변경 | ||
| | ||
| # 쉐이프가 변경된 텐서의 원소 개수는 | ||
| # 원래 텐서의 원소 개수와 같습니다. | ||
| # 그러므로 다음은 원소 개수를 유지하면서 | ||
| # 마지막 차원에 사용 가능한 수가 없기 때문에 에러를 발생합니다. | ||
| yet_another = tf.reshape(matrixAlt, [13, 2, -1]) # 에러! | ||
| ``` | ||
| | ||
| ## 데이터 타입(type) | ||
| | ||
| 차원뿐만 아니라, 텐서는 테이터 타입도 가지고 있습니다. | ||
| 전체 데이터 타입을 확인하려면 `tf.DType`를 참고하세요. | ||
| | ||
| `tf.Tensor`가 한 개이상의 데이터 타입을 가지는 것은 불가능합니다. | ||
| 임의의 데이터 구조를 직렬화한 `string`를 저장한 `tf.Tensor`는 예외입니다. | ||
| | ||
| `tf.cast`를 이용해서 `tf.Tensor`의 데이터 타입을 다른 것으로 변경하는 것은 가능합니다: | ||
| | ||
| ``` python | ||
| # 정수형 텐서를 실수형으로 변환. | ||
| float_tensor = tf.cast(tf.constant([1, 2, 3]), dtype=tf.float32) | ||
| ``` | ||
| | ||
| `tf.Tensor`의 데이터 타입을 확인하기 위해서는 `Tensor.dtype` 속성을 활용하세요. | ||
| | ||
| 파이썬 객체를 이용해서 `tf.Tensor`를 생성할 때 데이터 타입을 선택적으로 명시할 수 있습니다. | ||
| 그렇지 않으면 텐서플로가 데이터 표현에 적합한 데이터 타입을 선택합니다. | ||
| 텐서플로는 파이썬 정수를 `tf.int32`로 변환하고 파이썬 실수는 `tf.float32`으로 변환합니다. | ||
| 그외에 동일한 규칙을 numpy를 배열로 변경할 때 사용합니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| ## 텐서 계산하기(evaluate) | ||
| | ||
| 일단 계산 그래프를 만들었다면, 특정 `tf.Tensor`를 생성하고 그것에 지정된 값을 가져오는 계산을 실행할 수 있습니다. | ||
| 이것은 대부분의 텐서플로가 작업하는데 필요할 뿐 아니라 디버깅에 종종 유용합니다. | ||
| ||
| | ||
| 텐서를 계산하는 가장 간단한 방법은 `Tensor.eval` 메서드를 사용하는 것입니다. 예를 들어: | ||
| | ||
| ```python | ||
| constant = tf.constant([1, 2, 3]) | ||
| tensor = constant * constant | ||
| print(tensor.eval()) | ||
| ``` | ||
| | ||
| `eval` 메서드는 기본 `tf.Session`이 활성화된 경우에만 작동합니다 | ||
| (자세한 내용은 [그래프와 세션](./graphs.md)에서 확인하세요). | ||
| | ||
| `Tensor.eval`은 텐서와 같은 내용을 가지는 numpy 배열을 반환합니다. | ||
| | ||
| 때때로 그 값이 이용할 수 없는 동적인 정보에 의존하기 때문에 | ||
| 컨텍스트(context)가 없는 `tf.Tensor`는 계산할 수 없는 경우가 있습니다. | ||
| 예를 들어, `placeholder`인 텐서는 그 `placeholder`에 해당하는 값이 제공되지 않으면 계산할 수 없습니다. | ||
| ||
| | ||
| ``` python | ||
| p = tf.placeholder(tf.float32) | ||
| t = p + 1.0 | ||
| t.eval() # 플레이스홀더(placeholder)가 값을 가지고 있지 않기 때문에, 이것은 실패할 것입니다. | ||
| t.eval(feed_dict={p:2.0}) # 플레이스홀더에 해당하는 값을 제공받기 때문에 | ||
| # 이것은 성공할 것입니다. | ||
| ``` | ||
| | ||
| 플레이스홀더뿐만 아니라 어떤 `tf.Tensor`도 값을 제공받는 것이 가능하다는 것에 유의하세요. | ||
| | ||
| 다른 모델 구조는 `tf.Tensor`를 계산하는 것을 복잡하게 만들 수 있습니다. | ||
| 텐서플로는 함수안이나 제어 흐름안에 정의된 `tf.Tensor`를 직접 계산할 수 없습니다. | ||
| 만약에 `tf.Tensor`가 큐(queue)에 있는 값을 사용한다면, | ||
| 무언가가 큐에 들어간 후에 만 `tf.Tensor` 계산을 할 수 있습니다; 그렇지 않으면 계산은 중단될 것입니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| 큐와 같이 작업할 때, `tf.Tensor`를 계산하기 전 `tf.train.start_queue_runners`를 호출하세요. | ||
| | ||
| ## 텐서 출력하기 | ||
| | ||
| 디버깅을 위해서 `tf.Tensor` 값을 출력하고 싶을 것입니다. | ||
| 고급 디버깅에 대해 [tfdbg](../guide/debugger.md)에서 가이드를 제공하지만, | ||
| 텐서플로는 `tf.Tensor`값을 직접 출력할 수 있는 연산자를 가지고 있습니다. | ||
| | ||
| `tf.Tensor`를 출력할 때 다음과 같은 패턴을 쓰고자 하는 경우는 거의 없습니다: | ||
| | ||
| ``` python | ||
| t = <<some tensorflow operation>> | ||
| print(t) # 이것은 그래프가 생성되어질 때 기호화된 텐서(symbolic tensor)를 출력할 것입니다. | ||
| # 이 텐서는 이 컨텍스트(context)안에서 값을 가지고 있지 않습니다. | ||
| ``` | ||
| | ||
| 이 코드는 `tf.Tensor`의 값이 아닌 객체(지연 계산으로 표현)를 출력합니다. | ||
| 실제로 텐서플로는 두번째 인수로 전달된 `tf.Tensor` 집합을 출력하는 동안 | ||
| 변경되지 않는 첫번째 텐서 인수를 반환하는 `tf.Print` 연산을 제공합니다. | ||
| | ||
| `tf.Print`을 제대로 사용하기 위해서는 반환된 값을 사용해야 합니다. 아래 예를 보면 | ||
| | ||
| ``` python | ||
| t = <<some tensorflow operation>> | ||
| tf.Print(t, [t]) # 어떤 일도 하지 않습니다 | ||
| t = tf.Print(t, [t]) # 여기서 tf.Print에 의해 반환된 값을 사용할 수 있습니다. | ||
| result = t + 1 # 이제 결과를 계산할 때 `t` 값이 출력될 것입니다. | ||
| ``` | ||
| | ||
| `result`를 계산할 때 `result`이 관련된 모든 것이 계산될 것입니다. | ||
wckim marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| `result`는 `t`와 의존성이 있고, `t`를 계산하는 것이 그 입력(`t`의 이전 값)을 출력하는 부가 효과가 있기 때문에 `t`는 출력됩니다. | ||
| | ||
Uh oh!
There was an error while loading. Please reload this page.