博客背景是学习《深度学习之TensorFlow》这本书籍中的作业,修改第七章的作业,把XOR-异或的错误代码修改为正确的。
主要修改有三个地方:
- 隐藏层一的运算从sigmoid修改为add运算;
- 输出层的运算修改为sigmoid(原来是什么运算忘记了。。);
- 将优化算法从GradientDescentOptimizer修改为牛逼的Adam算法;
-
# -*- coding: utf-8 -*-
-
"""
-
"""
-
import tensorflow
as tf
-
import numpy
as np
-
import matplotlib.pyplot
as plt
-
-
tf.reset_default_graph()
-
tf.set_random_seed(
55)
-
np.random.seed(
55)
-
-
learning_rate =
0.01
-
input_data = [[
0.,
0.], [
0.,
1.], [
1.,
0.], [
1.,
1.]]
# XOR input
-
output_data = [[
0.], [
1.], [
1.], [
0.]]
# XOR output
-
hidden_nodes =
10
#代表该网络层的神经元个数
-
n_input = tf.placeholder(tf.float32, shape=[
None,
2], name=
"n_input")
-
n_output = tf.placeholder(tf.float32, shape=[
None,
1], name=
"n_output")
-
# hidden layer's bias neuron
-
b_hidden = tf.Variable(
0.1, name=
"hidden_bias")
-
W_hidden = tf.Variable(tf.random_normal([
2, hidden_nodes]), name=
"hidden_weights")
-
"""修改sigmoid为add运算"""
-
hidden = tf.add(tf.matmul(n_input, W_hidden) ,b_hidden)
-
hidden1 = tf.nn.relu(hidden)
-
################
-
# output layer #
-
################
-
W_output = tf.Variable(tf.random_normal([hidden_nodes,
1]), name=
"output_weights")
# output layer's
-
b_output = tf.Variable(
0.1, name=
"output_bias")
#
-
-
#output = tf.nn.relu(tf.matmul(hidden, W_output)+b_output) # 出来的都是nan calc output layer's
-
#softmax
-
y = tf.matmul(hidden1, W_output)+b_output
-
"""修改sigmoid运算"""
-
output = tf.nn.sigmoid(y)
-
#交叉熵
-
loss = -(n_output * tf.log(output) + (
1 - n_output) * tf.log(
1 - output))
-
-
#optimizer = tf.train.GradientDescentOptimizer(0.01)
-
"""修改为Adam的优化器"""
-
optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate)
-
train = optimizer.minimize(loss)
# let the optimizer train
-
-
#####################
-
# train the network #
-
#####################
-
with tf.Session()
as sess:
-
sess.run(tf.global_variables_initializer())
-
for epoch
in range(
0,
2001):
-
# run the training operation
-
cvalues = sess.run([train, loss, W_hidden, b_hidden, W_output],
-
feed_dict={n_input: input_data, n_output: output_data})
-
-
# print some debug stuff
-
if epoch %
200 ==
0:
-
print(
"")
-
print(
"step: {:>3}".format(epoch))
-
print(
"loss: {}".format(cvalues[
1]))
-
#print(W_hidden.value())
-
# print("b_hidden: {}".format(cvalues[3]))
-
# print("W_hidden: {}".format(cvalues[2]))
-
# print("W_output: {}".format(cvalues[4]))
-
-
-
print(
"")
-
for i
in range(len(input_data)):
-
print(
"input: {} | output: {}".format(input_data[i], sess.run(output, feed_dict={n_input: [input_data[i]]})))
-
备注:理论知识还是薄弱啊,花了一天的时间来修改该error
顺便把7-10和7-11的源码修改了
7-10修改部分:
隐藏层的神经元个数更改为10个(经测试只要大于2即可)
hidden_nodes = 10
将输出层的激活函数更改为sigmoid即可:
-
"""将激活函数修改sigmoid即可"""
-
output = tf.nn.sigmoid(y)
7-11修改部分:
隐藏层的神经元个数更改为10个(经测试只要大于2即可)
hidden_nodes = 10
""""修改损失函数为均值平方差"""
-
#cross_entropy = -tf.reduce_mean(n_output * tf.log(output))#
-
cross_entropy = tf.square(n_output-output)
总结:(个人理解,不对请回复)
- 神经网络的层里面的神经元个数要大于输入的维度,以本文解决异或问题,二维的输入,那么针对单层隐藏层来说,其神经元个数大于二才有效;
- 激活函数的选择。该处主要体现在7-10的代码修改上,“Relu”与“Sigmiod”相比容易陷入局部最优解,所以选择合适的激活函数尤其重要,这部分理解还不太透彻,主要是看书的结论得知的,具体是为什么再作深入理解;此处看到有博客说“relu和softmax两层不要连着用,最好将relu改成tanh”尚未理解,正在证明其真实性。
- 损失函数。损失函数也很重要,以7-11的代码修改为例,损失函数尽可能选择已知的比较常用合理的函数,比如均值平方差和交叉熵等。
- 梯度下降的函数,即优化函数“optimizer”的选择。常用的有BGD、SGD等,其实就是根据每次计算损失函数所需的训练样本数量来划分的。为克服BGD和SGD的缺点,一般是使用小批量的数据进行损失函数更新,即降低了随机性又提高了训练效率。TF中常用的梯度下降函数有七种,但比较牛逼的"Adam"优化函数,高效解决优化问题(具体的内容会另写一篇博客介绍)。
博客背景是学习《深度学习之TensorFlow》这本书籍中的作业,修改第七章的作业,把XOR-异或的错误代码修改为正确的。