深度学习-推荐系统-CV-NLP大数据,机器学习,人工智能opencv 入门图像处理

Keras+CNN+Opencv 深度学习初探:狗的品种识别

2019-07-14  本文已影响38人  可乐还是百事好
1.jpg

一 介绍:

通过卷积神经网络对哈士奇、拉布拉多、金毛、柯基犬的数据集进行学习 ,训练出一个可以识别出这四种狗的品种的模型 。本文适合有mnist手写数字识别基础的读者观看 ,如果你对深度学习只有一些模糊概念的话,建议你在阅读本文之尝试此篇文章:Keras入门数字手写识别

二 :数据集

数据集 提取码: 1ik1
通过爬虫自行构建的,共2700余张狗的品种图片 ,分别放置在分好类别HSQ、LBLD、JM、KJQ (文件夹之所以设置为英文是因为opencv在open图片时候不支持路径存在中文) 的四个文件夹内 。如果你需要爬虫源码请访问:Github

准备数据集:

图片预处理

class Datasets:
    
    def __init__(self,filepath,fields,image_size):
        
        self.images = []
        self.labels = []
        self.classs = []
        self.rename = []
        self.fields = fields
        self.filepath = filepath
        self.image_size=image_size
    def Rename(self):

        for field in self.fields:
            label = self.fields.index(field)
            count = 0
            for file in os.listdir(self.filepath+field):
                #print(self.filepath+field+'/'+str(label)+'_'+str(count)+field+'.jpg')
                count += 1 
                os.rename(self.filepath+field+'/'+file,self.filepath+field+'/'+str(label+1)+'_'+str(count)+'.jpg')

     
    def Load_img(self):
            
        for field in self.fields:
            index = self.fields.index(field)
            for file in os.listdir(self.filepath+field):
                try:
                    image = cv2.imread(self.filepath+field+'/'+file)

                    image = cv2.resize(image, (self.image_size, self.image_size), cv2.INTER_LINEAR)
                    image = image.astype(np.float32)
                    image = np.multiply(image, 1.0 / 255.0)
                    self.images.append(image)
                    label = np.zeros(len(self.fields))
                    label[index] = 1.0
                    self.labels.append(label)
                    self.classs.append(field)
                    self.rename.append(file)
                except:
                    continue
        
        images = np.array(self.images)
        labels = np.array(self.labels)
        fields = np.array(self.classs)
        filenm = np.array(self.rename)
        return images,labels,fields,filenm

构造一个图片预处理的类Datasets,主要功能就是把图片改名字、并且转为cnn需要的数据类型 。接受三个参数数据集文件夹(总文件夹)、类别(即为分类文件夹名字)以及调整的图像像素大小。

返回的参数为,包含所有图像像素信息的列表的array 、图像分类信息的列表的array ,这里的label的形式为[0,0,1,0]表示属于第三类即:JM(金毛)。fields为labels对应的说明 。

数据读取

def Read_datas(self,validation_size):
        class Temp(object):
            pass
        data_sets = Temp()
        images,labels,fields,filenm=self.Load_img()
        images,labels,fields,filenm=shuffle(images,labels,fields,filenm)#随机打乱序列
        if isinstance(validation_size, float):
            validation_size = int(validation_size * images.shape[0])


        train_images = images[validation_size:]
        train_labels = labels[validation_size:]
        train_fields = fields[validation_size:]
        train_filenm = filenm[validation_size:]

        validation_images = images[:validation_size]
        validation_labels = labels[:validation_size]
        validation_fields = fields[:validation_size]
        validation_filenm = filenm[:validation_size]


        data_sets.train = DataSet(train_images, train_labels, train_fields,train_filenm)
        data_sets.valid = DataSet(validation_images, validation_labels, validation_fields,validation_filenm)

        return data_sets

