引子
对于初学者来说,我相信很容易对神经网络中的各种 Shape 形式产生混乱。(事实证明,我和我的同学就做过相关讨论)
比如,神经网络中,对于一张图片的输入需要怎么样处理呢,除了把图像压缩成一个向量外,一个样本看做一行还是一列的形式输入呢,权重
W
W
的形式是什么样的,等等
下面我将对比 吴恩达的Deep Learning 中教学的知识 与 TensorFlow 中的各种 Shape 进行解释:
在我实现神经网络的时候(http://blog.youkuaiyun.com/MachineRandy/article/details/79546994),遇到这样的一个问题,对于一个第 层的网络,神经元的数量分别是 n,m n , m ,权重 W W 的维度 shape 到底如何定义?
logistics 回归中权重的表述
在吴恩达的视频中,多以 表示,习惯是,我在里面的陈述中更多的使用
W
W
表示权重 ,两者均表示权重这一相同的含义,我们看一下神经网络的最简单形式 Logistic 回归的情况:
权重 和 输入
X
X
都是以列向量的形式给出
在李航博士的《统计学习方法》中,内积部分习惯上使用 W⋅X W ⋅ X 的形式,两种表达形式均可以。对于权重的shape 形式,这里显而易见, shape(θT)=shape(W) s h a p e ( θ T ) = s h a p e ( W ) ,具体维度之后分析。
再如下面的网络结构
假设第一层为输入
X
X
, 的特征数就是 4 ,第二层为隐藏层
在计算的时候,根据公式
和矩阵乘法 W W 的列数等于 的行数,因为 W⋅X W ⋅ X 得到的一定是与样本数、第二层神经元数相关,可以容易想到,相等的部分就是 X X 的特征数量。
即对于 比如有 10 个样本,每个样本有 4 个特征,那么输入为 X4×10 X 4 × 10
那么 W→num_units(i+1)×num_units(i) W → n u m _ u n i t s ( i + 1 ) × n u m _ u n i t s ( i ) 即 ( ( 后一层神经元数 ,前一层神经元数 对应上图的就是 W3×4 W 3 × 4
之后,我们会在输出层(这里是指第二层)的每个单元上加上一个偏置 b b ,因此这里的偏置为
这就是推导的形式和我按照公式以及授课内容的理解,我们看看在我们使用计算的过程中有什么问题:
首先,在以往处理结构化数据时,我们都是采用一行表示一个样本数,每一列表示数据的一个特征(或属性),而在这里正好相反,这容易造成混淆,另外,对于权重
W
W
在定义网络时,按照向前传播的趋势,我们更容易接受前后两层的神经元数与权重 的前后维度顺序一致的情况(即更倾向于理解 吴恩达的
θT
θ
T
中
θ
θ
)
我之所以辨析,就是因为我发现在 TensorFlow 中的各个变量的 shape 与之前的理解是不一样的。
在 TensorFlow 中,
W
W
、、
b
b
的形式均与之前数学推导相反。
对于输入形式 ,每一行代表一个样本实例,每一列代表一个特征(属性),因此一个有 10 个样本,每个样本有 4 个特征的数据集,表示为 X10×4 X 10 × 4 ;
对于权重形式
W
W
, 为
(
(
前一层神经元数 ,后一层神经元数 对应上面网络图的就是
W4×3
W
4
×
3
,
因此,内积形式
W3×4⋅X4×10+b3×1
W
3
×
4
⋅
X
4
×
10
+
b
3
×
1
变成
X10×4⋅W4×3+b1×3
X
10
×
4
⋅
W
4
×
3
+
b
1
×
3
,并且对于最终全连接的单输出节点
Y
Y
得到的结果也由 。
具体,可以从下面例子中看出:
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 19 15:24:06 2018
@author: lyh
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
def add_layer(inputs,in_size,out_size,activation_function=None):
W = tf.Variable(tf.random_normal([in_size,out_size]),name="wight")
b = tf.Variable(tf.zeros([1,out_size]) + 0.1,name="biase")
if activation_function is None:
ouput = tf.matmul(inputs,W) + b
else:
ouput = activation_function(tf.matmul(inputs,W) + b)
return ouput
def compute_accuracy(v_xs,v_ys):
global prediction
y_pre = sess.run(prediction,feed_dict={xs:v_xs})
correct_prediction = tf.equal(tf.argmax(y_pre,1),tf.argmax(v_ys,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
result = sess.run(accuracy,feed_dict={xs:v_xs,ys:v_ys})
return result
xs = tf.placeholder(tf.float32,[None,784]) #这里是28*28的照片,列数是784为特征维度
ys = tf.placeholder(tf.float32,[None,10]) #列数是10为输入的维度
#两个None 分别代表实际输入样本的个数
prediction = add_layer(xs,784,10,activation_function=tf.nn.softmax)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),reduction_indices=[1])) #loss
train = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
#初始化
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for step in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
sess.run(train,feed_dict={xs:batch_xs,ys:batch_ys})
if step % 50 == 0:
print(compute_accuracy(mnist.test.images,mnist.test.labels))
这就是我所理解 TensorFlow 与 学习推导 之间,关于维度的不同表达形式。
初学者,有理解不对的地方欢迎大家提出纠正,谢谢。