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重複,更改前面顯示的就行