logo资料库

AI从入门到放弃:CNN的导火索,用MLP做图像分类识别.pdf

第1页 / 共13页
第2页 / 共13页
第3页 / 共13页
第4页 / 共13页
第5页 / 共13页
第6页 / 共13页
第7页 / 共13页
第8页 / 共13页
资料共13页,剩余部分请下载后查看
AI从⼊门到放弃:CNN的导⽕索,⽤MLP做图 像分类识别? ⼀. 前⾔ 阅读本⽂的基础: 1. 我会认为你对BP神经⽹络有充分的了解,熟读过我上⼀篇⽂章,本⽂会⼤量引⽤上⼀篇⽂章的知识以及代 码。 2. 上⼀篇笔记的传送门:《AI从⼊门到放弃:BP神经⽹络算法推导及代码实现笔记》 ⼆. ⽤MLP做图像分类识别? 1. 在没有CNN以及更先进的神经⽹络的时代,朴素的想法是⽤多层感知机(MLP)做图⽚分类的识别,没⽑ 病 2. 作为上篇笔记学习的延续,以及下⼀篇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') 1 2 3 4 5
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 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]) 4. 看看我的数据源的样⼦ ⽤来训练的图⽚集合,209张:
⽤来校验模型准确度的图⽚集合, 50张 ⽤来玩的,主⼦照骗,1张:
四. 开车了 1. 如何设计模型: 输⼊层: 我们的图⽚是64*64的像素尺⼨,那么算上RGB三个通道的数据,我们把三维矩阵拉成⾯条 64*64*3 = 12288。 也就是我们输⼊层的数据长度是12288。 隐藏层: 使⽤多层隐藏层,可以⾃⾏多尝试⼀下不同的结构。这⾥我使⽤3个隐藏层,隐藏层神经元个数分别是20, 7,5 输出层: 我们的⽬标就是判断某张图⽚是否是猫⽽已,所以输出层1个神经元,输出概率⼤于0.5认为是猫,⼩于等于 0.5认为不是。 【插播】:有⼈会想,第⼀层隐藏层的神经元和输⼊层数量⼀致是不是会好点?理论上是会好点,但是这涉 及到MLP的⼀个缺陷,因为全连接情况下,这样做,第⼀层的权重w参数就有1228的平⽅个,约为1.5个亿。 如果图⽚更⼤呢?参数会成指数级膨胀,后果尽情想象。 2. 如何训练模型 还⽤说,把209张图⽚的数据扔到神经⽹络,完成⼀次迭代,然后训练1万次,可⾃⾏尝试迭不同代次数观 察效果。 3. 如何衡量模型的准确度 ⼤神吴恩达(Andrew Ng)提到的⽅法之⼀,就是划分不同集合,⼀部分⽤来训练,⼀部分⽤来验证模型效 果,这样可以达到衡量你所训练的模型的效果如何。所以我们训练使⽤209张图⽚,最终使⽤50张测试模型 效果。 为了好玩,可以⾃⼰⽤不同图⽚通过模型去做分类识别。 五. ⽼规矩,甩代码 还是说明⼀下代码流程吧: 代码使⽤到的 NeuralNetwork 是我上⼀篇笔记的代码,实现了BP神经⽹络,import进来直接⽤即可。 代码做的事情就是: a. 从h5⽂件加载图⽚数据 b. 把原始图⽚显⽰出来,同时也保存成图⽚⽂件 c. 训练神经⽹络模型
d. 验证模型准确度 e. 把识别结果标注到原始图⽚上,同时也保存成图⽚⽂件 #coding:utf-8 import h5py import matplotlib.font_manager as fm import matplotlib.pyplot as plt import numpy as np from NeuralNetwork import * font = fm.FontProperties(fname='/System/Library/Fonts/STHeiti Light.ttc') def load_Cat_dataset(): train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r") train_set_x_orig = np.array(train_dataset["train_set_x"][:]) train_set_y_orig = np.array(train_dataset["train_set_y"][:]) test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r") test_set_x_orig = np.array(test_dataset["test_set_x"][:]) test_set_y_orig = np.array(test_dataset["test_set_y"][:]) mycat_dataset = h5py.File('datasets/my_cat_misu.h5', "r") mycat_set_x_orig = np.array(mycat_dataset["mycat_set_x"][:]) mycat_set_y_orig = np.array(mycat_dataset["mycat_set_y"][:]) classes = np.array(test_dataset["list_classes"][:]) train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0])) test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0])) mycat_set_y_orig = mycat_set_y_orig.reshape((1, mycat_set_y_orig.shape[0])) return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, mycat_set_x_orig, mycat_set_y_orig,classes def predict_by_modle(x, y, nn): m = x.shape[1] p = np.zeros((1,m)) output, caches = nn.forward_propagation(x) for i in range(0, output.shape[1]): if output[0,i] > 0.5: p[0,i] = 1 else: p[0,i] = 0 # 预测出来的结果和期望的结果⽐比对,看看准确率多少: # ⽐比如100张预测图⽚片⾥里里有50张猫的图⽚片,只识别出40张,那么识别率就是80% print(u"识别率: " + str(np.sum((p == y)/float(m)))) return np.array(p[0], dtype=np.int), (p==y)[0], np.sum((p == y)/float(m))*100 def save_imgs_to_h5file(h5_fname, x_label, y_label, img_paths_list, img_label_list): data_imgs = np.random.rand(len(img_paths_list), 64, 64, 3).astype('int') 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 label_imgs = np.random.rand(len(img_paths_list), 1).astype('int') 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]) 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 if __name__ == "__main__": # 图⽚片label为1代表这是⼀一张喵星⼈人的图⽚片,0代表不不是 #save_imgs_to_h5file('datasets/my_cat_misu.h5', 'mycat_set_x', 'mycat_set_y', ['misu.jpg'],[1]) train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, mycat_set_x_orig, mycat_set_y_orig, classes = load_Cat_dataset() train_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T test_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T mycat_x_flatten = mycat_set_x_orig.reshape(mycat_set_x_orig.shape[0], -1).T train_set_x = train_x_flatten / 255. test_set_x = test_x_flatten / 255. mycat_set_x = mycat_x_flatten / 255. print(u"训练图⽚片数量量: %d" % len(train_set_x_orig)) print(u"测试图⽚片数量量: %d" % len(test_set_x_orig)) plt.figure(figsize=(10, 20)) plt.subplots_adjust(wspace=0,hspace=0.15) for i in range(len(train_set_x_orig)): plt.subplot(21,10, i+1) plt.imshow(train_set_x_orig[i],interpolation='none',cmap='Reds_r',vmin=0.6,vmax=.9) plt.xticks([]) plt.yticks([]) plt.savefig("cat_pics_train.png") plt.show() plt.figure(figsize=(8, 8)) plt.subplots_adjust(wspace=0, hspace=0.1) for i in range(len(test_set_x_orig)): ax = plt.subplot(8, 8, i + 1) im = ax.imshow(test_set_x_orig[i], interpolation='none', cmap='Reds_r', vmin=0.6, vmax=.9) plt.xticks([]) plt.yticks([]) plt.savefig("cat_pics_test.png") plt.show() plt.figure(figsize=(2, 2)) plt.subplots_adjust(wspace=0, hspace=0) for i in range(len(mycat_set_x_orig)):
ax = plt.subplot(1, 1, i + 1) im = ax.imshow(mycat_set_x_orig[i], interpolation='none', cmap='Reds_r', vmin=0.6, vmax=.9) plt.xticks([]) plt.yticks([]) plt.savefig("cat_pics_my.png") plt.show() # ⽤用训练图⽚片集训练模型 layers_dims = [12288, 20, 7, 5, 1] nn = NeuralNetwork(layers_dims, True) nn.set_xy(train_set_x, train_set_y_orig) nn.set_num_iterations(10000) nn.set_learning_rate(0.0075) nn.training_modle() # 结果展示说明: # 【识别正确】: # 1.原图是猫,识别为猫 --> 原图显示 # 2.原图不不是猫,识别为不不是猫 --> 降低显示亮度 # 【识别错误】: # 1.原图是猫,但是识别为不不是猫 --> 标红显示 # 2.原图不不是猫, 但是识别成猫 --> 标红显示 # 训练⽤用的图⽚片⾛走⼀一遍模型,观察其识别率 plt.figure(figsize=(10, 20)) plt.subplots_adjust(wspace=0, hspace=0.15) pred_train, true, accuracy = predict_by_modle(train_set_x, train_set_y_orig, nn) for i in range(len(train_set_x_orig)): ax = plt.subplot(21, 10, i + 1) x_data = train_set_x_orig[i] if pred_train[i] == 0 and train_set_y_orig[0][i] == 0: x_data = x_data/5 if true[i] == False: x_data[:, :, 0] = x_data[:, :, 0] + (255 - x_data[:, :, 0]) im = plt.imshow(x_data,interpolation='none',cmap='Reds_r',vmin=0.6,vmax=.9) plt.xticks([]) plt.yticks([]) plt.suptitle(u"Num Of Pictrues: %d\n Accuracy: %.2f%%" % (len(train_set_x_orig), accuracy), y=0.92, fontsize=20) plt.savefig("cat_pics_train_predict.png") plt.show() # 不不属于训练图⽚片集合的测试图⽚片,⾛走⼀一遍模型,观察其识别率 plt.figure(figsize=(8, 8)) plt.subplots_adjust(wspace=0, hspace=0.1) 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
分享到:
收藏