Tensorflow Keras基於深度學習的圖像識別/人臉表情識別demo


1 簡單的深度學習過程常規流程:

PS: 標*的 構建神經網絡是最重要的。

 

 

 2 本demo功能:基於TensorFlow Keras來建立模型、訓練(喂給它已經分類好的人臉表情圖片)和預測 人臉表情圖片。

上代碼:

  1 import os
  2 import sys
  3 from PIL import Image   # 使用第三方包Pillow來進行圖像處理
  4 import numpy as np
  5 import tensorflow.contrib.keras as k
  6 import scipy.spatial.distance as distance   # 使用第三方包scipy來進行向量余弦相似度判斷
  7 import pandas as pd
  8 
  9 
 10 # 這是一個自定義函數,用於把圖片按比例縮放到最大寬度為maxWidth、最大高度為maxHeight
 11 def resizeImage(inputImage, maxWidth, maxHeight):
 12     originalWidth, originalHeight = inputImage.size
 13 
 14     f1 = 1.0 * maxWidth / originalWidth
 15     f2 = 1.0 * maxHeight / originalHeight
 16     factor = min([f1, f2])
 17 
 18     width = int(originalWidth * factor)
 19     height = int(originalHeight * factor)
 20     return inputImage.resize((width, height), Image.ANTIALIAS)
 21 
 22 
 23 ifRestartT = False
 24 roundCount = 20
 25 learnRate = 0.01
 26 trainDir = "./imagedata/"   # 用於指定訓練數據所在目錄
 27 trainResultPath = "./imageClassifySave/"     # 用於指定訓練過程保存目錄
 28 optimizerT = "RMSProp"  # 用於指定優化器
 29 lossT = "categorical_crossentropy"  # 用於指定誤差函數
 30 #predictFile = None  # 用於指定需預測的新圖像文件,如果為None則表示不預測
 31 predictFile = "./predictFile/xx.jpg"
 32 
 33 #  讀取meta.txt文件內容:分類
 34 #metaData = pd.read_csv(trainDir + "meta.txt", header=None).as_matrix()
 35 metaData = pd.read_csv(trainDir + "meta.txt", header=None).iloc[:,:].values
 36 
 37 # maxTypes表示種類個數
 38 maxTypes = len(metaData)
 39 print("maxTypes: %d" % maxTypes)
 40 
 41 argt = sys.argv[1:]
 42 print("argt: %s" % argt)
 43 
 44 for v in argt:
 45     if v == "-restart":
 46         print("我打印了嗎?")
 47         ifRestartT = True
 48     if v.startswith("-round="):
 49         roundCount = int(v[len("-round="):])
 50     if v.startswith("-learnrate="):
 51         learnRate = float(v[len("-learnrate="):])
 52     if v.startswith("-dir="):   # 用於指定訓練數據所在目錄(不使用默認目錄時才需要設置)
 53         trainDir = v[len("-dir="):]
 54     if v.startswith("-optimizer="):
 55         optimizerT = v[len("-optimizer="):]
 56     if v.startswith("-loss="):
 57         lossT = v[len("-loss="):]
 58     if v.startswith("-predict="):
 59         predictFile = v[len("-predict="):]
 60 
 61 print("predict file: %s" % predictFile)
 62 
 63 xData = []
 64 yTrainData = []
 65 fnData = []
 66 predictAry = []
 67 
 68 listt = os.listdir(trainDir)    # 獲取變量trainDir指定的目錄下所有的文件
 69 
 70 lent = len(listt)
 71 
 72 # 循環處理訓練目錄下的圖片文件,統一將分辨率轉換為256*256,
 73 # 再把圖片處理成3通道(RGB)的數據放入xData,然后從文件名中提取目標值放入yTrainData
 74 # 文件名放入fnData
 75 for i in range(lent):
 76     v = listt[i]
 77     if v.endswith(".jpg"):  # 只處理.jpg為擴展名的文件
 78         print("processing %s ..." % v)
 79         img = Image.open(trainDir + v)
 80         w, h = img.size
 81 
 82         img1 = resizeImage(img, 256, 256)
 83 
 84         img2 = Image.new("RGB", (256, 256), color="white")
 85 
 86         w1, h1 = img1.size
 87 
 88         img2 = Image.new("RGB", (256, 256), color="white")
 89 
 90         img2.paste(img1, box=(int((256 - w1) / 2), int((256 - h1) / 2)))
 91 
 92         xData.append(np.matrix(list(img2.getdata())))
 93 
 94         tmpv = np.full([maxTypes], fill_value=0)
 95         tmpv[int(v.split(sep="_")[0]) - 1] = 1
 96         yTrainData.append(tmpv)
 97 
 98         fnData.append(trainDir + v)
 99 
