猫狗分类来源于Kaggle上的一个入门竞赛——Dogs vs Cats。为了加深对CNN的理解,基于Pytorch复现了LeNet,AlexNet,ResNet等经典CNN模型,并探究哪些因素会对模型预测效果有明显影响(如模型结构、数据量、是否采用数据增强、dropout等等),源代码放在GitHub上,地址传送点击此处。项目大纲如下:
一、问题描述
基于训练集数据,训练一个模型,利用训练好的模型预测未知图片中的动物是狗或者猫的概率。
训练集有25,000张图片,测试集12,500 张图片。
数据集下载地址:https://www.kaggle.com/datasets/shaunthesheep/microsoft-catsvsdogs-dataset
二、数据集处理
1 损坏图片清洗
在 01_clean.py
中,用多种方式来清洗损坏图片:
- 判断开头是否有JFIF
- 用imghdr库中的imghdr.what函数判断文件类型
- 用Image.open(filename).verify()验证图片是否损坏
结果如下:

2 抽取图片形成数据集
由于一万多张图片比较多,并且需要将Cat类和Dog类的图片合在一起并重新命名,方便获得每张图片的labels,我们将从原数据集文件夹复制任意给定数量图片到train的文件夹,并且重命名如下:

程序为:02_data_processing.py
.
三、图片预处理
图片预处理部分需要完成:
- 对图片的裁剪:将大小不一的图片裁剪成神经网络所需的,我选择的是裁剪为(224x224)
- 转化为张量
- 归一化:三个方向归一化
- 图片数据增强
- 形成加载器:返回图片数据和对应的标签,利用Pytorch的Dataset包
在 dataset.py
中定义Mydata的类,继承pytorch的Dataset,定义如下三个方法:
(1)init 方法
读取图片路径,并拆分为数据集和验证集,完成对图片的处理(以下代码仅体现结构,具体见源码):
class Mydata(data.Dataset):
"""定义自己的数据集"""
def __init__(self, root, Transforms=None, train=True):
"""进行数据集的划分"""
if train:
self.imgs = imgs[:int(0.8*imgs_num)] #80%训练集
else:
self.imgs = imgs[int(0.8*imgs_num):] #20%验证集
"""定义图片处理方式"""
if Transforms is None:
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
self.transforms = transforms.Compose(
[ transforms.CenterCrop(224),
transforms.Resize([224,224]),
transforms.ToTensor(