【问题标题】:tf.data.Dataset - behavior of map() and cache() methodstf.data.Dataset - map() 和 cache() 方法的行为
【发布时间】:2021-06-01 06:08:55
【问题描述】:

问题TensorFlow 数据集
https://www.tensorflow.org/api_docs/python/tf/data/Dataset#map
https://www.tensorflow.org/api_docs/python/tf/data/Dataset#cache

  1. 地图功能实际上是如何工作的? mapfn() 中的 print(rand) 只打印一个值,但 print(x) 按预期打印值
  2. 为什么 map 函数的行为与 python map() 函数不同
    • dataset.map(mapfn) 仅打印 1 个值
    • map(mapfn, numbers) 打印 4 个值
  3. 当我得到以下 x 和 y 的相同结果时,使用 dataset.cache() 的目的是什么?
import tensorflow as tf
from random import random
from math import ceil

def mapfn(x):
    rand = ceil(5*random())
    print(rand)
    return x**rand

dataset = tf.data.Dataset.range(50)
dataset = dataset.map(mapfn)
# dataset = dataset.cache()

x = list(dataset.as_numpy_iterator())
print(x)

y = list(dataset.as_numpy_iterator())
print(y)

def mapfn(n):
    rand = ceil(5*random())
    print(rand)
    return n**rand
  
numbers = [1, 2, 3, 4]
result = map(mapfn, numbers)
print(list(result))

【问题讨论】:

    标签: python tensorflow tensorflow-datasets


    【解决方案1】:

    当您将mapfn 传递给dataset.map() 时,mapfn 将转换为 tensorflow 图,print() 在图模式下将无法正常工作。 print() 只会在追踪阶段打印,即如果mapfn 被追踪一次,那么它只会打印一次。

    要在图形模式下正确打印调试消息,您需要改用tf.print()

    如果cache() 附加在dataset.map(mapfn) 之后,则它会缓存映射的值,之后将使用缓存的值。 (内存必须足以容纳所有缓存的值)

    换句话说,在数据集的第一次循环之后,mapfn 将永远不会被再次调用。

    参见示例:

    ds=tf.data.Dataset.range(3)
    def mapfn(x):
      tf.print('I am called')
      return tf.pow(x,2) #mapfn needs to be graph-mode compatible
    
    ds=ds.map(mapfn)
    print('First loop:')
    for x in ds:
      print(x)
    print()
    print('Second loop:')
    for x in ds:
      print(x)
    print()
    
    ds=ds.cache()
    print('After cache():')
    print('First loop:')
    for x in ds:
      print(x)
    print()
    print('Second loop:')
    for x in ds:
      print(x)
    print()
    
    '''
    First loop:
    I am called
    tf.Tensor(0, shape=(), dtype=int64)
    I am called
    tf.Tensor(1, shape=(), dtype=int64)
    I am called
    tf.Tensor(4, shape=(), dtype=int64)
    
    Second loop:
    I am called
    tf.Tensor(0, shape=(), dtype=int64)
    I am called
    tf.Tensor(1, shape=(), dtype=int64)
    I am called
    tf.Tensor(4, shape=(), dtype=int64)
    
    After cache():
    First loop:
    I am called
    tf.Tensor(0, shape=(), dtype=int64)
    I am called
    tf.Tensor(1, shape=(), dtype=int64)
    I am called
    tf.Tensor(4, shape=(), dtype=int64)
    
    Second loop:
    tf.Tensor(0, shape=(), dtype=int64)
    tf.Tensor(1, shape=(), dtype=int64)
    tf.Tensor(4, shape=(), dtype=int64)
    '''
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 2015-11-26
      • 1970-01-01
      • 2012-02-19
      相关资源
      最近更新 更多