TensorFlow知识点

1. 使用指定的GPU和显存

如果设备上装备了多块GPU,TF运行时默认使用所有与他可见GPU,而且默认使用尽可能多的显存。可是,很多情况下我们的程序实际上并不需要消耗那么多资源,TF的这种独占性的处理方式就造成了资源浪费。那么如何限制TF 可使用的GPU数目和显存容量呢?

1.1 设置TF可使用GPU设备

GPU设备在TF下是从零开始编号的,如果设备上有四块GPU设备,他们的编号依次是 0,1,2,3. 设备名称依次是 "/gpu:0","/gpu:1","/gpu:2","/gpu:3"。默认所有设备是TF运行时可见的,而TF默认也会占用所有与他可见的GPU设备。我们可以通过环境变量
CUDA_VISIBLE_DEVICES 来设置哪些GPU对TF可见,具体语法如下:

Environment Variable Syntax Results
CUDA_VISIBLE_DEVICES=1 Only device 1 will be seen
CUDA_VISIBLE_DEVICES=0,1 Devices 0 and 1 will be visible
CUDA_VISIBLE_DEVICES="0,1" Same as above, quotation marks are optional
CUDA_VISIBLE_DEVICES=0,2,3 Devices 0, 2, 3 will be visible; device 1 is masked

为保证设备使用上的灵活性, CUDA_VISIBLE_DEVICES 环境变量应为临时变量 ,默认情况下该临时变量不存在或未设置。终端中配置使用方法如下:

## Windows 下设置使用方法
# set  CUDA_DEVICE_ORDER=PCI_BUS_ID     # 设置按PCI_BUS_ID 顺序索引设备
set CUDA_VISIBLE_DEVICES=1     # 设置/gpu:1或1号GPU对后续CUDA程序可见
python mywork.py
## Linux 下设置使用方法
CUDA_VISIBLE_DEVICES=1 python mywork.py

CUDA_VISIBLE_DEVICES临时变量的设置还可放置在Python代码中设置,这样既能保证跨平台的统一性又免去了手动设置临时变量的麻烦。

import os
# os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"     # 见 Tensorflow issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = "1"

通过这种方式设置的临时变量值会覆盖在终端中手动设置的值。
注1: 通过设置临时变量 CUDA_VISIBLE_DEVICES 来设置对TF可见的GPU设备并非TF的专属操作,临时变量CUDA_VISIBLE_DEVICES 是CUDA用来限制CUDA Application 可见GPU设备的手段,参见CUDA_VISIBLE_DEVICES 环境变量说明
注2: CUDA_VISIBLE_DEVICES 设置的运行时可见设备序号可能与NVML 工具nvidia-smi输出的不一致,参见CUDA_DEVICE_ORDER 环境变量说明

1.2 设置TF可使用GPU内存容量

默认情况下,TF将占用尽可能多的可见GPU内存,用户可在启动TF Session时设置GPU参数来加以限制。典型设置分为定量使用和按需使用。

1.2.1 GPU内存定量使用

这种设置方法使得TF最多只能使用指定比例的可见显存。

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.7)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))  

Tips: 可见显存 = 可见GPU显存总和
通过上述设置,TF最多只能使用70%的可见显存。

1.2.2 GPU内存按需使用

通过设置allow_growth GPU参数,TF可按需使用可见显存。

gpu_options = tf.GPUOptions(allow_growth=True)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) 

2. Variables

A TensorFlow variable is the best way to represent shared, persistent state manipulated by your program. Variables are manipulated via the tf.Variable class.
Features:

  1. A variable is a tensor whose value can be changed by running ops on it.
  2. Modifications on a variable are visible across multiple tf.Sessions.
  3. A variable exists outside the context of a single session.run call.

The best way to create a variable is to call the tf.get_variable function.
Usage: name = tf.get_variable(str_name,shape=[1], dtype=tf.float32, initializer=tf.glorot_uniform_initializer, collections, trainable)
params:

