Author: zhouzhi
02现代计算机视觉入门之:什么是视频
桃李春风一杯酒,江湖夜雨十年灯
有一些颇具江湖之气的诗词,读起来很爽,这些作者里面有些人确实是跨马扬刀在战场上杀过人的。现代社会还是需要一些江湖侠义之气,要婉约、要豪放、还要霸气。下面收集了一些,有的可能只有一两句传唱度比较高的,已经用下划线标明。排名不分先后。
我杀过人,为兄弟挡过刀
首先当然是我们大家熟悉的诗仙李白了。李白一生怀有赤子之心,诗文豪爽大气。相关历史资料说他平时带剑在身,可能真有武术。他诗歌里面经常有“杀”一字,至于是否真的杀过人就不得而知了。他有两首跟江湖有关知名度比较高的诗:
《侠客行》
赵客缦胡缨,吴钩霜雪明。
银鞍照白马,飒沓如流星。
十步杀一人,千里不留行。
事了拂衣去,深藏身与名。
闲过信陵饮,脱剑膝前横。
将炙啖朱亥,持觞劝侯嬴。
三杯吐然诺,五岳倒为轻。
眼花耳热后,意气素霓生。
救赵挥金槌,邯郸先震惊。
千秋二壮士,烜赫大梁城。
纵死侠骨香,不惭世上英。
谁能书阁下,白首太玄经。
《赠从兄襄阳少府皓》
结发未识事,所交尽豪雄。
却秦不受赏,击晋宁为功。
托身白刃里,杀人红尘中。
当朝揖高义,举世称英雄。
小节岂足言,退耕舂陵东。
归来无产业,生事如转蓬。
一朝乌裘敝,百镒黄金空。
弹剑徒激昂,出门悲路穷。
吾兄青云士,然诺闻诸公。
所以陈片言,片言贵情通。
棣华倘不接,甘与秋草同。
第一首诗表面上是李白赞美燕赵侠客精神,实际上是将自己比作侠客,希望能够寻找信陵君这样的明主可以施展政治抱负。我有剑,武功高,能杀人,还不求功名利禄,但求有人赏识我!
第二首诗定位就没这么高了。李白说自己年轻的时候豪爽大气,经常结交一些热血之士。红尘滚滚之中杀过人,也曾为了朋友两肋插过刀,白刀子进红刀子出,千金散尽帮助别人,但并不觉得解人之难是什么了不起的事情。现在我的生活非常落魄,腰间的盘缠也都用完了,请兄弟拉我一把!废话不多说了,你懂的。你如果不帮我,我就去自生自灭了啊。这首诗的创作背景是李白当时仕途不顺,求朋友帮助自己。熟悉李白的朋友可能知道,李白一生仕途都不顺,这种动不动说自己要杀人的人,应该顺不起来。
从上面两首诗可以看到,李白不管是求职还是找朋友帮忙,先要把自己猛夸一顿。不仅仅这两首诗,他其余大部分诗都这样。这是李白裘马轻狂,豪爽用事的真实写照。
少打仗,少杀人
说完李白就应该提杜甫,因为他两齐名。需要注意的是,在当时社会,虽然他两年龄只差11岁,杜甫却比李白名气小太多了。李白现在如果知道他跟杜甫齐名,有可能要发飙。中年的杜甫经历过“安史之乱”,山河破碎,写了很多忧国忧民的诗歌,他的诗歌格局都比较高。这里挑一首我觉得跟本次主题关联性比较大的诗:
《前出塞九首·其六》
挽弓当挽强,用箭当用长。
射人先射马,擒贼先擒王。
杀人亦有限,列国自有疆。
苟能制侵陵,岂在多杀伤。
前出塞有好几首,这是其中之一。这首诗应该是我接触比较早的,可能是小学时候看到的一本书上,还配有插图,只是我读书时代对这些不太感兴趣,基本也背不会。据我了解,杜甫应该没有带兵打过仗,所以这首诗前面的四句应该是他臆想出来的,不过写的非常好。前面四句很好理解,说的是打仗杀敌应该拿最好的武器、还要找准取胜的关键点。后四句话锋一转,开始讲道理了。他说不能无休止的去打仗杀人,国家疆域差不多就行了。能够击退侵犯的敌人就行,不在于要杀多少人。这首诗的创作背景是,当时唐朝打仗频繁,连年征兵上战场,死了很多人,全国人数骤减。
从这首诗作者所要表达的观点来看,杜甫和李白迥然不同。有人可能觉得这一两首诗说明不了什么问题,其实如果再多读读他两其他的诗歌,就会发现他两不仅诗风不同,处事态度也不同,诗歌内容格局自然也就不同了。
戍边杀敌太苦了
有一位边塞诗人大家应该非常熟悉,叫王昌龄,他的有些诗上学的时候必背。王昌龄算作是唐朝边塞诗人鼻祖,唐朝当时很多文人去边疆寻求边功,这人真的去过西域边塞战场,至于有没有亲自拿刀杀过人我就不太清楚了。这里我挑两首比较有代表性的:
《出塞二首·其一》
秦时明月汉时关,万里长征人未还。
但使龙城飞将在,不教胡马度阴山。
《从军行七首·其四》
青海长云暗雪山,孤城遥望玉门关。
黄沙百战穿金甲,不破楼兰终不还。
他的这两首诗的主旨思想都是:戍边战士太幸苦了,但是想到国家人民能够安居乐业,顿时鸡血满满。我们可以看到,作为亲临一线的人和杜甫这种没有上过战场的人思考问题的角度不太一样,所谓屁股决定脑袋。王昌龄深刻体验到了戍边环境的恶劣以及戍边战士的艰辛,但是他秉着“舍小家,保大家”的崇高境界,认为戍守边疆、抵御外敌是军人的指责所在。这样一种矛盾的心情可能也是现如今为祖国戍守边疆战士的心情。
据相关专家考证,王昌龄应该是历史上边塞诗的先驱鼻祖。但是这人最后死得太可惜了,不是战死的,也不是被朝廷陷害死的,是被某地刺史所杀。具体原因不详,有说是因为嫉妒他的才华。
追人杀敌?一切尽在掌握之中
下面要说的这首诗是我个人很喜欢的一首,作者相对来讲不太出名,叫卢纶,也是唐朝诗人。具体内容如下:
《塞下曲》
月黑雁飞高,单于夜遁逃。
欲将轻骑逐,大雪满弓刀。
这首诗的创作背景我其实不太了解,但是这首诗描述的内容我倒是非常喜欢。它描述的是,在一个月黑风高的晚上,敌人(单于代指北方胡人)半夜准备撤离,我方将军正准备集结骑兵部队去追剿,这时候天降大雪,雪花落在战士背上的武器(弓刀)上,挡住了寒气。
敌人要跑没关系,老大率领若干轻骑去追。之所以是轻骑,因为骑兵跑得快,轻装上路。将军胸有成竹,仿佛瓮中捉鳖,因此不需要大军前往。这首诗描写的场景应该是唐太宗时期(初唐,而写这首诗的时间应该是安史之乱之后),唐朝开国名将李靖奉旨扫平突厥的时候,没错这人就是哪吒他爹。
谁需要杀人?请找我
下面这首诗的作者大家应该比较熟悉,名叫贾岛。这人之前是一个和尚,后来还俗了并且受到了韩愈的赏识。他还写过其他比较有名的诗,知道的人肯定比这首要多,比如“松下问童子,言师采药去”。
《剑客》
十年磨一剑,霜刃未曾试。
今日把示君,谁有不平事?
这首诗的字面意思浅显易懂,意思是说,我花十年铸就了一把剑,还未见血,今天将它拿出来给大伙看看,你们谁有不平事呀?可以来找我,我来帮你杀人。当然这只是字面意思,其实作者想要表达的是:我寒窗苦读十几年,非常想要寻得一个赏识我的人,实现我的政治抱负。其实意思跟前面说的李白一样,古人施展自己的才华主要途径是入仕做官,而当官一是靠科举,二是靠人引荐。如果科举屡考不中,那么只能奢求第二种了。
打个猎,突然想上战场杀敌
苏轼一生多次被贬,他写的诗词大部分都是表达豁达乐观的。就这首《江城子·密州出猎》有些江湖气,勉强拿出来:
《江城子·密州出猎》
老夫聊发少年狂,左牵黄,右擎苍,锦帽貂裘,千骑卷平冈。为报倾城随太守,亲射虎,看孙郎。
酒酣胸胆尚开张。鬓微霜,又何妨!持节云中,何日遣冯唐?会挽雕弓如满月,西北望,射天狼。
这首词写于苏轼任密州知州的时候,这时候他还没被贬过。宋朝的疆域其实是中原所有统一王朝中最小的,北宋时期西边有西夏,北边有辽人、后来又来了金人,而且北方的这些人占领了幽云十六州,因此宋朝北边边境缺少了天然的地理保护屏障。苏轼写这首词的时候正逢西夏入侵北宋疆域,喝完酒,打着打着猎,突然觉得自己很牛掰了,所以想象着哪天朝廷能够派他去往边疆抗击西夏入侵。该词读书时肯定背过太熟悉了,此处不再做过多解读,文中引用了好几处典故。
苏轼这首词开启了宋词豪放一派,之前宋朝大部分词都是写爱、写情之类的婉约风格。他好像就这一首有些江湖气,比较符合这次的主题。苏轼嘛,侧重点不在这块。
跨马杀敌,我已经饥渴难耐了
辛弃疾是为数不多的拿过刀、杀过人的古代诗人,证据确凿。他出生于南宋时期,那时候北宋已经经历过“靖康之难”灭亡了,大部分北方疆域被金人占领,南宋疆域面积比北宋更小。他二十岁就带兵抗金杀敌(应该属于自己组织的那种民兵),骁勇善战,有勇有谋。后来投靠南宋朝廷想发挥更大的抗金价值,结果被朝廷雪藏了,一生再没上过战场。他的一生出场就是巅峰,始于武,但是终于文。下面这首词是他被雪藏二十年后写的:
《破阵子·为陈同甫赋壮词以寄之》
醉里挑灯看剑,梦回吹角连营。八百里分麾下炙,五十弦翻塞外声,沙场秋点兵。
马作的卢飞快,弓如霹雳弦惊。了却君王天下事,赢得生前身后名。可怜白发生!
这首词写的是他喝醉酒了,梦到自己上战场杀敌的画面。该词描写的画面也只有亲自上过战场的人才能写得出来,让杜甫和李白去写,肯定没这个效果。这首词是我认为描写沙场打仗画面最好的一首诗词。该词读书时肯定背过太熟悉了,此处不再做过多解读。
那么,辛弃疾为什么会写这么一首词呢?那就要了解一下这首词的创作背景了。他这时候被朝廷雪藏了二十年,基本每天在家种地(可以看一下他写的田园词,非常好)。这时候一个名叫陈亮的人找到他,这人是主战派,主张抗金的人,给朝廷上了很多奏折。两人志向相投,一拍即合,聊着天越聊越兴奋,辛弃疾就幻想着马上可以去战场杀人了。要知道这时候的辛弃疾已经大概五十岁了,只可惜这次会面并没有什么效果,朝廷投降派占主导。最终辛弃疾的一生也在遗憾中结束。
不止杀人,还要干革命
很早之前周杰伦参演的一部张艺谋的电影,电影名叫《满城尽带黄金甲》,其实这个名字取自于一首晚唐名诗,黄巢写的。这人科举考试多次落榜,后来实在受不了了,干脆起义当皇帝,最后搞起了历史上的“黄巢起义”著名事件,掀起了唐朝末年农名起义的浪潮,唐朝也开始真正走向灭亡了。其实他还有另外一首诗也比较有名,两首内容如下:
《不第后赋菊》
待到秋来九月八,我花开后百花杀。
冲天香阵透长安,满城尽带黄金甲。
《题菊花》
飒飒西风满院栽,蕊寒香冷蝶难来。
他年我若为青帝,报与桃花一处开。
我来给大家翻译一下,第一首看名字就知道是考试落榜之后写的,字面意思是:等到秋天九月八重阳节,菊花盛开之后其他的花都凋零了。菊花的香气飘满整个长安城,满城的菊花就像战士身上穿的铠甲一般金光灿灿。其实实际表达的意思可能更接近于:总有一天老子要杀进长安城,我来当皇帝。最终结果确实如这首诗里面讲的这样,黄巢率领起义军攻进了长安城,但是成功并不长久,很快就失败了。
第二首是他起义之前写的,他说菊花盛开的这个季节不太好,秋天有风又冷还没有蝴蝶,什么时候他当了青帝,要让菊花和桃花一样,在春天盛开。这首诗多么霸气,不服不行。我觉得黄巢的这两首诗是古代干革命的人写的诗中最好之一,像后来清朝末年天平天国的洪秀全,也是考不上跑去干革命了,但是写出来的诗比这个差远了。另外,从黄巢的人生经历来看,肯定是真杀过人的了。
死了也要去阴间杀阎罗
提到干革命,这里不得不说一下咱们伟大的开国元帅——陈毅。1936年国民党围剿时,陈毅率领的游击队被困于梅岭(大概在江西和广东接壤处),形势非常不妙,于是写下了下面三首诗:
《梅岭三章》
断头今日意如何?创业艰难百战多。
此去泉台招旧部,旌旗十万斩阎罗。
南国烽烟正十年,此头须向国门悬。
后死诸君多努力,捷报飞来当纸钱。
投身革命即为家,血雨腥风应有涯。
取义成仁今日事,人间遍种自由花。
近现代诗的内容没有古诗那么难于理解,基本就是字面上的意思。“此去泉台招旧部,旌旗十万斩阎罗。”意思是说,即使我被杀,去了阴曹地府也要集结之前死去的旧部,继续斩杀国民党反动派。而“后死诸君多努力,捷报飞来当纸钱。”跟陆游的“王师北定中原日,家祭无忘告乃翁”有异曲同工之妙。我死之后,渴望收到前方传来的捷报。
陈毅肯定也是为数不多亲自杀过人的诗人,梅岭遭劫,最终突围了。这三首诗慷慨激昂,非常适合青少年读。另外再多说一下这个梅岭,这个位置在古代应该属于岭南瘴毒之地,即使不是,可能也远不了。古代当官儿的只要被贬,比较惨的基本都被贬到了岭南,因为这个地方环境恶劣,湿热虫多,主要古代没有空调电扇,广州没有空调夏天能住人不?苏轼有一句词“试问岭南应不好,却道,此心安处是吾乡”,可见这个地方大家都怕(苏轼后来也被贬到这个地方了)。杜牧有一首诗写的杨贵妃,“一骑红尘妃子笑,无人知是荔枝来”,里面描写驿卒快马加鞭将荔枝从岭南运往洛阳,大概就是要经过这里吧。
废话太多,小心我砍你
大家一提到朱元璋,就说他是乞丐出身,当过和尚要过饭。其实他也有一些江湖霸气的诗句流传下来:
《示僧》
杀尽江南百万兵,腰间宝剑血犹腥!
老僧不识英雄汉,只管哓哓问姓名。
传说当年朱元璋起义时经过金陵的一个寺庙。寺庙的和尚不认识他,一直问他是谁,朱元璋被问不耐烦了,提笔写下这首诗。他说,老子江南杀人千千万,腰间的宝剑上还能闻出血腥味,这里的一个老和尚居然不认识我这个大英雄,逼叨逼叨没完没了。言下之意是,你再问小心我拿剑砍你。
有人说朱元璋的诗词创作水平不高,那是肯定的,毕竟没有正儿八经上过学,底子薄。跟其他一些帝王将相相比,差很远。比如五代南唐后主李煜,北宋耻辱之帝宋徽宗,他们适合搞这些,但就是不适合当皇帝。康熙乾隆写过很多诗,乾隆爷写过四万首,但是你背过嘛?
你们都不行,让我来
最后让主席来镇楼,主席的诗词大气磅礴,不是一般人写得出来的,读起来非常爽。原因很简单,人家干过这个事情,你让李白杜甫苏轼来写,打死估计也写不出来。下面以这首《沁园春·雪》结尾:
《沁园春·雪》
北国风光,千里冰封,万里雪飘。
望长城内外,惟余莽莽;大河上下,顿失滔滔。
山舞银蛇,原驰蜡象,欲与天公试比高。
须晴日,看红装素裹,分外妖娆。
江山如此多娇,引无数英雄竞折腰。
惜秦皇汉武,略输文采;唐宗宋祖,稍逊风骚。
一代天骄,成吉思汗,只识弯弓射大雕。
俱往矣,数风流人物,还看今朝。
主席把中国牛掰一点的帝王全部都鄙视了一遍,嬴政、刘彻、李世民、赵匡胤这些人都不行,总觉得哪里差了点,成吉思汗简直莽夫一个,只知道骑马打猎杀人。看现在,风流人物还是得看我(们)呀!不得不说,主席不仅带兵打仗厉害,写诗也强得很。这首词完全没有自大的表象,倒是让人一读振奋人心,激昂斗志。
庄子真的很消极吗?
如果说庄子代表的道家思想是消极的,那么孔子代表的儒家肯定就是积极的了。前者叫你要顺其自然,无所待而逍遥,凡事莫强求;后者劝你要修身、齐家、治国、平天下,学而优则仕,施展远大抱负。
其实在我看来,道家和儒家只是思想的侧重点不同,并没有明确的对立关系。道家的“顺其自然”是指在你“洞察世事之规则后,顺应天道,从而达到心如止水的境界”,这里的天道就是指“自然规律”。顺应天道的前提是在你“洞察世事之规则后”,换句话说,他不是让你无脑躺平、让你消极生活,而是告诉你,平时要多动动脑子,领悟世间万物运行之根本,明白个人与自然宇宙之间的关系,不要有过分的想法和欲望,徒增烦恼,最终达到精神上的真正自由。所以你看,庄子给每个道家信徒都设置了一个门槛,就是首先你得有领悟这个思想的慧根。
庄子在《逍遥游》中说大鹏展翅一飞冲天,借助的是外部的“风”,没有风它就飞不了了,换言之大鹏是有所依赖的,所以做不到真正的自由。庄子还讲了一个“相濡以沫,不如相忘于江湖”的故事,说两条快要干死的鱼在泥土里靠相互的唾沫苟活下去,还不如各自去到大江大河里逍遥快活。庄子极度推崇个人的自由,告诉你要遵从自己的内心,这个前提可能是要求你牺牲掉你的“本来所得”。
严格来讲,儒家的某些思想是反人性的,但是现代社会的发展、生产力的提升,反而恰恰离不开这种“反人性”的约束。每个人有内外的诸多限制,或者说诸多缺陷。这就会让人觉得,从本质上来说,以庄子为代表的这种“逍遥“的境界是人在现实中所无法达到的。但是有的时候理想之所以伟大,并不是因为它可以实现,恰恰是因为它的不可实现性。因为只有这样,它对人才具有更高的提升意义。陶渊明、苏轼他们正是以庄子这种逍遥思想为精神向导,才能留下《归去来兮辞》、《赤壁赋》这种千古名篇。
为什么“吃得苦中苦,方为人上人”的思想很可怕?
努力的目标不应该是为了过人上人的生活
吃得苦中苦,方为人上人
那如果以这一种目标去努力的话
你会发现是非常可怕的
因为你努力的目标
居然是爬在别人身上作威作福
那也就是说你所吃的一切苦
将来都要加倍的找补回来
那这是非常痛苦的
会进入到一个社会达尔文主义的恶性循环
因为每个人都有跌倒有摔跤的时候
每个人都有可能从强变弱的时候
即便你暂时强
还有比你更强的
那如果强者通吃一切
你作为人的尊严可能就会丧失
那些在社会竞争中处于优势的人
一定要知道
他们其实靠的并不单纯是自己的努力
还有一些大量的人所无法掌控的东西
时也,命也,运也
这些是人所无法掌控的
300年前
一个人会打篮球绝对什么都不是
但是生活在300年后的今天
一个人如果是篮球高手
他甚至能进NBA
就能够获取巨大的财富
所以最重要的是内心的充盈和内心的优秀
一个内心优秀的人
他就可以安之若素
泰然自若
与这个时代狭路相逢
努力的目标不是为了成为人上人,是为了能够内心平静
(摘自网络)
01现代计算机视觉入门之:什么是图片
如何写好一篇技术文档
完整PDF电子版请点击《如何写好一篇技术文档》
苏轼生平时间线(1036-1101)
什么是RAG?
RAG全称Retrieval-Augmented Generation,翻译成中文是“检索增强生成”。其中检索指的是“文本相似性检索”,生成指的是“基于大语言模型的生成型算法”,比如OpenAI的GPT系列,以及阿里的通义千问系列等等。完整去理解这个术语应该是:用文本语义相似性检索的结果,来丰富大语言模型的输入上下文,以此提升大语言模型的输出效果。RAG技术之所以重要,近几年热度持续上升,其主要原因还是受大语言模型影响,尤其大语言模型技术在实际使用过程中本身存在的一些缺陷。
大语言模型的缺陷
除去模型的复杂性对数据和算力的要求太高(这顶多算是门槛高,造成一般中小型公司无法入坑),大语言模型(LLM)在实际应用过程中有两个缺陷:
(1)知识的局限性
CV领域中常见的YOLO系列检测算法,模型参数量大概在百万~千万级别。而大语言模型参数量通常十亿起步,更复杂的甚至达到了千亿万亿级别。更多的参数量意味着模型能存储(学习)更多的知识,无论从知识深度还是广度都比传统的“小”模型要更优。但是,这个世界是复杂的,不同行业的知识千差万别,俗话说:隔行如隔山,这个在大模型技术中尤为突出。通常一些公司在训练大模型时,采用的数据主要来源于互联网,大部分都是公开的知识数据,模型从这些公开的数据中学习当前数据的基本规律,但是对于那些由于各种原因没有公开到网络上的垂直细分领域的知识数据,大模型在训练过程中完全无法接触到,这也导致模型在实际应用推理过程中,对特定领域问题回答效果不佳、甚至完全一本正经的胡说八道。下面是我向ChatGPT询问“车道收费软件程序无法正常运行如何处理?”,可以看到,ChatGPT在这种专业问题中表现不足,虽然回答的条理清晰(第一张图),但是并不是我们想要的答案(第二张图)。
<ChatGPT回答结果↑>
<标准答案↑>
(2)知识的实时性
大模型掌握的知识受限于训练它用到的数据,模型训练(迭代)一次消耗的时间相对较长(几个月甚至一年),很多知识数据虽然是公开的,但是由于时间关系,并不能及时被大模型掌握。比如前几天(2024/12/3)网络上出现了韩国总统尹锡悦突然发动戒严的新闻,你如果向一个11月份就上线的大模型问韩国的相关历史事件,这个戒严事件肯定不在回答之列,原因很简单,因为模型在训练过程中并没有相关数据。下面是我向ChatGPT询问“韩国近现代有哪些主要的政治事件?”,在它给出的回答中,可以看到回答的主要事件截止时间在2022年尹锡悦上台后不久,回答中没有更新的数据。
<ChatGPT关于韩国近代历史事件的回答↑>
提示工程的重要性
在2022年底ChatGPT刚出来不久,GitHub上就有一个非常火爆的项目仓库叫awesome-chatgpt-prompts(截止2024/12/15已经有114K星星),这个仓库核心就是一个README文件,里面包含了我们在使用ChatGPT时常用到的一些“提示词”。提示词的作用是告诉大模型一些上下文背景,让模型能够根据你的提示词来给出想要的回答。提示词完全使用自然语言编写,好的提示词能够得到更加准确的回答。下面给出两个例子,第一个是让ChatGPT充当Linux操作系统命令行终端(类似ssh工具),响应用户输入的Linux命令;第二个是让通义千问充当一个关键信息提取器,将两个人语音对话中的关键信息提取出来然后按指定格式输出。
<ChatGPT扮演Linux终端↑>
<给通义千问设置提示词↑>
<通义千问根据提示词给出的回答↑>
可以说如何用好大模型,提示词是关键。提示词的设计可以复杂,比如提供一些输入输出的示例,让大模型参考,也可以提供“思考”逻辑或者方向,给大模型提供一些回答问题的思路,当然也可以交代一些背景知识,让大模型“实时”去消化。
既然提示词如此重要,它能够丰富大模型问答上下文,让模型了解更多的背景知识,从而提升大模型的使用效果。那么我们能否使用类似提示词这种方式去弥补前面提到的那些大模型应用缺陷呢?答案是肯定的,这就是RAG采用的技术思路。针对“知识的局限性”和“知识的实时性”问题,我们可以借用类似“提示词”之手告诉大模型,让它能够在“外部补充数据”的上下文环境中,给出我们想要的答案,从而规避知识的局限性和实时性问题。
为了让大模型能够掌握额外的背景知识,我们引进了“外部补充数据”,那么我们应该如何获取这个外部补充数据呢?很明显这个获取的过程很关键,有两个原因:
1、外部补充数据一定要与用户query有关,而且相关性越高越好,否则就是误导模型思考,补充数据越详细越好,模型获取的外部信息就越充足。
2、我们事先并不知道用户需要query什么问题,所以获取外部补充数据一定是一个检索的过程,从一个大规模特定领域的非结构化数据集合中检索与query相关的部分,这个检索是实时性的,针对不同的query可能都需要这个操作。
现在我们将上一张图更新一下,大概可以修改成这样:
针对用户的每个query,我们先从“知识库”(大规模特定领域的非结构化数据集合,可随时更新)检索出与query相关的信息,然后再和原始query一起合并输入到大模型。目前这里的检索方式通常采用“文本语义相似性检索”,这个跟CV领域图像相似性检索类似,一般基于高维特征去做相似度匹配。
文本语义相似性检索
一般在讲语义相似性检索的时候,通常也会提到关键字检索,这是两种不同的文本检索方式。下面是两种方式特点:
1、语义相似性检索。基于文本内容含义去做匹配,算法能够理解句子(词语)的内在含义,然后找出意义与之相似的内容。比如“这个产品令人眼前一亮”和“这个产品设计很新颖”虽然文本内容本身不尽相同,但是其意义相似,那么算法认为它们相似度很高。类似的,“汽车”和“轿车”相似度很高,“跑步鞋”和“耐克”相似度很高,“晴朗的天”和“万里无云”相似度很高。
2、关键字检索。基于文本内容本身去做匹配,算法只匹配句子(词语)内容本身,“晴朗的天”和“万里无云”如果从关键字去匹配的话,相似度基本为零。在学习《数据结构和算法
》课程的时候,里面提到的“汉明距离”可以算作关键字匹配的一种方式,主要用来计算字符串之间的相似度。
我们从上面的解释可以了解到,语义相似性检索方式显得更加“聪明”,更贴近人类思考的方式,所以在RAG技术栈中,一般采用语义相似性检索的方式去获取前面提到的“外部补充数据”。文本的语义相似性检索一般基于“高维特征”去完成,大概思路就是事先对知识库中的文本内容进行特征编码,生成高维特征向量(通常128/256/512维度),最后存入专用向量数据库(比如Faiss/Milvus向量数据库),形成底库。在检索阶段,先对query文本使用相同的特征编码算法生成特征向量,然后使用该向量去向量数据库中检索前TOP N个相似特征,最后映射回前TOP N个原始文本内容。那么得到的这些原始文本内容,就和query文本在语义上存在很高的相似度。
上面图中,A和B是特征向量底库,C是query特征向量,最终C和A之间的相似度要比C和B之间更高,所以“今天万里无云,天气很好”可以匹配到“真是一个晴朗的天”。那么如何衡量特征向量之间的相似度呢?以2维向量为例(3维或更高维类似),可以把特征向量看做是二维坐标系中的一个点,最后计算两点之间的距离,通常有两种距离计算方式,一个叫“欧氏距离(直线距离)”,一个叫“余弦距离”。
欧氏距离越小,两个点越靠近,代表越相似(图中红色);余弦距离代表的是点与原点连线之间的夹角,夹角越小(余弦值越大,图中紫色),代表越相似。(关于特征编码,以及特征相似度计算可以参考之前的文章)。目前网络已经有很多开源的文本特征编码模型,针对不同国家语言,可以为其提取文本特征标识。下面是我对鲁迅的《故乡》全文做特征编码,然后去检索“我情不自禁地伤心起来。”这句话的例子,最后返回TOP 10个与之语义相似的句子,可以看到整体表现还算可以,尤其排名靠前的几个结果,基本和query句子的含义比较接近。
从“单阶段推理”到“两阶段推理”
我们现在回顾一下大语言模型的工作流程,基本上就是用户提供query问题输入(可以携带一些简单的上下文,比如历史对话记录),大模型直接给出回答,注意这里大模型完全基于训练时积累的经验给出的答案。这个可以看做是一个“端到端”的推理过程,我们称之为“单阶段推理”(可以类比CV领域中经典的YOLO系列检测算法)。那么相比较而言,RAG就是“两阶段推理”,问答系统先要从知识库中检索与用户query有关的信息,然后再与query一起,传入大模型,之后的流程就和单阶段推理一致。以此可以看出,RAG指的并不是具体哪一个算法或者技术,而是一套解决问题的技术方案,它需要用到文本特征编码算法、向量数据库、以及大语言模型等等。Github上有很多RAG相关的框架,都提供了灵活的接口,可以适配不同的文本编码模型、不同的向量数据库、不同的大语言模型。
总结RAG的优劣势和应用场景
1、RAG的优势
可以有效解决单纯使用大语言模型时碰到的一些问题,比如知识的局限性和实时性,能够解决大模型在垂直细分领域落地的难题,让大模型更接地气、给出的回答更贴近标准答案而不是一本正经的胡说八道。同时,让中小型企业可以基于开源大模型快速搭建自己的知识库问答(建议)系统,而无需对其进行二次训练或微调(算力和数据,包括大模型的训练门槛都是相当之高)。
2、RAG的劣势
引入了更多的技术栈,提升了系统的复杂性,无论开发还是后期维护工作量更高。同时,由于前期引入了“语义检索”的流程,涉及到准确性问题,一旦前期检索环节出问题,直接影响后面大模型效果。
3、RAG应用场景
RAG可以用在垂直细分领域的知识问答(建议)场景,对数据隐私要求比较高,同时对知识库实时更新有要求。当然除了本文介绍的这种基于知识库问答系统,类似的还可以用在基于数据库、基于搜索引擎等问答系统,原理基本类似。
什么是神经网络
(2019年文章)
大部分介绍神经网络的文章中概念性的东西太多,而且夹杂着很多数学公式,读起来让人头疼,尤其没什么基础的人完全get不到作者想要表达的思想。本篇文章尝试零公式(但有少量数学知识)说清楚什么是神经网络,并且举例来说明神经网络能干什么。另外一些文章喜欢举“根据历史交易数据预测房子价值”或者“根据历史数据来预测未来几天是否下雨”的例子来引入“机器学习/深度学习/神经网络/监督学习”的主题,并介绍他们的作用,这种例子的样本(输入X输出Y)都是数值,数字到数字的映射,简单易懂,但是现实应用中还有很多场景并非如此,比如本文后面举的“图像分类”例子,输入是图片并不是简单的数值输入。
分类和回归
我们平时讨论的机器学习/深度学习/神经网络大部分时候说的是“监督学习”范畴,监督学习应用最为广泛,也是神经网络发挥巨大作用的领域,因此,本文所有内容都是基于监督学习。从带有标签的样本数据中学习“经验”,最后将经验作用于样本之外的数据,得到预测结果,这就是监督学习。监督学习主要解决两大类问题:
(1)分类
分类很好理解,就是根据输入特征,预测与之对应的分类,输出是离散数值,比如明天是否下雨(下雨/不下雨)、短信是否是垃圾短信(是/否)、图片中包含的动物是猫、狗还是猴子(猫/狗/猴子)等等。分类模型的输出一般是N维向量(N为分类数),每个向量值代表属于此分类的概率。
如上图,根据样本数据(黄色圆形、蓝色正方形、绿色棱形),监督学习可以确定两条边界线,对于任何样本之外的数据(图中灰色正方形),可以预测它所属分类为B,对应的预测输出可以是[0.04, 0.90, 0.06],代表属于A类的概率为0.04,属于B类的概率为0.90,属于C类的概率为0.06,属于B类的概率最大,因此我们可以认为它的分类为B。请注意图中用来划分类型区域的两条虚线,同类样本并没有完全按照虚线分割开来,有黄色的圆形被划分到B类中,也有蓝色的正方形被划分到A类中。这种情况之所以出现,是因为监督学习得到的经验应该具备一定程度的泛化能力,所以允许学习过程中出现一定的误差,这样的学习才是有效的。
(2)回归
与分类相反,回归主要解决一些输出为具体数值的问题,比如明天的气温(20、21、30等)、明天股票开盘价(100、102、200等)。回归模型的输出一般是具体数值(包含向量,向量中包含每个具体的数值)。
如上图,根据样本数据(图中蓝色正方形,平面坐标系点),监督学习可以确定一条直线y=1.5x+1,对于任何样本之外的输入(Xn),可以预测对应的输出Y为1.5*Xn+1。请注意通过监督学习得到的直线y=1.5*x+1,事实上并不是每个样本都刚好落在该条直线上,大部分分布在直线周围。原因跟上面提到的一样,监督学习过程允许出现一定的误差,这样才是有效的学习。
学习的过程
不管是分类还是回归问题,监督学习都是从样本数据中学习经验,然后将经验应用到样本之外的数据。那么这个经验具体指什么?学习的本质是什么呢?
以上面回归问题为例,我们得到直线y=1.5*x+1的过程如下:
(1)确定样本数据呈直线分布(近似直线分布);
(2)设定一个目标函数:y=w*x+b;
(3)调整w和b的值,使样本数据点尽可能近地分布在直线周围(可以使用最小二乘法);
(4)得到最优的w和b的值。
以上是4步完成学习的过程,这个也是最简单的监督学习过程。至于其中“如何确定样本呈直线分布”、“如何判断目标函数为y=w*x+b”以及“如何去调整w和b的值,可以使样本数据点尽可能近的分布在直线周围”这些问题,后面一一介绍。
我们经常听到的深度学习中模型训练,其实指的就是学习的过程,最后输出的模型中主要包含的就是w和b的值,换句话说,训练的过程,主要是确定w和b的值,可以称这些参数为“经验”。
监督学习的过程就是找出X->Y的映射关系,这里的输入X可以称之为“特征”,特征可以是多维的,实际上X大多数情况都是多维向量,类似[1, 1.002, 0.2, …],输出Y称为“预测值”,预测值也可以是多维的,类似[0.90, 0.08, 0.02],比如前面提到的分类问题中,输出Y为多维向量,每个向量值代表预测对应分类的概率大小。
全连接神经网络
全连接神经网络由许许多多的“神经元”连接而成,每个神经元可以接收多个输入,产生一个输出,类似前面提到的X->Y的映射,如果输入是多维的,格式就是[x1, x2, …, xn]->Y(对于单个神经元来讲,输出都是一个数值)。多个神经元相互连接起来,就形成了神经网络,神经元的输入可以是来自其他多个神经元的输出,该神经元的输出又可以作为其他神经元的输入(的一部分)。下图为一个神经元的结构:
如上图所示,一个神经元接收[x1, x2, …, xn]作为输入,对于每个输入Xi,都会乘以一个权重Wi,将乘积结果相加再经过函数f作用后,产生输出Y。多个神经元相互连接之后,得到神经网络:
如上图,多个神经元相互连接起来组成全连接神经网络(图中只包含w参数,省略了b),图中神经网络一共包含3层(Layer1,Layer2和Layer3),上一层每个神经元的输出全部作为后一层每个神经元的输入,这种网络叫“全连接神经网络”(顾名思义,全连接的意思)。图中黄色部分就是两个完整的神经元结构,第一个神经元有三个输入(x1,x2和x3),分别乘以对应的权重w31,w32和w33,第二个神经元有四个输入(分别来自于Layer1层中的4个输出)。该神经网络可以接受一个3维向量作为输入(格式为[x1, x2, x3]),从左往右计算,最后输出一个2维向量(格式为[y1, y2])。对应它学习到的经验,可以用来处理符合如下映射关系的“分类”或者“回归”问题:
全连接神经网络是结构最简单的神经网络,相邻两层之间的神经元每个之间都有连接,因为结构最简单,因此通常以它作为入口来介绍其他结构更复杂的网络。注意,大部分神经网络并不是每个神经元都有连接关系,而且有些并不是严格遵从“数据从左往右移动”这种顺序。
神经网络中的矩阵计算
对于单个神经元的计算过程而言,是非常简单的,分三步:
(1)计算每个输入参数Xi和对应权重Wi的乘积;
(2)将乘积加起来,再加上一个偏移值b;
(3)最后将函数f作用在(2)中的结果上,得到神经元的输出。
但是对于神经网络这种包含大量的神经元而言,如何可以更加方便、代码中更简洁地去实现呢?答案是使用矩阵,线性代数搞忘记的同学也不要紧,这里仅仅是利用了“矩阵相乘”和“矩阵相加”的规则。
(1)矩阵相加
矩阵相加要求两个矩阵维度相同,矩阵中对应的数字直接相加即可,生成一个新的矩阵,维度跟之前一样:
(2)矩阵相乘
矩阵相乘要求第一个矩阵包含的列数和第二个矩阵包含的行数相同,M*N的矩阵乘以N*T的矩阵,得到M*T的一个新矩阵:
第一个矩阵A的第一行每个元素与第二个矩阵B的第一列各个元素相乘然后加起来,作为结果矩阵C中的第一行第一列,第一个矩阵A的第一行每个元素与第二个矩阵B的第二列各个元素相乘然后加起来,作为结果矩阵C中的第一行第二列,以此类推。上图中3*3的矩阵乘以3*2的矩阵,得到一个3*2的新矩阵。如果将上图7中A矩阵换成神经网络中的参数W(W11,W12,W22…),将B矩阵换成输入X特征(X1, X2, X3…),那么全连接神经网络中每一层(可以包含多个神经元)的计算过程可以用矩阵表示成:
如上图,使用矩阵我们可以批量操作。对于图4中第一层(Layer1)所有神经元的计算过程,可以通过图8一次性计算完成。图中W矩阵先和X矩阵相乘,再加上偏移值B矩阵,得到一个中间结果(也是一个矩阵),然后再将中间结果传给函数f,输出另外一个新矩阵Y,那么这个Y就是神经网络第一层Layer1的输出,它会作为下一层Layer2的输入,后面以此类推。注意,函数f接受一个矩阵为参数,并作用于矩阵中每个元素,返回一个维度一样的新矩阵,后面会提到。可以看到,之前需要计算4次f(w*x+b),现在只需要一次就可以了。
通过前面的介绍,可以得知,神经网络的训练过程就是找到最合适的W矩阵(多个)和最合适的b矩阵(多个)使得神经网络的输出与真实值(标签)最接近,这个过程也叫做模型训练或者调参(当然模型训练远不止这样,还有其他诸如超参数的确定)。
非线性变换
即使输入是高维向量,经过简单的W*X+b这样处理之后,输出和输入仍然呈线性关系。但是现实场景中大部分待解决的问题都不是线性模型,因此我们需要在输入和输出之间增加一个非线性变换,也就是前面多次提到的f函数(又称为激活函数)。由于各种原因(这里涉及到神经网络具体的训练过程,反向传播计算权重值,暂不过多解释),常见可用的激活函数并不多,这里举两个函数为例:
(1)Sigmoid函数
Sigmoid函数能将任意实数映射到(0, 1)之间,具体函数图像如下:
上图中Sigmoid函数将任意输入映射到(0, 1)之间的值,因此Sigmoid函数又经常被称为逻辑函数,常用于二分类预测问题,假设有两个分类A和B,对于任何输入特征X,Sigmoid返回值越趋近于1,那么预测分类为A,反之则为B。
(2)ReLu函数
ReLu函数很简单,返回值为max(x, 0),具体函数图像为:
上图中ReLu函数将任意输入的负数转换为0,其他输入原样输出。ReLu函数是目前深度学习中应用最多的激活函数,具体原因这里不做解释。这里需要说一下,深度学习/神经网络中有些东西并没有非常充足的理论依据,完全靠前人经验总结而来,比如这里的ReLu函数看似简单为什么在大部分场合下效果最好,或者神经网络训练中神经元到底如何组织准确性最高等等问题。
神经网络解决分类问题
经过前面的介绍不难得出,神经网络可以解决复杂映射关系的“分类”问题。将特征输入到神经网络,经过一系列计算得到输出。下图举一个形象的例子来说明神经网络如何解决分类问题:
上图显示一个和全连接神经网络同样结构的管道网状结构,从上到下有多个阀门可以调节控制液体走向(图中①),经过事先多次样本液体训练(使用不同品牌、不同酒精度、不同子型号的白酒),我们将阀门调节到最佳状态。随后将一杯白酒从最顶部倒入网状结构,最后经过管道所有液体会分别流进三个玻璃杯中(图中③)。如果我们将一杯五粮液倒入管道,理论情况所有的液体应该完全流进第一个玻璃杯中(图中左侧),但是实际上由于神经网络具备泛化能力,对于任何输入(包括训练样本),大部分时候不会跟正确结果100%一致,最终只会保证第一个玻璃杯中的液体最多(比如占85%),其余两个玻璃杯同样存在少量液体(图中右侧)。
那么现在有个问题,神经网络最后输出的是数值(或多维向量,向量包含具体数值),结果是如何体现“分类”的概念呢?本文最开始讲到过,分类问题最后都是通过概率来体现,某个分类的概率最高,那么就属于该分类,下图显示如何将数值转换成概率:
如上图所示,对于2分类问题,我们通常使用前面提到的Sigmoid函数将其转换成(0,1)之间的概率值,然后再根据概率值划分类别。对于N分类(N也可以为2),我们要使用另外一个函数Softmax,该函数接受一个向量作为参数,返回一个新向量,维度跟输入一致,新向量的每个值均分布在在(0, 1)之前,并且所有概率之和为1。注意该函数作用在整个向量上,向量中的每个值之间相互有影响,感兴趣的同学上网查一下公式。
图像分类任务
图像分类又称为图像识别,给定一张图,要求输出图中包含的目标类型,比如我们常见的“微软识花”、“识别猫还是狗”等等,这是计算机视觉中最典型的“分类”问题。图像分类是其他诸如“目标检测”、“目标分割”的基础。
(1)图像的定义
数字图像本质上是一个多维矩阵,常见的RGB图像可以看作是3个二维矩阵,矩阵中每个值表示对应颜色通道上的值(0~255),还有其他比如灰度图,可以看作是是1个二维矩阵,矩阵中每个值表示颜色的像素值(0~255)。
如上图所示,一张RGB全彩数字图片大小为180*200,对应3个矩阵,大小都是180*200,矩阵中的数值范围都在0~255。对于单通道灰度图而言,对应1个矩阵,大小也是180*200:
(2)使用全连接神经网络做图像分类
前面已经讲到如何使用全连接神经网络解决“分类”的问题,图像分类同样属于分类问题,因此也可以使用神经网络的方式解决,唯一的区别是前面提到的都是数值特征输入[x1, x2, x3, …],那么对于图像而言,该将什么输入给神经网络呢?答案是图像矩阵,图像矩阵中包含数值,将一个M*N的二维矩阵展开后,得到一个M*N维向量,将该向量输入神经网络,经过神经网络计算,输出各个分类概率。下面以“手写数字图像识别”为例,介绍全连接神经网络如何做图像分类。手写数字图像识别是深度学习中的一个HelloWorld级的任务,大部分教程均以此为例子讲解图像识别,下图为手写数字图片:
上图显示4张手写数字图片,分别为“5”、“0”、“4”、“1”,每张图片大小为28*28,即长宽都为28像素,图片都是灰度图像,也就是说每张图片对应1个28*28维矩阵,将该矩阵展开得到一个28*28维向量,直接输入到全连接神经网络中。从0到9一共10个分类,因此神经网络的输出是一个10维向量。
如上图所示,原始输入图片大小为28*28,将其展开成[784*1]的特征X传入神经网络。神经网络一共包含两层,第一层W矩阵大小为[1000*784],W*X之后得到大小为[1000*1]的输出,该输出作为第二层的输入X,第二层W矩阵大小为[10*1000],W*X之后得到大小为[10*1]的输出,该输出(经过Softmax作用后)即为数字0~9的概率。
注意上面定义的神经网络结构中,只包含两层(图中蓝色和绿色,黄色部分不算),第一层的W矩阵尺寸为[1000*784],这里的1000是随意设定的,可以是500甚至2000,它和神经元数量保持一致。第二层的W矩阵尺寸为[10*1000],这里的1000跟前面一样,这里的10是分类数,因为一共10个分类,所以为10,如果100分类,这里是100。神经网络的层数和每层包含的神经元个数都可以调整,这个过程就是我们常说的“修改网络结构”。
通过上面的方式做手写数字图片识别的准确性可能不高(我没有试验过),即使已经很高了它也不是一种非常好的方式,这种方式也许对于手写数字图片识别的任务很有效,但是对于其他图片比如猫、狗识别仍然很有效吗?答案是否定的,原因很简单:直接将整张图片的数据完全输入到神经网络中,包含的特征太复杂,或者噪音太多,这种现象可能在手写数字这种简单的图片中有效,一旦换成复杂的图片后可能就不行了。那么针对一般图像分类的任务,在将数据传到神经网络进行分类之前,我们还需要做什么呢?
(3)图像特征
图像特征在计算机视觉中是一个非常非常重要的概念,它在一定程度上可以当作图片的特定标识,每张图片都包含一些人眼看不到的特征。关于图像特征的介绍,大家可以参考我之前的一篇博客:https://www.cnblogs.com/xiaozhi_5638/p/11512260.html
在使用神经网络对图片进行分类之前,我们需要先提取图像特征,然后再将提取到的特征输入到全连接神经网络中进行分类,因此解决图像分类问题的正确神经网络结构应该是这样的:
如上图所示,在全连接神经网络之前增加了一个模块,该模块也是神经网络的一部分,同样由许许多多的神经元组成,但是可能不再是全连接这种结构了,它可以自动提取图片特征,然后将特征输入到后面的全连接网络进行分类,我们通常把这里的全连接网络称为“分类器”(是不是似曾相识?)。这样一来,全连接网络的输入特征大小不再是[784*1]了(图中黄色部分),而应该根据前面的输出来定。图中这种由全连接神经网络(分类器)和特征提取部分组合起来的神经网络有一个专有名词,叫“卷积神经网络”,之所以叫“卷积”,因为在提取特征的时候使用了卷积操作,具体后面介绍。
卷积神经网络
卷积神经网络中包含一个特征提取的结构,该结构主要负责对原始输入数据(比如图像,注意还可以是其他东西)进行特征提取、抽象化、降维等操作,它主要包括以下几个内容:
(1)卷积层
卷积层主要负责特征提取,它使用一个卷积核(一个小型矩阵)以从左到右、从上到下的顺序依次作用于原始输入矩阵,然后生成一个(或多个)新矩阵,这些新矩阵我们称之为feature maps。具体操作过程如下图:
如上图所示,图中绿色部分为原始输入矩阵,黄色矩阵为卷积核(一个3*3的矩阵),经过卷积操作后生成一个新的矩阵(粉色),该矩阵称为feature map。卷积核可以有多个,每个卷积核不同,同一个输入矩阵经过不同的卷积核处理之后会得到不同的feature map。因此在卷积层中,存在多个卷积核处理之后就会生成多个feature maps,这些feature map各不相同,每个都代表一定的特征。
如果原始输入矩阵是一张图片,经过卷积核处理之后,生成的多个feature maps虽然仍然是矩阵的形式,但是不能再把它们当作图片来对待。下图显示一张图片经过两个不同的卷积核处理之后生成的两个feature maps,我们用工具将这两个feature maps以图片的形式显示出来:
如上图所示,一张原始图片经过一次卷积处理之后,生成的feature map以图片的方式显示出来之后似乎还是可以人眼识别出来。但是,如果经过多次卷积处理之后,那么最终的feature map就无法人眼识别了。上图还可以看出,不同的卷积核处理同一张输入图片后,生成的feature map之间有差别。
这里再次强调,虽然经过卷积操作得到的feature maps仍然可以以图片的形式显示出来,但是它不在是我们通常理解中的“图片”了。虽然人眼看不再有任何意义,但是对于计算机来讲,意义非常重大。卷积层可以存在多个,一个卷积层后面可以紧跟另外一个卷积层,前一层的输出是下一层的输入。卷积层中的一些参数,比如卷积核矩阵中的具体数值,都需要通过训练得到,这个道理跟前面提到的W和b参数一样,也是需要通过训练去拟合。
(2)非线性变换(激活函数)
和前面讲全连接神经网络一样,经过卷积层处理之后生成的feature maps仍然需要进行非线性转换,这里的方式跟前面一样,使用常见的激活函数,比如ReLu函数作用在feature map上的效果如下图:
如上图,feature map经过激活函数处理之后,得到另外一个矩阵,我们称之为 Rectified feature map。根据前面介绍ReLu的内容,我们可以得知,该激活函数(max(0, x))将原feature map矩阵中的所有负数全部变成了0。
(3)池化层
只有卷积操作和激活处理还是不够,因为到目前为止,(Rectified) feature maps包含的特征数据还是太大,为了让模型具备一定的泛化能力,我们需要对feature maps进行降维,这个过程称之为池化:
如上图,池化层在原始feature maps上进行操作,还是按照“从左往右从上到下”的顺序,选择一个子矩阵(图中圆圈部分2*2,类似前面的卷积核),选取该子矩阵范围内最大的值作为新矩阵中的值,依次处理后最后组成一个全新矩阵,这个全新矩阵尺寸比原来的小。除了取最大值外,还有取平均值和求和的做法,但是经过前人实践证明,取最大值(最大池化)效果最好。
经过池化层处理之后的feature maps仍然可以以图片的方式显示出来,还是和前面一样,人眼已经分不清是啥了,但是对于计算机来讲意义重大。
如上图所示,一张feature map经过两种方式池化,取最大值和求和,分别得到不同的新矩阵,然后将新矩阵以图片的方式显示出来,可以看到差别还是非常大(虽然人眼已经分不清内容)。
通常情况下,卷积层后面不需要都紧跟一个池化层,可以经过多个卷积层之后再加一个池化层,也就是说,卷积和池化可以不按照1:1的比例进行组合。卷积神经网络中特征提取部分就是使用卷积层、激活处理、池化层等组合而成,可以根据需要修改相应网络层的数量(通常所说的“调整网络结构”)。最后一个池化层输出的结果就是我们提取得到的图像特征,比如最后一个池化层输出T个矩阵(feature maps),每个大小为M*N,那么将其展开后得到一个T*M*N维向量,那么这个向量就是图像特征。到这里应该就很清楚了,我们如果将这个特征向量传到一个“分类器”中,通过分类器就可以得到最终的分类结果,分类器可以使用前面讲到的全连接神经网络。
(4)全连接层(分类器)
其实看到这里的同学,如果前面的内容都看懂了,这块就不难了。图像特征已经得到了,直接将它输入到全连接神经网络中去,就可以得到最终分类结果。下图显示将一个手写数字图片传入卷积神经网络中的过程,先分别经过两个卷积层和两个池化层(交叉相连而成,图中忽略了激活处理等其他操作),然后将最后一个池化层的输出先展开再作为全连接网络的输入,经过两个全连接层,最终得到一个10*1的输出结果。
关于卷积神经网络的配图均来自:https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/
关于模型训练
一些深度学习框架会帮我们去做模型训练的具体工作,比如上面提到的w和b的确定,找出最合适的w和b尽量使预测值与真实值之间的误差最小。下面举个例子,使用tensorflow来优化 loss=4*(w-1)^2这个函数,找到最合适的w使loss最小:
如上图所示,我们学过的数学知识告诉我们,w等于1时loss最小,这个过程可以通过求导得出(导数等于0的时候)。那么使用tensorflow来帮我们确定w该是怎样呢?下面是使用tensorflow来优化该函数,确定最有w的值:
w = tf.get_variable(“w”, initializer = 3.0)optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)for i in range(5):optimizer.minimize(lambda: 4*(w-1)*(w-1))print(w.numpy())
1.4
1.0799999
1.016
1.0032
1.00064
我们可以看到,经过5次寻找,我们得到最优的w为1.00064,已经非常接近1了。这个过程其实就是深度学习框架训练模型的简单版本。
注意:
- 本篇文章没有涉及到具体模型训练的原理,也就是求W和b矩阵的具体过程,因为该过程比较复杂而且涉及到很多数学公式,读者只需要知道:模型训练的本质就是使用大量带有标签的样本数据找到相对比较合适的W和b矩阵,之后这些矩阵参数可以作用于样本之外的数据。
- 深度学习很多做法缺乏实际理论依据,大部分还是靠经验,比如到底多少层合适,到底用什么激活函数效果更好,很多时候针对不同的数据集(或者问题)可能有不同的答案。
- 除了名字相同外,深度学习中的神经网络跟人脑神经网络工作原理没有关系,之前以为有关系,所以取了一个类似的名字,后来科学家发现好像没什么关系,因为人脑太复杂。