前段时间,日剧《轮到你了》大火,作为程序员的我,看到了另外一个程序员—二阶堂,他的生活作息,以及饮食规律,让我感同身受,最让我感触的是他做的AI聊天机器人,AI菜品分析机器人,AI罪犯分析。 这让作为程序员的我突然萌生了一股攀比和一种激情,我也得做一个出来(小声bb,都得尝试下): 于是,我想从相对简单的做起,《AI菜品分析机器人》: AI菜品分析机器人: 1.建立语料库,爬取各个网站的对话和问答,这里我采用的是知乎以及调用api获取实时对话,至于代码的话我这里就不放了,涉及比较多,我这里侧重点是图像识别,大概获取了将近4万条数据, 这里给出部分结果: 2.关于图像识别: 1.图像训练需要极大的数据,我这里找了很久,通过各种手段,找到了kaggle比赛曾用过的101000张图片,里面有101种食物图片,如下(部分)
类似于上述图片,每一个图片都是都是对应得食物,我们需要提取每一张图片的特征值。 2.我们可以看出上述图片,大小不一,还具有色彩,我们特征值提取,是将图片进行矩阵化,所以我们在这里需要将图片变成大小一样,并且灰度处理。这里我们解释下: 将图片处理成大小一样:我们训练数据的时候是将图片矩阵化,如果图片大小不一样,我们得矩阵大小就不一样,所以在训练得时候会有问题,为了简单方便,我们直接将其同一化: import numpy as np from PIL import Image img =Image.open(“F:/images/baby_back_ribs/”+i).convert(‘L’) img=img.resize((512,512)) img.save(“F:/baby_back_ribs28/”+i) 这里,我们通过img =Image.open(“F:/images/baby_back_ribs/”+i).convert(‘L’)将图片灰度处理,然后img=img.resize((512,512))处理图片为512,512,最后保存:
可以看出,我们处理过后得图片如上,得出这样的图片后,我们就可以用来作为数据了 3.我们将我们获取的灰度图片矩阵化: for i in range(512): for j in range(512): pixel=1.0-float(img.getpixel((j,i)))/255.0
所以我们可以将其矩阵化: 每张图片有512*512个数据,我们这里是将一个二维矩阵扁平化为一维矩阵。所以我们可以将这101000张图片所有数据都矩阵化,然后测试算法。
具体的代码,还在测试中,目前遇到得问题比较多,正在一步一步处理,后面会继续更新,下面给出我遇到的一些问题和解决: 1.数据的获取:这101000张图片我找了很久才找到的数据(约有5个g)。 2.数据量比较大,在处理的时候容易出错,所以大家在写的时候一定要仔细,最好把源图复制一份,保留下来。 3.图片特征比较多,普通的算法难以满足,容易出现过拟合现象,而且1000张图也不算特别多,准确率较低,容易识别出错。 4.在实现矩阵算法的时候,每次带入100张图片进行训练,注意图片维度,以及图片长度。 等数据测试稳定后会放出源码让大家学习。 持续更新中,希望大家留意后面的博客…
一个月前,我将kaggle里面的food-101(101000张食物图片),数据包下载下来,想着实现图像识别,做了很长时间,然后自己电脑也带不动,不过好在是最后找各种方法实现出了识别,但是准确率真的非常低,我自己都分辨不出来到底是哪种食物,电脑怎么分的出来呢? 在上一篇博客中,我提到了数据的下载处理,然后不断地测试,然后优化代码,反正过程极其复杂,很容易出错。 再说下代码流程吧: 关于数据集的处理,我上篇博客写道:将其灰度处理,实际上是应该二值化,将彩色图片转化为(0,1)的范围里面,首先是读取每一个文件的数据(这里的每张图片都有一个标签),然后将其随机分为80%的训练集,20%的测试集: for filename in dir: img = np.multiply(img, 1.0/255.0) size = int(config.size * len(images))
这里采用循环的方式,每一张都进行二值化,然后存入列表,再根据我设置的大小进行选择。 神经网络训练,我将图片二值化后,下一步需要将我得图片数据传入我得训练中,循环训练,分批传入,我采用卷积操作实现其识别: def jj(): conv = tf.nn.relu(tf.nn.conv2d(input, filter, [1, 1, 1, 1], padding=“SAME”)+b) pool = tf.nn.max_pool2d(conv, [1, 2, 2, 1], [1, 2, 2, 1], padding=“SAME”) 我这里采用的是相同大小卷积,所以我在全连接层的地方就需要注意我的神经元个数,最后通过激励函数得出结果。 prediction = tf.nn.softmax(fc2,name=“y_pred”) loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=fc2,labels=labels_batch)) optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=1e-4).minimize(loss) correct_prediction = tf.equal(tf.argmax(prediction,1), tf.argmax(labels_batch,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
数据训练的方法:当我们建立神经网络后,需要让机器自动去训练,所以我们需要将模型保存在电脑中,同时需要电脑能够停止训练(当损失函数的值处于某一最小值的时候)。 if loss < 0.01: print(“迭代收敛,结束训练”) break 这里我们上传数据为50一个批次,具体多少按照自己处理。 服务器中跑代码时,需要注意的是肯定需要大型cpu/gpu计算机,不然容易崩溃,然后也没有什么需要注意的地方了。 其实每个神经网络的训练处理方式都不一样,但是大致流程都差不多:数据处理-网格搭建-数据训练-网格优化。根据自己数据的不同和侧重点不同,需要建立不同的卷积算法。 总结下遇到的问题: 图片处理:在处理图片的时候我发现有的图片格式,大小,色彩都不相同,所以我在这里将其分类和处理,主要是分开除黑白图和彩色图 def image(url): im=Image.open(url) pix=im.convert(‘RGB’) width=im.size[0] height=im.size[1] type=“黑白Image” is_color=[] for x in range(width): for y in range(height): r,g,b=pix.getpixel((x,y)) r=int® g=int(g) b=int(b) if (rg) and (gb): pass else: type=‘彩色 Image’ return type 数据处理其实是这里面最好做的。 在神经网络搭建中,需要避免过拟合和欠拟合的问题,图片数据不能太少,同时神经元不能太多,需要考虑到多个问题,以及卷积操作的方式,这里都需要自己摸索 虽然大型服务器好用,但是贫民学生不配拥有,借用个服务器真是太难了,真的太难了!
其实这个kaggle提供的数据我的识别率才0.1。