TensorFlow 的一些笔记

真的是哪儿哪儿都是坑。简单记个笔记备查。

笔记

  • TensorFlow 可以用 float16 和 float32,但是 NumPy 默认使用的可能是 float64。存成 tfrecord 的时候需要注意类型转换
  • tf.image.decode_png 转换出来的图片是 tf.uint8 类型的,可以使用 tf.image.convert_image_dtype 将其转换成 tf.float32 类型。会自动转换值范围。
  • tf.image.decode_png 解析出来的图片带有空间维度
  • tf.image.decode_pngtf.image.decode_jpeg 都可以解析所有图片文件,是通用的
  • 需要做类似于 foo[index]=value 这样的操作的时候,去找 tf.scatter_nd 函数。
  • 合理使用各种层里面的 xxxx_initializer,可以达到 “灌入任意初始值” 的效果。可见这个项目
  • 想在运行过程中看 Tensor 的值? 使用 tf.Print(). 例如 a = tf.Print(a, [a], "The value of a:", summarize=1000),相当于执行了 a=a,side effort 是「输出 [a]

  • tf.gather_nd,如果 index 指向的东西不存在(例如会导致 params 数组越界),那么有可能不报错,而是获取到一大堆 0
  • tf.reshape 的时候,维度不能用 None,而要用-1
  • tf.image.decode_image 解析出来的图片没有空间维度(长、宽),只有深度

别问我是怎么知道这些坑的……都是泪……

代码段

如何像 NumPy 一样,以一个数组为下标进行选择?

result = tf.gather(your_array, index_array)

注意: 不支持带有下标的东西当左值。可以找 tf.scatter_nd 函数。

Dataset 设置 batch

第一维是 None 的:

dataset = dataset.batch(batch_size)

第一维是确定维度的:

dataset = dataset.apply(tf.contrib.data.batch_and_drop_remainder(batch_size))

具体解释在这里这里,不得不说神坑。

NOTE: If the number of elements (N) in this dataset is not an exact multiple of batch_size, the final batch contain smaller tensors with shape N % batch_size in the batch dimension. If your program depends on the batches having the same shape, consider using the @{tf.contrib.data.batch_and_drop_remainder} transformation instead.

如何读单张图片?

def get_single_image(filename):
    image_string = tf.read_file(filename)
    image = tf.image.decode_png(image_string, channels=3)
    image = tf.image.convert_image_dtype(image, tf.float32)
    return image

如何批量读图片?

def get_dataset(path, width, height, batch_size=4, epoch=2, shuffle=False):
    def _parse_function(filename):
        image_string = tf.read_file(filename)
        image = tf.image.decode_png(image_string, channels=3)
        image = tf.image.convert_image_dtype(image, tf.float32)
        image = tf.image.resize_images(image, [width, height])
        return image

    filenames = [os.path.join(path, f) for f in os.listdir(path)]
    filenames = [f for f in filenames if os.path.isfile(f)]
    if shuffle:
        random.shuffle(filenames)
    else:
        filenames = sorted(filenames)

    dataset = tf.contrib.data.Dataset.from_tensor_slices(filenames)

    dataset = dataset.map(_parse_function)
    dataset = dataset.batch(batch_size)
    dataset = dataset.repeat(epoch)

    return dataset

给单张图片添加「Batch」维度

image_batch = tf.expand_dims(image, 0)

去掉单张图片的「Batch」维度

image = tf.squeeze(image_batch)

获取以 transform 开头的层的名字

vars = [v for v in tf.trainable_variables() if v.name.startswith('transform')]
vars = [v for v in slim.get_model_variables() if v.name.startswith('transform')]

Global Pooling

net = tf.reduce_mean(net, [1, 2])

或者

_b, _h, _w, _c = net.get_shape().as_list()
net = slim.avg_pool2d(net, [_h, _w], padding="VALID")
net = tf.reshape(net,[_b,-1])

留下评论