很早就想做这个猫狗识别的程序,所以跟着唐宇迪教程做了一遍,中间部分参数做了修改。
后面预测部分用自己的猫猫图片做了预测,虽然有点问题,但最后还是可以识别出来,问题不大,下面对程序几个部分进行讲解,最后会附上整个程序的附件。
一、数据处理
整个训练集用了cat dog两个文件,每个数据集里面有500张图片,并且图片的大小不一样,因此导入图片时需要对图片进行压缩处理,程序中的image_size就是压缩处理的像素。但是这个像素选取会有个问题,对于这个项目中使用训练集来讲的话没有什么问题,因为图片本身很小,但如果你用自己拍的图片,就会出现最后识别的数据有些不准。我分析原因可能是因为我们手机拍照的像素很大,有些都是4K的,那么压缩成64x64可能会导致猫狗不分,解决方式也很简单,你把你的图片缩小一点,然后放进去训练集中训练一下。dataset.py主要讲一下load_train(train_path,image_size,classes)这个函数,里面就是使用join函数,把path+field+"*g"合成一个地址字符串,作用其实就是把/train_data/cats/*jpg所有的jpg文件都拿到手,相当于可以读取所有的jpg文件,然后用cv2进行缩放,变成64*64,接着处以255进行归一化,再把文件名存进img_name。这个没什么难度,稍微理解一下就可以了。
def load_train(train_path,image_size,classes):
images = []
labels = []
img_names = []
cls = []
print_hi("Going to read train data")
# classes : dog and cat
for fields in classes:
index = classes.index(fields)
print("now going to read {} flies (Index:{})".format(fields,index))
# '*g':maybe mean jpg file
path = os.path.join(train_path,fields,'*g')
print(path)
# read all the file in path
files = glob.glob(path)
for fl in files:
image = cv2.imread(fl)
image = cv2.resize(image,(image_size,image_size),0,0,cv2.INTER_LINEAR)
image = image.astype(np.float32)
image = np.multiply(image,1.0/255)
images.append(image)
label = np.zeros(len(classes))
label[index] = 1.0
labels.append(label)
# get the file name of fl
flbase = os.path.basename(fl)
img_names.append(flbase)
cls.append(fields)
images = np.array(images)
labels = np.array(labels)
img_names = np.array(img_names)
cls = np.array(cls)
return images,labels,img_names,cls
二、建立模型
这个模型是三层cnn:(conv+max+relu)*3+fc1+fc2。每个conv层其实都是一样,采用relu(max(X*W+B))格式,随后fc1拉成1024*10,再fc2拉成2*1,2*1其实就是概率值。其实程序看多之后,就会发现使用CONV都是一样的套路,区别就是中间多少层。对于初学者来说,有个可能会范迷糊的地方,就是filter的数量,我这里写一下自己的理解:对于一张64*64*3的彩色图片,3就是我的channel,即RGB三通道,我需要对每一个通道进行filter卷积,同时为了增加准确率,我一次可用好多个filter,例如32个,那么最后卷积效果会出现32*(conv(channel1,filter),conv(channel2,filter),conv(channel2,filter)),那么对于第二次卷积,你需要对上一次的32个中间变量进行二次卷积,假设二次卷积的filter值有64个,就会有64*(32*(conv(channel1,filter),conv(channel2,filter),conv(channel2,filter))),每一层的filte值都需要注意对应你上一层用了多少个filter。如果上一层是32个filter,并且这一层你想输出64个特征图,那么你的第二层w值维度就是[m,n,32],并且有64个这种w值。
如下图所示,一一对应
三、跑模型
跑模型比较简单,但需要注意几个地方。
第一,使用GPU还是CPU。tensorflow-gpu可以让我们调用自己电脑得GPU,某些模型真的是GPU有天然优势,之前做的一个mnist数据集,GPU是CPU的6倍。我现在用的配置是I7-11+3060 6g+16G运存的笔电,处理起来是比较快的。要成功使用GPU需要满足几个条件,我这里列出我的版本:tensorflow2.8,tensorflow-gpu2.8,cnn11.4,cuda8.2.4,你需要安装下载这几个东西之后才能正确识别到GPU,并且进行计算,成功后会有下面提示。我的电脑跑这个模型用了2分多钟。
第二,影响模型准确率的参数。batch_size,用多了准确率降低,想一下,如果一次性训练全部数据,那准确率都一样;img_size,其实这个我也不确定影响不影响,但我加大图像像素,准确率确实没那么高,那如果你想增加准确率要怎么做呢,可以加drop_out;drop out,如果、img_size只有64的话,可以不加drop out,准确率可以到1,如果增加了size,那可以调整drop out,一般0.1-0.5吧;学习率,一般1-e4吧,太大太小都有问题。
四、数据展示
我的训练结果如图所示。6000次迭代,准确率为1。后面开始用实际图片去判断,也就是predict.py,效果还可以。
资源链接:https://download.csdn.net/download/wenpeitao/85251992