刚学了TensorFlow2.0的梯度下降原理,觉得是否可以用到连续函数求最值问题中,先从简单的函数入手,一元多次函数,比如:
x
7
∗
(
1
−
x
)
3
x^7*(1-x)^3
x7∗(1−x)3
把梯度下降代码稍微改了下,利用TensorFlow2.0自动求导函数
import tensorflow as tf
def func1(x):
return (x ** 7) * (1 - x) ** 3
x1 = tf.constant(0.5) # 初始点的值
for step in range(20001): # 迭代20000次。
with tf.GradientTape() as tape:
tape.watch([x1])
y1 = func1(x1)
grads = tape.gradient(y1, [x1])[0]
# print(grads)
# 求最大值为 + ,最小值为 -
x1 += 0.01 * grads
if step % 2000 == 0:
print('step {0}: x1 = {1}, y1 = {2}'.format(step, x1.numpy(), y1.numpy()))
多迭代几次,这里设置的是2万次。
此时求的是这个函数的最大值,求最小值就改为减号
结果为
step 0: x1 = 0.5000781416893005, y1 = 0.0009765625
step 2000: x1 = 0.647747278213501, y1 = 0.002091002417728305
step 4000: x1 = 0.6929699182510376, y1 = 0.0022209687158465385
step 6000: x1 = 0.6991444826126099, y1 = 0.0022235270589590073
step 8000: x1 = 0.6998952031135559, y1 = 0.00222356547601521
step 10000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
step 12000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
step 14000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
step 16000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
step 18000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
step 20000: x1 = 0.6999719142913818, y1 = 0.0022235659416764975
可以看出当x1=0.7时,y1取最大值0.0022235659416764975
x的值不断趋近最值,这就是梯度下降的原理。
要不来个更复杂的函数,例如
2
∗
s
i
n
(
x
)
+
c
o
s
(
x
)
2*sin(x)+cos(x)
2∗sin(x)+cos(x)
用遗传算法得到最大值为:2.23606797749979
遗传算法结果为
那我们修改梯度下降的代码,求解这个函数(其实就是改了func1的表达式!!!)
import tensorflow as tf
import math
def func1(x):
return 2 * tf.sin(x) + tf.cos(x)
x1 = tf.constant(0.5) # 初始点的值
for step in range(20001): # 迭代20000次。
with tf.GradientTape() as tape:
tape.watch([x1])
y1 = func1(x1)
grads = tape.gradient(y1, [x1])[0]
# print(grads)
# 求最大值为 + ,最小值为 -
x1 += 0.01 * grads
if step % 2000 == 0:
print('step {0}: x1 = {1}, y1 = {2}'.format(step, x1.numpy(), y1.numpy()))
结果为
step 0: x1 = 0.512757420539856, y1 = 1.8364336490631104
step 2000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 4000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 6000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 8000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 10000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 12000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 14000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 16000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 18000: x1 = 1.107146143913269, y1 = 2.2360680103302
step 20000: x1 = 1.107146143913269, y1 = 2.2360680103302
求得x = 1.107146143913269时,y有最大值2.2360680103302,和遗传算法求的2.23606797749979,基本一样,但是代码量肯定比遗传算法少多了,原理也比它简单,有意思。
本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/weixin_45092662。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。