[英]How to parallelize simple linear regression with gradient descent - using numpy?
[英]Simple gradient descent using mxnet
我正在嘗試使用MXNet的梯度下降優化器來最小化功能。 Tensorflow中的等效示例是:
import tensorflow as tf
x = tf.Variable(2, name='x', dtype=tf.float32)
log_x = tf.log(x)
log_x_squared = tf.square(log_x)
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(log_x_squared)
init = tf.initialize_all_variables()
def optimize():
with tf.Session() as session:
session.run(init)
print("starting at", "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))
for step in range(10):
session.run(train)
print("step", step, "x:", session.run(x), "log(x)^2:", session.run(log_x_squared))
我不確定如何在MXNet中完成相同的工作。 優化程序API 文檔似乎沒有等效方法。 這是我到目前為止所嘗試的內容。 主要的困惑是需要傳遞培訓數據:
import mxnet as mx
x = mx.sym.Variable('data')
log_x = mx.sym.log(x)
log_x_squared = mx.sym.square(log_x)
mod = mx.mod.Module(log_x_squared) # Create a module where the loss function
# is the one we want to optimize
mod.bind(data_shapes=[('data', (1,1))]) # ?? not sure if this is correct - we
# are saying our input is a scalar
mod.init_params()
mod.init_optimizer() # SGD is default
mod.fit() # ?? must pass data_iter to fit
似乎x
變量應該以某種方式作為data_iter
反饋,但我不知道如何實現這一點。
更新:感謝kevinthesun的出色答案! 這是一個建立在單個隱藏層神經網絡之上的工作最小化例程:
import mxnet as mx
import numpy as np
def minimize(objective_function,
initial_params,
max_iters=1000,
optimizer='sgd',
optimizer_params=(('learning_rate', 0.1),),
tol=1e-8):
class InitialParam(mx.init.Initializer):
def __init__(self, vals):
super(InitialParam, self).__init__()
self._vals = vals
def _init_weight(self, _, arr):
arr[:] = self._vals.asnumpy()[:, np.newaxis]
x = mx.sym.Variable('data')
params_len = initial_params.shape[0]
fc = mx.sym.FullyConnected(data=x, name='fc1',
num_hidden=params_len,
no_bias=True)
# Passing the FullyConnected layer into the objective function
# is difficult to manipulate. If the fully connected layer represents
# [x, y] for optimizing a 2 dimensional function f(x, y) it is easier
# to work with x, and y. So we split the fully connected layer into a
# number of symbols for each parameter:
param_syms = []
for i in range(params_len):
ps = mx.sym.slice(fc, begin=(0, i), end=(1, i + 1))
param_syms.append(ps)
# The loss function for the network is our objective function.
loss = mx.sym.MakeLoss(objective_function(param_syms))
mod = mx.mod.Module(loss)
mod.bind(data_shapes=[('data', (1,))])
mod.init_params(InitialParam(initial_params))
mod.init_optimizer(optimizer=optimizer,
optimizer_params=optimizer_params)
(o_name, o_shape), = mod.output_shapes
i = 0
params = initial_params
old_val = np.full(o_shape, np.nan)
while i < max_iters:
mod.forward_backward(mx.io.DataBatch(
data=[mx.nd.ones((1,))]))
mod.update()
params = mod.get_params()[0]['fc1_weight']
val = mod.get_outputs()[0].asnumpy()
if np.allclose(old_val, val, atol=tol):
print 'Function value: {}'.format(val)
print 'Iterations: {}'.format(i)
return params
old_val = val
i += 1
return params
並使用它:
def my_func(x):
return (x[0] + 1) ** 2
p = minimize(my_func, mx.nd.array([1.0]))
p.asnumpy()
>>> array([[-0.99999988]], dtype=float32)
另一個:
def my_func(x):
return (x[0] + 1) ** 2 + (x[1] - 2) ** 2 + (x[2] + 3) ** 2
p = minimize(my_func, mx.nd.array([1.0, 1.5, 2.0]))
p.asnumpy()
>>> array([[-0.99996436],
[ 1.99999106],
[-2.99991083]], dtype=float32)
目前,由於前端缺乏支持,使用MXNet優化簡單功能並不像tensorflow那么容易。
首先,您需要一個損失功能作為網絡的最后一層。 這是log_x_squared。 使用MakeLoss創建損失函數。
第二是輸入和權重。 由於目前MXNet中的變量不計入可訓練的重量,因此需要將x設置為重量。 這是一個解決方法:設置一個'假的'輸入變量,它總是為1.在它添加一個完全連接的圖層后,它有一個隱藏單元,沒有偏差。 這給了我們“1 * x”。 現在我們的x是一個重量。
第三,如果您想在單個數據樣本上多次優化,module.fit可能不是最佳選擇。 初始化優化器后。 您只需要多次調用module.forward_backward()和module.update()。 對於forward_backward函數,您需要傳遞數據集,與數據服務器相比,這是一個更簡單的接口。 這里我們只需要每次都傳遞一個1的常量ndarray。
實際上我們構造了log(1 * x)^ 2的計算圖,x變成了重量而不是變量。
無論如何,我們應該考慮提供類似的tensorflow接口來優化變量。
希望這是有用的信息!
mxnet與tensorflow不同。 您需要閱讀本教程
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.