--name: 变量名,用于上下文中引用该变量
--str_name: 变量名, to name this variable's value when checkpointing and exporting models.
--shape: 可遍历值(list,tuple etc.), 变量的维度和每一维的长度,类似numpy 数组。默认1维,即标量。
--dtype:变量数据类型,默认tf.float32
--initializer: 调用tf.global_variables_initializer()session.run(name.initializer)时变量初始方式,默认tf.glorot_uniform_initializer
--collections: 变量所在集合
--trainable: 变量是否可学习,将被放在tf.GraphKeys.TRAINABLE_VARIABLES集合if True
注:为保证变量使用上的一致性,name 和 str_name 常设成一样。

#### Variable 使用示例
## create a variable in tf.GraphKeys.LOCAL_VARIABLES collection, in which variables are not trainable
my_local = tf.get_variable("my_local", shape=(), 
collections=[tf.GraphKeys.LOCAL_VARIABLES])

## create a variable which is not trainable
my_non_trainable = tf.get_variable("my_non_trainable", 
                                   shape=(), 
                                   trainable=False)

## add an existing variable named my_local to a collection named my_collection_name
tf.add_to_collection("my_collection_name", my_local)

## retrieve a list of all the variables (or other objects)  in collection  named my_collection_name
tf.get_collection("my_collection_name")

## creates a variable named v and places it on the second GPU device
with tf.device("/device:GPU:1"):
    v = tf.get_variable("v", [1])

## initialize all variables
session.run(tf.global_variables_initializer())

## initialize variable my_variable only
session.run(my_variable.initializer)

## prints the names of all variables which have not yet been initialized
print(session.run(tf.report_uninitialized_variables()))

## initialize w with v's value
v = tf.get_variable("v", shape=(), initializer=tf.zeros_initializer())
w = tf.get_variable("w", initializer=v.initialized_value() + 1)

## set reuse=True to reuse variables
with tf.variable_scope("model"):
  output1 = my_image_filter(input1)
with tf.variable_scope("model", reuse=True):
  output2 = my_image_filter(input2)

## call scope.reuse_variables() to trigger a variable reuse
with tf.variable_scope("model") as scope:
  output1 = my_image_filter(input1)
  scope.reuse_variables()
  output2 = my_image_filter(input2)

## initialize a variable scope based on another one
## set reuse=true to share variables
with tf.variable_scope("model") as scope:
  output1 = my_image_filter(input1)
with tf.variable_scope(scope, reuse=True):
  output2 = my_image_filter(input2)
  1. Any string is a valid collection name, and there is no need to explicitly create a collection.
  2. Note that by default tf.global_variables_initializer does not specify the order in which variables are initialized. Therefore, if the initial value of a variable depends on another variable's value, it's likely that you'll get an error. Any time you use the value of a variable in a context in which not all variables are initialized, it is best to use variable.initialized_value() instead of variable.
  3. Variable scopes allow you to control variable reuse when calling functions which implicitly create and use variables. They also allow you to name your variables in a hierarchical and understandable way.
  4. Since depending on exact string names of scopes can feel dangerous, it's also possible to initialize a variable scope based on another one

Goto Tensorflow Docs -- Variables

3. Tensorboard multiple scalar summaries in one plot

Tensorboard 一张图中画两个变量,方便对比,如:


对比图
import tensorflow as tf
from numpy import random

writer_1 = tf.summary.FileWriter("./logs/plot_1")
writer_2 = tf.summary.FileWriter("./logs/plot_2")

log_var = tf.Variable(0.0)
tf.summary.scalar("loss", log_var)

write_op = tf.summary.merge_all()

session = tf.InteractiveSession()
session.run(tf.global_variables_initializer())

for i in range(100):
    # for writer 1
    summary = session.run(write_op, {log_var: random.rand()})
    writer_1.add_summary(summary, i)
    writer_1.flush()

    # for writer 2
    summary = session.run(write_op, {log_var: random.rand()})
    writer_2.add_summary(summary, i)
    writer_2.flush()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345