2015-12-04 324 views
27

假设我有一个非常简单的神经网络,如多层感知器。对于每一层,激活功能都是S形,并且网络完全连接。TensorFlow培训

在TensorFlow这可能是这样定义的:

sess = tf.InteractiveSession() 

    # Training Tensor 
    x = tf.placeholder(tf.float32, shape = [None, n_fft]) 
    # Label Tensor 
    y_ = tf.placeholder(tf.float32, shape = [None, n_fft]) 

    # Declaring variable buffer for weights W and bias b 
    # Layer structure [n_fft, n_fft, n_fft, n_fft] 
    # Input -> Layer 1 
    struct_w = [n_fft, n_fft] 
    struct_b = [n_fft] 
    W1 = weight_variable(struct_w, 'W1') 
    b1 = bias_variable(struct_b, 'b1') 
    h1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1) 

    # Layer1 -> Layer 2 
    W2 = weight_variable(struct_w, 'W2') 
    b2 = bias_variable(struct_b, 'b2') 
    h2 = tf.nn.sigmoid(tf.matmul(h1, W2) + b2) 

    # Layer2 -> output 
    W3 = weight_variable(struct_w, 'W3') 
    b3 = bias_variable(struct_b, 'b3') 
    y = tf.nn.sigmoid(tf.matmul(h2, W3) + b3) 

    # Calculating difference between label and output using mean square error 
    mse = tf.reduce_mean(tf.square(y - y_)) 

    # Train the Model 
    # Gradient Descent 
    train_step = tf.train.GradientDescentOptimizer(0.3).minimize(mse) 

该模型的设计目标是FFT频谱映射n_fft点到另一个n_fft目标频谱。我们假设训练数据和目标数据的大小都是[3000, n_fft]。它们存储在变量spec_trainspec_target中。

现在问题来了。对于TensorFlow,这两种训练有什么区别?

培训1:

for i in xrange(200): 
     train_step.run(feed_dict = {x: spec_train, y_: spec_target}) 

培训2:

for i in xrange(200): 
     for j in xrange(3000): 
      train = spec_train[j, :].reshape(1, n_fft) 
      label = spec_target[j, :].reshape(1, n_fft) 
      train_step.run(feed_dict = {x: train, y_: label}) 

非常感谢您!

回答

36

在第一个培训版本中,您正在训练整批培训数据,这意味着spec_train的第一个和第3000个元素将在一个步骤中使用相同的模型参数进行处理。这就是所谓的(批次)渐变下降

在第二个培训版本中,您正在训练训练数据的一个示例,这意味着spec_train的第3000个元素将使用自第一个元素最近一次更新2999次的模型参数进行处理处理。这就是所谓的随机梯度下降(或者如果元素是随机选择的话)。

一般来说,TensorFlow与太大的数据集一起使用,因此批量小,因此小批量SGD(其中一个示例的子集是一步处理的)受到青睐。一次处理单个元素在理论上是理想的,但由于矩阵乘法和其他操作不像计算密度那样固有地是连续的并且具有高固定成本。因此,一次处理小批量(例如32或128个)例子是常用方法,并行地对不同批次的多个副本进行训练。

请参阅此Stats StackExchange question以了解何时应使用一种方法与其他方法的更多理论讨论。

+0

这是我从您的文章了。在版本1中,权重和偏差不会更新,直到程序将整批数据提供给模型。这意味着3000个数据点会产生一个很大的重量调整。对于版本2,就像我使用3000个数据点来更新权重3000次,3000次小重量调整。它是否正确?谢谢。 – yc2986

+1

这是正确的,是的。如果你做了3000次单独的更新,后面的更新将使用更多的参数版本,这将改进收敛性(每个数据点经过训练)。 – mrry

+0

@mrry你能解释为什么“一次处理单个元素在理论上是可取的”?我一直认为更大批量更好。 –

0

是的,有区别。我认为第二种方式损失功能可能有点混乱。这更像在线培训。对于整个批次中的每个数据点,您都会更新所有参数。但在第一种方式中,它被称为批次渐变,您一次只能获取一个批次,并取平均损失,然后更新参数。

请参考以下链接 https://stats.stackexchange.com/questions/49528/batch-gradient-descent-versus-stochastic-gradient-descent 第一个答案是非常好的在这个环节