tensorflow入门之训练简单的神经网络方法


Posted in Python onFebruary 26, 2018

这几天开始学tensorflow,先来做一下学习记录

一.神经网络解决问题步骤:

1.提取问题中实体的特征向量作为神经网络的输入。也就是说要对数据集进行特征工程,然后知道每个样本的特征维度,以此来定义输入神经元的个数。

2.定义神经网络的结构,并定义如何从神经网络的输入得到输出。也就是说定义输入层,隐藏层以及输出层。

3.通过训练数据来调整神经网络中的参数取值,这是训练神经网络的过程。一般来说要定义模型的损失函数,以及参数优化的方法,如交叉熵损失函数和梯度下降法调优等。

4.利用训练好的模型预测未知的数据。也就是评估模型的好坏。

二.训练简单的向前传播神经网络

一下训练的神经模型是最简单的一类,而且是线性的(也就是说没有用激活函数去线性话),没有反向传播的过程,只是简单的说明神经网络工作的流程。

import tensorflow as tf

#定义隐藏层参数,每个w变量是一个tensor(可以当成是n*m的数组,n表示上一层结点个数,m表示本层结点个数)表示上一层与本层的连接权重,这里先随机定义权重
w1=tf.Variable(tf.random_normal([2,3],stddev=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1))

#定义存放输入数据的地方,也就是x向量,这里shape为前一个传入训练的样本个数,后面出入每个样本的维度大小
x=tf.placeholder(tf.float32,shape=(None,2),name="input")
#矩阵乘法
a=tf.matmul(x,w1)
y=tf.matmul(a,w2)

with tf.Session() as sess:
  #新版本好像不能用这个函数初始化所有变量了
  init_op=tf.initialize_all_variables()
  sess.run(init_op)
  #feed_dict用于向y中的x传入参数,这里传入3个,则y输出为一个3*1的tensor
  print(sess.run(y,feed_dict={x:[[0.7,0.9],[1.0,1.5],[2.1,2.3]]}))

至此,一个用x的每个维度乘以两层权重之后输出单个值得线性神经网络就定义好了。

三.定义损失函数以及反向传播算法

有了上面的基础,我们可以定义损失函数以及反向传播算法去拟合数据了,非线性数据我们可以定义激活函数去线性化。还有一些细节就是学习率的问题,这次使用的是动态学习率,首先把学习率设定为比较大的值,加速收敛,然后随着迭代次数的增加,学习率不断下降,防止错过局部最小值。还有一个问题,就是防止过拟合。一般神经网络防止过拟合的策略有两种,一种是正则化,一种是dropout,我们暂且不作讨论后者

损失函数:交叉熵

反向传播算法:梯度下降法

激活函数:relu

# -*- coding: utf-8 -*-
"""
Created on Fri Aug 18 14:02:19 2017

@author: osT
"""
import tensorflow as tf 
import numpy as np
#导入数据,这里的数据是每一行代表一个样本,每一行最后一列表示样本标签,0-32一共33个类
data=np.loadtxt('train_data.txt',dtype='float',delimiter=',')

#将样本标签转换成独热编码
def label_change(before_label):
  label_num=len(before_label)
  change_arr=np.zeros((label_num,33))
  for i in range(label_num):
    #该样本标签原本为0-32的,本人疏忽下32标记成33
    if before_label[i]==33.0:
      change_arr[i,int(before_label[i]-1)]=1
    else:
      change_arr[i,int(before_label[i])]=1
  return change_arr

#定义神经网络的输入输出结点,每个样本为1*315维,以及输出分类结果
INPUT_NODE=315
OUTPUT_NODE=33

#定义两层隐含层的神经网络,一层300个结点,一层100个结点
LAYER1_NODE=300
LAYER2_NODE=100

#定义学习率,学习率衰减速度,正则系数,训练调整参数的次数以及平滑衰减率
LEARNING_RATE_BASE=0.5
LEARNING_RATE_DECAY=0.99
REGULARIZATION_RATE=0.0001
TRAINING_STEPS=2000
MOVING_AVERAGE_DECAY=0.99

#定义整个神经网络的结构,也就是向前传播的过程,avg_class为平滑可训练量的类,不传入则不使用平滑
def inference(input_tensor,avg_class,w1,b1,w2,b2,w3,b3):
  if avg_class==None:
    #第一层隐含层,输入与权重矩阵乘后加上常数传入激活函数作为输出
    layer1=tf.nn.relu(tf.matmul(input_tensor,w1)+b1)
    #第二层隐含层,前一层的输出与权重矩阵乘后加上常数作为输出
    layer2=tf.nn.relu(tf.matmul(layer1,w2)+b2)
    #返回 第二层隐含层与权重矩阵乘加上常数作为输出
    return tf.matmul(layer2,w3)+b3
  else:
    #avg_class.average()平滑训练变量,也就是每一层与上一层的权重
    layer1=tf.nn.relu(tf.matmul(input_tensor,avg_class.average(w1))+avg_class.average(b1))
    layer2=tf.nn.relu(tf.matmul(layer1,avg_class.average(w2))+avg_class.average(b2))
    return tf.matmul(layer2,avg_class.average(w3))+avg_class.average(b3)

