深度学习

理解和使用深度学习网络

深度啤酒设计师

这篇文章来自Ieuan Evans,他创建了一个非常独特的例子,将深度学习与LSTM和啤酒结合起来。(请负责任地喝酒!)
我喜欢精酿啤酒。如今,有太多的选择,可能会让人不知所措,这是个大问题!最近我发现自己在酒吧里仔细挑选啤酒时变得懒惰起来,我倾向于只买名字听起来最好的啤酒。
我开始想:MATLAB能否自动分析一串名字,为我选择一种啤酒?为什么止步于此?我能让MATLAB为我设计一种独特的啤酒吗?
在这个示例中,我将展示如何对给定名称的啤酒风格进行分类,如何生成新的啤酒名称,甚至还将自动生成一些品尝记录。

Happe Hill Hefeweizen

漂亮的模糊效果来自图像处理工具箱。

“一种浓郁果香的传统比利时Marthe酵母。酒体饱满,带有坚果的气息和略带甜味的水果味。”

(matlab生成的名称和品尝笔记。不坏!)


导入数据

本例中有两个数据源可用: 从Kaggle加载精酿啤酒数据。
Rng (0) filename = "beers.csv";dataKaggle = readtable(文件名,'TextType','string','Encoding','UTF-8');
查看数据的随机样本。
idx = randperm(size(dataKaggle,1),10);disp (dataKaggle (idx[“名称”“风格”)))
的名字 风格
_______________________________________ _______________________________________
“隆(2014)” “Saison /农舍麦芽酒”
“耀西的花蜜” “加州普通/蒸汽啤酒”
“1327 Pod的ESB” “特别/强苦(ESB)”
“Parade Ground Coffee Porter” “美国波特”
“永恒的黑暗” “比利时浓啤酒”
La Frontera高级IPA “美国音标”
“峡谷奶油啤酒” “奶油啤酒”
“引领比利时风格的智慧” “Witbier”
“Squatters Hop Rising双IPA” “美国双IPA /皇家IPA”
“Good Vibes IPA” “美国音标”
加载剑桥啤酒节的数据,除了名称和风格,还包含品酒笔记。从文本分析工具箱中使用HTML解析工具提取数据。
Url = "https://www.cambridgebeerfestival.com/下载188bet金宝搏products/cbf44-beer";代码= webread(url);tree = htmlTree(code);
提取啤酒名称。
subtrees = findElement(树,"span[class=""productname""]");name = extractHTMLText(subtrees);
提取品尝笔记。
subtrees = findElement(tree,"span[class=""tasting""]");notes = extractHTMLText(subtrees);dataCambridge = table(name,notes);
把品尝笔记想象成文字云。的 wordcloud “文本分析工具箱”中的函数直接从字符串数据创建词云。
图wordcloud(笔记);标题(“口味”)

