当然在学习本课程之前,我们需要明白在TensorFlow的世界里,变量的定义和初始化是分开的,所有关于图变量的赋值和计算都要通过tf.Session的run来进行。想要将所有图变量进行集体初始化时应该使用tf.global_variables_initializer。而我们这篇文章进行的工作是定义前向传播。
mnist_forward.py文件详情:
import tensorflow as tf
INPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500
def get_weight(shape, regularizer):
w = tf.Variable(tf.truncated_normal(shape, stddev=0.1))
if regularizer != None:
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
return w
def get_bias(shape):
b = tf.Variable(tf.zeros(shape))
return b
def forward(x ,regularizer):
w1 = get_weight([INPUT_NODE, LAYER1_NODE], regularizer)
b1 = get_bias([LAYER1_NODE])
y1 = tf.nn.relu(tf.matmul(x, w1)+b1)
w2 = get_weight([LAYER1_NODE, OUTPUT_NODE], regularizer)
b2 = get_bias([OUTPUT_NODE])
y = tf.matmul(y1, w2) + b2
return y
接下来是对代码的详解:
(1)第一步我们需要明白我们构建的神经网络的节点数。
INPUT_NODE是输入数据的维数,也就是28*28个。
OUTPUT_NODE是输出数据的维数,因为最后输出的结果是一组一行10列的数组,其值是代表出现某一个数字的概率,所以维数为10。
LAYER1_NODE是中间隐藏层的节点数,共有500个节点。
现在我们明白了我们构建的是一个简单的双层全连接神经网络。
(2)我们注意到我们的权重和偏置都是使用的Variable()函数产生,所以我们来细讲一下这个函数。
tf.Variable.init(initial_value, trainable=True, collections=None, validate_shape=True, name=None)
参数名称 | 参数类型 | 含义 |
initial_value | 所以可以转化为tensor类型 | 变量的初始值 |
trainable | bool | 如果为True,会把它加入到GraphKeys.TRAINABLE_VARIABLES,才能对它使用Optimizer |
collections | list | 指定该图变量的类型、默认为[GraphKeys.GLOBAL_VARIABLES] |
validate_shape | bool | 如果为False,则不进行类型和维度检查。 |
name | string | 变量的名称,如果没有指定则系统会自动分配一个唯一的值 |
当然还有其他的参数,如果想了解更多可以去官网。
关于两个常用的initial_value(tf.truncated_normal()和tf.random_normal())的区别可以通过以下链接学习。
https://blog.csdn.net/u014687582/article/details/78027061
(3)到这里我们已经将神经网络的节点和其中的参数设置完成了,最后我们需要把这些节点连接起来,以构成一幅完整的计算图。
我们使用tf.matmul()函数对两个tensor进行运算(这里类似于高等代数里面两个矩阵相乘),之后使用激活函数tf.nn.relu()将偏置数b加上去。
之后我们注意到我们的权重w的shape是[INPUT_NODE,LEARY1_NODE],根据矩阵相乘的算法,[INPUT_NODE] * [INPUT_NODE, LAYER1_NODE] = [LAYER1_NODE] (第一个隐藏的节点数的值),[LAYER1_NODE] * [LAYER1_NODE, OUTPUT_NODE] = [OUTPUT_NODE]。
tf.nn.relu()激活函数的讲解:
tf.nn.relu()函数是将大于0的数保持不变,小于0的数置为0。
import tensorflow as tf
a = tf.constant([[-2,-4],[4,-2]])
with tf.Session() as sess:
print(sess.run(tf.nn.relu(a)))
输出的结果为:
[[0 0]
[4 0]]
(4)最后我们注意还有一个regularizer参数没有解释,这个是正则化的超参数。
正则化缓解过拟合
正则化的损失函数中引入模型复杂度指标,利用给W加权值,弱化了训练数据的噪声(一般不正则化b)
loss = loss(y与y_) + REGULARIZER * loss(w)
loss(y与y_)是指模型中所有参数的损失函数,如:交叉熵,均方误差
REGULARIZER是用超参数REGULARIZER给出参数w在总loss中的比例,即正则化的权重
loss(w)是 指需要正则化的参数
其中loss(w)的代码为以下两种:
loss(w) = tf.contrib.layers.l1_regularier(REGULARIZER)(w)
loss(w) = tf.contrib.layers.l2_regularier(REGULARIZER)(w)
这里还涉及到add_to_collection()函数的使用,可以参考这个链接:https://blog.csdn.net/nini_coded/article/details/80528466
最后谢谢大家。