이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

tf.map_fn

텐서 플로우 1 버전 GitHub에서 소스보기

변환 elems 인가함으로써 fn 축 0 (되지 인자)에 언 스택 각 요소

노트북에서 사용

가이드에서 사용 튜토리얼에서 사용

tf.scan 도 참조하십시오.

map_fn unstacks의 elems 요소들의 시퀀스를 획득하기 위해 축 0; fn 을 호출하여 각 요소를 변환합니다. 그런 다음 변환 된 값을 다시 스택합니다.

단일 텐서 입력 및 출력으로 기능 매핑

elems 가 단일 텐서이고 fn 의 서명이 tf.Tensor->tf.Tensor 인 경우 map_fn(fn, elems)tf.stack([fn(elem) for elem in tf.unstack(elems)]) 예 :

tf.map_fn(fn=lambda t: tf.range(t, t + 3), elems=tf.constant([3, 5, 2]))
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
  array([[3, 4, 5],
         [5, 6, 7],
         [2, 3, 4]], dtype=int32)>

map_fn(fn, elems).shape = [elems.shape[0]] + fn(elems[0]).shape .

다중 -arity 입력 및 출력으로 함수 매핑

map_fn 은 다중 map_fn 입력 및 출력 기능도 지원합니다.

  • elems 가 텐서의 튜플 (또는 중첩 구조) 인 경우 해당 텐서는 모두 동일한 외형 크기 ( num_elems )를 num_elems 합니다. fnelems 에서 해당 슬라이스의 각 튜플 (또는 구조)을 변환하는 데 사용됩니다. 예를 들어, elems 가 튜플 (t1, t2, t3) 인 경우 fn 은 조각의 각 튜플을 변환하는 데 사용됩니다 (t1[i], t2[i], t3[i]) (여기서 0 <= i < num_elems ) .

  • fn 이 텐서의 튜플 (또는 중첩 구조)을 반환하면 결과는 해당 구조에서 해당 요소를 쌓아서 형성됩니다.

fn 의 출력 서명 지정

fn 의 입력 및 출력 서명이 다른 경우 fn_output_signature 사용하여 출력 서명을 지정해야합니다. (구조 및 dtype 또는 tensor 유형이 일치하지 않으면 입력 및 출력 서명이 다릅니다). 예 :

tf.map_fn(fn=tf.strings.length,  # input & output have different dtypes
          elems=tf.constant(["hello", "moon"]),
          fn_output_signature=tf.int32)
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([5, 4], dtype=int32)>
tf.map_fn(fn=tf.strings.join,  # input & output have different structures
          elems=[tf.constant(['The', 'A']), tf.constant(['Dog', 'Cat'])],
          fn_output_signature=tf.string)
<tf.Tensor: shape=(2,), dtype=string,
 numpy=array([b'TheDog', b'ACat'], dtype=object)>

fn_output_signature 는 다음 중 하나를 사용하여 지정할 수 있습니다.

너덜 너덜 한

map_fntf.RaggedTensor 입력 및 출력을 지원합니다. 특히:

  • elemsRaggedTensor 인 경우 해당 텐서의 각 행과 함께 fn 이 호출됩니다.

    • elems 비정형 치수가 하나만 있으면 fn 전달 된 값은 tf.Tensor 입니다.
    • 경우 elems 여러 누더기 차원이 다음 값이 전달 fn 될 것 tf.RaggedTensor 한 적은 비정형 차원과들.
  • map_fn 의 결과가 map_fn 여야하는 경우 RaggedTensor 을 사용하여 tf.RaggedTensorSpec 를 지정 fn_output_signature .

# Example: RaggedTensor input
rt = tf.ragged.constant([[1, 2, 3], [], [4, 5], [6]])
tf.map_fn(tf.reduce_sum, rt, fn_output_signature=tf.int32)
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([6, 0, 9, 6], dtype=int32)>
# Example: RaggedTensor output
elems = tf.constant([3, 5, 0, 2])
tf.map_fn(tf.range, elems,
          fn_output_signature=tf.RaggedTensorSpec(shape=[None],
                                                  dtype=tf.int32))
