tensorflow - 为什么 keras (SGD) optimizer.minimize() 在这个例子中没有达到全局最小值?
问题描述
我正在通过 DataCamp 完成 TensorFlow 教程,并且正在转录/复制我在自己的 Jupyter 笔记本中处理的代码示例。
以下是编码问题的原始说明:
我正在运行以下代码片段,但无法得出与教程中生成的结果相同的结果,我已通过 x 与 loss_function(x) 的连接散点图确认了正确的值,如图所示再往下一点。
# imports
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import Variable, keras
def loss_function(x):
import math
return 4.0*math.cos(x-1)+np.divide(math.cos(2.0*math.pi*x),x)
# Initialize x_1 and x_2
x_1 = Variable(6.0, np.float32)
x_2 = Variable(0.3, np.float32)
# Define the optimization operation
opt = keras.optimizers.SGD(learning_rate=0.01)
for j in range(100):
# Perform minimization using the loss function and x_1
opt.minimize(lambda: loss_function(x_1), var_list=[x_1])
# Perform minimization using the loss function and x_2
opt.minimize(lambda: loss_function(x_2), var_list=[x_2])
# Print x_1 and x_2 as numpy arrays
print(x_1.numpy(), x_2.numpy())
我绘制了一个快速连接的散点图,以确认(成功地)我使用的损失函数让我回到示例提供的同一图表(如上面的屏幕截图所示)
# Generate loss_function(x) values for given range of x-values
losses = []
for p in np.linspace(0.1, 6.0, 60):
losses.append(loss_function(p))
# Define x,y coordinates
x_coordinates = list(np.linspace(0.1, 6.0, 60))
y_coordinates = losses
# Plot
plt.scatter(x_coordinates, y_coordinates)
plt.plot(x_coordinates, y_coordinates)
plt.title('Plot of Input values (x) vs. Losses')
plt.xlabel('x')
plt.ylabel('loss_function(x)')
plt.show()
根据 DataCamp 环境,以下分别是生成的全局最小值和局部最小值:
4.38是正确的全局最小值, 0.42确实对应于图 RHS 上的第一个局部最小值(从 x_2 = 0.3 开始时)
以下是我的环境的结果,两者都与寻求最小化损失值时应该朝着的方向相反:
在过去 90 分钟的大部分时间里,我都在试图弄清楚为什么我的结果与 DataCamp 控制台的结果不一致/为什么优化器未能将这个简单玩具示例的损失降到最低……?
感谢您在自己的环境中运行提供的代码后可能提出的任何建议,非常感谢!
解决方案
事实证明,输出的差异源于 tf.division()(vs np.division())和 tf.cos()(vs math.cos())的默认精度——在 (我转录的,“自定义”)loss_function()的定义。
loss_function() 已在本教程的正文中进行了预定义,当我使用检查包(使用 inspect.getsourcelines(loss_function) )“检查”它以便在我自己的环境中重新定义它时,所述检查的输出没有t 清楚地表明已使用 tf.division 和 tf.cos 而不是它们的 NumPy 对应物(我的代码版本已使用)。
实际差异很小,但显然足以将优化器推向相反的方向(远离两个相应的最小值)。
在交换 tf.division() 和 tf.cos(如下所示)后,我能够得到与 DC 控制台中相同的结果。
这是 loss_function 的代码,它将返回与控制台中看到的相同结果(屏幕截图):
def loss_function(x):
import math
return 4.0*tf.cos(x-1)+tf.divide(tf.cos(2.0*math.pi*x),x)
推荐阅读
- javascript - 如何使用带有 post 方法的 link_to
- android - 开发android应用程序时代码无法正常工作
- vmware-clarity - 我们可以在可扩展行内使用 clr-dg-row
- python - macOS Mojave 10.14 的 Python 慢
- pandas - 根据 Pandas 中的值删除重复的值
- android - 在android中使用格式(XXX)XXX-XXXX ext.XXXXXX的蒙面EditText?
- pandas - 如何绘制关于唯一 ID 的异常值
- c# - ASP.NET Core 2.1 中的 Scaffold Identity UI 并添加全局过滤器
- vue.js - Vuepress - 将组件添加到每个页面
- python - 如何将每个基于芹菜类的任务保存在 django 项目中的单独文件中?