开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第六天,点击查看活动详情
总结:此文为12月更文计划第六天第十一篇。
图graph
图是使用tensorflow提供的接口,将python的函数变为图,用来提高程序的运行速度。
自己编写代码实现relu激活函数,如果scale不为1,那就是selu
# tf.function and auto-graph.
def scaled_elu(z, scale=1.0, alpha=1.0):
# z >= 0 ? scale * z : scale * alpha * tf.nn.elu(z)
is_positive = tf.greater_equal(z, 0.0)
# return scale * tf.where(is_positive, z, alpha * tf.nn.elu(z))
return scale * tf.where(is_positive, z, alpha * (tf.math.exp(z)-1))
可以先运行一下,此可是python函数:
print(scaled_elu(tf.constant(-3.)))
print('-'*50)
print(scaled_elu(tf.constant([-3., -2.5])))
print('-'*50)
然后将python函数转化为图,可以提高运速度:
通过tf.function可以把py的函数变为图实现的函数
scaled_elu_tf = tf.function(scaled_elu)
print(scaled_elu_tf(tf.constant(-3.)))
print('-'*50)
我们来测试一下性能,100万个数
%timeit scaled_elu(tf.random.normal((1000, 1000)))
%timeit scaled_elu_tf(tf.random.normal((1000, 1000)))
输出的结果如下:
通过装饰器把函数变为图
#加了@tf.function装饰后就变为图结果,但是输入类型上不会有变化
@tf.function
def converge_to_2(n_iters):
total = tf.constant(0.)
increment = tf.constant(1.)
for _ in range(n_iters):
total += increment
increment /= 2.0
return total
print(converge_to_2)
print('-'*50)
print(converge_to_2(20))
加了@tf.function装饰后就变为图结果,但是输入类型上不会有变化
@tf.function
def converge_to_2(n_iters):
total = tf.constant(0.)
increment = tf.constant(1.)
for _ in range(n_iters):
total += increment
increment /= 2.0
return total
print(converge_to_2)
print('-'*50)
print(converge_to_2(20))
输出的结果如下:
tf要把变量定义在函数外面,不能放里边
var = tf.Variable(0.)
@tf.function
def add_21():
return var.assign_add(21) # +=
print(add_21())
输出的结果如下:
cube计算立方,py是泛型设计,我们通过input_signature加类型限制可以防止调错
# @tf.function(input_signature=[tf.TensorSpec([None], tf.int32, name='x')])
@tf.function
def cube(z):
return tf.pow(z, 3)
try:
print(cube(tf.constant([1., 2., 3.])))
except ValueError as ex:
print(ex)
print('-'*50)
#这行没问题
print(cube(tf.constant([1, 2, 3])))
输出的结果如下: