1. 程式人生 > >TensorFlow的學習之路--人臉識別

TensorFlow的學習之路--人臉識別

     本次學習所採用的是olivettifaces資料影象,該影象有40個人,每個人10張影象,每張影象的大小為57*47,採用的還是CNN卷積,由於是初學者,很多函式重新認識,下面把次演算法的主要函式歸納一下:

    1.讀取影象:Image.open(path)

    2.讀取的圖片格式為IMAGE,需要轉換為所需要的浮點型,np.asarray(A,"float32")

    3.建立空矩陣以及零矩陣 np.empty((x,y)),np.zeros((x,y))

    4.把二位矩陣轉換成一維 np.ndarray.flatten()

    5.另外一種取隨機變數函式 tf.truncated_normal(shape,stddev=0.1)

    6.取常量矩陣 tf.constant(0.1,shape)

    7.卷積函式 tf.nn.conv2d(X,W,strides=[1,1,1,1],padding='SAME') 步長與邊界均可選

    8.池化函式 tf.nn.pool_max(X,ksize=[1,2,2,1],strides=[1,2,2,1],pdding='SAME')

    9.格式轉換tf.reshape(X,[])

    10.求損失函式:    cost_func=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predict,labels=Y))

                               optimizer=tf.train.AdamOptimizer(0.001).minimize(cost_func)

    11.資料對比 tf.equal(tf.argmax(N,1),tf.argmax(M,1)),此所產生的並非為資料型別,而是true和 false

    12.把true和false轉換成資料並求平均值 tf.reduce_mean(tf.cast(N,tf.float32))

# -*- coding: utf-8 -*-
"""
Created on Fri Mar  9 17:16:23 2018

@author: kxq
"""
import tensorflow as tf
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.patches as patches

def load_img(data_path):
    image=Image.open(data_path)
    img=np.asarray(image,"float32")/256
    img_face=np.empty((400,57*47))
    img_label=np.zeros((400,40))
    ##把二位人頭影象平鋪成一維影象
    for row in range(20):
        for col in range(20):
            img_face[row*20+col]=np.ndarray.flatten(img[57*row:(row+1)*57,47*col:(col+1)*47])
    for i in range(40):
        img_label[i*10:(i+1)*10,i]=1
    ##設定訓練集和測試集    
    train_set=np.empty((320,57*47))
    train_label=np.empty((320,40))
    
    vaild_set=np.empty((40,57*47))
    vaild_label=np.empty((40,40))
    
    test_set=np.empty((40,57*47))
    test_label=np.empty((40,40))
    
    for j in range(40):
        train_set[j*8:(j+1)*8]=img_face[j*10:j*10+8]
        train_label[j*8:(j+1)*8]=img_label[j*10:j*10+8]
        
        vaild_set[j]=img_face[j*10+8]
        vaild_label[j]=img_label[j*10+8]
        
        test_set[j]=img_face[j*10+9]
        test_label[j]=img_label[j*10+9]
    train_set=train_set.astype("float32")
    vaild_set=vaild_set.astype("float32")
    test_set=test_set.astype("float32")
    return [(train_set,train_label),
            (vaild_set,vaild_label),
            (test_set,test_label)]
    
def weight_variable(shape):
    weight=tf.truncated_normal(shape,stddev=0.1)
    return tf.Variable(weight)

def bias_variable(shape):
    bias=tf.constant(0.1,shape=shape)
    return tf.Variable(bias)

def conv2d(X,W):
    return tf.nn.conv2d(X,W,strides=[1,1,1,1],padding='SAME')

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

def conv_network(data):
    
    train_set_x=data[0][0]
    train_label_y=data[0][1]
        
    test_set_x=data[2][0]
    test_label_y=data[2][1]
    
    batch_size=40
    X=tf.placeholder(shape=[batch_size,57*47],dtype=tf.float32)
    Y=tf.placeholder(shape=[batch_size,40],dtype=tf.float32)   
    image=tf.reshape(X,[-1,57,47,1])
    
    ##conv1
    w_conv1=weight_variable([5,5,1,32])
    b_conv1=bias_variable([32])
    h_conv1=(conv2d(image,w_conv1)+b_conv1) ##57*47*32
    h_pool1=pool_2x2(h_conv1)                     ##29*24*32
    ##conv2
    w_conv2=weight_variable([5,5,32,64])
    b_conv2=bias_variable([64])
    h_conv2=(conv2d(h_pool1,w_conv2)+b_conv2)  ##29*24*64
    h_pool2=pool_2x2(h_conv2)                            ##15*12*64
    
    h_pool2_flat=tf.reshape(h_pool2,[-1,15*12*64])
    
    ##fc1
    w_fc1=weight_variable([15*12*64,1024])
    b_fc1=bias_variable([1024])
    h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,w_fc1)+b_fc1)
    
    ##fc2
    w_fc2=weight_variable([1024,40])
    b_fc2=bias_variable([40])
    prediction=tf.nn.softmax(tf.matmul(h_fc1,w_fc2)+b_fc2)   
    loss=tf.reduce_mean(-tf.reduce_sum(Y*tf.log(prediction),reduction_indices=[1]))#計算loss
    train_step=tf.train.AdamOptimizer(0.0001).minimize(loss)  
    
    with tf.Session() as sess:     
        sess.run(tf.global_variables_initializer())
        best_loss=float('Inf')
        for i in range(40):
            epoch_loss=0
            for epoch in range(8):
                x=train_set_x[40*epoch:(epoch+1)*40]
                y=train_label_y[40*epoch:(epoch+1)*40]
                _,l=sess.run([train_step,loss],feed_dict={X:x,Y:y})  
                epoch_loss+=l
                print("epoch:",i,epoch_loss)
            if best_loss>epoch_loss:
                best_loss=epoch_loss
                print("best_loss:",best_loss)
                correct=tf.equal(tf.argmax(prediction,1),tf.argmax(Y,1))
                accuracy=tf.reduce_mean(tf.cast(correct,dtype=tf.float32))
                A=sess.run(accuracy,feed_dict={X:test_set_x,Y:test_label_y})
                print("accuracy",A)
def main():
    data=load_img("./olivettifaces.gif")
    conv_network(data)
if __name__ =="__main__":
    main()

 此過程中,出現一些錯誤:

     1.訓練過程中,loss出現non的現象,降低學習率後正常

    2.另外一個損失函數出現non的現象,經檢視,是因為再prediction時,矩陣出現0的現象,導致在求損失函式時,log(prediction)沒有意義,出現non,主要原因是最開始定義隨機變數是,tf,truncated.normal(shape,stddev=0.1),把0.1寫成了1。

     3.在執行過程中,出現類似“”Fetch argument 19.575699 has invalid type <class 'numpy.float32'>, must be a string or Tensor. (Can not convert a float32 into a Tensor or Operation.)“”這個錯誤,檢查了一下,是因為在定義這個函式

_,l=sess.run([train_step,loss],feed_dict={X:x,Y:y})

過程中,把l寫成了loss,使得前後loss重複,更改前面顯示的就行