在 TensorFlow 中执行梯度下降时,如何将偏差项与其他权重一起包含在内?
How do I include the bias term with other weights when performing gradient descent in TensorFlow?
我是 ML 的初学者,一直在关注 Coursera 的介绍教学大纲。我正在尝试使用 TensorFlow 而不是 Octave 来实施练习。
我有三个版本 - 前两个工作正常,第三个不工作。我想知道为什么。
注意 - 我在 F# 中使用 TensorFlow.Net,但绑定是 API 的 1:1 映射,所以它应该看起来Python 开发者非常熟悉。
1.) 完全手动,工作正常
let gradientDescent (x : Tensor) (y : Tensor) (alpha : Tensor) iters =
let update (theta : Tensor) =
let delta =
let h = tf.matmul(x,theta)
let errors = h - y
let s = tf.matmul((tf.transpose x), errors)
s / m
theta - alpha * delta
let rec search (theta : Tensor) i =
if i = 0 then
theta
else
search (update theta) (i - 1)
let initTheta = tf.constant([| 0.; 0. |], shape = Shape [| 2; 1 |])
search initTheta iters
let ones = tf.ones(Shape [| m; 1 |], dtype = TF_DataType.TF_DOUBLE)
let X = tf.concat([ ones; x ], axis = 1)
let theta = gradientDescent X y alpha iterations
2.) 使用 Gradient Tape 通过单独的偏差项进行自动微分 - 也可以正常工作
let gradientDescent (x : Tensor) (y : Tensor) (alpha : float32) iters =
let W = tf.Variable(0.f, name = "weight")
let b = tf.Variable(0.f, name = "bias")
let optimizer = keras.optimizers.SGD alpha
for _ in 0 .. iters do
use g = tf.GradientTape()
let h = W * x + b
let loss = tf.reduce_sum(tf.pow(h - y,2)) / (2 * m)
let gradients = g.gradient(loss, struct (b,W))
optimizer.apply_gradients(zip(gradients, struct (b,W)))
tf
.constant(value = [| b.value(); W.value() |], shape = Shape [| 2; 1 |])
.numpy()
.astype(TF_DataType.TF_DOUBLE)
let theta = gradientDescent x y alpha iterations
3.) 像以前一样使用渐变带,这次将偏差项作为权重的一部分 - 这会在调用 apply_gradients
.
时抛出堆栈溢出异常
let gradientDescent (x : Tensor) (y : Tensor) (alpha : float32) iters =
let W = tf.Variable(tf.constant([| 0.; 0. |], shape = Shape [| 2; 1 |]))
let optimizer = keras.optimizers.SGD alpha
for _ in 0 .. iters do
use g = tf.GradientTape()
let h = tf.matmul(x, W)
let loss = tf.reduce_sum(tf.pow(h - y,2)) / (2 * m)
let gradients = g.gradient(loss, W) // correct gradient tensor returned here
optimizer.apply_gradients(struct(gradients, W)) // boom!
tf
.constant(value = W.value().ToArray<double>(), shape = Shape [| 2; 1 |])
.numpy()
let ones = tf.ones(Shape [| m; 1 |], dtype = TF_DataType.TF_DOUBLE)
let X = tf.concat([ ones; x ], axis = 1)
let theta = gradientDescent X y alpha iterations
我解决了 - optimizer.apply_gradients
需要一个可迭代对象。
我所要做的就是改变
optimizer.apply_gradients(struct(gradients, W))
到
optimizer.apply_gradients(zip([|gradients|], [|W|]))
加上一点 float32 / 64 转换
我是 ML 的初学者,一直在关注 Coursera 的介绍教学大纲。我正在尝试使用 TensorFlow 而不是 Octave 来实施练习。
我有三个版本 - 前两个工作正常,第三个不工作。我想知道为什么。
注意 - 我在 F# 中使用 TensorFlow.Net,但绑定是 API 的 1:1 映射,所以它应该看起来Python 开发者非常熟悉。
1.) 完全手动,工作正常
let gradientDescent (x : Tensor) (y : Tensor) (alpha : Tensor) iters =
let update (theta : Tensor) =
let delta =
let h = tf.matmul(x,theta)
let errors = h - y
let s = tf.matmul((tf.transpose x), errors)
s / m
theta - alpha * delta
let rec search (theta : Tensor) i =
if i = 0 then
theta
else
search (update theta) (i - 1)
let initTheta = tf.constant([| 0.; 0. |], shape = Shape [| 2; 1 |])
search initTheta iters
let ones = tf.ones(Shape [| m; 1 |], dtype = TF_DataType.TF_DOUBLE)
let X = tf.concat([ ones; x ], axis = 1)
let theta = gradientDescent X y alpha iterations
2.) 使用 Gradient Tape 通过单独的偏差项进行自动微分 - 也可以正常工作
let gradientDescent (x : Tensor) (y : Tensor) (alpha : float32) iters =
let W = tf.Variable(0.f, name = "weight")
let b = tf.Variable(0.f, name = "bias")
let optimizer = keras.optimizers.SGD alpha
for _ in 0 .. iters do
use g = tf.GradientTape()
let h = W * x + b
let loss = tf.reduce_sum(tf.pow(h - y,2)) / (2 * m)
let gradients = g.gradient(loss, struct (b,W))
optimizer.apply_gradients(zip(gradients, struct (b,W)))
tf
.constant(value = [| b.value(); W.value() |], shape = Shape [| 2; 1 |])
.numpy()
.astype(TF_DataType.TF_DOUBLE)
let theta = gradientDescent x y alpha iterations
3.) 像以前一样使用渐变带,这次将偏差项作为权重的一部分 - 这会在调用 apply_gradients
.
let gradientDescent (x : Tensor) (y : Tensor) (alpha : float32) iters =
let W = tf.Variable(tf.constant([| 0.; 0. |], shape = Shape [| 2; 1 |]))
let optimizer = keras.optimizers.SGD alpha
for _ in 0 .. iters do
use g = tf.GradientTape()
let h = tf.matmul(x, W)
let loss = tf.reduce_sum(tf.pow(h - y,2)) / (2 * m)
let gradients = g.gradient(loss, W) // correct gradient tensor returned here
optimizer.apply_gradients(struct(gradients, W)) // boom!
tf
.constant(value = W.value().ToArray<double>(), shape = Shape [| 2; 1 |])
.numpy()
let ones = tf.ones(Shape [| m; 1 |], dtype = TF_DataType.TF_DOUBLE)
let X = tf.concat([ ones; x ], axis = 1)
let theta = gradientDescent X y alpha iterations
我解决了 - optimizer.apply_gradients
需要一个可迭代对象。
我所要做的就是改变
optimizer.apply_gradients(struct(gradients, W))
到
optimizer.apply_gradients(zip([|gradients|], [|W|]))
加上一点 float32 / 64 转换