导语:在没有CNN以及更先进的神经网络的时代,朴素的想法是用多层感知机(MLP)做图片分类的识别;但残酷的现实是,MLP做这事的效果并不理想。本文通过使用MLP做图片分类识别的尝试作为思路指引,实为下一篇CNN相关笔记的引子文章。 本文的文档和代码,传送门: github项目地址
一. 用MLP做图像分类识别?在没有CNN以及更先进的神经网络的时代,朴素的想法是用多层感知机(MLP)做图片分类的识别,没毛病
作为上篇笔记学习的延续,以及下一篇CNN的药引,使用MLP来做图片分类识别,实在是个不错的过度例子。通过这个例子,从思路上引出一系列的问题,我不卖关子,自问自答吧,即:
MLP能做图片分类识别吗?—> 答案是是可以的,上一篇我们是拟合非线性分类函数,这里是拟合图像特征,数学本质没区别。
MLP做这个事情效果如何?—> 个人认知内,只能说一般一般。
MLP在这一领域效果一般,是有什么缺陷吗? —> 缺陷是有的,下文会详细说。
有更好的解决方案吗? —> 那也是必须有的,地球人火星人喵星人都知道有CNN等等更先进的东东;但是在没有这些东西存在的时代,你发明出来了,那才真是666。
二. 先上车 1. 数据源数据源当然是图片,但是是经过数据化处理的图片,使用的是h5文件。h5文件简单说就是把数据按索引固化起来,挺简单的不多说,度度一下 —> h5py入门讲解
我们有3个h5文件,存着不重复的图片数据,分别是:
train_catvnoncat.h5 (用来训练模型用的,一共有209张,其中有猫也有不是猫的图片,尺寸64*64像素)
test_catvnoncat.h5 (用来测试模型准确度的,一共有50张图片,,其中有猫也有不是猫的图片,尺寸64*64像素)
my_cat_misu.h5 (用来玩的,我家猫主子的1张照骗,尺寸64*64像素)
2. 数据结构拿train_catvnoncat.h5举例,这个文件有2个索引:
train_set_x:这是一个数组,因为是209张图片,所以数组长度是209。数组中的元素是一个 64*64*3 的矩阵。64*64是图片像素尺寸,3是什么鬼?别忘了这是彩色图片,3就是代表RGB这3个颜色通道的值。
train_set_y:图片标签数组,长度也是209,是209张图片的标签(label),对应数组下标的值是1时,代表这张图片是喵星人,0则代表不是。
同理,test_catvnoncat.h5 中有 test_set_x 和 test_set_y;my_cat_misu.h5 中有 mycat_set_x 和 mycat_set_y
3. 告诉你怎么制作图片的h5文件,以后做cnn等模型训练时,非常有用以我主子为例子:
原图:
自己处理成64*64的图片,当然你也可以写代码做图片处理,我懒,交给你实现了:
python代码,用到h5py库:
def save_imgs_to_h5file(h5_fname, x_label, y_label, img_paths_list, img_label_list): # 构造n张图片的随机矩阵 data_imgs = np.random.rand(len(img_paths_list), 64, 64, 3).astype('int') label_imgs = np.random.rand(len(img_paths_list), 1).astype('int') # plt.imread可以把图片以多维数组形式读出来,然后我们存成 n*n*3 的矩阵 for i in range(len(img_paths_list)): data_imgs[i] = np.array(plt.imread(img_paths_list[i])) label_imgs[i] = np.array(img_label_list[i]) # 创建h5文件,按照指定的索引label存到文件中,完事了 f = h5py.File(h5_fname, 'w') f.create_dataset(x_label, data=data_imgs) f.create_dataset(y_label, data=label_imgs) f.close() return data_imgs, label_imgs #用法 # 图片label为1代表这是一张喵星人的图片,0代表不是 save_imgs_to_h5file('datasets/my_cat_misu.h5', 'mycat_set_x', 'mycat_set_y', ['misu.jpg'],[1])