100 rowCount = len(xData)
101 print("rowCount: %d" % rowCount)
102 
103 # 轉換xData、yTrainData、fnData為合適的形態
104 xData = np.array(xData)
105 xData = np.reshape(xData, (-1, 256, 256, 3))
106 
107 yTrainData = np.array(yTrainData)
108 
109 fnData = np.array(fnData)
110 
111 # 使用Keras來建立模型、訓練和預測
112 if (ifRestartT is False) and os.path.exists(trainResultPath + ".h5"):
113     # 載入保存的模型和可變參數
114     print("模型已經存在!!!!!!!!...")
115     print("Loading...")
116     model = k.models.load_model(trainResultPath + ".h5")
117     model.load_weights(trainResultPath + "wb.h5")
118 else:
119     # 新建模型
120     model = k.models.Sequential()
121 
122     # 使用4個卷積核、每個卷積核大小為3*3的卷積層
123     model.add(k.layers.Conv2D(filters=4, kernel_size=(3, 3), input_shape=(256, 256, 3), data_format="channels_last", activation="relu"))
124 
125     model.add(k.layers.Conv2D(filters=3, kernel_size=(3, 3), data_format="channels_last", activation="relu"))
126 
127     # 使用2個卷積核、每個卷積核大小為2*2的卷積層
128     model.add(k.layers.Conv2D(filters=2, kernel_size=(2, 2), data_format="channels_last", activation="selu"))
129 
130     model.add(k.layers.Flatten())
131     # 此處的256沒有改
132     model.add(k.layers.Dense(256, activation='tanh'))
133 
134     model.add(k.layers.Dense(64, activation='sigmoid'))
135 
136     # 按分類數進行softmax分類
137     model.add(k.layers.Dense(maxTypes, activation='softmax'))
138 
139     model.compile(loss=lossT, optimizer=optimizerT, metrics=['accuracy'])
140 
141 
142 if predictFile is not None:
143     # 先對已有訓練數據執行一遍預測,以便后面做圖片相似度比對
144     print("preparing ...")
145     predictAry = model.predict(xData)
146 
147     print("processing %s ..." % predictFile)
148     img = Image.open(predictFile)
149 
150     #  下面是對新輸入圖片進行預測
151     img1 = resizeImage(img, 256, 256)
152 
153     w1, h1 = img1.size
154 
155     img2 = Image.new("RGB", (256, 256), color="white")
156 
157     img2.paste(img1, box=(int((256 - w1) / 2), int((256 - h1) / 2)))
158 
159     xi = np.matrix(list(img2.getdata()))
160     xi1 = np.array(xi)
161     xin = np.reshape(xi1, (-1, 256, 256, 3))
162 
163     resultAry = model.predict(xin)
164     print("x: %s, y: %s" % (xin, resultAry))
165 
166     # 找出預測結果中最大可能的概率及其對應的編號
167     maxIdx = -1
168     maxPercent = 0
169 
170     for i in range(maxTypes):
171         if resultAry[0][i] > maxPercent:
172             maxPercent = resultAry[0][i]
173             maxIdx = i
174 
175     # 將新圖片的預測結果與訓練圖片的預測結果逐一比對,找出相似度最高的
176     minDistance = 200
177     minIdx = -1
178     minFile = ""
179 
180     for i in range(rowCount):
181         dist = distance.cosine(resultAry[0], predictAry[i])     # 用余弦相似度來判斷兩張圖片預測結果的相近程度
182         if dist < minDistance:
183             minDistance = dist
184             minIdx = i
185             minFile = fnData[i]
186 
187     print("推測表情:%s,推斷正確概率:%10.6f%%,最相似文件:%s,相似度:%10.6f%%" % (metaData[maxIdx][1], maxPercent * 100, minFile.split("\\")[-1], (1 - minDistance) * 100))
188 
189     sys.exit(0)
190 
191 model.fit(xData, yTrainData, epochs=roundCount, batch_size=lent, verbose=2)
192 
193 print("saving...")
194 model.save(trainResultPath + ".h5")
195 model.save_weights(trainResultPath + "wb.h5")

3 用於訓練的圖片:

 

 

 PS: 這些圖是在網上隨便找噠。這里需要注意圖片的命名規則:eg: 01_06.jpg  01代表圖片的類型,和meta.txt中的類型對應,06代表01類型下的第幾張

meat.txt文件:

1 1,微笑
2 2,大笑
3 3,哭
4 4,憤怒
5 5,平靜

4 預測:

用於預測的圖片:小公舉~~~

 

 

預測結果:

 

 

PS: 后續有需要會繼續更新。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM