Theano 使用 `scan` 替代 `for` 循环进行线性回归

我正在尝试更好地理解 theano 中的 scan 功能,根据文档,我的理解是它类似于 for 循环。我创建了一个非常简单的可运行示例,用于在执行线性回归时查找权重和偏置。

#### 库# 第三方库import numpy as npimport theanoimport theano.tensor as T# 非迷你批量使用def gen_data(num_points=50, slope=1, bias=10, x_max=50):    f = lambda z: slope * z + bias    x = np.zeros(shape=(num_points), dtype=theano.config.floatX)    y = np.zeros(shape=(num_points), dtype=theano.config.floatX)    for i in range(num_points):        x_temp = np.random.uniform()*x_max        x[i] = x_temp        y[i] = f(x_temp) + np.random.normal(scale=3.0)    return (x, y)##########################################################################################################################train_x, train_y = gen_data(num_points=50, slope=2, bias=5)epochs = 50# 声明变量learn_rate = T.scalar(name='learn_rate', dtype=theano.config.floatX)x = T.vector(name='x', dtype=theano.config.floatX)y = T.vector(name='y', dtype=theano.config.floatX)# 将被更新的变量theta = theano.shared(np.random.rand(), name='theta')bias = theano.shared(np.random.rand(), name='bias')hyp = T.dot(theta, x) + biascost = T.mean((hyp - y)**2)/2f_cost = theano.function(inputs=[x, y], outputs=cost)grad_t, grad_b = T.grad(cost, [theta, bias])train = theano.function(inputs=[x, y, learn_rate], outputs=cost,                        updates=((theta, theta-learn_rate*grad_t),                                  (bias, bias-learn_rate*grad_b)))print('weight: {}, bias: {}'.format(theta.get_value(), bias.get_value()))for i in range(epochs): # 尝试将此处改为 `scan`    train(train_x, train_y, 0.001)print('------------------------------')print('weight: {}, bias: {}'.format(theta.get_value(), bias.get_value()))

我想将那个 for 循环改为 theano.scan 函数,但我每次尝试都遇到一个接一个的错误消息。


回答:

为了使用 theano.scan,我从 collection 中导入了 OrderedDict 以便用于共享变量。使用 dict 会导致以下错误消息:

Expected OrderedDict or OrderedUpdates, got <class 'dict'>. This can make your script non-deterministic.

其次,我定义了一个函数来计算损失和梯度。该函数返回 loss 和一个 OrderedDict()。函数如下:

def cost(inputs, outputs, learn_rate, theta, bias):    hyp = T.dot(theta, inputs) + bias    loss = T.mean((hyp - outputs)**2)/2    grad_t, grad_b = T.grad(loss, [theta, bias])    return loss, OrderedDict([(theta, theta-learn_rate*grad_t),                              (bias, bias-learn_rate*grad_b)])

接着,我定义了 theano.scan() 如下:

results, updates = theano.scan(fn=cost,                               non_sequences=[x, y, learn_rate, theta, bias],                               n_steps=epochs)

我选择将 xy 作为 non_sequences 包含进来,因为这个玩具示例相对较小,并且与将其作为 sequences 传递相比速度提高了大约两倍。

最后,使用 theano.scan()results, updates 定义了 theano.function()

train = theano.function(inputs=[x, y, learn_rate, epochs], outputs=results,                        updates=updates)

将所有内容整合在一起,我们有:

#### 库# 标准库from collections import OrderedDict# 第三方库# import matplotlib.pyplot as pltimport numpy as np# from sklearn import linear_modelimport theanoimport theano.tensor as T# def gen_data(num_points=50, slope=1, bias=10, x_max=50):#     pass # 使用上文中的代码生成样本点######################################################################### 生成数据train_x, train_y = gen_data(num_points=50, slope=2)# 声明变量x = T.vector(name='x', dtype=theano.config.floatX)y = T.vector(name='y', dtype=theano.config.floatX)learn_rate = T.scalar(name='learn_rate', dtype=theano.config.floatX)epochs = T.iscalar(name='epochs')# 将被更新的变量,因此声明为 `theano.share`theta = theano.shared(np.random.rand(), name='theta')bias = theano.shared(np.random.rand(), name='bias')def cost(inputs, outputs, learn_rate, theta, bias):    hyp = T.dot(theta, inputs) + bias    loss = T.mean((hyp - outputs)**2)/2    grad_t, grad_b = T.grad(loss, [theta, bias])    return loss, OrderedDict([(theta, theta-learn_rate*grad_t),                              (bias, bias-learn_rate*grad_b)])results, updates = theano.scan(fn=cost,                               non_sequences=[x, y, learn_rate, theta, bias],                               n_steps=epochs)# results, updates = theano.scan(fn=cost,#                              sequences=[x, y],#                              non_sequences = [learn_rate, theta, bias],#                              n_steps=epochs)train = theano.function(inputs=[x, y, learn_rate, epochs], outputs=results,                        updates=updates)print('weight: {}, bias: {}'.format(theta.get_value(), bias.get_value()))train(train_x, train_y, 0.001, 30)print('------------------------------')print('weight: {}, bias: {}'.format(theta.get_value(), bias.get_value()))

为了完整性,我包含了将 xy 作为 sequences 传递的代码。只需取消注释该部分代码,并并且注释掉另一个 theano.scan() 实例。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注