TensorFlow实现简单卷积神经网络,tensorflow卷积神经
分类:计算机编程

前方大家曾有篇作品中关系过有关用tensorflow锻练手写2828像素点的数字的辨别,在那篇文章中大家把手写数字图像直接碾压成了二个784列的数码举行识别,但实则,那几个图疑似2828长度宽度结构的,大家此番运用CNN卷积神经网络来进展识别。

那是五个TensorFlow的后生可畏连串小说,本文是第三篇,在这里个类别中,你讲明白到机械学习的大器晚成都部队分基本概念、TensorFlow的运用,并能实际到位手写数字识别、图像分类、风格迁移等实战项目。

二〇一六年来人工智能的定义越来越火,AlphaGo以4:1战胜李世石更是起到拉动的法力。作为二个开发现机的生手,深深感觉不上学一下deep learning早晚要被淘汰。

本文使用的数据集是MNIST,首要使用三个卷积层加一个全连接层营造的卷积神经互连网。

卷积神经互联网自己的领会是一些模仿了人眼的效果。
小编们在看一个图像时不是一个像素点叁个像素点去分辨的,大家的眼睛天然地具备大局观,大家来看某些图像时自动地会把里面包车型地铁细节部分给聚合起来实行识别,相反,尽管大家用个放大镜看见当中的逐黄金时代像素点时反而不明了那是啥东西了。

小说将尽恐怕用平实的言语描述、少用公式、多用代码截图,简单的讲那将是意气风发份异常的赞的入门指南。迎接分享/关注。

既然如此要最早学,当然是搭二个深度神经网络跑多少个数据集体会一下作为入门最直观了。自身写代码实现的话debug的进度和平运动转功用都会很忧伤,小编也不精晓怎么调用GPU…

先载入MNIST数据集(手写数字识别集卡塔 尔(阿拉伯语:قطر‎,并创造暗许的Interactive Session(在并未有一些名回话对象的景况下运作变量卡塔 尔(阿拉伯语:قطر‎

故而卷积神经网络就把每个像素点的图像进行自然水平上的模糊化,而怎么开展模糊化呢?它是经过甄选一小片的区域约束,把那小片中的图像数据减弱其长度宽度,但净增其高度值。然后开展某种总计,最后实现多少雷同模糊化图像的目标,但以此模糊化的图像中反而能够比比较简单于辨别出相应的界线及形状。

图片 1

之所以照旧站在圣人的肩部上,用现成的框架吧。粗略明白一下,以往相比有名的有caffe、mxnet、tensorflow等等。选哪些吧?对自个儿的话接纳的正式就四个,第风华正茂要便于安装(想赶紧入门的殷切情绪实在麻烦忍受一大堆的安排安装…);第二文书档案要齐全(那应当是废话

-)。那多少个响当当的框架文档都是比较康健的,那就看最轻便安装的。看了多少个文书档案,tensorflow算是最容易安装的了。基本便是pip intall 给定的URL就能够了。安装方式的文档能够在tensorflow安装教程上查看。

tensorflow基本概念与用法

tensorflow直译过来正是张量流。二〇一八年google刚推出tensorflow的时候本人就纳闷,为啥深度学习会牵扯到张量,从前学弹塑性力学的时候就是一大堆张量看的很烦…可是辛亏要理解tensorflow里的tensor完全不用理会那个。先来看一下合日语档的说明:

class tf.Tensor
Represents a value produced by an Operation.
A Tensor is a symbolic handle to one of the outputs of an Operation. It does not hold the values of that operation's output, but instead provides a means of computing those values in a TensorFlow Session.

from tensorflow.examples.tutorials.mnist import input_data 
import tensorflow as tf 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) 
sess = tf.InteractiveSession()

实际大家能够到英特网寻找相关的理论知识,这里不细讲,只留意于怎样在tensorflow中贯彻CNN的效果与利益。

下风流倜傥期,我们用Tensorflow实现了Kaggle的手写识别项目,但精确率相当低,只有92%,这一次大家策画把识别的准确率升高到98%以上。

首先,Tensor代表了实践一个操作(运算)所产生的值。其次,八个Tensor实例并不会保留具体的值,而只是象征了发出这一个值的演算情势。好像有一点点别扭,也正是说假若有一个加法操作add,令c

add(1,1)。那么c便是三个tensor实例了,代表了1 1的结果,可是它并未存储2以此现实的值,它只精晓它代表1 1以此运算。自此处也足以阅览,tensorflow里的api都以惰性求值,等的确供给通晓具体的值的时候,才会试行总计,其余时候都以在概念计算的经过。

Tensor能够表示从常数平昔到N维数组的值。

Flow指的是,指的是tensorflow这套框架里的多寡传递全都是tensor,也正是运算的输入,输出都以tensor。

常用操作

此地只是简短介绍一下在背后定义卷积神经网络的时候会用到的事物。想要掌握更详尽的剧情还得仿照效法官英特网的文书档案。

首先import tensorflow as tf,后面的tf就代表tensorflow啦。

常数

tf.constant 是一个Operation,用来发生常数,能够生出scalar与N-D array. a是一个tensor,代表了由constant那么些Operation所发出的标量常数值的进程。 b正是象征了产生二个2*2的array的过程。

a = tf.constant(3)
b = tf.constant(3,shape=[2,2]) 

变量

变量代表了神经网络中的参数,在优化总括的历程中须要被改成。tf.Variable当然也是三个Operation,用来发生四个变量,构造函数需求传入叁个Tensor对象,传入的那几个Tensor对象就决定了这些变量的值的类别(float 或 int)与shape。

变量即便与Tensor有分化的花色,可是在思谋进度中是与Tensor雷同能够看作输入输出的。(能够领略为Tensor的派生类,不过实际可能而不是如此,笔者还尚无看源码)

变量在应用前都必需起头化。

w = tf.Variable(b)

Operation

骨子里Operation不应当单独拿出的话,因为前边的tf.constant和tf.Variable都是Op,可是仍然说一下健康的操作,比方tf.matmul实践矩阵总括,tf.conv2d用于卷积总结,Op的详实用法以致此外的Op可以参考api文书档案。

tf.matmul(m,n)
tf.conv2d(...)

TensorFlow的计算由差别的Operation组成,比方下图

图片 2

定义了6*(3 5)那几个总结进程。6、3、5实际也是Op,那在前边介绍过了。

卷积神经网络用于人脸关键点识别

写到这里终于要起初步入正题了,先从CNN做起吗。Tensorflow的tutorial里面有介绍用CNN(卷积神经互连网)来识别手写数字,直接把这里的代码copy下来跑三遍也是足以的。可是那相比未有意思味,kaggle上有一位脸关键点识其他竞技,有数据集也正如有意思,就拿那么些来练手了。

概念卷积神经互联网

先是是概念网络布局,在这里个事例里作者用了3个卷积层,第四个卷积层用3∗3的卷积核,前边多个用2∗2的卷积核。每种卷积层前边都跟max_pool池化层,之后再跟3个全连接层(多个隐层二个输出层卡塔尔国。每个卷积层的feature_map分别用32、64、128。

发出权值的函数代码如下

#根据给定的shape定义并初始化卷积核的权值变量
  def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

  #根据shape初始化bias变量
  def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

概念卷积运算的代码如下。对tf.nn.con2d()的参数依然要证实一下

  1. x是输入的样板,在这间正是图像。x的shape=[batch, height, width, channels]。

  2. - batch是输入样板的数量

  3. - height, width是每张图像的高和宽
  4. - channels是输入的通道,举个例子开首输入的图疑似灰度图,那么channels=1,假若是rgb,那么channels=3。对于第二层卷积层,channels=32。

2. W象征卷积核的参数,shape的含义是[height,width,in_channels,out_channels]。

3. strides参数表示的是卷积核在输入x的顺序维度下移动的宽度。领悟CNN的都精通,在宽和高方向stride的轻重决定了卷积后图像的size。这里为啥有4个维度呢?因为strides对应的是输入x的维度,所以strides第叁个参数表示在batch方向移动的大幅度,第多个参数表示在channels上移步的增长幅度,那些参数都安装为1就好。重视正是第贰个,第四个参数的含义,也正是在height于width方向上的增进率,这里也都安装为1。

4. padding参数用来决定图片的边距,'SAME'代表卷积后的图样与原图片大小同等,'VALID'的话卷积以后图像的高为Heightout=Height原图−Height卷积核 1/StrideHeight, 宽也同理。

def conv2d(x,W):
  return tf.nn.cov2d(x,W,strides=[1,1,1,1],padding='VALID')

随时是定义池化层的代码,这里用2∗2的max_pool。参数ksize定义pool窗口的轻重,各类维度的含义与事先的strides相像,所以其实大家设置第叁个,第三维就足以了。

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')

概念好爆发权重、卷积、池化的函数今后将要早先创设那一个卷积神经网络了。定义在此之前再定义一下输入样板x与相应的指标值y_。这里用了tf.placeholder表示这时候的x与y_是钦命shape的站位符,之后在概念互联网布局的时候并无需真的输入了切实的范本,只要在求值的时候feed进去就足以了。激活函数用relu,api也正是tf.nn.relu。
keep_prob是最后dropout的参数,dropout的目标是为着抗过拟合。

rmse是损失函数,因为此地的指标是为着检查评定人脸关键点的义务,是回归难点,所以用root-mean-square-error。况且最后的输出层无需套softmax,直接输出y值就足以了。

如此就创立好了三个卷积神经互连网。后续的步调便是依据输入样板来train那些参数啦。

  x = tf.placeholder("float", shape=[None, 96, 96, 1])
  y_ = tf.placeholder("float", shape=[None, 30])
  keep_prob = tf.placeholder("float")

  def model():
    W_conv1 = weight_variable([3, 3, 1, 32])
    b_conv1 = bias_variable([32])

    h_conv1 = tf.nn.relu(conv2d(x, W_conv1)   b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)

    W_conv2 = weight_variable([2, 2, 32, 64])
    b_conv2 = bias_variable([64])

    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2)   b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)

    W_conv3 = weight_variable([2, 2, 64, 128])
    b_conv3 = bias_variable([128])

    h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3)   b_conv3)
    h_pool3 = max_pool_2x2(h_conv3)

    W_fc1 = weight_variable([11 * 11 * 128, 500])
    b_fc1 = bias_variable([500])

    h_pool3_flat = tf.reshape(h_pool3, [-1, 11 * 11 * 128])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool3_flat, W_fc1)   b_fc1)

    W_fc2 = weight_variable([500, 500])
    b_fc2 = bias_variable([500])

    h_fc2 = tf.nn.relu(tf.matmul(h_fc1, W_fc2)   b_fc2)
    h_fc2_drop = tf.nn.dropout(h_fc2, keep_prob)

    W_fc3 = weight_variable([500, 30])
    b_fc3 = bias_variable([30])

    y_conv = tf.matmul(h_fc2_drop, W_fc3)   b_fc3
    rmse = tf.sqrt(tf.reduce_mean(tf.square(y_ - y_conv)))
    return y_conv, rmse

