[英]Tensorflow (GPU) vs. Numpy
所以我有两种使用梯度下降的线性回归实现。 Tensorflow中的一个,Numpy中的一个。 我发现Numpy中的那个比Tensorflow中的快大约3倍。 这是我的代码-
Tensorflow:
class network_cluster(object):
def __init__(self, data_frame, feature_cols, label_cols):
self.init_data(data_frame, feature_cols, label_cols)
self.init_tensors()
def init_data(self, data_frame, feature_cols, label_cols):
self.data_frame = data_frame
self.feature_cols = feature_cols
self.label_cols = label_cols
def init_tensors(self):
self.features = tf.placeholder(tf.float32)
self.labels = tf.placeholder(tf.float32)
self.weights = tf.Variable(tf.random_normal((len(self.feature_cols), len(self.label_cols))))
self.const = tf.Variable(tf.random_normal((len(self.label_cols),)))
def linear_combiner(self):
return tf.add(tf.matmul(self.features, self.weights), self.const)
def predict(self):
return self.linear_combiner()
def error(self):
return tf.reduce_mean(tf.pow(self.labels - self.predict(), 2), axis = 0)
def learn_model(self, epocs = 100):
optimizer = tf.train.AdadeltaOptimizer(1).minimize(self.error())
error_rcd = []
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for epoc in range(epocs):
_, error = sess.run([optimizer, self.error()], feed_dict={
self.features: self.data_frame[self.feature_cols],
self.labels: self.data_frame[self.label_cols]
})
error_rcd.append(error[0])
return error_rcd
def get_coefs(self):
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
coefs = sess.run([self.weights, self.const])
return coefs
test_cluster = network_cluster(dataset, ['ship_jumps', 'npc_kills', 'ship_kills', 'pod_kills'], ['hour_of_week'])
%timeit test_cluster.learn_model(epocs = 100)
和numpy的:
def grad_descent(dataset, features, predictor, max_iters = 10000):
def initialize_model(dataset, features, predictor):
constant_array = np.ones(shape = (len(dataset), 1))
features_array = dataset.loc[:, features].values
features_array = np.append(constant_array, features_array, axis = 1)
predict_array = dataset.loc[:, predictor].values
betas = np.zeros(shape = (len(features) + 1, len(predictor)))
return (features_array, predict_array, betas)
def calc_gradient(features_array, predict_array, betas):
prediction = np.dot(features_array, betas)
predict_error = predict_array - prediction
gradient = -2 * np.dot(features_array.transpose(), predict_error)
gradient_two = 2 * np.expand_dims(np.sum(features_array ** 2, axis = 0), axis = 1)
return (gradient, gradient_two)
def update_betas(gradient, gradient_two, betas):
new_betas = betas - ((gradient / gradient_two) / len(betas))
return new_betas
def model_error(features_array, predict_array, betas):
prediction = np.dot(features_array, betas)
predict_error = predict_array - prediction
model_error = np.sqrt(np.mean(predict_error ** 2))
return model_error
features_array, predict_array, betas = initialize_model(dataset, features, predictor)
prior_error = np.inf
for iter_count in range(max_iters):
gradient, gradient_two = calc_gradient(features_array, predict_array, betas)
betas = update_betas(gradient, gradient_two, betas)
curr_error = model_error(features_array, predict_array, betas)
if curr_error == prior_error:
break
prior_error = curr_error
return (betas, iter_count, curr_error)
%timeit grad_descent(dataset, ['ship_jumps', 'npc_kills', 'ship_kills', 'pod_kills'], ['hour_of_week'], max_iters = 100)
我正在使用Spyder IDE进行测试,并且确实有Nvidia GPU(960)。 Tensorflow代码的时钟约为20秒,而Numpy代码的时钟约为7秒。 数据集几乎有100万行。
我本来希望Tensorflow在这里轻松击败Numpy,但事实并非如此。 当然,我是使用Tensorflow的新手,并且Numpy实现不使用类,但是Numpy还是好3倍?
希望对我在这里做错的事情有一些想法/想法。
无需详细查看您的代码(没有那么多的TF经验):
这种比较是有缺陷的 !
比较这些不同的算法非常困难,尤其是仅使用一个任务/数据集时。
即使您引入了提前停止,您也会观察到难以解释的基于随机种子的不确定性表现。
您基本上是在测量迭代时间,但这并不是一个好方法。 将一阶方法(梯度-> SGD,GD等)与二阶方法(hessian-> Newton)进行比较。 后者的迭代速度非常慢,但通常会获得二次收敛行为,从而减少了所需的迭代次数! 在NN应用中,此示例更多:LBFGS与SGD / ...(尽管我不知道TF中是否提供LBFGS; 火炬支持它)。 已知LBFGS实现了局部二次收敛,这在现实世界中的任务中再次难以解释(特别是因为逆基数的这种有限内存近似是LBFGS的参数)。 这种比较也可以在线性编程中完成,在线性编程中,单纯形法具有快速迭代,而内部点方法(基本上基于牛顿;但是在这里处理约束优化,还需要一些其他想法)每次迭代都慢得多(尽管在很多情况下更快地达到收敛)。
我在这里忽略的是:关于收敛和协方差的几乎所有理论结果。 仅限于凸函数和平滑函数。 NN通常是非凸的,这意味着评估这些绩效指标的任务更加艰巨。 但是,这里的问题当然是凸的。
我还必须承认,即使无约束的光滑凸优化是数值优化中较容易的任务之一(与受约束的,非光滑的非凸优化相比),我的回答也只是在摸索这个复杂问题的表面。
对于数值优化的一般介绍,其中还讨论了一阶与二阶方法(并且之间有很多方法),我建议您可以在网上找到Nocedal和Wright进行的数值优化。 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.