Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tensorflow(GPU)vs.Numpy_Python_Numpy_Tensorflow_Tensorflow Gpu - Fatal编程技术网

Python Tensorflow(GPU)vs.Numpy

Python Tensorflow(GPU)vs.Numpy,python,numpy,tensorflow,tensorflow-gpu,Python,Numpy,Tensorflow,Tensorflow Gpu,我有两个使用梯度下降的线性回归的实现。一个在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)

我有两个使用梯度下降的线性回归的实现。一个在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还是比使用Tensorflow好3倍


希望能对我在这里犯的错误有一些想法/想法。

无需详细查看您的代码(没有太多TF经验):

这个比较是有缺陷的

  • Yaroslav的评论当然是正确的:GPU计算有一些开销(至少是数据准备;不确定这里记录的是哪种编译)
  • 您在完整批处理模式下比较纯GD和ADADDelta,似乎:
    • ADADDelta当然会带来一些开销(比计算梯度和乘以当前迭代次数还要多的操作),因为它是一种常见的方差减少方法,需要付出代价!
      • 其想法是:投资一些额外的业务:
        • 在给定一定学习率的情况下,删除所需的迭代次数
        • (这要复杂得多:对大多数人来说->使用默认的学习速率实现良好的收敛)
  • 看起来你每个人只跑了100个纪元,并且记下了这个
    • 那没有意义!
      • 很有可能目标非常不同:
        • 如果迭代大小不够
        • 或者初始学习率选择不当
      • 或者是相同的,但是不存在的提前停止确保了一个可能的更好的算法,并且证明了收敛性(根据一些标准)浪费了一些额外的时间进行所有迭代,直到达到100
  • (ADADDelta可能设计用于SGD设置,而不是GD)
很难比较这种不同的算法,特别是当只使用一个任务/数据集时

即使引入提前停止,也会观察到基于随机种子的不确定性能,这很难解释

您基本上是在测量迭代时间,但这不是一个好的测量方法。比较一阶方法(梯度->SGD,GD,…)和二阶方法(hessian->牛顿)。后者迭代速度非常慢,但通常会获得二次收敛行为,从而减少所需的迭代次数!在NN应用程序中,此示例更为详细:LBFGS与SGD/。。。(尽管我不知道TF中是否有LBFGS;是否支持它)。已知LBFGS可实现局部二次收敛,这在实际任务中很难解释(特别是因为逆hessian的有限内存近似是LBFGS的一个参数)。这种比较也可以在线性规划上进行,其中单纯形法迭代速度快,而内点法(基本上基于牛顿法;但这里处理约束优化需要一些额外的想法)每次迭代速度慢得多(尽管在许多情况下收敛速度更快)

我在这里忽略的是:几乎所有关于收敛和协同的理论结果都局限于凸函数和光滑函数。NN通常是非凸的,这意味着评估这些性能度量的任务更加艰巨。但你这里的问题当然是凸的

我还必须承认,我的答案只是触及了这个复杂问题的表面,即使无约束光滑凸优化是数值优化中比较容易的任务之一(与约束、非光滑非凸优化相比)


对于数值优化的一般介绍,其中也谈到了很多关于一阶和二阶方法(中间有许多方法),我推荐可以在web上找到的方法。

注意,当您执行“sess.run([optimizer,self.error()],feed_dict={”时,numpy和TensorFlow有单独的内存系统,它在每一步都将数据从numpy复制到TensorFlow GPU空间