本文主要是介绍罗斯基白话:TensorFlow+实战系列(二)从零构建传统神经网络,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
白话TensorFlow+实战系列(二)
从头构建传统神经网络
这次主要用TensorFlow从头构建一个传统神经网络作为案例,并总结需要注意的地方
创建一个神经网络主要有一下4个步骤:
1.定义神经网络的结构,即计算图
2.定义损失函数
3.在会话中,将数据输入进构建的神经网络中,反复优化损失函数,直至得到最优解
4.将测试集丢入训练好的神经网络进行验证
假设我们创建一个只有两个隐藏层的神经网络
先来看第一步:构建神经网络结构
一般在构建神经网络的初始,会先定义好超参数。参数与超参数是不一样的!参数指的是神经元进行计算时用到的权重(W)和偏置(b),而超参数一般指的是如学习率(learning_rate),一次性输入数据的个数(batch_size),遍历总数(epoch)等。
定义超参数如下:
learning_rate:用于控制梯度下降的幅度
batch_size:一次性输入数据个数
epoch_size:遍历总数
display_step:打印中间结果的步数
然后我们定义输入层、隐藏层、输出层神经元,如图
x:输入层。tf.placeholder函数在TensorFlow中可理解为占位用的,因为输入的数据在每次循环中都不一样,为了避免每次循环都要定义一个输入,可以用该函数存储当前循环的数据。float定义了数据类型, [None, 20]表示x的维度,其中None代表该数暂时不确定,其实这个None与batch_size的数据相对应,x可理解为一次性输入batch_size个数据,而每个数据有20个特征向量组成,即输入层有20个神经元。
y:输出层。因为有None个数据输入,所以输出也为None。5代表进行5分类
layer1、layer2代表隐藏层神经元个数
接着定义神经网络参数w、b
w中,h1代表的是输入层到第一层隐藏层的权重,因为输入层有20个神经元,隐藏层神经元个数为layer1,所以维度为[20,layer1]。h2同理。out表示第二层隐藏层到输出层的权重。
b同理。
其中tf.Variable是用来定义变量的函数,tf.random_normal是随机生成正太分布函数。
然后定义神经网络函数,如下:
其中,tf.nn.relu是非线性激励函数,常用的还有tf.sigmoid、tf.tanh
tf.matmul是矩阵相乘
output就是最后的输出。
至此,第一部分就已完成。
第二部分:定义损失函数
因为我们假设的是一个分类问题,将数据分成5类,正确的标签第一类可由[1,0,0,0,0]代表,第二类可由[0,1,0,0,0],因此输出层需要5个神经元来代表分成的5类。实际输出层的输出可能是[0.1,0.1, 0.6, 0.1, 0.1],因为与[0,0,1,0,0]最相近,我们可判定它属于第三类。
需要注意的是,在分类问题中,神经网络的输出层输出的数据需要经过一层额外的处理,叫做softmax层,softmax层的作用是将输出层的数据全部压缩至0~1之间,并且所有和等于1。这就可以理解成将输出层的数据变成概率分布的形式。然后就可以用交叉熵函数定义损失函数了。
TensorFlow中的tf.nn.softmax_cross_entropy_with_logits损失函数集成了上面所说的步骤,即先经过softmax层然后使用交叉熵就算损失。
由此,定义损失函数如下:
其中pred为预测的数据,即神经网络的输出
cost即损失函数,tf.reduce_mean是求平均损失,因为一次性输入的是多个(batch_size个)数据。
tf.train.AdamOptimizer是选择的优化器,其作用是最小化cost
init为初始化变量
至此,第二部分也已经完成
第三部分:创建会话,执行神经网络
首先进行初始化sess.run(init)
接着遍历epoch_step次所有数据,avg_cost用来记录一个epoch里所损失平均,注意cost是一个batch_size里的平均损失,两次平均不一样。total_batch表示batch_size的个数。
然后遍历每一个batch_size,x_batch与y_batch表示输入数据与对应的标签。
执行optimizer与cost,因为之前定义的x与y是用的占位符tf.placeholder,这里就要用feed_dict进行数据喂养。
epoch% display_step表示每display_step次数的epoch进行打印avg_cost
至此第三部分完成。
第四部分:将测试集丢入训练好的神经网络进行验证
首先在定义cost下面定义准确率的算法,如下
其中correct_pred代表预测正确的标签
tf.argmax函数返回的是张量在某一维最大值的索引值,由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签。如果pred的最大值所在的索引值等于类别标签的索引值,表示这个结果分类正确
tf.equal是TensorFlow中判断两个张量是否相等,返回的是一个布尔型张量,如[True,False,False]。
因为corret_pred是一个布尔型张量,因此需要用tf.cast()函数转化成float型来计算准确率,如[True,False,False,False]会变成[1,0,0,0],经过reduce_mean取平均值0.25来表示准确率。
最后打印准确率,为测试训练集的结果,如下:
feed_dict的是test_x与test_y
至此,一个完整的传统神经网络构建完成
完整代码如下:
import tensorflow as tflearning_rate = 0.01
batch_size = 16
epoch_step = 10000
display_step = 100x = tf.placeholder("float", [None, 20])
y = tf.placeholder("float", [None, 5])layer1 = 16
layer2 = 32w = {"h1":tf.Variable(tf.random_normal([20, layer1])),"h2":tf.Variable(tf.random_normal([layer1, layer2])),"out": tf.Variable(tf.random_normal([layer2, 5]))
}b = {"h1":tf.Variable(tf.random_normal([layer1])),"h2":tf.Variable(tf.random_normal([layer2])),"out":tf.Variable(tf.random_normal([5]))
}def network(x_input,weights,biases):net1 = tf.nn.relu(tf.matmul(x_input, weights["h1"]) + biases["h1"])net2 = tf.nn.relu(tf.matmul(net1, weights["h2"]) + biases["h2"])output = tf.matmul(net2, weights["out"]) + biases["out"]return outputpred = network(x, w, b)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)correct_pred = tf.equal(tf.argmax(y,1), tf.argmax(pred,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, "float"))init = tf.global_variables_initializer()with tf.Session() as sess:sess.run(init)for epoch in range(epoch_step):avg_cost = 0total_batch = int(alldata / batch_size)for i in range(total_batch):x_batch, y_batch = 一个batch_size的输入,相对应输入的标签_,output = sess.run([optimizer, cost], feed_dict = {x:x_batch, y:y_batch})avg_cost += output / total_batchif epoch % display_step == 0:print("cost:",avg_cost)print("finish!")print("accuracy: ", sess.run(accuracy, feed_dict = {x: test_x, y: test_y}))
这篇关于罗斯基白话:TensorFlow+实战系列(二)从零构建传统神经网络的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!