前言
大家好,我是沐浴在曙光下的贰货道士 。随着人工智能技术日新月异的迅猛发展,gpt
等生成式预训练模型如雨后春笋般遍地开花,在各个领域展现出蓬勃的生命力和令人叹为观止的应用。尽管AI
的出现为我们的日常开发带来了极大的便利,但同时也引发了一系列诸如前端已死的连锁焦虑。
作为曾经有囫囵吞枣地涉略过一些零零散散深度学习知识的我,愚以为:当今时代,人工智能的发展空前绝后,为我们带来了前所未有的机遇和挑战。我们应该积极迎接人工智能带来的挑战,并将其转化为我们自身的优势。也许,作为前端开发者,我们能利用AI
去做点什么。思绪恍惚间,这篇文章横空出世。
本文主要分为两大部分:
- 对
前端已死
这类观点的探讨(蹭一小波热度,也是我写这篇文章的一个理由
) - 前端生成
风格迁移
图片的效果展示、原理、实现、展望及前端AI
的应用场景分析
我擅长总结,乐于分享,但创作是一件费心费力的事,有些更重要的事情,等着我去学习。本文将是我今年最后一篇文章,在此,沐浴在曙光下的贰货道士 向大家说声抱歉,感谢大家的支持。我们,明年再见!
浅谈前端已死
众说纷纭
前段时间随着gpt
等生成式预训练模型的层出不穷,一些人开始提出前端已死
的观点,引发了激烈的探讨和争议。这一观点认为,生成式预训练模型可以自动生成代码,从而威胁到前端开发,使得前端开发岗位面临挑战。
正方
- 技术发展: 新的技术和工具的出现可能减少了前端开发的一些繁琐工作。例如,低代码/无代码平台和自动化工具可以使非技术人员也能够快速生成网站和应用程序的基础结构和样式,创建简单的网站和应用程序,减少了从零开始开发的工作量。这使得一些简单的任务可以更快地完成,从而减少了对前端开发人员的需求。
- 全栈开发趋势: 全栈开发者可以同时处理前端和后端任务,这可能导致一些人认为专门的前端开发不再必要。全栈开发者在某些项目中可以完成整个开发流程,包括数据库设计、后端逻辑和前端实现。前端门槛低,现在很多后端都能通过自学前端知识,完成一些比较简单的前端页面交互,这就使得前端的地位显得十分尴尬。
- 疫情冲击: 近几年,全球范围内的疫情对许多小公司带来了巨大的冲击,导致了一系列的倒闭和裁员。在这个不幸的背景下,前端岗位的就业市场变得更具挑战性。
反方
- 定制化需求: 尽管有许多低代码/无代码平台前赴后继的涌现,但某些项目和应用程序仍然需要定制化的前端开发。这些项目可能涉及复杂的交互逻辑、动画效果、数据可视化等需求,需要专业的前端开发人员来实现。定制化的前端开发能够满足不同行业、不同企业的独特需求,因此前端开发依然具备市场需求和发展空间。
- 用户体验的重要性: 前端开发在用户体验方面发挥着重要作用。随着数字化时代的发展,用户对于产品和服务的期望也越来越高。前端开发人员负责设计和实现交互界面,优化页面加载速度,提升用户的操作流畅性和满意度。无论是网站还是移动应用程序,用户体验是吸引用户、留住用户的关键。因此,前端开发在提供出色用户体验方面具有不可替代的重要性。
- 多平台应用需求: 随着智能手机、平板电脑和其他智能设备的普及,用户对于跨平台应用的需求也越来越高。前端开发人员可以使用各种跨平台开发框架和技术,来开发适用于多个平台的应用程序。这种能力使得前端开发不仅局限于网页,而是可以在各种平台上进行应用开发,从而拓宽了前端开发的领域。
我的看法(小菜鸡视角,求同存异,不喜勿喷
)
为什么会出现这种声音?
- 供大于求: 近几年随着疫情的影响,小公司纷纷倒闭,大公司放缓脚步。前端从业人员达到饱和,新鲜血液却不断涌入,这就造成了狼多肉少的局面。
- 一传十,十传百,感同身受者一呼百应,老鸟也跟风玩梗唱衰。
前端不会死
- 前端的地位无法被撼动: 生成式预训练模型的出现确实让一些简单的前端开发任务自动化成为可能,但这些并不能完全取代前端开发的重要性。前端开发需要具备一定的审美能力,不仅仅是写代码,还涉及用户体验、交互设计、性能优化等方面。此外,前端开发人员在项目中扮演着至关重要的角色,需要与产品、
UI
、后端等其他团队成员紧密合作,共同完成项目。在项目开始前,我们可以通过分析产品需求、思考和评估需求合理性(40m大刀
)、探讨页面交互细节、确定后端数据结构及完成技术选型等方式,来提前规避开发过程中可能会遇到的潜在问题,而这些是自动化开发工具所不具备的。 - 抓住机遇,直面挑战,化压力为动力: 一些简单、重复性的任务可能会被自动化工具替代,但这也为前端工程师提供了机会。我们可以面向自动化工具开发,将更多的精力投入到更具备挑战性和创造性的工作上,比如优化用户体验、研究前沿技术等。
前端已死的观点在一定程度上是夸大了生成式预训练模型对前端开发的影响。虽然技术的发展会对行业产生一定的影响,但前端开发作为一个重要的角色,仍然具有广泛的需求和发展空间。随着技术的不断演进,前端开发者需要保持学习和适应能力,不断提升自身的技术水平和创新能力,以应对行业的变化和挑战。
前端开发不会被AI
取代,GPT
远没有我们想象的那么强大(gpt4体验卡
)
- 精准性: 对于稍稍复杂些的问题,
gpt
生成的答案有待商榷,需要开发者去明辨是非。即使我们不断地引导它朝着正确的方向前进,但它依然会沉浸在自己的世界中,自娱自乐,循规蹈矩,固步自封。如下所示,gpt4
给出的封装好的toFixed
方法,其实是存在问题的。因为js
中所有涉及到小数运算的方法,都会存在误差。由于此前就有讨论过这个问题,在此不展开细聊。如果有不明所以的小伙伴,烦请移步🔥🔥🔥自从学会这些奇技淫巧,日常开发可以快乐地摸🐟了。 - 时效性: 由于
gpt
是基于2021
年9
月之前的数据进行训练,所以在gpt4
未开启联网功能之前,无法知晓此时间轴之后发生的事情。
- 逆推性: 大预言模型存在一种逆转诅咒 的通病,即使它学会
A
是B
,也无法得出B
是A
的结论。
破局之道
- 嘲笑卷王、质疑卷王、理解卷王、成为卷王、超越卷王: 提高自身的核心竞争力;
- 避免自我安慰式的无效学习:
我已经很努力了, 我已经很强了
,避免心理作用引导的自我安慰,以及避免使用第三方框架开发带来的温床心理。需要带有明确目的,有规划地去学习,不可漫无目的,囫囵吞枣。最好学习那些能在日常开发中用到的知识,测试也能在不知不觉中帮你验证学习成果。 - 做一份与众不同的简历(
突出自己的核心优势
): 一个一个去罗列做过的项目以及使用到的技术,这种流水账式的简历是不可取的。如果要我现在写一份简历,相比于千篇一律的项目经历和技能优势,我可能会更倾向于加入以下几点:
js
**荣誉上:**
`硕士学位`,`多次`获得`校级奖学金`
`连续多次`获得公司`月度优秀员工`称号
**工作上:**
时间观念强,规划合理,经常`提前完成`任务,并`分担`其他小伙伴的开发任务
`独立`开发对外mes系统,(`谨慎,一定要充分理解,避免前后不一`)充分理解业务背景和需求, 具备一定的产品前瞻性
`主动承担`离职小伙伴的开发项目及日常维护
愿意`加班`,会在工作之外`博览群书`(包括技术、沟通等相关书籍)
对公司具有极高的`忠诚度`,不会轻易跳槽
**性格上:**
勤于学习,善于总结,乐于`分享`,在掘金上发布了多篇不温不火的文章,并被多个公众号转载
具备一定的`自我反思`能力,不限于工作,更包括学习、生活和做人
`毅力惊人`,曾在考研期间(包含过年)三个月内成功瘦身70余斤
具备一定的`领导力`(能让自己的某些观点或建议,在整个小组甚至其他团队中盛行,便是领导力)
`技能方面因人而异,贵在真实, 面试会围绕简历提问。本人才疏学浅,就不做展示了`
`可以依据面试公司的要求,去填写个人技能以及项目经历(有可能会存在和面试公司一拍即合的情况)`
前端与AI
的花火
风格迁移实现效果
操作指南(电脑性能鉴定器, 如果发生内存不足的情况,不要慌张,先拍个照,发个朋友圈
)
- 选择待转换图片
- 选择风格图片
- 控制图片的高度、选择是否将风格图片转换为方形输入以及设置风格图片的权重
- 点击风格迁移按钮,一键生成图片
效果一览(界面比较简洁)
1. first blood:
2. double kill:
缺陷
- 风格迁移的效果差强人意,模型的泛化能力有待增强
- 风格迁移的结果存在不可预知性,我们只能猜测出大概的模样,这也是图像处理领域的通病
改进
- 使用
GAN
训练模型,加载预训练好的GAN
模型,构建模型的输入和输出(可以从国内外顶级期刊入手
)
技术背景
细数如白驹过隙的时光,大概有三年没做AI
了。讲解这些技术背景的文章数不胜数,本文不想再做重复的工作,不如以自己的理解,聊聊对这些技术的看法。如果本文提到的知识存在错误或者缺陷,欢迎广大掘友们在评论区中指出。
卷积神经网络
卷积神经网络是一种深度学习模型,其设计灵感来源于人脑的视觉系统。为此,我们需要理解,我们的视觉系统是如何运作的。Genius is one percent inspiration and ninety-nine percent perspiration
,人类的认知能力在某种程度上是与生俱来的,但也受到后天的环境和经验的影响,爱迪生如此,仲永更是如此。人类在出生时已经具备一些基础的认知能力,例如感知、注意力、记忆和学习等。这些能力是人类大脑固有的特点,通过基因和生物发展形成。新生儿具有一定的感知能力,能够感知声音、触觉和视觉刺激,并能对一些基本的模式和面孔作出反应。
假定一个穿着背带裤,梳着中分,打着篮球的帅哥迎面走来,从未见过坤坤的人,能认出这位帅哥就是家喻户晓的坤坤 吗?答案是否定的。人虽然具备一定的感知能力,但是在他/她的数据库中,并没有关于坤坤 的认知,他/她只会认为哇,眼前的男人好帅哦
。那么,他/她最后是如何识别出坤坤的呢?
- 数据集收集、划分及预处理 :要想识别坤坤,必须得具备来自男神不同角度不同状态下的照片(
对于视频而言,就是每一帧图片
)、非坤坤的图片(可以来自于人脑记忆中的数据库,也可以来自于包括众多小帅和小美在内的其他人类图片。如果不提供非坤坤的图片,那么人脑识别坤坤这项学习任务,将会变得毫无意义。此时,给定任意一张人类图片,人脑都会识别为坤坤。
)和标签(二分类,这张图片对应的男神是/不是坤坤
):包括唱歌的坤坤、跳舞的坤坤、rap
的坤坤、打篮球的坤坤、傲娇的坤坤等。坤坤所处的环境、他的穿着、姿势这些上下文信息,都有助于我们更好地理解和确认坤坤的身份。而这些数据集会按照一定比例,划分为训练集
(占据较大的比例,供我们学习并识别坤坤
)、验证集
(验证人类的学习成果,识别出错后,人类会思考如何提升识别坤坤的能力
)和测试集
(考试,是坤坤or不是坤坤, 评估人类学习成果的泛化能力
),参与到人类识别坤坤的任务中。如果这些图片过少,我们可以通过裁剪、旋转、平移、缩放、加入噪声等方式来增加数据集,从而提高我们识别坤坤的准确度; - 参数初始化,接收图片输入: 他/她接收到学习识别坤坤的任务,而在学习之前,他/她可能需要补充一些食物,看看电视,打打游戏,释放压力,来酝酿学习情绪。待一切准备就绪之后,人脑会随机采取某种学习方法,接收来自坤坤的视觉信号,感受来自坤坤五光十色的像素信息;
- 特征选择/提取: 从提取坤坤的边缘特征,到提取坤坤的面部特征、肤色、发型、眼睛、嘴巴、鼻子等局部特征,人类的视觉系统会将它们组合起来,形成一个整体的认知,这就是特征提取 的过程(
哦,原来坤坤是一个人,而且还是一个男人
)。而在特征提取 的过程中,人类的视觉系统会赋予这些特征一个权重(可能服装作为无效特征,发型作为低权重特征,而👀、👃、👂具有更高的权重
),具有较高权重的特征会被保留,而具有较低权重/无效的特征则会被舍弃。由于舍弃了一些无关紧要的特征,而保留了那部粪至关重要的特征,就大大降低了人类学习并识别坤坤的时间。假如坤坤换发型了,此时的人类仍然能准确地识别出坤坤(虽然具有较低权重的部粪特征发生了变化,但是还有其它很多具有较高权重的特征,用于识别坤坤
),这一过程就被称作特征选择。局部结合整体,这样就对坤坤有了一个大致的认知; - 反向传播,优化网络超参数 :在学习之初,他/她随机按照某种方法学习,膜拜了一批来自坤坤的美图(
正向学习
),此时给定一张带有差弧
标签的图片,他/她最后却给出坤坤
的错误答案(被坤坤的美貌所吸引,满眼坤坤,无法自拔
)。为了早日提高坤坤识别的精准度,人类会调整学习姿势,并根据反馈结果,确立新的学习方法(反向传播 )。这就好比,我们位于一座险峻的顶峰,通向谷底的道路有无数条(不借助工具/不被阻挡的情况下,直接滚下去,能最快到达谷底,也能产生无数条路线,手动滑稽
)。但什么时间我们该前往哪个方向(遇见猛兽请绕行
),什么时间我们要加速下降(看到了曙光
),什么时间我们要缓步下降(长途跋涉
),这些都是我们经过一次次尝试后,需要深思熟虑的问题,这样才能得出一个最优解。吃一堑,长一智,经过无数次错误洗礼的训练,我们已经足够强大了,能够精准地识别坤坤/非坤坤了。
在学习识别坤坤的过程中,也可能会遇到一些极端情况:
- 欠拟合: 在训练集和测试集上都表现不好,无法达到准确识别坤坤的效果。解决方法是提高模型的复杂程度、增加更多的特征表达及降低正则化约束等方法;
- 过拟合: 在训练集上表现巨好,但在测试集或新数据上无法准确识别坤坤。解决方法是降低模型复杂度、减少特征数、使用正则化约束、增加训练集数据、使用
dropout
及提前结束训练等方法。
大致梳理下卷积神经网络的训练流程吧:
- 在训练的过程中,
CNN
通过反向传播算法, 来调整卷积核和各类超参数的值,使得模型能够更好地拟合训练数据。 训练数据中的图像和对应的标签被用来计算损失函数,然后通过优化算法来最小化损失函数,使CNN
能够学习到更好的特征提取和分类能力。 CNN
通过一系列的卷积层,来自动地提取图像中的特征,免去传统手动设计特征提取器的步骤。 卷积层使用一组称为卷积核的小型滤波器,将其放在图像上滑动,计算出每个位置的特征响应。然后,在输出的每张特征图上应用激活函数,为模型添加非线性表达能力。卷积的整个过程,类似于我们观察图像时,通过眼睛的视觉窗口来捕捉图片的局部特征;- 通过池化层,
CNN
可以对激活后的特征图进行降采样。 池化层可以将特征图中的每个小区域合并成一个单独的值,减少特征图的尺寸,同时保留重要的特征信息,这样可以减少模型对图像的位置变化和噪声的敏感性; - 通过全连接层,
CNN
将特征图转换成一维向量,然后通过全连接层进行分类或回归等任务。 全连接层就像是我们的大脑,将之前提取的特征整合起来,做出最终的判断或预测。
生成对抗网络
GAN
由两部分组成:生成器和判别器。它们通过对抗的方式相互学习,以生成逼真的新样本。我们可以把生成对抗网络比作一个画家和一个鉴赏家之间的游戏。生成器就像是一个画家,它尝试从随机噪声中,画出逼真的齐白石赝品。而判别器就像是一个鉴赏家,它要区分画家创作的作品是齐白石真迹还是赝品(双兔傍地走,安能辨我是雄雌?
)。
训练开始时,画家随机创作出一些作品,鉴赏家会对这些作品进行判断,然后告诉生成器,这些作品都是赝品。得到鉴赏家的反馈后,画家会尝试努力改进自己的创作能力,生成更加逼真的赝品,以欺骗鉴赏家。同时,鉴赏家也会不断学习,提高自己辨别赝品的能力。
随着训练的进行,画家和鉴赏家会相互竞争、相互提升。画家希望创作的作品越来越逼真,以骗过鉴赏家;而鉴赏家希望越来越准确地判断真假赝品,不被画家欺骗。最终,当画家创作的作品达到以假乱真的地步,鉴赏家也无法区分真假时,我们就得到了一个训练有素的生成对抗网络模型。
风格迁移
风格迁移算法这篇文章通俗易懂,妙笔生花,我就不重复介绍了,干脆借花献佛放在这里。掘友们喝杯奶茶,静下心来认真读一读,定能有所收获。
核心代码解析
本项目基于vue2
+ tensorflow.js
框架实现,适用于任意风格的图片做风格迁移。整个风格迁移模型是我在网上找的,具体地址忘记了,完整代码放在 我的github上,欢迎star
。有兴趣的掘友们可以下载下来,安装依赖,运行查看效果。
js
`1. 使用预训练好的Inception-v3模型作为风格网络,得到风格图片的特征表示`
`2. 如果设置的风格比率不为1,那么风格图片的特征表示,就是以风格图片和内容图片分别作为风格网络输入,`
`得到的特征的加权组合(此时风格图片和内容图片都作为风格,参与到风格网络中)`
`3. 如果设置的风格比率为1,那么风格图片的特征表示,就是以风格图片作为风格网络输入,得到的特征`
`4. 得到图片的风格特征后,加载预训练好的卷积神经网络作为迁移网络,以内容图片和风格图片作为网络输入,得到输出`
async onTransfer() {
let bottleneck = await tf.tidy(() => {
return this.inceptionStyleNet.predict(
tf.browser
.fromPixels(this.styleImg)
`将像素值转换为浮点数`
.toFloat()
`将图片的像素值,归一化到 [0,1] 范围内`
.div(tf.scalar(255))
`添加一个额外的维度以匹配模型的输入形状`
.expandDims()
)
})
`用于在下一个浏览器渲染帧执行一个操作,有点类似与vue的$nextTick()`
await tf.nextFrame()
if (this.styleRatio !== 1.0) {
const identityBottleneck = await tf.tidy(() => {
return this.inceptionStyleNet.predict(
tf.browser
.fromPixels(this.contentImg)
.toFloat()
.div(tf.scalar(255))
.expandDims()
)
})
const styleBottleneck = bottleneck
bottleneck = await tf.tidy(() => {
const styleBottleneckScaled = styleBottleneck.mul(
tf.scalar(this.styleRatio)
)
const identityBottleneckScaled = identityBottleneck.mul(
tf.scalar(1.0 - this.styleRatio)
)
return styleBottleneckScaled.addStrict(identityBottleneckScaled)
})
`用于释放张量占用的内存资源`
styleBottleneck.dispose()
identityBottleneck.dispose()
}
await tf.nextFrame()
const stylized = await tf.tidy(() => {
return this.transformeNet
.predict([
tf.browser
.fromPixels(this.contentImg)
.toFloat()
.div(tf.scalar(255))
.expandDims(),
bottleneck
])
`从输出中去除额外的维度`
.squeeze()
})
`将风格化的图像张量转换为像素,并在画布上显示`
await tf.browser.toPixels(stylized, this.$refs.canvas)
bottleneck.dispose()
stylized.dispose()
}
两种风格的图片迁移思路扩展(特殊)
原本打算做一个适用于单风格和多风格图片迁移的网页应用,但由于最近项目加急,也有些更重要的事情等着我去处理,暂且就先搁置吧。在此简单地说下思路,后续如果有空了,再看是否把这部分的代码给补上。两种风格的图片迁移,其实是上述场景的一种特殊情况。 在上述代码中,如果有设置风格比率,风格特征为风格图片作为风格网络输入
和内容图片作为风格网络输入
得到特征的加权组合。如果我们要对两种风格的图片进行风格迁移,那么此时得到的风格特征,就是以风格图片A作为风格网络输入
和风格图片B作为风格网络输入
所得特征的加权组合,然后将内容图片和得到的风格特征作为预训练好的卷积神经网络的输入,最后将结果展示到canvas
上。讲到这里,想必小伙伴们已经跃跃欲试了呢。
深度学习从新手到放弃的建议:
- 吴恩达---机器学习B站视频
- 周志华机器学习 (
西瓜书
)
前端做AI
如何做?
前端如果想做AI
, 可以从以下几个步骤入手:
训练深度学习模型:
如果对深度学习领域怀抱浓厚的兴趣,对python
语言有一定的了解,且具备一些深度学习知识的小伙伴,可以在阿里云上购买GPU
,训练属于自己独有的深度学习模型(浏览器通常不具备足够的计算资源和内存来支持高效的深度学习训练,烧显卡,耗性能,电脑容易崩,一般将模型的训练过程放在专门的计算机或云服务上进行 );如果个人条件不允许的小伙伴,也可以在自己感兴趣的深度学习领域上,搜索国内外顶级期刊,看其是否有提供开源的model
(一般存放在github
上。如果使用tensorflow.js
作为前端开发框架, 则必须提供使用tensorflow
深度学习框架开发的模型)。选取合适的开发框架:
tensorflow.js、brain.js、ml5.js等;- 加载预训练好的深度学习模型;
- 依据开发框架提供的
api
,构建训练模型对应网络的输入和输出;
应用场景:
1. 集各类图像处理功能于一体的应用
- 图像分类
- 超分辨率重建
- 去水印
- 老旧照片修复
- 去模糊
- 去马赛克
- 图像生成(为商家提供卡通代言形象,结合
自然语言处理
,可以生成语义化的图片) - 目标识别
- 行为检测
- 图片融合
- 风格迁移
2. 其他各种领域上的应用(如视频上的行为检测
、音频上的语音识别
等)
参考文献
结语
往期精彩推荐(强势引流):
大概就这样吧~