在 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 转换