训练卷积神经网络

读取练习多少

概念好卷积神经网络的构造从今未来,将在起来练习。练习首先是要读取练习样品。上面包车型大巴代码用于读取样板。

  import pandas as pd
  import numpy as np

  TRAIN_FILE = 'training.csv'
  TEST_FILE = 'test.csv'
  SAVE_PATH = 'model'


  VALIDATION_SIZE = 100  #验证集大小
  EPOCHS = 100       #迭代次数
  BATCH_SIZE = 64     #每个batch大小,稍微大一点的batch会更稳定
  EARLY_STOP_PATIENCE = 10 #控制early stopping的参数


  def input_data(test=False):
    file_name = TEST_FILE if test else TRAIN_FILE
    df = pd.read_csv(file_name)
    cols = df.columns[:-1]

    #dropna()是丢弃有缺失数据的样本,这样最后7000多个样本只剩2140个可用的。
    df = df.dropna()  
    df['Image'] = df['Image'].apply(lambda img: np.fromstring(img, sep=' ') / 255.0)

    X = np.vstack(df['Image'])
    X = X.reshape((-1,96,96,1))

    if test:
      y = None
    else:
      y = df[cols].values / 96.0    #将y值缩放到[0,1]区间

    return X, y

  #最后生成提交结果的时候要用到
  keypoint_index = {
    'left_eye_center_x':0,
    'left_eye_center_y':1,
    'right_eye_center_x':2,
    'right_eye_center_y':3,
    'left_eye_inner_corner_x':4,
    'left_eye_inner_corner_y':5,
    'left_eye_outer_corner_x':6,
    'left_eye_outer_corner_y':7,
    'right_eye_inner_corner_x':8,
    'right_eye_inner_corner_y':9,
    'right_eye_outer_corner_x':10,
    'right_eye_outer_corner_y':11,
    'left_eyebrow_inner_end_x':12,
    'left_eyebrow_inner_end_y':13,
    'left_eyebrow_outer_end_x':14,
    'left_eyebrow_outer_end_y':15,
    'right_eyebrow_inner_end_x':16,
    'right_eyebrow_inner_end_y':17,
    'right_eyebrow_outer_end_x':18,
    'right_eyebrow_outer_end_y':19,
    'nose_tip_x':20,
    'nose_tip_y':21,
    'mouth_left_corner_x':22,
    'mouth_left_corner_y':23,
    'mouth_right_corner_x':24,
    'mouth_right_corner_y':25,
    'mouth_center_top_lip_x':26,
    'mouth_center_top_lip_y':27,
    'mouth_center_bottom_lip_x':28,
    'mouth_center_bottom_lip_y':29
  }

发端演练

施行教练的代码如下,save_model用于保存当前练习得到在验证集上loss最小的模子,方便今后直接拿来用。

tf.InteractiveSession()用来生成二个Session,(好疑似废话…)。Session也正是三个引擎,TensorFlow框架要确实的扩充总括,都要透过Session引擎来运转。

tf.train.AdamOptimizer是优化的算法,Adam的消逝速度会异常快,1e-3是learning rate,这里先轻易的用固定的。minimize正是要最小化的靶子,当然是最小化均方根基值误差了。

  def save_model(saver,sess,save_path):
    path = saver.save(sess, save_path)
    print 'model save in :{0}'.format(path)

  if __name__ == '__main__':
    sess = tf.InteractiveSession()
    y_conv, rmse = model()
    train_step = tf.train.AdamOptimizer(1e-3).minimize(rmse)

    #变量都要初始化 
    sess.run(tf.initialize_all_variables())
    X,y = input_data()
    X_valid, y_valid = X[:VALIDATION_SIZE], y[:VALIDATION_SIZE]
    X_train, y_train = X[VALIDATION_SIZE:], y[VALIDATION_SIZE:]

    best_validation_loss = 1000000.0
    current_epoch = 0
    TRAIN_SIZE = X_train.shape[0]
    train_index = range(TRAIN_SIZE)
    random.shuffle(train_index)
    X_train, y_train = X_train[train_index], y_train[train_index]

    saver = tf.train.Saver()

    print 'begin training..., train dataset size:{0}'.format(TRAIN_SIZE)
    for i in xrange(EPOCHS):
      random.shuffle(train_index) #每个epoch都shuffle一下效果更好
      X_train, y_train = X_train[train_index], y_train[train_index]

      for j in xrange(0,TRAIN_SIZE,BATCH_SIZE):
        print 'epoch {0}, train {1} samples done...'.format(i,j)

        train_step.run(feed_dict={x:X_train[j:j BATCH_SIZE], 
          y_:y_train[j:j BATCH_SIZE], keep_prob:0.5})

      #电脑太渣,用所有训练样本计算train_loss居然死机,只好注释了。
      #train_loss = rmse.eval(feed_dict={x:X_train, y_:y_train, keep_prob: 1.0})
      validation_loss = rmse.eval(feed_dict={x:X_valid, y_:y_valid, keep_prob: 1.0})

      print 'epoch {0} done! validation loss:{1}'.format(i, validation_loss*96.0)
      if validation_loss < best_validation_loss:
        best_validation_loss = validation_loss
        current_epoch = i
        save_model(saver,sess,SAVE_PATH)  #即时保存最好的结果
      elif (i - current_epoch) >= EARLY_STOP_PATIENCE:
        print 'early stopping'
        break

在测量检验集上估计

上面包车型地铁代码用于预测test.csv里面包车型客车人脸关键点,最后的y值要倍加96,因为在此之前缩放到[0,1]区间了。

  X,y = input_data(test=True)
  y_pred = []

  TEST_SIZE = X.shape[0]
  for j in xrange(0,TEST_SIZE,BATCH_SIZE):
    y_batch = y_conv.eval(feed_dict={x:X[j:j BATCH_SIZE], keep_prob:1.0})
    y_pred.extend(y_batch)

  print 'predict test image done!'

  output_file = open('submit.csv','w')
  output_file.write('RowId,Locationn')

  IdLookupTable = open('IdLookupTable.csv')
  IdLookupTable.readline()

  for line in IdLookupTable:
    RowId,ImageId,FeatureName = line.rstrip().split(',')
    image_index = int(ImageId) - 1
    feature_index = keypoint_index[FeatureName]
    feature_location = y_pred[image_index][feature_index] * 96
    output_file.write('{0},{1}n'.format(RowId,feature_location))

  output_file.close()
  IdLookupTable.close()

结果

用那么些结构的卷积神经网络练习出来的模子,在测验集上预计的结果提交以后的实际绩效是3.4144,在kaggle的leaderboard上是41名,初试CNN,感到还能了。那只是数量,依旧找一些现实的相片来试试这几个模型如何,所以本人找了一张anglababy的,标记出来的关键点感到还算可靠。基于TensorFlow的卷积神经网络先写到那了,有啥样疏漏的想起来再补偿,之后对纵深学习更掌握了,再写写CNN的规律,bp的推理进度之类的。

图片 3

以上就是本文的全体内容,希望对我们的就学抱有利于,也期望大家多多指教脚本之家。

在概念贰个最早化函数,因为卷积神经网络有那些权重和偏置供给创建。

前面在tensorflow分类-【老鱼学tensorflow】中意气风发度用平时的神经网络进行过手写数字的辨别,大家在非常程序的根基上来进展,那篇小说的地点为:

为什么不是上次说的晋升到99%以上呢?因为92%到98%是相比比较简单于的,而再从98%到99%是要费不菲功力的,后生可畏篇作品难以承载这么多内容,所以将会分成两篇文章,首先是从92%到98%,下二遍是从98%到99%。

您大概感兴趣的稿子:

  • Tensorflow达成亚历克斯Net卷积神经网络及运算时间评测
  • Tensorflow卷积神经网络实例进级
  • Tensorflow卷积神经网络实例
  • TensorFlow实现卷积神经互连网
  • tensorflow实现轻易的卷积神经互连网
  • TensorFlow达成轻便卷积神经互联网
  • tensorflow学习笔记之mnist的卷积神经互连网实例
  • TensorFlow深度学习之卷积神经网络CNN
  • TensorFlow完毕卷积神经网络CNN
  • Tensorflow达成卷积神经网络的事必躬亲代码
def weight_variable(shape): 
 initial = tf.truncated_normal(shape, stddev=0.1)
#给权重制造一些随机的噪声来打破完全对称, 
 return tf.Variable(initial) 
#使用relu,给偏置增加一些小正值0.1,用来避免死亡节点 
def bias_variable(shape): 
 initial = tf.constant(0.1, shape=shape) 
 return tf.Variable(initial) 
import tensorflow as tf

# 准备数据
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('D:/todel/python/MNIST_data/', one_hot=True)