分类啤酒类型 首先,使用Kaggle数据,创建一个长短期记忆(LSTM)深度学习模型,对给定名称的啤酒风格进行分类。使用词汇云可视化啤酒样式的分布。
textData = dataKaggle.name;labels = categorical(dataKaggle.style);图wordcloud(标签);标题(“啤酒风格”)
正如您在字云中看到的,样式非常不平衡,有些样式只包含几个实例。为了改进模型,去掉实例数小于5的样式,然后将数据分成90%的训练分区和10%的测试分区。
(数据准备的细节可以在完整的示例文件中找到)
将每个啤酒名转换为一个整数序列,其中每个整数代表一个字符。 答案是啤酒的风格。
YTrain = labelsTrain;YTest = labelsTest;YTrain (1:6)
Ans = 6x1字符串数组
美国淡啤酒
美国音标
美国Double / Imperial IPA
美国音标
燕麦片的
接下来创建深度学习网络架构。使用单词嵌入层学习字符嵌入并将整数映射到向量。使用双向LSTM (BiLSTM)层来学习啤酒名称中字符之间的双向长期依赖关系。
为了学习BiLSTM层的隐藏单元之间更强的相互作用,包括一个额外的大小为50的全连接层。使用dropout层来帮助防止网络过拟合。
numFeatures = 1;embeddingDimension = 100;numCharacters = max([XTrain{:}]);numClasses = nummel(类别(YTrain));layers = [sequenceInputLayer(numFeatures) wordEmbeddingLayer(embeddingDimension,numCharacters) bilstmLayer(200,'OutputMode','last') dropoutLayer(0.5) fullyConnectedLayer(50) dropoutLayer(0.5) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
指定培训选项。
选项= trainingOptions('adam',…“MaxEpochs”,100年,…“InitialLearnRate”,0.01,…“GradientThreshold”,2,…“洗牌”、“every-epoch’,……ValidationData, {XTest,欧美},…“ValidationFrequency”,80年,…“阴谋”、“训练进步”,…“详细”,假);
培训网络。
beerStyleNet = trainNetwork(XTrain,YTrain,layers,options);
在这里,我们可以看到模型过拟合。该模型能有效地记忆训练数据,但对测试数据的泛化效果不佳。
这也许是意料之中的:很多啤酒的名字在风格方面并没有透露太多,所以网络没有什么可做的。有些很容易分类,因为名字中包含了啤酒的风格。
例如,你认为下面这些是什么类型的啤酒?你能打败分类器吗?
Idx = [1 4 5 8 9 10 12 14 15 17];textDataTest (idx)
Ans = 10x1字符串数组
“一知半解的季节”
“分裂的天空”
“亲爱的Kolsch”
“阿拉斯加琥珀”
“加州啤酒”
”兄弟姐妹“蒸汽
《愤怒的果园苹果姜》
“长叶”
《本季金发女郎》
“拉”
比较你的猜测和网络的预测以及正确的标签
YPred =分类(beerStyleNet,XTest);disp(table(textDataTest(idx),YPred(idx),YTest(idx),'VariableNames',["Name" "预测" "True"]))
的名字 预测 真正的
______________________________ ______________________________ ______________________________
“一知半解的季节” Saison /农家乐啤酒 Saison /农家乐啤酒
“分裂的天空” 美国琥珀/红啤酒 美国音标
“亲爱的Kolsch” Kolsch Kolsch
“阿拉斯加琥珀” 美国琥珀/红啤酒 酿造
“加州啤酒” 美国琥珀/红窖藏啤酒 美国琥珀/红窖藏啤酒
”兄弟姐妹“蒸汽 美国淡麦酒 加州普通/蒸汽啤酒
《愤怒的果园苹果姜》 苹果酒 苹果酒
“长叶” 慕尼黑Helles拉格啤酒 美国音标
《本季金发女郎》 奶油啤酒 美国金发啤酒
“拉” 果蔬啤酒 美国Double / Imperial IPA
那么,我可以用这个网络为我选择啤酒吗?假设测试集包含酒吧中所有可用的啤酒。我喜欢喝印度淡啤酒。让我们来看看这些啤酒中哪些是国际淡啤酒。这可以是包含“IPA”的任何类标签。
classNames = string(beerStyleNet.Layers(end).Classes);idx = contains(classNames,"IPA");classNamesIPA = classNames(idx)
Ans = 5x1字符串数组
“美国音标”
“美国音标”
“美国白IPA”
“比利时音标”
英国印度淡啤酒
[YPred,scores] = category (beerStyleNet,XTest);Idx = contains(字符串(YPred),“音标”);select = textDataTest(idx)
让我们来看看这些酒中有多少是IPA。
(包含(string(YTest(idx)),"IPA")))
accuracyIPA = 0.7241
查看按评分排序的前10个预测。更令人兴奋的是,让我们排除所有名字中含有“IPA”的名字
topScores = max(scores(idx,:),[],2);[~,idxSorted] = sort(topScores,' descent ');selectionSorted = select (idxSorted);%除去名称中含有IPAidx = contains(selectionSorted,["IPA" "印度淡啤酒"]);selectionSorted(idx) = [];selectionSorted (1:10)
Ans = 10x1字符串数组
《美国白痴啤酒》(2012)
“Citra面临“
《公海上的跳跃》(卡利普索)
“孟加拉虎”
剑铁天鹅啤酒
“26”
“伊西斯”
“En Parfaite harmony”
“分别为圣”
“红鲑Maibock”
看起来是一些很好的建议!
生成新的啤酒名称

我们建立了一个深厚的网络,为我找啤酒做了合理的工作。我的下一个愿望是用MATLAB为我设计一种啤酒。首先它需要一个名字。为此,我将使用LSTM网络进行序列预测,它预测序列的下一个字符。为了改进模型,我还将包括来自英国剑桥啤酒节的啤酒名称。验证数据在这里没有帮助,所以我们将在所有数据上进行训练。

