【问题标题】:Gradient Descent optimizer TensorFlow梯度下降优化器 TensorFlow
【发布时间】:2018-08-18 21:14:30
【问题描述】:

我是这个深度学习世界的新手。这些天来,我试图很好地理解神经网络是如何工作的,所以我正在做不同的测试。到目前为止,我正在使用数字从 0 到 9 的 MNIST 数据库。我已经应用了一个没有隐藏层的全连接网络。代码如下:

from keras.datasets import mnist # subroutines for fetching the MNIST dataset
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
from keras.utils import np_utils # utilities for one-hot encoding of ground truth values
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

x_train = mnist.train.images
y_train = mnist.train.labels
x_test = mnist.test.images
y_test = mnist.test.labels

test = np.reshape(x_train,[-1,28,28]) #THRESHOLDING
x_train = np.zeros([55000,28,28])
x_train[test > 0.5] = 1


print(x_train.shape)

x_train = np.reshape(x_train,[55000,784])
y_train = np_utils.to_categorical(y_train, 10) # One-hot encode the labels

print(x_train.shape)
print(y_train.shape)

x_test = np.reshape(x_test,[10000,784])

input = tf.placeholder(tf.float32, name='Input')
output = tf.placeholder(tf.float32, name = 'Output')

syn0 = tf.Variable(2*tf.random_uniform([784,10],seed=1)-1, name= 'syn0')
#syn0 = tf.Variable(tf.zeros([784,10], dtype = tf.float32), name= 'syn0')


b1 = tf.Variable(2*tf.random_uniform([10],seed=1)-1, name= 'b1')
#b1 = tf.Variable(tf.zeros([10],dtype = tf.float32), name= 'syn0')

init = tf.global_variables_initializer()

#model

l1 = tf.nn.softmax((tf.matmul(input,syn0) + b1),name='layer1')

error = tf.square(tf.subtract(l1,output),name='error')
loss = tf.reduce_sum(error, name='cost')

#optimizer
with tf.name_scope('trainning'):
    optimizer = tf.train.GradientDescentOptimizer(0.01)
    train = optimizer.minimize(loss)


#session
sess = tf.Session()
sess.run(init)

syn0_ini = sess.run(syn0)

#trainning
for i in range (10000):
    batch_xs, batch_ys = mnist.train.next_batch(128)
    _,lossNow =  sess.run([train,loss],{input: batch_xs,output: batch_ys})

    if i%10 == 0:
        print("Loss in iteration " , i, " is: ", lossNow )

#print debug 

y_pred = sess.run(l1,{input: x_test,output: y_test})

correct_prediction = tf.equal(tf.argmax(y_pred,1), tf.argmax(y_test,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print()
print("Final Accuracy: ", sess.run(accuracy))

我已经打印了权重 (syn0),但我什么也没看到。但是如果我将它们初始化为零,我可以看到数字的形状。这是逻辑,因为没有隐藏层,所以它就像一个相关性。

所以在第一种情况下,我可以假设我可以看到任何东西,因为权重没有被修改并且它们被初始化为随机值。

我不明白为什么训练函数只修改了一些权重,因为我给它喂食的损失只有一个数字。所以在我看来,所有的权重都必须以同样的方式修改。

这里有随机初始化的权重: weigths for 0 weights for 1

现在我将权重设为零初始化:

weigths for 0 weigths for 1

如您所见,有些权重与开始时一样,但有些权重发生了变化。损失函数只是一个标量,这怎么可能?

希望我的问题很清楚。如果不告诉我。

非常感谢。

【问题讨论】:

  • 抱歉,我无法理解您的问题。您能否在问题中包含一些示例,说明您已经获得了哪些价值以及您期望获得哪些价值?
  • @Neb 当然!我添加了一些照片来补充解释。希望它很清楚。谢谢!

标签: python tensorflow neural-network deep-learning mnist


【解决方案1】:

我不明白为什么训练函数只修改了一些权重,因为我给它喂食的损失只有一个数字。所以在我看来,所有的权重都必须以同样的方式修改。

这并不完全正确。

考虑单个训练样本情况下的线性激活:

Z = W*X + b    #(tf.matmul(input,syn0) + b1

在这里,您正在执行 W 和 X 之间的点积。基本上,您正在执行:

Z = sum(W[j] * X[j]) + b

oss:matmul 有效,因为您的权重是行向量,而特征是列向量。

之后,你应用非线性激活函数,即 softmax 函数。这将为您提供用于计算损失的预测,如您所说,这是一个标量。

现在,在执行反向传播步骤时,TF 将计算损失相对于 W 的每个分量的导数。明确地:

dW[j] = dL/dZ * dZ/dW[j]

地点:

  • dL/dZ 是损失对 Z 的导数
  • dZ/dW[j] 是 Z wrt 对 W 的导数

前面的公式是由链式法则得出的。

事实证明:

dZ/dW[j] = x[j]

这就是为什么您最终会为每个组件设置不同的值。

如需进一步分析,请参阅this 问题。基本上,将所有神经元的所有权重初始化为 0,会使您的网络变得多余,因为所有神经元的 W 值都相同。但是,在每个神经元中,W 的分量会有所不同。

【讨论】:

  • 非常感谢您的回答!我什么都明白了。
猜你喜欢
  • 1970-01-01
  • 2016-10-30
  • 2019-01-31
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2019-04-19
  • 1970-01-01
相关资源
最近更新 更多