本文主要是记录课程设计,使用Python和TensorFlow平台进行图像训练识别。
识别结果:
代码:
#coding=utf-8
import os
import sys
from PIL import Image #使用第三方包进行图像处理
import numpy as np
import tensorflow.contrib.keras as k
import scipy.spatial.distance as distance
import pandas as pd
def resizeImage(inputImage, maxWidth, maxHeight):
originalWidth, originalHeight = inputImage.size
f1 = 1.0*maxWidth / originalWidth
f2 = 1.0*maxHeight / originalHeight
factor = min([f1,f2])
width = int(originalWidth*factor)
height = int(originalHeight*factor)
return inputImage.resize((width,height),Image.ANTIALIAS)
ifRestartT = False
roundCount = 20
learnRate = 0.01
trainDir="../imageData/animals" #用于指定训练数据所在的目录
trainResultPath = "./imageclassifySave/" #用于指定训练数据保存目录
optimizerT = "RMSProp"
lossT = "categorical_crossentropy"
predictFile = None
#读取meta.txt文件内容
metaData=pd.read_csv(trainDir+"meta.txt",header=None).as_matrix()
maxTypes = len(metaData)
print("maxTypes: %d" % maxTypes)
argt = sys.argv[1:]
print("argt:%s" % argt)
for v in argt:
if v == "-restart":
ifRestartT = True
if v.startswith("-round="):
roundCount = int(v[len("-round="):])
if v.startswith("-learnrate="):
learnRate = float(v[len("-learnrate="):])
if v.startswith("-dir="):
trainDir = v[len("-dir="):]
if v.startswith("-optimizer="):
optimizerT = v[len("-optimizer="):]
if v.startswith("-loss="):
lossT = v[len("-loss="):]
if v.startswith("-predict="):
#predictFile="imageData/test/"+v[len("-predict="):]
predictFile=v[len("-predict="):]
print("predict file: %s" % predictFile)
xData =[]
yTrainData = []
fnData = []
predictAry = []
listt = os.listdir(trainDir)
lent = len(listt)
for i in range(lent):
v = listt[i]
if v.endswith(".jpg"):
print("processing %s ..." % v)
img = Image.open(trainDir + "/"+v)
w,h =img.size
img1 = resizeImage(img,512,512)
img2 = Image.new("RGB",(512,512),color = "white")
w1,h1 = img1.size
img2 = Image.new("RGB",(512,512),color ="white")
img2.paste(img1,box=(int((512 - w1)/2),int((512 -h1)/2)))
xData.append(np.matrix(list(img2.getdata())))
tmpv = np.full([maxTypes],fill_value=0)
tmpv[int(v.split(sep="_")[0]) - 1] = 1
yTrainData.append(tmpv)
fnData.append(trainDir+v)
rowCount = len(xData)
print("rowCount:%d" % rowCount)
#转换XData,yTrainData,fnCount为合适的形态
xData = np.array(xData)
xData = np.reshape(xData,(-1,512,512,3))
yTrainData = np.array(yTrainData)
fnData = np.array(fnData)
if(ifRestartT is False) and os.path.exists(trainResultPath+".h5"):
#载入保存的模型和可变参数
print("Loading...")
model = k.models.load_model(trainResultPath+".h5")
model.load_weights(trainResultPath+"wb.h5")
else:
model=k.models.Sequential()
model.add(k.layers.Conv2D(filters=4,kernel_size=(3,3),input_shape=(512,512,3),data_format="channels_last",activation="relu"))
model.add(k.layers.Conv2D(filters=3,kernel_size=(3,3),data_format="channels_last",activation="relu"))
model.add(k.layers.Conv2D(filters=2,kernel_size=(2,2),data_format="channels_last",activation="selu"))
model.add(k.layers.Flatten())
model.add(k.layers.Dense(256,activation='tanh'))
model.add(k.layers.Dense(64,activation='sigmoid'))
#按分类数进行softmax分类
model.add(k.layers.Dense(maxTypes,activation='softmax'))
model.compile(loss=lossT,optimizer=optimizerT,metrics=['accuracy'])
if predictFile is not None:
#先对已有训练数据执行一遍预测,以便后面做图片相似度比对
print("preparing...")
predictAry = model.predict(xData)
print("processing %s ..." % predictFile)
img = Image.open(predictFile)
#下面对新输入图片进行预测
img1=resizeImage(img,512,512)
w1, h1=img1.size
img2=Image.new("RGB",(512,512),color="white")
img2.paste(img1,box=(int((512 - w1)/2),int((512 - h1)/2)))
xi = np.matrix(list(img2.getdata()))
xi1 = np.array(xi)
xin = np.reshape(xi1,(-1,512,512,3))
resultAry = model.predict(xin)
print("x:%s, y:%s"%(xin,resultAry))
#找出预测结果中最大可能的概率及其对应的编号
maxIdx = -1
maxPercent = 0
for i in range(maxTypes):
if resultAry[0][i]>maxPercent:
maxPercent = resultAry[0][i]
maxIdx = i
#将新图片的预测结果与训练图片的预测结果逐一比对,找出相似度最高的
minDistance = 200
minIdx = -1
minFile = ""
for i in range(rowCount):
dist = distance.cosine(resultAry[0],predictAry[i])
if dist<minDistance:
minDistance = dist
minIdx = i
minFile = fnData[i]
print("图片类型: %s,推断正确概率: %10.6f%%, 最相识文件:%s, 相似度: %10.6f%%" %(metaData[maxIdx][1],maxPercent*100,minFile.split("\\")[-1],(1-minDistance)*100))
sys.exit(0)
model.fit(xData,yTrainData,epochs=roundCount,batch_size=lent,verbose=2)
print("saving...")
model.save(trainResultPath+".h5")
model.save_weights(trainResultPath +"wb.h5")
然后在pc控制台进入到工程目录:
然后在控制台输入指令:python 文件名 -predict=预测文件
完成后即可获取预测结果,我这里使用的训练图片比较少,所以预测结果可能有差异,在神经网络学习中,需要使用大量数据来进行训练。