优化器
优化器
一般来说,优化器可以使用 Adam,前期使用 Adam 优化器快速下降,后期使用 SGD 并精调优化器参数得到更好的结果。此外目前也有一些前沿的优化算法,据称效果比 Adam 更好,例如 LazyAdam, Look-ahead, RAdam, Ranger 等.
优化器的使用
优化器主要使用 apply_gradients 方法传入变量和对应梯度从而来对给定变量进行迭代,或者直接使用 minimize 方法对目标函数进行迭代优化。当然,更常见的使用是在编译时将优化器传入 keras 的 Model,通过调用 model.fit 实现对 Loss 的的迭代优化。
初始化优化器时会创建一个变量 optimier.iterations 用于记录迭代的次数。因此优化器和 tf.Variable 一样,一般需要在@tf.function 外创建。
# 求f(x) = a*x**2 + b*x + c的最小值
# 使用optimizer.apply_gradients
x = tf.Variable(0.0,name = "x",dtype = tf.float32)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
@tf.function
def minimizef():
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)
while tf.constant(True):
with tf.GradientTape() as tape:
y = a*tf.pow(x,2) + b*x + c
dy_dx = tape.gradient(y,x)
optimizer.apply_gradients(grads_and_vars=[(dy_dx,x)])
# 迭代终止条件
if tf.abs(dy_dx)<tf.constant(0.00001):
break
if tf.math.mod(optimizer.iterations,100)==0:
printbar()
tf.print("step = ",optimizer.iterations)
tf.print("x = ", x)
tf.print("")
y = a*tf.pow(x,2) + b*x + c
return y
tf.print("y =",minimizef())
tf.print("x =",x)
我们也可以使用 optimizer.minimize 来求最小值:
# 求f(x) = a*x**2 + b*x + c的最小值
# 使用optimizer.minimize
x = tf.Variable(0.0,name = "x",dtype = tf.float32)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
def f():
a = tf.constant(1.0)
b = tf.constant(-2.0)
c = tf.constant(1.0)
y = a*tf.pow(x,2)+b*x+c
return(y)
@tf.function
def train(epoch = 1000):
for _ in tf.range(epoch):
optimizer.minimize(f,[x])
tf.print("epoch = ",optimizer.iterations)
return(f())
train(1000)
tf.print("y = ",f())
tf.print("x = ",x)