TensorFlow的tensor张量是不可变的无状态对象。在机器学习实现中,Variables是一个存在值的对象,可以表示模型中的参数。当其被使用时被隐式地被从存储中读取,而当有诸如tf.assign_sub, tf.scatter_update这样的操作时,得到的新值会储存到原对象中。
并且梯度计算时会自动跟踪Variables变量的计算(不用watch,入门笔记3中用watch的结果和不用是一样的),对表示嵌入的变量,TensorFlow会默认使用稀疏更新,这样可以提高计算和存储效率。
x = tf.Variable(1.0)
with tf.GradientTape() as t:
with tf.GradientTape() as tt:
#tt.watch(x)
y = x*x*x
dy_dx = tt.gradient(y, x)
print(dy_dx)
#t.watch(dy_dx)
# 计算z关于x的梯度
dy2_d2x = t.gradient(dy_dx, x)
print(dy2_d2x)
已知线性模型y = W*x+b,所以有:
class Model(object):
def __init__(self):
# 初始化变量
self.W = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def __call__(self, x):
return self.W * x + self.b
# 测试
model = Model()
print(model(2))
def loss(predicted_y, true_y):
return tf.reduce_mean(tf.square(predicted_y - true_y))# L2=1/2(z-z_hat)^2
TRUE_W = 3.0
TRUE_b = 2.0
num = 1000
# 随机输入
inputs = tf.random.normal(shape=[num])
# 随机噪音
noise = tf.random.normal(shape=[num])
# 构造数据
outputs = TRUE_W * inputs + TRUE_b + noise
import matplotlib.pyplot as plt
plt.scatter(inputs, outputs, c='b')
plt.scatter(inputs, model(inputs), c='r')
plt.show()
# 当前loss
print('Init Loss:')
print(loss(model(inputs), outputs))
Init Loss:
tf.Tensor(9.0944395, shape=(), dtype=float32)
遇到问题1:No module named ‘matplotlib’
解决:在终端中输入
source activate tensorflow
pip install matplotlib
遇到问题2:Figures now render in the Plots pane by default. To make them also appear inline in the Console, uncheck “Mute Inline Plotting” under the Plots pane options menu.
解决:修改设置Tools > Preferences > iPython console > Graphics > Graphics backend > Automatic,然后重启ide。
现在已经有了模型和训练数据,可以准备开始训练。
目标:用训练数据来更新模型的变量(W和b),使用梯度下降来减少损失loss。
输入:模型y=W*x+b,输入(用于计算模型估计的输出),实际的输出结果,学习率。
输出:训练之后得到的W和b
# 写梯度下降的训练函数
def train(Model,inputs,outputs,learning_rate):
with tf.GradientTape() as t:
current_loss = loss(model(inputs), outputs)
dW,db = t.gradient(current_loss, [model.W, model.b])#沿着梯度方向下降最快
model.W.assign_sub(dW*learning_rate)#W:= W-a*dW
model.b.assign_sub(db*learning_rate)#b:= b-a*db
# 收集W,b画图
Ws, bs = [], []
for epoch in range(100):#迭代计算100次
Ws.append(model.W.numpy())#将variable转成numpy之后添加在向量后面
bs.append(model.b.numpy())
# 计算loss
current_loss = loss(model(inputs), outputs)
train(model, inputs, outputs, learning_rate=0.1)
print('Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f' %
(epoch, Ws[-1], bs[-1], current_loss))
# 画图
# Let's plot it all
epochs = range(100)
plt.plot(epochs, Ws, 'r',
epochs, bs, 'b')
plt.plot([TRUE_W] * len(epochs), 'r--',
[TRUE_b] * len(epochs), 'b--')
plt.legend(['W', 'b', 'true W', 'true_b'])
plt.show()