本文翻譯自: 《Prototyping kernels and advanced visualization with Python ops》, 若有侵權請聯繫刪除,僅限於學術交流,請勿商用。若有謬誤,請聯繫指出。python
TensorFlow中的內核操做徹底用C ++編寫,以提升效率。可是用C++編寫TensorFlow內核的話可能會很是痛苦。所以,在花費數小時實現屬於本身的內核以前,你也許須要先實現一個操做的原型,儘管這樣的效率會很低。經過tf.py_func()
你能夠將任何一個python源代碼轉換爲TensorFlow的操做。git
舉個例子而言,這裏有一個用python本身實現的ReLU非線性激活函數,經過tf.py_func()
轉換爲TensorFlow操做的例子:github
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,你能夠確認這些梯度是否計算正確:canvas
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()
函數進行圖片的可視化。app
image = tf.placeholder(tf.float32)
tf.summary.image("image", image)
複製代碼
可是這僅僅是可視化了輸入的圖片,爲了可視化其預測結果,你還必須找一個方法在圖片上添加預測標識,固然這在現有的tensorflow操做中是不存在的。一個更簡單的方法就是經過python將預測標誌繪製到圖片上,而後再封裝它。dom
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
一般只評估一次(並非每步都執行),所以能夠在實踐中可使用而沒必要擔憂效率。ide