我正在尝试做 Stanfords CS20: TensorFlow for Deep Learning Research类(class)。前 2 个讲座很好地介绍了低级管道和计算框架(坦率地说,官方介绍性教程似乎因为我只能理解为虐待狂的原因而直接跳过)。在 lecture 3 ,它开始执行线性回归,并对我来说似乎是一个相当大的认知飞跃。而不是 session.run
在张量计算中,它在 GradientDescentOptimizer 上进行。
sess.run(optimizer, feed_dict={X: x, Y:y})
完整代码可在 lecture 3 notes 的第 3 页上找到。 .
编辑:代码和数据也可用 at this github - 代码在
examples/03_linreg_placeholder.py
中可用和数据在 examples/data/birth_life_2010.txt
编辑:代码如下根据要求
import tensorflow as tf
import utils
DATA_FILE = "data/birth_life_2010.f[txt"
# Step 1: read in data from the .txt file
# data is a numpy array of shape (190, 2), each row is a datapoint
data, n_samples = utils.read_birth_life_data(DATA_FILE)
# Step 2: create placeholders for X (birth rate) and Y (life expectancy)
X = tf.placeholder(tf.float32, name='X')
Y = tf.placeholder(tf.float32, name='Y')
# Step 3: create weight and bias, initialized to 0
w = tf.get_variable('weights', initializer=tf.constant(0.0))
b = tf.get_variable('bias', initializer=tf.constant(0.0))
# Step 4: construct model to predict Y (life expectancy from birth rate)
Y_predicted = w * X + b
# Step 5: use the square error as the loss function
loss = tf.square(Y - Y_predicted, name='loss')
# Step 6: using gradient descent with learning rate of 0.01 to minimize loss
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
with tf.Session() as sess:
# Step 7: initialize the necessary variables, in this case, w and b
sess.run(tf.global_variables_initializer())
# Step 8: train the model
for i in range(100): # run 100 epochs
for x, y in data:
# Session runs train_op to minimize loss
sess.run(optimizer, feed_dict={X: x, Y:y})
# Step 9: output the values of w and b
w_out, b_out = sess.run([w, b])
我已经完成了 coursera machine learning course当然,所以我(认为)我理解梯度下降的概念。但是我对这个特定案例中发生的事情感到非常困惑。
我期望必须发生的事情:
我知道在实践中你会应用诸如批处理和子集之类的东西,但在这种情况下,我相信这只是在整个数据集上循环 100 次。
我之前可以(并且已经)实现了这一点。但我正在努力理解上面的代码是如何实现这一目标的。一方面是在每个数据点上调用优化器(即它在 100 个时期的内部循环中,然后是每个数据点)。我本来期望一个优化调用会接收整个数据集。
问题 1 - 梯度调整是在整个数据集上运行 100 次,还是在整个数据集上运行 100 次,每批 1 次(所以 100*n 次,对于 n 个示例)?
问题 2 - 优化器如何“知道”如何调整 w 和 b?它只提供了损失张量 - 它是通过图表读回并只是“好吧,w和b是唯一的变量,所以我会摆脱这些”
问题 2b - 如果是这样,如果您放入其他变量会发生什么?或者更复杂的功能?它是否只是自动神奇地计算前导图中每个变量的梯度调整**
问题 2c - 据此,我尝试按照教程第 3 页中的建议调整为二次表达式,但最终得到了更高的损失。这是正常的吗?该教程似乎建议它应该更好。至少我希望它不会更糟 - 这是否会改变超参数?
编辑:我尝试调整为二次方的完整代码在这里。并不是说这与上面的相同,其中第 28、29、30 和 34 行被修改为使用二次预测器。这些编辑(我的解释)是 lecture 3 中建议的内容。第 4 页的注释
""" Solution for simple linear regression example using placeholders
Created by Chip Huyen (chiphuyen@cs.stanford.edu)
CS20: "TensorFlow for Deep Learning Research"
cs20.stanford.edu
Lecture 03
"""
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import time
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import utils
DATA_FILE = 'data/birth_life_2010.txt'
# Step 1: read in data from the .txt file
data, n_samples = utils.read_birth_life_data(DATA_FILE)
# Step 2: create placeholders for X (birth rate) and Y (life expectancy)
X = tf.placeholder(tf.float32, name='X')
Y = tf.placeholder(tf.float32, name='Y')
# Step 3: create weight and bias, initialized to 0
# w = tf.get_variable('weights', initializer=tf.constant(0.0)) old single weight
w = tf.get_variable('weights_1', initializer=tf.constant(0.0))
u = tf.get_variable('weights_2', initializer=tf.constant(0.0))
b = tf.get_variable('bias', initializer=tf.constant(0.0))
# Step 4: build model to predict Y
#Y_predicted = w * X + b #linear
Y_predicted = w * X * X + X * u + b #quadratic
#Y_predicted = w # test of nonsense
# Step 5: use the squared error as the loss function
# you can use either mean squared error or Huber loss
loss = tf.square(Y - Y_predicted, name='loss')
#loss = utils.huber_loss(Y, Y_predicted)
# Step 6: using gradient descent with learning rate of 0.001 to minimize loss
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)
start = time.time()
writer = tf.summary.FileWriter('./graphs/linear_reg', tf.get_default_graph())
with tf.Session() as sess:
# Step 7: initialize the necessary variables, in this case, w and b
sess.run(tf.global_variables_initializer())
# Step 8: train the model for 100 epochs
for i in range(100):
total_loss = 0
for x, y in data:
# Session execute optimizer and fetch values of loss
_, l = sess.run([optimizer, loss], feed_dict={X: x, Y:y})
total_loss += l
print('Epoch {0}: {1}'.format(i, total_loss/n_samples))
# close the writer when you're done using it
writer.close()
# Step 9: output the values of w and b
w_out, b_out = sess.run([w, b])
print('Took: %f seconds' %(time.time() - start))
print(f'w = {w_out}')
# plot the results
plt.plot(data[:,0], data[:,1], 'bo', label='Real data')
plt.plot(data[:,0], data[:,0] * w_out + b_out, 'r', label='Predicted data')
plt.legend()
plt.show()
对于线性预测器,我失去了(这与讲义一致):
Epoch 99: 30.03552558278714
对于我在二次方的尝试,我失去了:
Epoch 99: 127.2992221294363
最佳答案
data
的每个元素都是单个输入)。 IE。计算关于单个示例的损失梯度,更新参数,转到下一个示例……直到遍历整个数据集。这样做100次。 minimize
优化器的调用。实际上,您只需要考虑成本:在幕后,Tensorflow 将计算成本计算中涉及的所有请求变量的梯度(我们将在稍后讨论)(它可以从计算图中推断出这一点)并返回一个“应用”渐变的操作。这意味着一个操作接受所有请求的变量并为它们分配一个新值,例如 tf.assign(var, var - learning_rate*gradient)
.这与您提出的另一个问题有关:minimize
只返回一个操作,这没有任何作用!在 session 中运行此操作将每次执行“渐变步骤”。 至于哪些变量实际受此操作影响:您可以将其作为参数提供给
minimize
称呼! See here -- 参数是 var_list
.如果没有给出,Tensorflow 将简单地使用所有“可训练变量”。默认情况下,您使用 tf.Variable
创建的任何变量或 tf.get_variable
是可训练的。但是你可以通过 trainable=False
这些函数创建的变量(默认情况下)不会受到 minimize
返回的操作的影响。 .玩这个!看看如果您将某些变量设置为不可训练,或者您传递自定义 var_list
会发生什么情况至 minimize
.通常,Tensorflow 的“整体思想”是它可以“神奇地”仅基于模型的前馈描述来计算梯度。
编辑:这是可能的,因为机器学习模型(包括深度学习)由非常简单的构建块组成,例如矩阵乘法和主要的逐点非线性。这些简单的块也有简单的导数,可以通过链式法则组成。您可能想阅读反向传播算法。
对于非常大的模型,肯定需要更长的时间。但是,只要在所有组件都定义了导数的计算图中有一条清晰的“路径”,它总是可能的。
至于这是否会产生较差的模型:是的,这是深度学习的一个基本问题。非常复杂/深度的模型会导致高度非凸的成本函数,这些成本函数很难用梯度下降等方法进行优化。
关于二次函数:看起来这里有两个问题。
还有Adam等方法使用“自适应”学习率。通常,未调谐的自适应方法会优于未调谐的梯度下降法,因此它们适用于快速实验。然而,经过良好调整的梯度下降通常会反过来胜过它们。
关于tensorflow - TensowFlow GradientDescentOptimizer 在这个例子中做了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49434400/