<tf.RaggedTensor [[0, 1, 2], [0, 1, 2, 3, 4], [], [0, 1]]>

예 :

rt = tf.ragged.constant([[1, 2, 3], [], [4, 5], [6]])
tf.ragged.map_flat_values(lambda x: x + 2, rt)
<tf.RaggedTensor [[3, 4, 5], [], [6, 7], [8]]>

스파 스텐 서

map_fntf.sparse.SparseTensor 입력 및 출력을 지원합니다. 특히:

  • elemsSparseTensor 인 경우 해당 스파 스 텐서의 각 행과 함께 fn 이 호출됩니다. 특히, fn 전달 된 값은 elems 보다 차원이 하나 더 적은 tf.sparse.SparseTensor 입니다.

  • map_fn 의 결과가 map_fn 여야하는 경우 SparseTensor 을 사용하여 tf.SparseTensorSpec 를 지정 fn_output_signature . fn 의해 반환 된 개별 SparseTensor 는 하나 이상의 차원을 가진 단일 SparseTensor 입니다.

# Example: SparseTensor input
st = tf.sparse.SparseTensor([[0, 0], [2, 0], [2, 1]], [2, 3, 4], [4, 4])
tf.map_fn(tf.sparse.reduce_sum, st, fn_output_signature=tf.int32)
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([2, 0, 7, 0], dtype=int32)>
# Example: SparseTensor output
tf.sparse.to_dense(
    tf.map_fn(tf.sparse.eye, tf.constant([2, 3]),
              fn_output_signature=tf.SparseTensorSpec(None, tf.float32)))
<tf.Tensor: shape=(2, 3, 3), dtype=float32, numpy=
  array([[[1., 0., 0.],
          [0., 1., 0.],
          [0., 0., 0.]],
         [[1., 0., 0.],
          [0., 1., 0.],
          [0., 0., 1.]]], dtype=float32)>
  • 함수가 TensorFlow ops로 표현 가능한 경우 다음을 사용하십시오.
 tf.sparse.SparseTensor(st.indices, fn(st.values), st.dense_shape)
 
  • 그렇지 않으면 다음을 사용하십시오.
 tf.sparse.SparseTensor(st.indices, tf.map_fn(fn, st.values),
                       st.dense_shape)
 

map_fn 대 벡터화 된 작업

map_fnfn 에 의해 사용 된 연산을 elems 각 요소에 적용하여 O(elems.shape[0]) 총 연산이됩니다. 이것은 map_fn 이 요소를 병렬로 처리 할 수 ​​있다는 사실에 의해 다소 완화됩니다. 그러나 map_fn 사용하여 표현 된 변환은 일반적으로 벡터화 된 연산을 사용하여 표현 된 동등한 변환보다 여전히 덜 효율적입니다.

map_fn 은 일반적으로 다음 중 하나에 해당하는 경우에만 사용해야합니다.

  • 벡터화 된 연산으로 원하는 변환을 표현하는 것은 어렵거나 비싸다.
  • fn 은 큰 중간 값을 생성하므로 동등한 벡터화 된 변환에 너무 많은 메모리가 필요합니다.
  • 병렬 처리 요소는 동등한 벡터화 된 변환보다 효율적입니다.
  • 변환의 효율성은 중요하지 않으며 map_fn 사용 map_fn 것이 더 읽기 map_fn .

예를 들어 fn=lambda t: tf.range(t, t + 3) elems 걸쳐 fn=lambda t: tf.range(t, t + 3) 을 매핑하는 위에 제공된 예제는 벡터화 된 ops를 사용하여보다 효율적으로 다시 작성할 수 있습니다.

elems = tf.constant([3, 5, 2])
tf.range(3) + tf.expand_dims(elems, 1)
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
  array([[3, 4, 5],
         [5, 6, 7],
         [2, 3, 4]], dtype=int32)>