def train(data):
  #混洗数据
  np.random.shuffle(data)
  #取钱850个样本为训练样本,后面的全是测试样本,约250个
  data_train_x=data[:850,:315]
  data_train_y=label_change(data[:850,-1])
  data_test_x=data[850:,:315]
  data_test_y=label_change(data[850:,-1])

  #定义输出数据的地方,None表示无规定一次输入多少训练样本,y_是样本标签存放的地方
  x=tf.placeholder(tf.float32,shape=[None,INPUT_NODE],name='x-input')
  y_=tf.placeholder(tf.float32,shape=[None,OUTPUT_NODE],name='y-input')

  #依次定义每一层与上一层的权重,这里用随机数初始化,注意shape的对应关系
  w1=tf.Variable(tf.truncated_normal(shape=[INPUT_NODE,LAYER1_NODE],stddev=0.1))
  b1=tf.Variable(tf.constant(0.1,shape=[LAYER1_NODE]))

  w2=tf.Variable(tf.truncated_normal(shape=[LAYER1_NODE,LAYER2_NODE],stddev=0.1))
  b2=tf.Variable(tf.constant(0.1,shape=[LAYER2_NODE]))

  w3=tf.Variable(tf.truncated_normal(shape=[LAYER2_NODE,OUTPUT_NODE],stddev=0.1))
  b3=tf.Variable(tf.constant(0.1,shape=[OUTPUT_NODE]))

  #输出向前传播的结果
  y=inference(x,None,w1,b1,w2,b2,w3,b3)

  #每训练完一次就会增加的变量
  global_step=tf.Variable(0,trainable=False)

  #定义平滑变量的类,输入为平滑衰减率和global_stop使得每训练完一次就会使用平滑过程
  variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
  #将平滑应用到所有可训练的变量,即trainable=True的变量
  variable_averages_op=variable_averages.apply(tf.trainable_variables())

  #输出平滑后的预测值
  average_y=inference(x,variable_averages,w1,b1,w2,b2,w3,b3)

  #定义交叉熵和损失函数,但为什么传入的是label的arg_max(),就是对应分类的下标呢,我们迟点再说
  cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.arg_max(y_,1))
  #计算交叉熵的平均值,也就是本轮训练对所有训练样本的平均值
  cross_entrip_mean=tf.reduce_mean(cross_entropy)

  #定义正则化权重,并将其加上交叉熵作为损失函数
  regularizer=tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
  regularization=regularizer(w1)+regularizer(w2)+regularizer(w3)
  loss=cross_entrip_mean+regularization

  #定义动态学习率,随着训练的步骤增加不断递减
  learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,900,LEARNING_RATE_DECAY)
  #定义向后传播的算法,梯度下降发,注意后面的minimize要传入global_step
  train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
  #管理需要更新的变量,传入的参数是包含需要训练的变量的过程
  train_op=tf.group(train_step,variable_averages_op)

  #正确率预测
  correct_prediction=tf.equal(tf.arg_max(average_y,1),tf.arg_max(y_,1))
  accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

  with tf.Session() as sess:
    #初始所有变量
    tf.global_variables_initializer().run()
    #训练集输入字典
    validate_feed={x:data_train_x,y_:data_train_y}
    #测试集输入字典
    test_feed={x:data_test_x,y_:data_test_y}

    for i in range(TRAINING_STEPS):
      if i%1000==0:
        validate_acc=sess.run(accuracy,feed_dict=validate_feed)
        print("After %d training step(s),validation accuracy using average model is %g"%(i,validate_acc))
      #每一轮通过同一训练集训练,由于样本太少,没办法了
      sess.run(train_op,feed_dict=validate_feed)
    #用测试集查看模型的准确率
    test_acc=sess.run(accuracy,feed_dict=test_feed)
    print("After %d training step(s),test accuracy using average model is %g"%(TRAINING_STEPS,test_acc))
train(data)

然后我们来看一下为什么计算交叉熵时要传入样本的下标:

