我正在尝试做斯坦福大学CS20:TensorFlow深度学习研究课程。前两节讲座很好地介绍了低级管道和计算框架(坦率地说,官方入门教程似乎由于我只能理解为虐待狂而跳过了)。在第3课中,它开始执行线性回归,并在我看来是相当沉重的认知飞跃。它不是session.run在张量计算上而是在GradientDescentOptimizer上执行。
sess.run(optimizer, feed_dict={X: x, Y:y})
Run Code Online (Sandbox Code Playgroud)
完整的代码可在第3 讲笔记的第3页上找到。
编辑:此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])
Run Code Online (Sandbox Code Playgroud)
我已经完成了Coursera机器学习课程,所以(我认为)我了解Gradient Descent的概念。但是我对这种特定情况下发生的事情一无所知。
我期望发生的事情:
我知道在实践中您会应用批处理和子集之类的方法,但是在这种情况下,我认为这只是遍历整个数据集100次。
我可以(并且已经)实现了这一点。但是我正在努力弄清楚上面的代码如何实现这一目标。一方面是在每个数据点上调用了优化器(即,它在100个纪元的内循环中,然后在每个数据点中)。我本来希望接受整个数据集的优化调用。
问题1-梯度调整是对整个数据集进行100次操作,还是对整个数据集进行1次的100次操作(对于n个示例,则为100 * n次)?
问题2-优化器如何“知道”如何调整w和b?它只是提供了损失张量-它是通过图形读回来的,并且只是“嗯,w和b是唯一的变量,所以我会从那些中摇摆一下”
问题2b-如果是这样,如果输入其他变量会怎样?或更复杂的功能?它是否会自动神奇地计算前图中的每个变量的梯度调整**
问题2c-因此,我尝试按照本教程第3页中的建议调整为二次表达式,但最终损失更高。这正常吗?该教程似乎建议它应该更好。至少我希望情况不会更糟-这是否会更改超参数?
编辑:我尝试调整为二次方的完整代码在这里。这与上面的第28、29、30和34行修改为使用二次预测器的方法不同。这些编辑(根据我的解释)是第4页第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()
Run Code Online (Sandbox Code Playgroud)
对于线性预测变量,我会有所损失(这与讲义一致):
Epoch 99: 30.03552558278714
Run Code Online (Sandbox Code Playgroud)
对于二次方,我迷失了:
Epoch 99: 127.2992221294363
Run Code Online (Sandbox Code Playgroud)
data都是一个输入)。即计算相对于单个示例的损耗梯度,更新参数,转到下一个示例...,直到遍历整个数据集为止。这样做100次。minimize优化器的调用。确实,您只需要输入成本:在后台,Tensorflow将为成本计算中涉及的所有请求变量(我们将在稍后介绍)计算梯度(它可以从计算图中推断出)并返回一个“应用”渐变的操作。这意味着一个op接受所有请求的变量并为其分配一个新值,例如tf.assign(var, var - learning_rate*gradient)。这与您提出的另一个问题有关:minimize仅返回一个op,这不会执行任何操作!每次在会话中运行此操作都会执行“渐变步骤”。关于哪个变量实际上受此操作影响:您可以将此作为minimize调用的参数!参见此处 -参数为var_list。如果没有给出,Tensorflow将仅使用所有“可训练变量”。默认情况下,您使用tf.Variable或创建的任何变量tf.get_variable都是可训练的。但是你可以通过trainable=False这些功能来创建是变量不是(默认情况下)将通过返回的运算的影响minimize。玩这个!看看你设置一些变量不被训练的会发生什么,或者如果你通过自定义var_list来minimize。
通常,Tensorflow的“整体思路”是它可以仅基于模型的前馈描述“神奇地”计算梯度。
编辑:这是可能的,因为机器学习模型(包括深度学习)是由非常简单的构建块组成的,例如矩阵乘法和主要是逐点非线性。这些简单的块也具有简单的导数,可以通过链式规则来组成。您可能想阅读反向传播算法。
对于大型模型,当然会花费更长的时间。但是,只要在所有组件都定义了导数的计算图中有明确的“路径”,就总是可能的。
关于这是否会产生不良模型:是的,这是深度学习的基本问题。非常复杂/较深的模型会导致高度非凸的成本函数,而这些函数很难通过梯度下降等方法进行优化。
关于二次函数:看起来这里有两个问题。
| 归档时间: |
|
| 查看次数: |
3924 次 |
| 最近记录: |