图片分类是机器学习中的一项常见任务。notMNIST是这样的一个数据集:图片共分为A、B、C、D、E、F、G、H、I、J十类,宽高都是28个像素,样式各异、姿态万千。下图中的图片虽然都属于A类,但外观差异非常之大,因此比MNIST(手写数字图片)数据集的分类任务难度更大。
下面我们来训练一个逻辑回归模型,用于对notMNIST数据集的图片分类,使用Python2.7实现。
准备工作
加载需要的包,如numpy、os、sys、sklearn等。
下载数据
使用urlretrieve()函数下载数据,包括两个文件,notMNIST_large.tar.gz和notMNIST_small.tar.gz,分别对应训练集和测试集,前者247M,后者8.5M。
解压数据
使用tarfile包解压文件,对每一类单独生成一个文件夹,里面包含对应的图片。经统计,训练集共有529138张图片,测试集共有18737张图片。有的图片尺寸不符合28*28,跳过即可。有的图片和标签(也就是图片所属类别)看起来似乎并不一致,即存在一定的噪声。比如下面这些,虽说都属于A类,但是“度”和“千”也混进来了是什么鬼……
整理数据
接下来用ndimage包读入训练集和测试集中,每个分类下的全部图片,将每一张图片转换为28*28的numpy array,其中的每一个值为归一化之后的像素值。这样每个分类下的全部图片就变成了一个(image_number, 28, 28)的3D array,image_number为该分类下的图片数量。不妨为每个分类单独生成一个pickle,便于之后加载继续使用。
生成训练集、校验集和测试集
接下来,从全部训练数据中均匀随机地选出200000份作为训练集、10000份作为校验集,从全部测试数据中均匀随机地选出10000份作为测试集。不管是训练集、校验集还是测试集,各个类别所占比例都是相等的。
用一个字典来保存训练集、校验集和测试集的features以及labels,并存到一个pickle中,便于之后使用。
训练模型、评估效果
使用sklearn包提供的LogisticRegression来训练一个简单的逻辑回归模型,用fit()函数训练,用score()函数计算平均分类准确率。最后,模型在测试集上达到了89.3%的准确率。
代码
代码可以在我的Github上找到:https://github.com/Honlan/udacity-notes,其中的 实战1 notMNIST数字识别 部分。