梯度下降优化器 TensorFlow
Gradient Descent optimizer TensorFlow
我是深度学习领域的新手。这些天我试图很好地理解神经网络是如何工作的,所以我正在做不同的测试。到目前为止,我正在使用 MNIST 数据库,其中包含从 0 到 9 的数字。我应用了一个没有隐藏层的完全连接的网络。这是代码:
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
如您所见,有些权重与开始时保持不变,但有些权重发生了变化。这怎么可能,因为损失函数只是一个标量数?
希望我的问题很清楚。如果不行就告诉我。
非常感谢。
What I don't understand is why only some weights have been modified by the training function since I'm feeding it with a loss that is just one number. So in my opinion, all the weights must be modified in the same way.
这不完全正确。
考虑单个训练样本情况下的线性激活:
Z = W*X + b #(tf.matmul(input,syn0) + b1
这里你正在执行 W 和 X 之间的点积。基本上,你在做:
Z = sum(W[j] * X[j]) + b
oss:matmul 有效是因为你的权重是 row-vector,特征是 column-vector。
之后,你应用非线性激活函数,即softmax函数。这将为您提供用于计算损失的预测,即您所说的标量。
现在,在执行反向传播步骤时,TF 将计算损失相对于 W 的每个分量的导数。明确地:
dW[j] = dL/dZ * dZ/dW[j]
其中:
dL/dZ
是损失对 Z 的导数
dZ/dW[j]
是 Z 对 W 的导数
前面的公式由链式法则推导出来
结果是:
dZ/dW[j] = x[j]
这就是为什么您最终得到每个组件的不同值的原因。
进一步分析见this问题。基本上,将所有神经元的所有权重初始化为 0,会使您的网络变得冗余,因为所有神经元都将具有相同的 W 值。但是,在每个神经元中,W 的分量将不同。
我是深度学习领域的新手。这些天我试图很好地理解神经网络是如何工作的,所以我正在做不同的测试。到目前为止,我正在使用 MNIST 数据库,其中包含从 0 到 9 的数字。我应用了一个没有隐藏层的完全连接的网络。这是代码:
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
如您所见,有些权重与开始时保持不变,但有些权重发生了变化。这怎么可能,因为损失函数只是一个标量数?
希望我的问题很清楚。如果不行就告诉我。
非常感谢。
What I don't understand is why only some weights have been modified by the training function since I'm feeding it with a loss that is just one number. So in my opinion, all the weights must be modified in the same way.
这不完全正确。
考虑单个训练样本情况下的线性激活:
Z = W*X + b #(tf.matmul(input,syn0) + b1
这里你正在执行 W 和 X 之间的点积。基本上,你在做:
Z = sum(W[j] * X[j]) + b
oss:matmul 有效是因为你的权重是 row-vector,特征是 column-vector。
之后,你应用非线性激活函数,即softmax函数。这将为您提供用于计算损失的预测,即您所说的标量。
现在,在执行反向传播步骤时,TF 将计算损失相对于 W 的每个分量的导数。明确地:
dW[j] = dL/dZ * dZ/dW[j]
其中:
dL/dZ
是损失对 Z 的导数
dZ/dW[j]
是 Z 对 W 的导数
前面的公式由链式法则推导出来
结果是:
dZ/dW[j] = x[j]
这就是为什么您最终得到每个组件的不同值的原因。
进一步分析见this问题。基本上,将所有神经元的所有权重初始化为 0,会使您的网络变得冗余,因为所有神经元都将具有相同的 W 值。但是,在每个神经元中,W 的分量将不同。