使用TensorFlow和LSTM RNN生成烹饪食谱:分步指南

2020-06-18 23:20:57

我用TensorFlow训练了一个字符级的LSTM(长期短期记忆)RNN(递归神经网络),它使用TensorFlow对100K食谱数据集进行了训练,它建议我用洋葱泡芙糕点草莓汤做奶油苏打水,用西葫芦味茶做西葫芦味茶,用三文鱼慕斯做牛肉和斯蒂尔顿沙拉。

🎨烹饪食谱生成器演示-在您的浏览器中以交互方式尝试该模型。

🏋🏻‍LSTM模型培训流程-查看模型是如何培训的。

🤖交互式机器学习实验库-查看有关对象检测、草图识别、图像分类等的更多实验。

本文详细介绍了如何使用TensorFlow2和Kera API在Python上实际训练LSTM模型。

在几个小时的训练中,我们的字符级RNN模型将学习英语语法和标点符号的基本概念(我希望我能学得那么快!)。它还将学习如何生成食谱的不同部分,如📗[食谱名称]、🥕[食谱成分]和📝[食谱说明]。有时食谱名称、配料和说明书会很有趣,有时很愚蠢,有时很有趣。

📗[名称]橙子俱乐部茶三明治饼干🥕[配料]·1杯(2根)无盐黄油,软化·1杯糖果';糖·1/2杯亚麻籽粉·1/2杯去壳南瓜籽(山核桃,漂烫切片)·2茶匙香草提取物📝[说明书]▪︎预热烤箱至华氏350度·▪︎在一个大碗里混合蛋糕混合物,牛奶,鸡蛋和糖。搅拌至混合光滑,但不粘稠。用铲子将面饼洒在平底锅的底部。撒上糖,均匀地摊开。烤20分钟。从烤箱中取出,放在架子上冷却。上菜时要加巧克力。

📗[名称]蘑菇配扁豆炖葱和番茄🥕[配料]·1汤匙橄榄油·3瓣大蒜,捣碎·犹太盐·1 1/2磅瘦碎火鸡·1杯去皮粗酸苹果·2汤匙切碎的大蒜·1茶匙小茴香粉·1/2茶匙辣椒·1茶匙切碎的新鲜百里香·3/4杯切碎的新鲜罗勒。切成两半,垂直切片,分成粗略的排骨·3汤匙无盐黄油·2杯切碎的马苏里拉奶酪·1/4杯磨碎的帕尔马干酪·1/4杯准备好的罗勒酱📝[说明]▪︎在平底锅里搅拌橄榄油、大蒜、百里香和1茶匙盐;用中火炖熟。离开暖气。加入罗勒,将汤烤2分钟。同时,在平底锅中用中高火加热4到4英寸的植物油。(▪︎)同时,在平底锅中用中高火加热4到4英寸的植物油。加入橄榄油,大蒜,1/2茶匙盐和1/2茶匙胡椒,经常搅拌,直到煮透

⚠️本文中的食谱只是为了好玩和学习而生成的。食谱不是用来真正烹饪的!如果你想要一些真正的食谱,你可以去🥦主页_完整_of_食谱Instagram频道。

假设您已经熟悉了递归神经网络(RNNs)的概念,特别是长短期记忆(LSTM)体系结构。

ℹ️如果您对这些概念还不熟悉,我强烈推荐您参加由Andrew Ng编写的课程深度学习专业化认证(Deep Learning Specialization On Coursera)。阅读安德烈·卡帕西的“递归神经网络的不合理有效性”一文也可能是有益的。

从高层次上讲,递归神经网络(RNN)是一类深度神经网络,最常应用于基于序列的数据,如语音、语音、文本或音乐。它们用于机器翻译、语音识别、语音合成等。RNN的关键特征是它们是有状态的,并且它们具有内部存储器,其中可以存储序列的一些上下文。例如,如果序列的第一个单词是他,则RNN可以建议下一个要说话的单词,而不是仅仅说(以形成他说的短语),因为关于第一个单词的先验知识他已经在内部存储器中。

令人兴奋的是,RNN(尤其是LSTM)不仅可以记住单词到单词的依赖关系,还可以记住字符到字符的依赖关系!实际上,序列由什么组成并不重要:它可能是单词,也可能是字符。重要的是,它们形成了一个时间分布的序列。例如,我们有一个字符序列[';H';,';e';]。如果我们询问LSTM下一步要做什么,它可能会建议<;stop_word>;(意思是,构成单词he的序列已经完成,我们可以停止),或者它还可能建议一个字符l(意思是,它试图为我们构建Hello序列)。这种类型的RNN称为字符级RNN(与词级RNN相对)。

在本教程中,我们将依靠RNN网络的这种记忆特性,并且我们将使用LSTM的字符级版本来生成烹饪食谱。

让我们浏览几个可用的数据集,并探究它们的优缺点。我希望数据集满足的要求之一是,它不仅应该有配料列表,还应该有烹饪说明。我还想让它有每种配料的量度和数量。

