【技术】通过梯度下降逆向工程获取食品中不同成分的含量

这是一个外国人突发奇想(xiande danteng),用技术去了解包装食品各种成分含量的记录文章,文末附代码链接。

为了学习新的东西,我产生了一些奇怪的想法并写下这篇文章。这是一个小型的实验,我猜了包装食品中每种成分的不同含量。基于成分表和营养成分标签,我把这个任务表述成一个线性回归问题,以成分百分比作为参数。为了执行优化(梯度下降),我使用了最近很流行的官方推荐的深度学习库,PyTorch。

pytorch链接:http://pytorch.org/

我喜欢下厨,但并不总是有时间做饭。当我做的时候,我试着用一种非常科学的方法。例如,我喜欢简化并解密老奶奶食谱。在这个过程中,我可能必须控制好食物的数据,特别是营养数据(也就是碳水化合物,蛋白质,脂肪,盐等)。

在这个实验中,我试图通过使用大多数包装食品都带有的营养成分表来找到食谱中缺失的成分百分比。我的直觉告诉我,这样有足够的数据尝试会找到实际的配方。

注意:我们当然还有其他方法可以找到成分是什么,但是在这个大家都使用Alchemy的时代,为什么不在这个问题上使用梯度下降呢?

让我们以使用了棕榈油的Nutella为例。

成份如下:

糖、棕榈油、榛子粉、可可、脱脂奶粉、低矿物质乳清、磷脂作为乳化剂、香草精:人造香味剂。

权重

在我的线性回归模型中,参数(权重)是不同成分的克数:

  • w1是100gNutella中糖的量,
  • w2是100gNutella棕榈油的量,
  • 等等…

在某些情况下,一些百分比是已知的。欧洲Nutella就是这种情况,我们知道健康成分(榛子粉,可可等)的数量。在这种情况下,权重被设定为固定值,不可训练。

输入和输出

现在的营养成分标签:

每个营养成分成为训练的观察和例子(x,y)。

我们以全脂肪(Total Fat)成分为例,它产生了一个(x,y)元组。

x是包含每种成分中脂肪百分比的行向量:

  • x1是糖中脂肪的百分比(0%)
  • x2棕榈油中脂肪的百分比(100%)

这些还很简单。但是对于某些成分来说,很难猜测它的构成(比如卵磷脂,lecithin)。对于这个实验,我使用了了美国农业部的营养数据库,其中包含大部分基本成分的信息。

注意:有这个数据库并不意味着万事大吉了,因为营养成分的变化很大(比如榛子粉有不同的品种,你可以选择烘烤加工过的或者没有烘烤过的,可可也可以选择没有加工过的或者低脂的…)

最深的一层神经网络的另一面,y是一个标量,包含最终产品中的脂肪量。这些信息可以很容易地在营养成分表中找到: Nutella每份12克脂肪,或者使用更加文明的营养标识系统:31%(法国)

由于这个标签非常冗长,我们可以得到大约十个(x,y)样本。

训练

当然,在模型中,线性单位没有偏置。在食品配料中没有未知的东西,所有的东西都以总量的权重总和来计算。

在PyTorch中声明所有这些是相对容易的(这是我第一次用它),这个库是简单明了,我想我现在理解为什么那么多人疯狂安利它了。现在,我们可以减少原始的L2损失吗?不,为了它收敛于一个合理的局部最小值,我们必须在模型上设置很多限制条件,比如可可的量不能是负数。

特定领域的约束

  • 质量不能为负(我是认真的)
  • 固定某些权重(当它的百分比已知时)
  • 质量总和必须等于100g
  • 并且,重量要按降序排列(食品成分在包装上也按降序排列)

其中一些约束在更新权重时强制执行,另一些则通过损失函数中的“炼金”技巧来实施。

我用整个数据集(批量梯度下降)来计算每一步的损失函数。结果如下:

成分:糖(50.8%),棕榈油(19.7%),榛子粉(13.0%),可可(7.4%),脱脂奶粉(6.6%),乳化剂(1%*)

(*)乳化剂保持在1%以下(只是一种添加剂)

我承认得到的结果并没有什么令人眼前一亮的点。但我认为,实现的过程往往比结果更重要,希望你喜欢它!

附:花生巧克力成分

我还试图了解著名的Reese花生巧克力杯的成分。

这个任务非常困难,,没有人知道10种不同的成分的比例。

有两种复合成分,每种都有自己的成分列表:牛奶巧克力涂层和花生酱填充物。

成分:牛奶巧克力(62%)[糖(20.3g),可可脂(16.0g),可可块(6.3g),无脂牛奶(6.3g),乳脂(6.3g),乳糖(6.3g)乳化剂(0.3g)]花生馅(38%)[花生(18.7g),葡萄糖(18.7g),盐(0.7g)]

代码:https://github.com/jctestud/food-reverse-engineering

原文发布于微信公众号 - ATYUN订阅号(atyun_com)

原文发表时间:2017-12-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我和未来有约会

Silverlight制作逐帧动画 v2 - part2

Silverlight制作逐帧动画 v2 - part2 在这里完善了一下算法,加入了fps的机制进去。 private string[] ...

1886
来自专栏张善友的专栏

弹出式模态窗体选择文本控件

2006年就要到来了,最近比较忙,很少更新blog,今天发一个模态窗体选择文本控件辞旧迎新.新年在发几个asp.net2.0 webPart控件同各位分享: ...

1907
来自专栏xingoo, 一个梦想做发明家的程序员

【插件开发】—— 6 SWT 复杂控件使用以及布局

前文回顾: 1 插件学习篇 2 简单的建立插件工程以及模型文件分析 3 利用扩展点,开发透视图 4 SWT编程须知 5 SWT简单控件的使用与布局搭...

2349
来自专栏跟着阿笨一起玩NET

从sql server 中读取二进制图片

391
来自专栏自由而无用的灵魂的碎碎念

小项目分享---混色器

编写代码的同志们一般懂美术的就少了,偶也是,什么色轮、三维加色等等。虽然看过一些书籍(如内田广由纪的《配色基础原理》),不过还是一知半解的。

973
来自专栏菩提树下的杨过

Silverlight:利用异步加载Xap实现自定义loading效果

关键点: 1.利用WebClient的DownloadProgressChanged事件更新下载进度 2.下载完成后,分析Xap包的程序集Assembly信息 ...

18610
来自专栏跟着阿笨一起玩NET

treeview 绑定文件夹和文件

451
来自专栏大内老A

开发自己的Data Access Application Block[下篇]

上接:[原创] 我的ORM: 开发自己的Data Access Application Block - Part I 4. Database 下面来介绍重中之重...

2236
来自专栏木宛城主

曾今的代码系列——自己的分页控件+存储过程实现分页

项目里面的测试代码,仅供参考 LoginByAjax <title>Ajax登陆</title> <script src="Scripts/c...

1855
来自专栏hbbliyong

socket 通信 多线程调用窗体(委托)的几个知识点,记录在案,以备查阅

1.socket 通信传输汉字的方法:Encoding.GetEncoding("GB2312").GetString(Receivebyte) 发送接收都这样...

2737

扫码关注云+社区