ValueError:GraphDef cannot be larger than 2GB.解决办法
在使用TensorFlow 1.X版本的estimator的时候经常会碰到类似于ValueError:GraphDef cannot be larger than 2GB
的报错信息,可能的原因是数据太大无法写入graph。
一般来说,常见的数据构建方法如下:
def input_fn():
features, labels = (np.random.sample((100,2)), np.random.sample((100,1)))
dataset = tf.data.Dataset.from_tensor_slices((features,labels))
dataset = dataset.shuffle(100000).repeat().batch(batch_size)
return dataset
...
estimator.train(input_fn)
TensorFlow在读取数据的时候会将数据也写入Graph,所以当数据量很大的时候会碰到这种情况,之前做实验在多GPU的时候也会遇到这种情况,即使我把batch size调到很低。所以解决办法有两种思路,一直不保存graph,而是使用feed_dict
的方式来构建input pipeline。
不写入graph
我的代码环境是TensorFlow1.14,所以我以这个版本为例进行介绍。
首先总结一下estimator的运行原理(假设在单卡情况下),以estimator.train
为例(eval和predict类似),其调用顺序如下:
class Estimator():
...
def train():
...
loss = self._train_model(input_fn, hooks, saving_listeners)
...
def _train_model(self, input_fn, hooks, saving_listeners):
if self._train_distribution:
return self._train_model_distributed(input_fn, hooks, saving_listeners)
else:
return self._train_model_default(input_fn, hooks, saving_listeners)
def _train_model_default(self, input_fn, hooks, saving_listeners):
...
return self._train_with_estimator_spec(estimator_spec, worker_hooks,
hooks, global_step_tensor,
saving_listeners)
def _train_with_estimator_spec(self, estimator_spec, worker_hooks, hooks,
global_step_tensor, saving_listeners):
....
with training.MonitoredTrainingSession(
master=self._config.master,
is_chief=self._config.is_chief,
checkpoint_dir=self._model_dir,
scaffold=estimator_spec.scaffold,
hooks=worker_hooks,
chief_only_hooks=(tuple(chief_hooks) +
tuple(estimator_spec.training_chief_hooks)),
save_checkpoint_secs=0, # Saving is handled by a hook.
save_summaries_steps=save_summary_steps,
config=self._session_config,
max_wait_secs=self._config.session_creation_timeout_secs,
log_step_count_steps=log_step_count_steps) as mon_sess:
单步调试后发现,estimator写入event文件发生在调用MonitoredTrainingSession
的时刻,而真正写入event是在执行hook的时候,例如在我的实验中我设置了log_step_count_steps
这个值,这个值会每隔指定次数steps就会打印出计算速度和当前的loss值。而实现这一功能的是StepCounterHook
,它定义在tensorflow/tensorflow/python/training/basic_session_run_hooks.py
中,部分定义如下:
class StepCounterHook(session_run_hook.SessionRunHook):
"""Hook that counts steps per second."""
def __init__(...):
...
self._summary_writer = summary_writer
def begin(self):
if self._summary_writer is None and self._output_dir:
self._summary_writer = SummaryWriterCache.get(self._output_dir)
self._summary_tag = training_util.get_global_step().op.name + "/sec"
def before_run(self, run_context): # pylint: disable=unused-argument
return SessionRunArgs(self._global_step_tensor)
def _log_and_record(self, elapsed_steps, elapsed_time, global_step):
steps_per_sec = elapsed_steps / elapsed_time
if self._summary_writer is not None:
summary = Summary(value=[
Summary.Value(tag=self._summary_tag, simple_value=steps_per_sec)
])
self._summary_writer.add_summary(summary, global_step)
logging.info("%s: %g", self._summary_tag, steps_per_sec)
所以我们只需要将出现类似于self._summary_writer.add_summary
的地方注释掉,这样estimator在运行过程中就不会再生成event文件,也就不会有2GB的问题了。
feed_dict
为了在大数据量时使用 dataset,我们可以用 placeholder 创建 dataset。这时数据就不会直接写到 graph 中,graph 中只有一个 placeholder 占位符。但是,用了 placeholder 就需要我们在一开始对它进行初始化填数据,需要调用 sess.run(iter.initializer, feed_dict={ x: data })
。
但是estimator并没有显示的session可以调用,那应该怎么办呢?其实我们可以使用SessionRunHook
来解决这个问题。tf.train.SessionRunHook()
类定义在tensorflow/python/training/session_run_hook.py
,该类的具体介绍可参见【转】tf.SessionRunHook使用方法。
仔细看一下 estimator 的 train 和 evaluate 函数定义可以发现它们都接收 hooks 参数,这个参数的定义是:List of tf.train.SessionRunHook subclass instances. Used for callbacks inside the training loop. 也就是说我们可以自己定义一个SessionRunHook作为参数传递到hook就可以了。
train(
input_fn,
hooks=None,
steps=None,
max_steps=None,
saving_listeners=None
)
我们现在想要在训练之前初始化 dataset 的 placeholder,那么我们就应该具体实现 SessionRunHook 的after_create_session 成员函数:
class IteratorInitializerHook(tf.train.SessionRunHook):
def __init__(self):
super(IteratorInitializerHook, self).__init__()
self.iterator_initializer_fn = None
def after_create_session(self, session, coord):
del coord
self.iterator_initializer_fn(session)
def make_input_fn():
iterator_initializer_hook = IteratorInitializerHook()
def input_fn():
x = tf.placeholder(tf.float32, shape=[None,2])
dataset = tf.data.Dataset.from_tensor_slices(x)
dataset = dataset.shuffle(100000).repeat().batch(batch_size)
iter = dataset.make_initializable_iterator()
data = np.random.sample((100,2))
iterator_initializer_hook.iterator_initializer_fn = (
lambda sess: sess.run(iter.initializer, feed_dict={x: data})
)
return iter.get_next()
return input_fn, iterator_initializer_hook
...
input_fn, iterator_initializer_hook = make_input_fn()
estimator.train(input_fn, hooks=[iterator_initializer_hook])
参考
ValueError:GraphDef cannot be larger than 2GB.解决办法的更多相关文章
- moviepy音视频剪辑:headblur函数遇到的ValueError assignment destination is read-only问题及解决办法
☞ ░ 前往老猿Python博文目录 ░ 一.运行环境 运行环境如下: python版本:3.7 opencv-python版本:4.2.0.34 numpy版本:1.19.0 二.错误案例代码及报错 ...
- soapui加载天气预报接口报错Characters larger than 4 bytes are not supported: byte 0xb1 implies a length of more than 4 byte的解决办法
soapui加载天气预报接口时报错如下: Error loading [http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl ...
- Opencv ValueError: not enough values to unpack (expected 3, got 2)解决办法
问题背景 有些人在用我去年的毕设运行时(感谢QAQ),报错 Opencv ValueError: not enough values to unpack (expected 3, got 2) 当时就 ...
- python生成测试报告HTMLTestRunner时报错ValueError: write to closed file的解决办法
使用HTMLTestRunner时出现了以下问题: self.stream.write(output.encode('utf8')) ValueError: write to closed file ...
- 18年10月 python 中出现 ValueError: need more than 1 value to unpack 解决办法 (笨办法)
eg:a,b = argv :错误,我的理解也许不正确,但是能解决办法 a,b= argv,argv 正确 :经测试不会出现错误. ------------------------------ ...
- ios 静态库冲突的解决办法
最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理 ...
- PYTHON错误代码及解决办法
(1)用sklearn进行逻辑回归时,建立完模型,由于要预测的数据量很大,无法一次全部预测,只能每次预测一个样本数据, 在每次以列表形式输入数据进行预测时出现: /Users/donganlan/an ...
- JVM 崩溃 Failed to write core dump解决办法 WINDOWS
JVM 崩溃 Failed to write core dump解决办法 WINDOWS MIT key words: JVM,崩溃,windows,Failed,core dump,虚拟内存 最近从 ...
- Linux内核,文件系统移植过程中出现的一些问题与解决办法
1.bootm地址和load address一样 此种情况下,bootm不会对uImage header后的zImage进行memory move的动作,而会直接go到entry point开始执行. ...
随机推荐
- java 压缩图片(只缩小体积,不更改图片尺寸)
1.情景展示 在调用腾讯身份证OCR接口的时候,由于要求图片大小只能限制在1MB以内,这样,就必须使用到图片压缩技术 2.代码展示 /** * 图片处理工具类 * @explain * @auth ...
- Spring AOP 代理类,BeanNameAutoProxyCreator cglib
BeanNameAutoProxyCreator支持拦截接口和类,但不支持已经被jdk代理过的类$Proxy8.使用cglib才能代理,如下 <!-- 通过bean的名字来匹配选择要代理的bea ...
- Typescript 学习 - 类
class class 并不是一种新的数据结构,只是在函数原型基础上的语法糖 class People { hand: number; constructor(hand: number) { this ...
- 以前写的canvas 小游戏 贪吃蛇代码
效果如图,完成了贪吃蛇的基本的功能 代码地址 :https://github.com/my-new-git-hub/canvasSnake.git 预览地址:https://www.kzc275.to ...
- PostgreSQL中的Toast Pointer
1.分析背景 在使用数据库的过程中(PG的版本为9.2),遇到了错误"missing chunk number 0 for toast value XX in pg_toast_2619&q ...
- Calculation 2
Calculation 2 Given a positive integer N, your task is to calculate the sum of the positive integers ...
- 用代码写一个“Hello World!”
很简单:三步 第一步:电脑连上Microbit 第二步:打开Mu 第三步:写程序,flash 烧录 from microbit import * display.scroll("Hello ...
- StringToKenizer和Scanner的区别
相同点: StringToKenizer类和Scanner类都可用于分解字符序列中的单词! 不同点: StringToKenizer类把分解出的全部字符串都存放到StringToKenizer对象的实 ...
- Adobe Audition cc 修改音频 --- 淡出、淡入,合并、裁剪
1.导入音频到Adobe Audition cc中支持多个音频操作 也可以使用鼠标把音频放入其中 2.淡出淡入: 红色圈中的就是淡出淡入的控制符 左手按住ctrl 或者 shift 键 右手按住鼠 ...
- CentOS7-部署测试Apollo
linux部署apollo环境要求:jdk1.8.mysql5.7 centos7安装jdk1.8跟mysql5.7可以参考我这两篇文章 https://www.cnblogs.com/reasonz ...