🤷Epicurence-带评级和营养的食谱(仅限~20000份食谱,如果能找到更多会很好)

让我们尝试使用食谱方框数据集。食谱的数量看起来足够多了,而且还包含了配料和烹饪说明。看看RNN是否能够学习配料和说明之间的联系是很有趣的。

您可以按照以下几个选项来试验本教程中的代码:

您可以直接在浏览器中使用GoogleColab进行实验(不需要本地设置)。

您可以在浏览器中使用活页夹中的Jupyter笔记本进行实验(不需要本地设置)。

我建议使用GoogleColab选项,因为它不需要对您进行任何本地设置(您可以直接在您的浏览器中进行实验),而且它还提供了强大的GPU培训支持,这将使模型的培训速度更快。您还可以尝试使用训练参数。

#用于训练模型和使用数据集的包。导入TensorFlow作为TF导入matplotlib。pylot as plt import numpy as np import json#Utility/helper软件包。导入平台导入时间导入路径库导入操作系统。

首先,让我们确保我们的环境设置正确,并且我们正在使用TensorFlow的第二个版本。

让我们使用tf.keras.utils.get_file加载数据集。使用get_file()实用程序很方便,因为它可以为您处理开箱即用的缓存。这意味着您只需下载数据集文件一次,然后即使您再次启动笔记本中的相同代码块,它也会使用缓存,并且代码块的执行速度会更快。

总计521128drwxr-xr-x 7224五月13 18:10.drwxr-xr-x 4128五月18 18:00.-rw-r--r-1 20437五月20 06:46许可证-rw-r--r--1 53355492五月13 18:10食谱_raw.zip-rw-r--r--1 49784325五月20 06:46食谱_raw_nosource_ar.json-rw-r。--r--1 93702755 5月20 06:46菜谱_RAW_NOSOURCE_fn.json。

如您所见,数据集由3个文件组成。稍后,我们需要将这3个文件中的信息合并到一个数据集中。

def load_Dataset(SILENT=FALSE):#我们要合并的数据集文件列表。DATASET_FILE_NAMES=[';Recipe_raw_nosource_ar.json';,';Recies_raw_nosource_epi.json';,';Recipe_raw_nosource_fn.json';,]DataSet=[]用于DataSet_FILE_NAMES中的DataSet_FILE_NAME:DATASET_FILE_PATH=f';{CACHE_DIR}/DataSets/{DATASET_FILE。使用OPEN(DATASET_FILE_PATH)作为DATASET_FILE:json_data_dict=json。LOAD(DATASET_FILE)json_data_list=list(json_data_dict.。VALUES())DICT_KEYS=[json_data_list[0]中关键字的关键字]DICT_KEYS。Sort()DataSet+=json_data_list#此代码块输出每个数据集的摘要。如果静默==FALSE:Print(DATSET_FILE_PATH)PRINT(';=';)Print(';,Number of Example:';,LEN(JSON_DATA_LIST),';\n';)Print(';Example Object Key:\n';,DICT_KEYS,';)Print(';Example Object:\n';)Print(';Example Object:\n';,json_data_list[0],';\n';)打印(';必填键:\n';)打印(';标题:';,json_data_list[0][';title';],';\n&39;)打印(';配料:';,json_data_list[0][';配料';],';\n';)打印(';,json_data_list[0][';说明';])打印(';\n\n';)返回数据集DataSet_RAW=Load_DataSet()。