경우에 따라 tf.vectorized_map 을 사용하여 함수를 벡터화 eqivalent로 자동 변환 할 수 있습니다.

빠른 실행

열심히 실행하는 경우, parallel_iterations 가 1보다 큰 값으로 설정되어 있어도 map_fn 은 병렬로 실행되지 않습니다. tf.function 데코레이터를 사용하여 함수를 병렬로 실행하면 성능상의 이점을 얻을 수 있습니다.

fn=lambda t: tf.range(t, t + 3)
@tf.function
def func(elems):
  return tf.map_fn(fn, elems, parallel_iterations=3)
func(tf.constant([3, 5, 2]))
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
  array([[3, 4, 5],
         [5, 6, 7],
         [2, 3, 4]], dtype=int32)>

fn 수행 할 호출 가능 하나의 인수를 허용하는데 elems 와 동일한 (중첩 된) 구조를 갖습니다. 출력은 fn_output_signature 와 동일한 구조를 fn_output_signature 합니다 (제공된 경우). 그렇지 않으면 elems 와 동일한 구조를 가져야합니다.
elems 텐서 또는 텐서 시퀀스 (각각의 첫 번째 치수를 따라 스택 해제 됨) fn 은 결과 슬라이스의 중첩 시퀀스에 적용됩니다. elems 는 들쭉날쭉하고 희박한 텐서를 포함 elems 수 있습니다.
dtype 더 이상 사용되지 않음 : fn_output_signature 와 동일합니다.
parallel_iterations (선택 사항) 병렬로 실행할 수있는 반복 횟수입니다. 그래프 작성시 기본값은 10입니다. 열심히 실행하는 동안 기본값은 1로 설정됩니다.
back_prop (선택 사항) 더 이상 사용되지 않음 : 대신 tf.stop_gradient 를 사용하는 tf.stop_gradient 좋습니다. False는 역 전파 지원을 사용하지 않습니다.
swap_memory (선택 사항) True는 GPU-CPU 메모리 스와핑을 활성화합니다.
infer_shape (선택 사항) False는 일관된 출력 형태에 대한 테스트를 비활성화합니다.
name (선택 사항) 반환 된 텐서의 이름 접두사입니다.
fn_output_signature fn 의 출력 서명 fn 의 입력 및 출력 서명이 다른 경우 (예 : 구조, dtype 또는 tensor 유형이 일치하지 않는 경우) 지정해야합니다. fn_output_signature 는 다음 중 하나를 사용하여 지정할 수 있습니다.

텐서 또는 (아마 중첩 된) 텐서 시퀀스. 각 텐서는 첫 번째 차원에서 마지막으로 첫 번째 차원을 따라 요소에서 elems 텐서에 fn 을 적용한 결과를 쌓습니다. 그 결과 울퉁불퉁하고 희박한 텐서가 포함될 수 있습니다.

TypeError fn 호출 할 수 없거나 fnfn_output_signature 의 출력 구조가 일치하지 않는 경우
ValueError fnfn_output_signature 의 출력 길이가 일치하지 않는 경우

예 :

elems = np.array([1, 2, 3, 4, 5, 6])
tf.map_fn(lambda x: x * x, elems)
<tf.Tensor: shape=(6,), dtype=int64, numpy=array([ 1,  4,  9, 16, 25, 36])>
elems = (np.array([1, 2, 3]), np.array([-1, 1, -1]))
tf.map_fn(lambda x: x[0] * x[1], elems, fn_output_signature=tf.int64)
<tf.Tensor: shape=(3,), dtype=int64, numpy=array([-1,  2, -3])>
elems = np.array([1, 2, 3])
tf.map_fn(lambda x: (x, -x), elems,
         fn_output_signature=(tf.int64, tf.int64))
(<tf.Tensor: shape=(3,), dtype=int64, numpy=array([1, 2, 3])>,
 <tf.Tensor: shape=(3,), dtype=int64, numpy=array([-1, -2, -3])>)