内容简介:本文翻译自:TensorFlow中的内核操作完全用C ++编写,以提高效率。但是用C++编写TensorFlow内核的话可能会非常痛苦。因此,在花费数小时实现属于自己的内核之前,你也许需要先实现一个操作的原型,尽管这样的效率会很低。通过举个例子而言,这里有一个用python自己实现的ReLU非线性激活函数,通过
本文翻译自: 《Prototyping kernels and advanced visualization with Python ops》 , 如有侵权请联系删除,仅限于学术交流,请勿商用。如有谬误,请联系指出。
TensorFlow中的内核操作完全用C ++编写,以提高效率。但是用C++编写TensorFlow内核的话可能会非常痛苦。因此,在花费数小时实现属于自己的内核之前,你也许需要先实现一个操作的原型,尽管这样的效率会很低。通过 tf.py_func()
你可以将任何一个 python 源代码转换为TensorFlow的操作。
举个例子而言,这里有一个用python自己实现的ReLU非线性激活函数,通过 tf.py_func()
转换为TensorFlow操作的例子:
import numpy as np import tensorflow as tf import uuid def relu(inputs): # Define the op in python def _relu(x): return np.maximum(x, 0.) # Define the op's gradient in python def _relu_grad(x): return np.float32(x > 0) # An adapter that defines a gradient op compatible with TensorFlow def _relu_grad_op(op, grad): x = op.inputs[0] x_grad = grad * tf.py_func(_relu_grad, [x], tf.float32) return x_grad # Register the gradient with a unique id grad_name = "MyReluGrad_" + str(uuid.uuid4()) tf.RegisterGradient(grad_name)(_relu_grad_op) # Override the gradient of the custom op g = tf.get_default_graph() with g.gradient_override_map({"PyFunc": grad_name}): output = tf.py_func(_relu, [inputs], tf.float32) return output 复制代码
通过TensorFlow的 gradient checker ,你可以确认这些梯度是否计算正确:
x = tf.random_normal([10]) y = relu(x * x) with tf.Session(): diff = tf.test.compute_gradient_error(x, [10], y, [10]) print(diff) 复制代码
compute_gradient_error()
数值化地计算梯度,返回与理论上的梯度的差别,我们所期望的是一个非常小的差别。 注意到我们的这种实现是非常低效率的,这仅仅在实现模型原型的时候起作用,因为python代码并不能并行化而且不能在GPU上运算(导致速度很慢)。一旦你确定了你的idea,你就需要用C++重写其内核。 在实践中,我们一般在Tensorboard中用python操作进行可视化。如果你是在构建一个图片分类模型,而且想要在训练过程中可视化你的模型预测,那么TF允许你通过 tf.summary.image()
函数进行图片的可视化。
image = tf.placeholder(tf.float32) tf.summary.image("image", image) 复制代码
但是这仅仅是可视化了输入的图片,为了可视化其预测结果,你还必须找一个方法在图片上添加预测标识,当然这在现有的tensorflow操作中是不存在的。一个更简单的方法就是通过python将预测标志绘制到图片上,然后再封装它。
import io import matplotlib.pyplot as plt import numpy as np import PIL import tensorflow as tf def visualize_labeled_images(images, labels, max_outputs=3, name="image"): def _visualize_image(image, label): # Do the actual drawing in python fig = plt.figure(figsize=(3, 3), dpi=80) ax = fig.add_subplot(111) ax.imshow(image[::-1,...]) ax.text(0, 0, str(label), horizontalalignment="left", verticalalignment="top") fig.canvas.draw() # Write the plot as a memory file. buf = io.BytesIO() data = fig.savefig(buf, format="png") buf.seek(0) # Read the image and convert to numpy array img = PIL.Image.open(buf) return np.array(img.getdata()).reshape(img.size[0], img.size[1], -1) def _visualize_images(images, labels): # Only display the given number of examples in the batch outputs = [] for i in range(max_outputs): output = _visualize_image(images[i], labels[i]) outputs.append(output) return np.array(outputs, dtype=np.uint8) # Run the python op. figs = tf.py_func(_visualize_images, [images, labels], tf.uint8) return tf.summary.image(name, figs) 复制代码
请注意,因为 summary
通常只评估一次(并不是每步都执行),因此可以在实践中可以使用而不必担心效率。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 内核必须懂(六): 使用kgdb调试内核
- Linux内核如何替换内核函数并调用原始函数
- Linux内核工程师是怎么步入内核殿堂的?
- Linux内核工程师是怎么步入内核殿堂的?
- 面试官:说说操作系统微内核和 Dubbo 微内核?
- Linux 内核的核心维护者表示鲜有手机供应商更新内核
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
禅与摩托车维修艺术
(美)罗伯特·M.波西格 / 张国辰 / 重庆出版社 / 2011-9 / 36.00元
在一个炎热的夏天,父子两人和约翰夫妇骑摩托车从明尼苏达到加州,跨越美国大陆,旅行的过程与一个青年斐德洛研修科学技术与西方经典,寻求自我的解脱,以及探寻生命的意义的过程相互穿插。一路上父亲以一场哲学肖陶扩的形式,将见到的自然景色,野外露营的经历,夜晚旅店的谈话,机车修护技术等等日常生活与西方从苏格拉底以来的理性哲学的深入浅出的阐述与评论相结合,进行了对形而上学传统的主客体二元论的反思,以及对科学与艺......一起来看看 《禅与摩托车维修艺术》 这本书的介绍吧!