textData = [dataKaggle.name;dataCambridge.name];
为了帮助生成,将所有空格字符替换为“·”(中间的点)字符,在开头插入文本字符的开始,在结尾插入文本字符的结束。
startOfTextCharacter = compose("\x0002");whitespaceCharacter = compose("\x00B7");endOfTextCharacter = compose("\x2403");
对于预测器,在啤酒名称之前插入文本字符的开头。对于响应,将文本字符的结尾附加在啤酒名称之后。在这里,响应与预测因子相同,平移了一个时间步长。
textdatappredictors = startOfTextCharacter + replace(textData," ",whitespaceCharacter);textDataResponses = replace(textData," ",whitespaceCharacter) + endOfTextCharacter;
XTrain = cellfun(@double, textdatappredictors,'UniformOutput',false);YTrain = cellfun(@(Y) categorical(cellstr(Y')'),textDataResponses,'UniformOutput',false);
查看预测器和响应的第一个序列。
XTrain {1}
Ans = 1x9
2 80 117 98 183 66 101 101 114
YTrain {1}
Ans = 1x9分类
P u b·b e r␃
构建网络架构。
numFeatures = 1;numClasses = number (categories([YTrain{:}]));numCharacters = max([XTrain{:}]);layers = [sequenceInputLayer(numFeatures) wordEmbeddingLayer(200,numCharacters) lstmLayer(400) dropoutLayer(0.5) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
指定培训选项。
选项= trainingOptions('adam',…“InitialLearnRate”,0.01,…“GradientThreshold”,2,…“洗牌”、“every-epoch’,……“阴谋”、“训练进步”,…“详细”,假);
培训网络。
beerNameNet = trainNetwork(XTrain,YTrain,layers,options);

在这里,网络可能看起来不是特别好。同样,这也是意料之中的。为了获得较高的准确率,网络必须准确地生成训练数据。我们不希望网络过度拟合因为网络只会生成训练数据。
类生成一些啤酒名称 generateText 函数,该函数包含在文章末尾的完整示例文件中。
numBeers = 30;generatedBeers = strings(numBeers,1);for i = 1:numBeers generatedBeers(i) = generateText(beerNameNet,startOfTextCharacter,whitespaceCharacter,endOfTextCharacter);结束
有时,网络可能只是从训练数据中预测啤酒名称。移除它们。
idx = ismember(generatedBeers,textData);generatedBeers(idx) = [];
查看生成的啤酒。
generatedBeers
generatedBeers =
“Firis琥珀”
“Sprecian Claisper”
“沃瑟淡啤酒”
“Ma’s Canido冬季啤酒”
“跳激动”
"蜂蜜牛奶啤酒"
“Slowneck啤酒”
"CuDas Colora Lager"
“没有赖尔比尔森啤酒”
“Dark Light IPA”
生成品尝笔记
我们有了啤酒名,现在需要一些品酒笔记。与名称生成器类似,根据剑桥啤酒节笔记创建一个品尝笔记生成器。
textData = dataCambridge.notes;
与前面一样,为了帮助生成名称,将所有空格字符替换为“·”(中间的点)字符,在开头插入文本字符的开始,在结尾插入文本字符的结束。
同样,定义网络架构,指定训练选项,并训练网络。 (详细信息可在本文最后的主示例文件链接中找到)
使用示例末尾列出的generateText函数生成一些品尝笔记。
numBeers = 5;for i = 1:numBeers generatedNotes = generateText(beerNotesNet,startOfTextCharacter,whitespaceCharacter,endOfTextCharacter)结束
“这款淡色啤酒有一种很好的坚定的淡色和浓郁的酒体,回味悠长。”
“这是一款酒体醇厚的皇家黑啤,带有轻微而饱满的烘焙麦芽味,回味中还能感受到丝质黑啤的精致。Unfined。”
“淡铜味的传统苦啤酒,有很好的麦芽风味。酿造出最好的英国水獭马里斯酒的味道,有龙舌兰果味和苦甜的回味。”
"用多种香料酿造的黑啤。Unfined。”
“混合麦芽和水果开始煮沸。”
完美!我现在可以开始酿造我自己的完美啤酒了。您可以多次运行代码以生成更多的名称和品尝注释。迄今为止,我最喜欢的设计是:
Hopky Wolf印度啤酒
“这款双IPA有浓郁的麦芽味,柚子、橙子和柠檬的味道,并有潜在的花香和帐篷的味道。均衡的香气反映了它的口感。它是用Fuggle和Golding啤酒花混合制成的。”
现在我只需要MATLAB来自动化酿造过程…

版权所有2018 The MathWorks, Inc.
获取MATLAB代码


|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。