示例./tmp/datasets/recipes_raw_nosource_ar.json=Number:39802示例对象键:[';配料';,';说明';,';图片_LINK';,';标题';]示例对象:{';标题';:';慢煮鸡肉和饺子';,';配料';:[';4去皮、去骨鸡胸脯广告';2汤匙黄油广告,2汤匙(10.75盎司)浓缩奶油鸡汤广告,1洋葱,细丁广告,2(10盎司)包装冷藏饼干面团,撕碎广告广告#39;,#39;广告##39;],##39;说明书#39;:';将鸡肉、黄油、汤和洋葱放入慢火锅中,加满足够盖住的水。\n盖上盖子,在高温下煮5到6个小时。大约在上桌前30分钟,将撕裂的饼干面团放入慢火锅中。煮到面团不再生在中间。\n';,';Picture_link&39;:';55lznCYBbs2mT8BTx6BTkLhynGHzM.S&39;}必需键:标题:慢煮鸡肉和饺子配料:[';4去皮去骨鸡胸肉广告#39;,#39;2汤匙黄油广告#39;包装冷藏饼干面团,撕成碎片[说明:将鸡肉、黄油、汤和洋葱放入慢火锅中,加满足够的水,盖上盖子,用高压锅煮5到6小时。大约在上桌前30分钟,将撕裂的饼干面团放入慢火锅中。煮到面团在图片链接中不再是生的:25323示例对象键:[';center../tmp/datasets/recipes_raw_nosource_epi.json=Number';,';说明';,';图片_链接';,';标题';]示例对象:{';配料';:[';12蛋白';,';12个蛋黄';,';]示例对象:{';配料';:[';12蛋白';,';12蛋黄';,';1 1/2杯糖黑麦威士忌,3/4杯黑麦威士忌,12个蛋清,3/4杯白兰地,1到2杯朗姆酒,1到2杯重奶油,轻轻搅拌的装饰:磨碎的肉豆蔻],';Picture_link。将蛋白打至变硬,逐渐加入3/4杯糖。放在一边。把蛋黄打得又稠又淡,加入另外3/4杯糖,加入黑麦威士忌。好好调和。将蛋清混合物和蛋黄混合物混合,加入白兰地和朗姆酒。把混合物打好。上桌时,将稍加搅拌的重奶油折入蛋奶酒中即可。(如果需要更稀薄的混合物,加入未搅拌的重奶油。)。在蛋酒顶部撒上肉豆蔻调味。\n将蛋清咀嚼至变硬,逐渐加入3/4杯糖。放在一边。把蛋黄打得又稠又淡,加入另外3/4杯糖,加入黑麦威士忌。好好调和。将蛋白混合物拌入蛋黄混合物中,加入

RNN不理解对象。因此,我们需要将食谱对象转换为字符串,然后转换为数字(索引)。让我们从将食谱对象转换为字符串开始。

为了帮助我们的RNN更快地了解文本的结构,让我们在上面添加3个地标。我们将使用这些独特的标题、配料和说明标志来分隔每个食谱的逻辑部分。

以下函数将Recipe对象转换为字符串(字符序列),以供以后在RNN输入中使用。

def Recipe_to_String(Recipe):#该字符串是作为食谱的一部分出现的,所以我们需要清理它。NOIZE_STRING=';广告';标题=配方[';标题';]配料=配方[';配料';]说明=配方[';说明';]。对于配料中的配料:配料=配料,拆分(';\n&39;)配料_STRING=';';。如果配料:配料_STRING+=f';·{配料}\n';INSTRUCTIONS_STRING=';';中的说明请替换(Noize_STRING,';';';),则说明:Instruction=Instruction。如果指令:Instructions_String+=f';▪︎{Instruction}\n';Return f';{STOP_WORD_TITLE}{TITLE}\n{STOP_WORD_FIRECTIONS}{FORDIONS_STRIPTING}{STOP_WORD_INSTRUCTIONS}{INSTRUCTIONS_STRING}';

食谱#1-📗慢锅鸡肉饺子🥕·4去皮去骨鸡胸肉2汤匙黄油·2罐浓缩奶油鸡汤·1洋葱,切碎·2包(10盎司)冷藏饼干面团,撕成碎片📝▪︎将鸡肉、黄油、汤和洋葱放入慢火锅中,加满足够的水覆盖。▪︎盖上盖子,煮5到10盎司的饼干面团,然后把鸡肉、黄油、汤和洋葱放入慢火锅中,加满足够的水。盖上盖子,煮5到10盎司的冷藏饼干面团,把鸡肉、黄油、汤和洋葱放进慢火锅里,装满足够的水覆盖。大约在上桌前30分钟,将撕裂的饼干面团放入慢火锅中。烹饪直到面团在中心不再是生的。菜谱2-📗Awome慢锅烤锅🥕·2(10.75盎司)罐装浓缩奶油蘑菇汤·1(1盎司)包干洋葱汤混合·1 1/4杯水·5 1/2磅慢锅烤📝▪︎,混合奶油蘑菇汤,干洋葱汤混合物和水。将炖肉放入慢炖锅中,涂上汤混合物。▪︎用高温度煮3到4小时,或用低温度煮8到9小时。菜谱#3-📗红糖肉饼🥕·1/2杯包装红糖·1/2杯番茄酱·1 1/2磅瘦牛肉·3/4杯牛奶·2个鸡蛋·1/2茶匙盐·1/4茶匙磨碎黑胡椒粉·1个小洋葱。切碎·1/4茶匙姜末·3/4杯碎盐饼干屑📝▪︎预热烤箱至华氏350度(摄氏175度)。在一个5x9英寸的面包平底锅上轻轻涂上油。▪︎将准备好的面包平底锅底部的红糖按下,将番茄酱撒在糖上。▪︎在搅拌碗中,彻底混合所有剩余的配料,并将其成形为一条面包。放在番茄酱的上面。▪︎在预热的烤箱中烘焙1小时,直到果汁清澈。

出于好奇,让我们在数据集中间的某个位置预览食谱,看看它是否具有预期的数据结构:

📗菜豆Ragoút🥕·6盎司扁豆(法国细绿豆),横向修剪和对半·1(1磅)袋冷冻毛豆(豆荚中的大豆)或1 1/4杯冷冻去壳毛豆,未解冻·2/3杯切碎的洋葱·2个大蒜丁香,切碎·1个土耳其月桂叶或1/2个加州月桂叶·2(3英寸)新鲜迷迭香树枝。

..