罗斯基白话: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 tf

learning_rate = 0.01
batch_size = 16
epoch_step = 10000
display_step = 100

x = tf.placeholder("float", [None, 20])
y = tf.placeholder("float", [None, 5])

layer1 = 16
layer2 = 32


w = {
    "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 output

pred = 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 = 0
		total_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_batch

		if epoch % display_step == 0:
			print("cost:",avg_cost)

	print("finish!")

	print("accuracy: ", sess.run(accuracy, feed_dict = {x: test_x, y: test_y}))

 

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值