我试图做Stanfords CS20: TensorFlow for Deep Learning Research课程。前两个讲座提供了对低级管道和计算框架的一个很好的介绍(坦率地说,官方的入门教程似乎跳过了原因我只能理解为虐待狂)。在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行被修改为使用二次预测器。这些修改(我解释)是第4页lecture 3注释中的建议
""" 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
答案 0 :(得分:2)
data
的每个元素是单个输入)。即根据单个示例计算损失的梯度,更新参数,转到下一个示例...直到您遍历整个数据集。这样做100次。minimize
调用中发生了批次事件。实际上,您只需付出代价:在引擎盖下,Tensorflow将计算所有请求变量的梯度(我们将在一秒钟内得到它),这些变量涉及成本计算(它可以从计算图中推断出来)并返回一个“应用”渐变的操作。这意味着一个op,它接受所有请求的变量并为它们分配一个新值,如tf.assign(var, var - learning_rate*gradient)
。这与您提出的另一个问题有关:minimize
只返回一个操作,这不会做任何事情! 在会话中运行此操作将每次执行“渐变步骤”。关于哪个变量实际受此操作影响:您可以将此作为minimize
调用的参数! See here - 参数为var_list
。如果没有给出,Tensorflow将简单地使用所有“可训练变量”。默认情况下,您使用tf.Variable
或tf.get_variable
创建的任何变量都是可训练的。但是,您可以将trainable=False
传递给这些函数,以创建非(默认情况下)的变量,这些变量将受minimize
返回的操作的影响。玩这个!如果您将某些变量设置为无法训练,或者将自定义var_list
传递给minimize
,请查看会发生什么。
一般来说,Tensorflow的“整体想法”是它可以“神奇地”仅基于模型的前馈描述来计算渐变。
编辑:这是可能的,因为机器学习模型(包括深度学习)由非常简单的构建块组成,例如矩阵乘法和大多数逐点非线性。这些简单的块也有简单的导数,可以通过链规则组成。您可能想要阅读反向传播算法
非常大的模型肯定需要更长的时间。但只要在计算图中有一条明确的“路径”,所有组件都有定义的导数,它总是可能的
至于这是否会产生不良模型:是的,这是深度学习的基本问题。非常复杂/深的模型导致高度非凸的成本函数,难以用梯度下降等方法进行优化。
关于二次函数:看起来这里有两个问题。