def add_layer(inputs, in_size, out_size, activation_function=None):
    """
    添加层
    :param inputs: 输入数据
    :param in_size: 输入数据的列数
    :param out_size: 输出数据的列数
    :param activation_function: 激励函数
    :return:
    """

    # 定义权重,初始时使用随机变量,可以简单理解为在进行梯度下降时的随机初始点,这个随机初始点要比0值好,因为如果是0值的话,反复计算就一直是固定在0中,导致可能下降不到其它位置去。
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    # 偏置shape为1行out_size列
    biases = tf.Variable(tf.zeros([1, out_size])   0.1)
    # 建立神经网络线性公式:inputs * Weights   biases,我们大脑中的神经元的传递基本上也是类似这样的线性公式,这里的权重就是每个神经元传递某信号的强弱系数,偏置值是指这个神经元的原先所拥有的电位高低值
    Wx_plus_b = tf.matmul(inputs, Weights)   biases
    if activation_function is None:
        # 如果没有设置激活函数,则直接就把当前信号原封不动地传递出去
        outputs = Wx_plus_b
    else:
        # 如果设置了激活函数,则会由此激活函数来对信号进行传递或抑制
        outputs = activation_function(Wx_plus_b)
    return outputs

# 定义输入数据
xs = tf.placeholder(tf.float32, [None, 28*28])
ys = tf.placeholder(tf.float32, [None, 10]) #10列,就是那个one hot结构的数据

# 定义层,输入为xs,其有28*28列,输出为10列one hot结构的数据,激励函数为softmax,对于one hot类型的数据,一般激励函数就使用softmax
prediction = add_layer(xs, 28*28, 10, activation_function=tf.nn.softmax)

# 定义loss值
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), axis=1))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)


def computer_accuracy(v_xs, v_ys):
    """
    计算准确度
    :param v_xs:
    :param v_ys:
    :return:
    """
    # predication是从外部获得的变量
    global prediction
    # 根据小批量输入的值计算预测值
    y_pre = sess.run(prediction, feed_dict={xs:v_xs})
    correct_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs:v_xs, ys:v_ys})
    return result

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys})
    if i % 50 == 0:
        # 每隔50条打印一下预测的准确率
        print(computer_accuracy(mnist.test.images, mnist.test.labels))

不用轻视提升1%,越将来边,难度就越大。如若我们做到99%精确率,在Kaggle的手写识别这些连串上,也就进入了前五分三了,可以说入门了。

卷积移动步长都是1意味着会不脱漏的划过图片的每三个点,padding代表边界管理情势,same表示给边界加上padding让卷积的出口和输入保持生龙活虎致的尺寸。

拉长要求的函数

少年老成、回看下生龙活虎期

上一期咱们上学了梯度下落、神经网络、损失函数、交叉熵等概念,然后用4二零零一张图纸数据练习了三个简约的神经互连网,正确度92%。能够说,这只是三个Hello World。

图片 4

Hello World

def conv2d(x,W):#2维卷积函数,x输入,w是卷积的参数,strides代表卷积模板移动步长 
 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') 

def max_pool_2x2(x): 
 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], 
       padding='SAME') 

生成权重变量

# 生成权重变量
def weight_variable(shape):
    # 产生一个随机变量
    init = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(init)

二、怎样进展改正

首先,这一次我们将动用卷积神经网络来进展图纸识别。路人皆知,卷积神经网络对于图片识别是极其平价的。

这里小编酌量那样来营造那一个卷积神经网络:

卷积层1 池化层1 卷积层2 池化层2 全连接1 Dropout层 输出层

不过,什么是卷积神经网络?什么是卷积层、池化层、全连接层?Dropout又是什么样鬼?

1 什么是卷积神经网络?

大家人看出黄金时代幅图像,刹那就通晓图像中有啥样,图像中的主体在干什么。但Computer分裂,Computer见到的每风姿洒脱副图像都以叁个数字矩阵。那大家怎么让计算机从三个个数字矩阵中拿走有效的新闻吗,举例边缘,角点?更甚一点,怎么让计算机掌握图像呢?

对图像举行卷积,正是看似目的的首先步。

图像在Computer里的意味恐怕是那样的:

图片 5

一张图片

对图像卷积,正是求卷积核功能在图像后,拿到的图像对于该卷积核的丰硕数值。这个丰盛的数值可以代表那么些图形的片段性情。

如若是针对猫举办识别,人或许清楚猫头,猫尾巴等性子。CNN对图纸张开管理后,也会学习到部分风味,它大概不通晓猫头、猫尾巴这几个特色,但也会识别出后生可畏部分大家大概看不出来的性状,CNN通过这么些学习到的特征去做剖断。

2 什么是卷积层?

卷积层的作用是指对图片的矩阵张开卷积运算,得到一些数值,作为图片的有个别特征

3 什么是池化层?

池化曾的意义是对上层的数量实行采集样板,也正是只留下一部分,那样的机能是足以降低数据量和歪曲特征。

4 什么是全连接层?

全连接层便是连在最终的分类器。前面卷积层和池化层进行管理后,得到了累累的特色,全连接层使用那个特色进行分类。比方识别数字,那便是对0~9的拾个等级次序实行分类。

5 Dropout是什么?

Dropout层是为了防范CNN对训练样品过拟合,而形成管理新样板的时候效果不好,选择的裁撤部分激活参数的管理方式。

此地对那几个概念的表达都以比较轻易的,即便愿意详细驾驭,可以看天涯论坛的这么些链接:

CNN卷积神经网络是什么?

