【TF/Guide笔记】 08. Ragged/Sparse tensor, RNG
明明记得之前试过RaggedTensor不能下标访问,但是看到他支持reduce_mean就又试了一下发现是可以的,估计是之前搞的不对。既然支持下标访问,也可以按维度reduce,那说明它内部肯定记录了未定维每一行的长度
如果按列reduce,如果长度不够的话会被当做不存在而不是0
倒序取元素的时候就是从有元素的末尾取,跟直观的理解是一样的。
虽然支持broadcast,但是被broadcast的那个小tensor似乎不支持RaggedTensor,用Tensor是可以的
RaggedTensor连序列化都搞了好几套方法来应对不同情况的数据,就为了让编码后的内容占最小空间,绝了
看起来SparseTensor并不是key-value的形式,而是就像构造需要的那样,按顺序存放了index-value而已,print的时候也是这样的形式
reduce_max的例子里,from_dense在构造SparseTensor的时候是过滤了0值的,所以reduce_max出来才是负数,如果用其他方法使构造的SparseTensor有显式的0,那么max值依旧是0
没想到是在random这一节里明确的指出了Variable是thread safe的
从描述来看,Generator内部可以看作存了seed-state的Variable,值的存放位置受tf.device限制
global_generator可以看做是一个全局的种子,比如之前那样直接跑tf.random.normal的时候用的就是它。这个东西会在第一次被需要的时候声明,所以外侧的device scope应该会影响到它
如果global_generator是在声明计算图的时候被生成的,而在还未运行的时候调用set_global_generator则会出现bug,因为计算图里指向的老Variable被析构了
通过split生成的generator保证了是互相独立的,推测实现上是新生成了几个种子构造出了新generator,因为split之后,旧generator的状态会变。split可以用在声明计算图的时候,保证种子是存在当前device上的,避免重复拷贝。这里也可以新声明,文档里说风险在于可能并不是独立的,但我估计写from_seed(global_generator.normal([]))就行了
generator作为输入的时候,尽管他可以被看做是Variable,但依旧会触发多态,因为理论上随机数是可以控制图的形状的,所以即使是同一个generator通过get_concrete_function拿到的计算图依旧不能跑
从代码来看,一个checkpoint似乎只能有一个generator
generator的IO有个diverge的问题,因为checkpoint的存储是分布式的,存下的这多份checkpoint有的时候合起来才代表一个模型,而如果generator出现diverge的话,在cp.load的时候,如果concurrency不同,谁用哪个种子就不大好定义了(文档说只会采用第一个读到的)。当然我觉得种子这东西大部分情况下没必要存进去的