class DataSet(object):

    def __init__(self, images, labels, fields, filenm):

        self._num_examples = images.shape[0]
        self._images = images
        self._labels = labels
        self._fields = fields
        self._filenm = filenm
        self._epochs_done = 0
        self._index_in_epoch = 0

    @property
    def images(self):
        return self._images

    @property
    def labels(self):
        return self._labels

    @property
    def fields(self):
        return self._fields

    @property
    def filenm(self):
        return self._filenm
    

    @property
    def num_examples(self):
        return self._num_examples

    @property
    def epochs_done(self):
        return self._epochs_done

训练数据集

from Load_data import *
import numpy as np
from keras.optimizers import Adadelta
from keras.losses import categorical_crossentropy
from keras.datasets import mnist
from keras.utils import np_utils
from keras.layers import Activation,Conv2D,MaxPool2D,Flatten,Dense,Dropout
from keras.models import Sequential



class Train(object):
    """docstring for Train"""
    def __init__(self,epoch,classes,batch_size):
        
        self.epoch = epoch
        self.classes = classes
        self.batch_size = batch_size


    def read_datas(self,filepath,fields,image_size,validation_size):
        datasets = Datasets(filepath,fields,image_size).Read_datas(validation_size)
        self.train = datasets.train
        self.valid = datasets.valid
    def train_datas(self):
        X_train = self.train.images
        Y_train = self.train.labels
        X_valid = self.valid.images
        Y_valie = self.valid.labels
        
        model = Sequential([
                            Conv2D(filters=16,kernel_size=(5,5),padding='same',activation='relu',input_shape=(64,64,3)),

                            MaxPool2D(pool_size=(2,2),strides=(2,2),padding='same'),
                            Conv2D(filters=32,kernel_size=(5,5),padding='same',activation='relu'),
                            MaxPool2D(pool_size=(2,2),strides=(2,2),padding='same'),
                            Dropout(0.5),
                            Flatten(),
                            Dense(64,activation='relu'),
                            Dropout(0.25),
                            Dense(4,activation='softmax'),






            ])
        model.compile(loss=categorical_crossentropy,
                      optimizer=Adadelta(),
                      metrics=['accuracy']
                      )
        model.fit(X_train,Y_train,batch_size=self.batch_size,epochs=self.epoch,validation_data=(X_valid,Y_valie))#validation_data=(X_valid,Y_valie)
        model.save("my_model.h6")

        

if __name__ == '__main__':
    a=Train(30,4,64)
    a.read_datas(filepath="H:/DogRaw/",fields=["HSQ","JM","LBLD","KJQ"],image_size=64,validation_size=0.1)
    a.train_datas()




构造的数据训练类,传入三个参数:训练次数、输出层的分类数、以及batch_size 。
read_datas 函数功能是讲前一部分准备好的数据加载进来 。训练集(X_train,Y_train)验证集(X_valid,Y_valid)。
训练部分采用卷积神经网络隐藏层个数为64层,输出层4层 。

预测图片

import cv2
import numpy as np
from keras.models import load_model



class Pred(object):
    """docstring for Pred"""
    def __init__(self,filepath,fileds,image_size,modelfile):
        
        self.fileds = fileds
        self.filepath = filepath
        self.modelfile = modelfile
        self.image_size = image_size

    def read_data(self):

        image = cv2.imread(self.filepath)
        image = cv2.resize(image,(self.image_size,self.image_size))
        self.image = np.array(image).reshape(-1,self.image_size,self.image_size,3).astype("float32")/255


    def pred_data(self):
        
        model = load_model(self.modelfile)

        prediction = model.predict(self.image)
        
        count = 0
        for i in prediction[0]:
            percent = '%.5f%%'%(i*100)
            print(f"{self.fileds[count]}的概率:{percent}")
            count += 1





if __name__ == '__main__':
    pred = Pred(filepath="HSQ.jpg",fileds=["哈士奇","金毛","拉布拉多","柯基犬"],image_size=64,modelfile="my_model.h5")
    pred.read_data()
    pred.pred_data()

将上一个部分训练好的模型导入 ,再讲测试的数据图片导入并做好数据处理 ,进行预测


偷来的金毛镇楼
预测结果
上一篇下一篇

猜你喜欢

热点阅读