我是这个深度学习世界的新人。这些天我正在试图理解神经网络是如何工作的,所以我正在进行不同的测试。到目前为止,我正在使用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
现在我把权重置于零初始化:
正如你所看到的,有一些权重在开始时仍然存在,但有些权重会发生变化。这是怎么可能的,因为损失函数只是一个标量数?
希望我的问题很明确。如果不是只是告诉我。
非常感谢。
答案 0 :(得分:0)
我不明白的是为什么培训功能只修改了一些权重,因为我只用一个数字来减少它。因此,在我看来,所有权重必须以相同的方式进行修改。
这不完全正确。
在单个训练样本的情况下考虑线性激活:
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的分量将是不同的。