在标准陈设卷积神经互联网布局前,先定义输入的placeholder(相通于c 的cin,必要客户运维时输入)。因为卷积神经网络会利用到空间协会音信,由此须求将后生可畏维的输入向量转变为二维的图纸结构。同有时候因为唯有四个颜料通道,所以最终尺寸为【-1, 28,28, 1],-1意味着样品数量不稳固,1意味颜色通道的数目。

定义bias变量

# 定义bias变量
def bias_variable(shape):
    # bias的初始值比权重值稍微简单点,直接用非0常量定义就可以
    init = tf.constant(0.1, shape=shape)
    return tf.Variable(init)

三、 代码实现

图片 6

图片 7

1 标签的拍卖

图片 8

2 把数量分为操练集和验证集

图片 9

3 定义管理数量的函数

图片 10

4 定义互联网的布局

图片 11

5 定义种种参数

图片 12

6 进行练习

此间的tf.reshape是tensor变形函数。

概念卷积神经网络层

# 定义卷积神经网络层
def conv2d(x, W):
    # strides:结构为[1, x方向上的步长,y方向上的步长, 1],这里x方向上的步长和y方向上的步长都设置为1
    # padding可选值有VALID和SAME,VALID方式会在边界处比原始图片小一点,而SAME方式会在边界处用0来补充,从而保持跟原始图相同的大小
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

四、生成结果

此处迭代十多个周期:

图片 13

7 验证集上的正确度

接下来我们运用这几个模型对Kaggle的测验集举办前瞻,并生成cvs格式的结果

图片 14

8 生成结果

那边提出跑30轮以上,因为在验证集上有98.35%正确率,上传到Kaggle往往就唯有五分之四七点几的精确率了

祝我们好运~~~~

附带在此以前的三篇小说:

《五分钟带您入门TensorFlow》

《零幼功用TensorFlow玩转Kaggle的“手写识别”》

这里剧透一下,下生机勃勃篇小说将会利用Keras对模型进行重谈判优化,使得模型精确率达到99%以上,在Kaggle步向前十分六

想第有时间看见下风度翩翩篇优化模型的篇章?抓牢,喜欢和关心呢~~~

x = tf.placeholder(tf.float32, [None, 784])# x 时特征 
y_ = tf.placeholder(tf.float32, [None, 10])# y_时真实的label 
x_image = tf.reshape(x, [-1, 28, 28,1]) 

定义pooling

# 为了防止跨步太大丢失掉信息,我们会在中间建立一个pooling,使其跨度减小,但在pooling时跨度可以变大一点,这样在最后的图片生成时可以把大小减小下来但同时又尽可能保存了相关的信息
def max_pool_2x2(x):
    # strides结构依然为:[1, x方向上的步长,y方向上的步长, 1],这里x方向上的步长和y方向上的步长都设置为2,这样在pool时把图像的大小给减小了
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

接下去定义第贰个卷积层。

编纂主程序部分

w_conv1 = weight_variable([5, 5, 1, 32])
#代表卷积核尺寸为5X5,1个颜色通道,32个不同的卷积核,使用conv2d函数进行卷积操作, 
b_conv1 = bias_variable([32]) 
h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1)   b_conv1) 
h_pool1 = max_pool_2x2(h_conv1) 

概念输入数据

# 定义输入数据
xs = tf.placeholder(tf.float32, [None, 28*28])
ys = tf.placeholder(tf.float32, [None, 10]) #10列,就是那个one hot结构的数据
keep_prob = tf.placeholder(tf.float32)
# 为了使用卷积神经网络,我们需要把原始的一维的数据变换成长宽表示的平面图的数据,把xs的形状变成[-1,28,28,1],-1代表先不考虑输入的图片例子多少这个维度,
# 后面的1是channel的数量,因为我们输入的图片是黑白的,因此channel是1,例如如果是RGB图像,那么channel就是3。
x_image = tf.reshape(xs, [-1, 28, 28, 1])

概念第一个卷积层,与第一个卷积层相似,只然则卷积核的多寡形成了64,即那层卷积会提取64种特色

概念卷积层1

# 定义卷积层1,以5*5的面积进行扫描,因为黑白图片channel是1所以输入是1,输出是32个高度的值
W_conv1 = weight_variable([5, 5, 1, 32])
# bias的大小是32个长度,因此我们传入它的shape为[32]
b_conv1 = bias_variable([32])
# 定义好了Weight和bias,我们就可以定义卷积神经网络的第一个卷积层h_conv1=conv2d(x_image,W_conv1) b_conv1,同时我们对h_conv1进行非线性处理,
# 也就是激活函数来处理喽,这里我们用的是tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式,输出图片的大小没有变化依然是28x28,
# 只是厚度变厚了,因此现在的输出大小就变成了28x28x32
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1)   b_conv1)
# 最后我们再进行pooling的处理就ok啦,经过pooling的处理,输出大小就变为了14x14x32
h_pool1 = max_pool_2x2(h_conv1)
w_conv2 = weight_variable([5, 5, 32, 64])#这层提取64种特征 
b_conv2 = bias_variable([64]) 
h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2)   b_conv2) 
h_pool2 = max_pool_2x2(h_conv2) 

概念卷积层2

# 定义卷积层2
# 扫描的面积还是定义成5*5,输入大小为32,因为卷积层1中输出为32就被设置为这里的输入大小了。输出大小设定为64,也就是变得更高了
W_conv2 = weight_variable([5, 5, 32, 64])
# bias的大小是64个长度,因此我们传入它的shape为[64]
b_conv2 = bias_variable([64])
# 定义好了Weight和bias,我们就可以定义卷积神经网络的第二个卷积层h_conv2=conv2d(h_pool1,W_conv2) b_conv2,同时我们对h_conv2进行非线性处理,
# 也就是激活函数来处理喽,这里我们用的是tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式,输出图片的大小没有变化依然是在第一层卷集层输出时的14*14,
# 只是厚度变厚了,因此现在的输出大小就变成了14x14x64
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2)   b_conv2)
# 最后我们再进行pooling的处理就ok啦,经过pooling的处理,输出大小就变为了7x7x64
h_pool2 = max_pool_2x2(h_conv2)

由此五次大幅度为2x2的最大池化,此时图片尺寸造成了7x7,在运用tf.reshape函数,对第叁个卷积层的出口tensor实行变形,将其从二维转为风华正茂维向量,在连年贰个全连接层(隐含节点为1024卡塔尔,使用relu激活函数。

概念神经互联网全连接层1

# 定义神经网络全连接层1
# 其形状为h_pool2的输出形状7*7*64,输出为1024个神经元
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
# 把h_pool2的输出的包含长宽平面的信息形状转换成一个维度的数据,相当于变平的操作:[n_samples, 7, 7, 64] => [n_samples, 7*7*64]
h_pool1_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool1_flat, W_fc1)   b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
w_fc1 = weight_variable([7*7*64, 1024]) 
b_fc1 = bias_variable([1024]) 
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64]) 
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1)   b_fc1) 

概念神经网络全连接层2

# 定义神经网络全连接层2
# 其输入为全连接层1的输出1024,输出为0-9数字的one hot格式,因此为10列
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2)   b_fc2)

Dropout层:随机抛弃生龙活虎部分节点的多寡来缓慢解决过拟合。这里是通过几个placeholder传入keep_prob比率来决定的。

定义loss值

# 定义loss值
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), axis=1))
# 对于比较庞大的系统可以用AdamOptimizer比较好一点
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
#为了减轻过拟合,使用一个Dropout层 
keep_prob = tf.placeholder(tf.float32) 
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) 

#dropout层的输出连接一个softmax层,得到最后的概率输出 
w_fc2 = weight_variable([1024, 10]) 
b_fc2 = bias_variable([10]) 
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2)   b_fc2) 

执行

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
    if i % 50 == 0:
        # 每隔50条打印一下预测的准确率
        print(computer_accuracy(mnist.test.images, mnist.test.labels))

概念损失函数即评测正确率操作

大器晚成体代码

import tensorflow as tf

def add_layer(inputs, in_size, out_size, activation_function=None):
    """
    添加层
    :param inputs: 输入数据
    :param in_size: 输入数据的列数
    :param out_size: 输出数据的列数
    :param activation_function: 激励函数
    :return:
    """

    # 定义权重,初始时使用随机变量,可以简单理解为在进行梯度下降时的随机初始点,这个随机初始点要比0值好,因为如果是0值的话,反复计算就一直是固定在0中,导致可能下降不到其它位置去。
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    # 偏置shape为1行out_size列
    biases = tf.Variable(tf.zeros([1, out_size])   0.1)
    # 建立神经网络线性公式:inputs * Weights   biases,我们大脑中的神经元的传递基本上也是类似这样的线性公式,这里的权重就是每个神经元传递某信号的强弱系数,偏置值是指这个神经元的原先所拥有的电位高低值
    Wx_plus_b = tf.matmul(inputs, Weights)   biases
    if activation_function is None:
        # 如果没有设置激活函数,则直接就把当前信号原封不动地传递出去
        outputs = Wx_plus_b
    else:
        # 如果设置了激活函数,则会由此激活函数来对信号进行传递或抑制
        outputs = activation_function(Wx_plus_b)
    return outputs

def computer_accuracy(v_xs, v_ys):
    """
    计算准确度
    :param v_xs:
    :param v_ys:
    :return:
    """
    # predication是从外部获得的变量
    global prediction
    # 根据小批量输入的值计算预测值
    y_pre = sess.run(prediction, feed_dict={xs:v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs:v_xs, ys:v_ys, keep_prob: 1})
    return result


# 生成权重变量
def weight_variable(shape):
    # 产生一个随机变量
    init = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(init)

# 定义bias变量
def bias_variable(shape):
    # bias的初始值比权重值稍微简单点,直接用非0常量定义就可以
    init = tf.constant(0.1, shape=shape)
    return tf.Variable(init)

# 定义卷积神经网络层
def conv2d(x, W):
    # strides:结构为[1, x方向上的步长,y方向上的步长, 1],这里x方向上的步长和y方向上的步长都设置为1
    # padding可选值有VALID和SAME,VALID方式会在边界处比原始图片小一点,而SAME方式会在边界处用0来补充,从而保持跟原始图相同的大小
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