首先我们知道,输出结点有33个,通过与前面的权重相乘后,则每个结点都会有一个输出,每个输出我们暂且认为是对应每个类的概率,该值越大,我们就越认为该样本为对应的类。logits参数是神经网络的直接输出,也就是未经softmax函数处理的输出,labels传入的是单个值,也就是分类对应的下标,这是由于我们使用的计算交叉熵的函数 tf.nn.sparse_softmax_cross_entropy_with_logits()有关。这个函数对于在只有一个正确分类的模型计算起到加速作用,而这个labels的输入就是“这一个正确的分类”,对应到输出的结点,就是其下标了。我们还有一个没有加速的交叉熵函数:tf.nn.softmax_cross_entropy_with_logis(logis=,labels=)这个时候我们就应该传入本身的labels标签了。

最后,我们来总结一下提高模型准确率的方法:

1.使用激活函数。也就是去线性化,这步几乎是必须的。
2.增加隐含层。就本例而言,单隐含层300个结点,准确率在89%左右;单隐含层400个结点,准确率在93%左右;而双隐含层300结点和100结点,准确率在94%左右。但增加隐含层意味着增加训练时间。
3.使用动态学习率。这不但可以加快训练的速度,还可以增加神经网络收敛到较低的极小值处的概率,从而增加准确率。
4.使用平滑模型。主要可以增加模型的健壮性,使其泛化能力更强。
5.加入正则化或者使用dropout防止过拟合。

附上训练集

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python自动化构建工具scons使用入门笔记
Mar 10 Python
python复制文件的方法实例详解
May 22 Python
Python3指定路径寻找符合匹配模式文件
May 22 Python
详解Python里使用正则表达式的ASCII模式
Nov 02 Python
Python构建图像分类识别器的方法
Jan 12 Python
详解Python3中setuptools、Pip安装教程
Jun 18 Python
Python使用字典实现的简单记事本功能示例
Aug 15 Python
python 单线程和异步协程工作方式解析
Sep 28 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
Nov 08 Python
Python networkx包的实现
Feb 14 Python
python解决12306登录验证码的实现
Apr 18 Python
Python实现将多张图片合成MP4视频并加入背景音乐
Apr 28 Python
基于Python实现的微信好友数据分析
Feb 26 #Python
TensorFlow 实战之实现卷积神经网络的实例讲解
Feb 26 #Python
使用django-crontab实现定时任务的示例
Feb 26 #Python
Django中的CBV和FBV示例介绍
Feb 25 #Python
python中正则表达式的使用方法
Feb 25 #Python
python爬虫爬取淘宝商品信息(selenum+phontomjs)
Feb 24 #Python
python正则表达式爬取猫眼电影top100
Feb 24 #Python
You might like
php中计算未知长度的字符串哪个字符出现的次数最多的代码
2012/08/14 PHP
php简单smarty入门程序实例
2015/06/11 PHP
JS中引用百度地图并将百度地图的logo和信息去掉
2013/09/29 Javascript
input链接页面、打开新网页等等的具体实现
2013/12/30 Javascript
jquery制作多功能轮播图插件
2015/04/02 Javascript
JavaScript实现打字效果的方法
2015/07/10 Javascript
详解JavaScript中数组和字符串的lastIndexOf()方法使用
2016/03/13 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
AngularJS基础 ng-open 指令简单实例
2016/08/02 Javascript
微信小程序 网络请求(GET请求)详解
2016/11/16 Javascript
jQuery动态生成不规则表格(前后端)
2017/02/21 Javascript
mongoose设置unique不生效问题的解决及如何移除unique的限制
2017/11/07 Javascript
Bootstrap Table实现定时刷新数据的方法
2018/08/13 Javascript
微信小程序时间控件picker view使用详解
2018/12/28 Javascript
javascript实现摄像头拍照预览
2019/09/30 Javascript
Python变量和字符串详解
2017/04/29 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
python使用rsa非对称加密过程解析
2019/12/28 Python
python如何调用百度识图api
2020/09/29 Python
Python中过滤字符串列表的方法
2020/12/22 Python
CSS3模拟动画下拉菜单效果
2017/04/12 HTML / CSS
美国酒店控股公司:Choice Hotels
2018/06/15 全球购物
ASOS西班牙官网:英国在线时尚和美容零售商
2020/01/10 全球购物
应届大学生求职信
2013/12/01 职场文书
企业项目策划书
2014/01/11 职场文书
投标承诺书范本
2014/03/27 职场文书
安全生产责任书范本
2014/04/15 职场文书
代办社保委托书范文
2014/10/06 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
办公用品质量保证书
2015/05/11 职场文书
敬老院活动感想
2015/08/07 职场文书
经典励志格言:每日一句,让你每天充满能量
2019/08/16 职场文书
Python使用UDP实现720p视频传输的操作
2021/04/24 Python
SQL实现LeetCode(196.删除重复邮箱)
2021/08/07 MySQL
利用Python将list列表写入文件并读取的方法汇总
2022/03/25 Python