# 为了防止跨步太大丢失掉信息,我们会在中间建立一个pooling,使其跨度减小,但在pooling时跨度可以变大一点,这样在最后的图片生成时可以把大小减小下来但同时又尽可能保存了相关的信息
def max_pool_2x2(x):
    # strides结构依然为:[1, x方向上的步长,y方向上的步长, 1],这里x方向上的步长和y方向上的步长都设置为2,这样在pool时把图像的大小给减小了
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')


# 准备数据
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('D:/todel/python/MNIST_data/', one_hot=True)


# 定义输入数据
xs = tf.placeholder(tf.float32, [None, 28*28])
ys = tf.placeholder(tf.float32, [None, 10]) #10列,就是那个one hot结构的数据
keep_prob = tf.placeholder(tf.float32)
# 为了使用卷积神经网络,我们需要把原始的一维的数据变换成长宽表示的平面图的数据,把xs的形状变成[-1,28,28,1],-1代表先不考虑输入的图片例子多少这个维度,
# 后面的1是channel的数量,因为我们输入的图片是黑白的,因此channel是1,例如如果是RGB图像,那么channel就是3。
x_image = tf.reshape(xs, [-1, 28, 28, 1])

# 定义卷积层1,以5*5的面积进行扫描,因为黑白图片channel是1所以输入是1,输出是32个高度的值
W_conv1 = weight_variable([5, 5, 1, 32])
# bias的大小是32个长度,因此我们传入它的shape为[32]
b_conv1 = bias_variable([32])
# 定义好了Weight和bias,我们就可以定义卷积神经网络的第一个卷积层h_conv1=conv2d(x_image,W_conv1) b_conv1,同时我们对h_conv1进行非线性处理,
# 也就是激活函数来处理喽,这里我们用的是tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式,输出图片的大小没有变化依然是28x28,
# 只是厚度变厚了,因此现在的输出大小就变成了28x28x32
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1)   b_conv1)
# 最后我们再进行pooling的处理就ok啦,经过pooling的处理,输出大小就变为了14x14x32
h_pool1 = max_pool_2x2(h_conv1)

# 定义卷积层2
# 扫描的面积还是定义成5*5,输入大小为32,因为卷积层1中输出为32就被设置为这里的输入大小了。输出大小设定为64,也就是变得更高了
W_conv2 = weight_variable([5, 5, 32, 64])
# bias的大小是64个长度,因此我们传入它的shape为[64]
b_conv2 = bias_variable([64])
# 定义好了Weight和bias,我们就可以定义卷积神经网络的第二个卷积层h_conv2=conv2d(h_pool1,W_conv2) b_conv2,同时我们对h_conv2进行非线性处理,
# 也就是激活函数来处理喽,这里我们用的是tf.nn.relu(修正线性单元)来处理,要注意的是,因为采用了SAME的padding方式,输出图片的大小没有变化依然是在第一层卷集层输出时的14*14,
# 只是厚度变厚了,因此现在的输出大小就变成了14x14x64
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2)   b_conv2)
# 最后我们再进行pooling的处理就ok啦,经过pooling的处理,输出大小就变为了7x7x64
h_pool2 = max_pool_2x2(h_conv2)

# 定义神经网络全连接层1
# 其形状为h_pool2的输出形状7*7*64,输出为1024个神经元
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
# 把h_pool2的输出的包含长宽平面的信息形状转换成一个维度的数据,相当于变平的操作:[n_samples, 7, 7, 64] => [n_samples, 7*7*64]
h_pool1_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool1_flat, W_fc1)   b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# 定义神经网络全连接层2
# 其输入为全连接层1的输出1024,输出为0-9数字的one hot格式,因此为10列
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2)   b_fc2)

# 定义loss值
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), axis=1))
# 对于比较庞大的系统可以用AdamOptimizer比较好一点
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
    if i % 50 == 0:
        # 每隔50条打印一下预测的准确率
        print(computer_accuracy(mnist.test.images, mnist.test.labels))

输出为:

0.0853
0.7785
0.8835
0.9084
0.9241
0.9316
0.9412
0.9463
0.9485
0.951
0.9561
0.9578
0.9599
0.9611
0.964
0.9644
0.966
0.9673
0.9687
0.9685

此次用卷积神经互连网把结果提升了好多。

#损失函数,并且定义优化器为Adam 
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), 
            reduction_indices=[1])) 
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 

correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1)) 
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 

初叶演练

#初始化所有参数 
tf.global_variables_initializer().run() 
for i in range (20000): 
 batch = mnist.train.next_batch(50) 
 if i0 == 0: 
  train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_: batch[1], 
             keep_prob: 1.0}) 
  print("step %d, training accuracy %g"%(i, train_accuracy)) 
 train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5}) 

全套操练成功后,大家在终极的测验集上拓宽周全的测量检验,获得完整的分类正确率。

print("test accuracy %g" 
			

本文由pc28.am发布于计算机编程,转载请注明出处:TensorFlow实现简单卷积神经网络,tensorflow卷积神经

上一篇:net的粗略包装,NET营造筑组织调的动态作业调整 下一篇:没有了
猜你喜欢
热门排行
精彩图文