低内存实例分段
将实例分段 web 应用程序部署到 google cloud
机器学习模型是内存密集型的。我当前的 web 应用程序至少消耗 1GB 的内存。这使得它很难部署到云上。
想到的直接解决方案是增加 VM 实例的内存。但是我不想花更多的钱。毕竟,这是一个附带项目。
所以我想出了一个办法。它实际上是受杰森·安蒂奇的 deoldify 的启发。在运行他的机器学习模型之前,Jason 使用渲染因子来缩小图像并将其转换为正方形。
我认为在这里应用同样的思想可以减少内存需求。
解决方案
简而言之,这就是解决方案。很大程度上取自这里的。
我们缩放到大小为targ
的正方形。targ
本质上就是 Jason 在 deoldify 中提到的渲染因子。
如果渲染因子太高,可能会导致 OOM 错误。太低的话,结果的分辨率会很差。
实际上这看起来很简单。首先,我们将图像缩放到一个大小为targ
的正方形。然后我们对缩放图像进行推理。推理的结果通过_unsquare
函数传递。这将我们的正方形大小的图像转换为原来的大小。
此后,我们终于可以在大多数云平台上部署,而不会出现任何面向对象的问题。如果你得到一个 OOM 错误,只要减少渲染因子。
我将使用这里描述的 web 应用程序作为起点。
我们需要修改app.py
脚本来实现上面描述的run_inference_transform
函数。修改后的版本在 Github 上。
有许多方法可以获得谷歌云的推广积分。所以我将在这个项目中使用他们的服务。我的计划是,我所做的一切都将由这些免费学分支付:)。
我在 google cloud 上创建了一个项目,并最终部署工作。谷歌云文档写得很好——但我还是会出错。我发现这个回购非常有用。
像往常一样,我创建了一个 shell 脚本来实现我们在终端中需要做的事情。
一旦我们在 google cloud 上部署了这个,detectron2 模型终于可以工作了。输出的分辨率低于输入,但一切都符合 2G 内存的限制。
在用docker stats
构建之后,我可以确认这种方法使用的内存要少得多。在我的本地计算机上,它在峰值时使用 1.16 GB 的内存。而之前的方法使用超过 2GB(大约。2.23 GB)。
你可以点击访问谷歌云实例分割 web 应用。
原载于 2020 年 7 月 26 日https://spiyer 99 . github . io。
LSTM-FCN 心脏病学
具有完全卷积网络(LSTM-FCN)的长短期记忆是 FCN 的增强,其已经被证明在对时间序列序列进行分类的任务上实现了最先进的性能
心电图(来源:https://i.ytimg.com/vi/HWzACHkCi3U/maxresdefault.jpg
我们将致力于在包含两种不同类型心电图(ECG)的数据库上应用该算法,并看看这种新模型是否可以帮助检测猝死风险高的患者。
LSTM-FCN 建筑
https://ieeexplore.ieee.org/stamp/stamp.jsp?tp= LSTM-FCN 建筑(来源:&ar number = 8141873
该算法由两部分组成:LSTM 块和具有 3 个卷积层的 FCN 部分。
LSTM 部分
长短期记忆递归神经网络是对普通递归神经网络的一种改进,它具有消失梯度问题。LSTM 神经网络通过将选通函数结合到其状态动态中,解决了普通递归神经网络中常见的消失梯度问题。想了解更多关于 LSTM 网络的信息,你可以阅读克里斯托弗·奥拉写的这篇的好文章。
除了 LSTM 模块,这部分还包括一个维度混洗。同时,完全卷积模块将时间序列视为具有多个时间步长的单变量时间序列,所提出的架构中的 LSTM 模块将输入时间序列视为具有单个时间步长的多变量时间序列。这是通过维度混排层来实现的,维度混排层调换了时间序列的时间维度。长度为 N 的单变量时间序列在转换后将被视为具有单一时间步长的多变量时间序列(具有 N 个变量)。维度混洗通过减少一个数量级的训练时间来提高该模型的效率。
FCN 部分
我们使用时间卷积网络作为全卷积网络(FCN)分支中的特征提取模块,这意味着我们在这些层中的每一层上应用一组 1D 滤波器(滤波器大小分别为 128、256 和 128),以捕捉输入信号在动作过程中如何演变。一个基本的卷积模块包括一个卷积层,接着是批量归一化(用于提高网络的速度、性能和稳定性),接着是一个激活函数,这里是一个整流线性单元(ReLU)。如果你想了解更多关于卷积层和 CNN 模型的信息,可以看看我关于 CNN 架构的文章。
最后,在最后的卷积块之后应用全局平均池。它用于在分类之前减少模型中的参数数量。
全局池层和 LSTM 块的输出被连接并传递到 softmax 分类层。
数据集
猝死高风险患者和健康对照受试者的心电图记录
我们的数据集分为两部分:一部分用于模型训练,另一部分用于测试。训练将在 23 个序列上进行,测试将在 1189 个序列上进行,这些序列是心电图(ECG)。心电图是一种通过测量心脏的电活动来检查心脏功能的测试。我们有两种不同类别的心电图:一种对应于猝死风险高的患者,另一种对应于健康受试者。
这个数据集被命名为 TwoLeadECG,是 UCR 数据集的一部分,你可以从这里下载。
基线
作为判断 LSTM-FCN 模型结果的参考的算法是 k-最近邻(k-NN)。选择这种算法是因为它是一种既简单又有效的时间序列分类算法。
应用于时态数据的 k-NN 背后的一般思想非常简单,我们将查看 k 个最近邻(多么令人惊讶!)并查看哪个类构成了这些序列的大多数,以便推导出新序列的类。为了知道最近的邻居,我们使用动态时间弯曲算法,该算法允许测量两个时间序列之间的相似性(或距离)。
我们用范围从 1 到 10 的 k(最近邻的数量)的不同值进行测试,我们发现我们自己在测试数据集上的准确度在 0.70 和 0.93 之间变化,当 k = 1 时达到最后一个值
LSTM-FCN 模型
密码
LSTM-FCN 函数
结果
正如我们在模型损失图上看到的,损失函数曲线(训练和验证)逐渐减少并向同一点收敛,表明学习进行得很好,既没有过拟合也没有欠拟合。
关于模型精度图,它证实了模型的良好学习,特别是表明模型给出了非常好的结果。因此,当我们对测试数据集应用该模型时,我们具有 100%的准确性,我们的模型成功地对不同的心电图进行了分类。
这一性能超过了我们已经看到的 k-NN 的结果,甚至可以被认为比心脏病专家的更好,因为我们获得了 100%的准确性!
代码可从以下网址获得:
LSTM-FCN 长短期记忆全卷积网络是 FCN 的一个改进,被认为是…
github.com](https://github.com/koukou10/lstm-fcn)
参考
[## IEEE Xplore 全文 PDF:
编辑描述
ieeexplore.ieee.org](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8141873) [## 麻省理工学院-BIH 长期数据库
当引用这些材料时,请包括生理网的标准引文:Goldberger AL,Amaral LAN,Glass L…
archive.physionet.org](https://archive.physionet.org/physiobank/database/ltdb/)
用于股票价格预测的 LSTM
为谷歌股价预测创建基于 LSTM 的递归神经网络的技术演练
来自 unsplash 的 Img 通过链接
在本文中,我将一步一步地介绍如何建立一个基于 LSTM 的递归神经网络(RNN)来预测谷歌股票价格。它分为如下 7 个部分。
- 问题陈述
- 数据处理
- 模型结构
- 模型编译
- 模型拟合
- 模型预测法
- 结果可视化
让我们开始旅程吧🏃♀️🏃♂️.
- 问题陈述
我们得到了 2012 年 1 月至 2016 年 12 月的谷歌股价。任务是预测 2017 年 1 月的股价趋势。注意, 基于布朗运动,股票价格的未来变化独立于过去。因此,预测准确的股票价格是不可能的,但预测和捕捉上涨和下跌趋势是可能的。
2.数据处理
2.1 导入数据
训练/测试数据保存在中。分别为 csv 文件。我们将用 开盘 价格进行预测。图 1 显示了训练集的一个片段及其散点图。
图 1 训练集及其散点图
train = pd.read_csv(‘Google_Stock_Price_Train.csv’)#keras only takes numpy array
training_set = dataset_train.iloc[:, 1: 2].values
注意 dataset_train.iloc[:,1:2]中的索引范围。值,因为我们需要使它成为 NumPy 数组,不是单个向量,也不是用于训练的数据帧。
2.2 特征缩放
下一步是在(0,1)之间缩放股票价格,以避免密集的计算。常见的方法有标准化和正常化如图 2 所示。建议进行归一化,尤其是在输出层使用 Sigmoid 函数处理 RNN 时。
图 2 特征缩放方法(作者创建的 Img)
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (0, 1))training_set_scaled = sc.fit_transform(training_set)
2.3 数据结构创建
创建滑动窗口很重要!
需要一个特殊的数据结构来覆盖 60 个时间戳,基于此,RNN 将预测第 61 个价格。这里,基于实验,过去时间戳的数量被设置为 60。因此, X_train 是一个嵌套列表,它包含 60 个时间戳价格的列表。 y_train 是第二天的股票价格列表,对应 X_train 中的各个列表。具体来说,
X_train = []
y_train = []
for i in range(60, len(training_set_scaled)):
X_train.append(training_set_scaled[i-60: i, 0])
y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)
图 3 显示了 X_train 和 y_train 的片段。 X_train 中每一行 60 个价格用于预测 y_train 中对应的第二天股票价格。
图 3 X_train 和 y_train 数据
2.4 数据重塑
如上所述,我们用 开盘 价格进行预测。也就是说,我们只有一个指标或特征。但是我们可以按照同样的数据处理方法添加更多的指标。为此,我们需要为指标的数量添加一个新的维度。具体来说,
X_train = np.reshape(X_train, newshape = (X_train.shape[0], X_train.shape[1], 1))
new shapein(批量大小、时间戳数量、指示器数量)。(批量大小,时间戳个数)是 X_train 的形状。这里我们只有一个指标。
太好了。✌✌.,我们把训练器材准备好了
3.模型构建
基本上,我们正在使用 LSTM 构建一个用于连续值预测的神经网络回归器。首先,初始化模型。
regressor = Sequential()
然后,添加第一个 LSTM 图层,接着添加删除图层。
regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))regressor.add(Dropout(rate = 0.2))
注意对于 LSTM 层,单位是该层中 LSTM 神经元的数量。50 个神经元将赋予模型高维度,足以捕捉向上和向下的趋势。 return_sequences 为真,因为我们需要在当前图层之后添加另一个 LSTM 图层。 input_shape 对应的是时间戳的个数和指示器的个数。对于退出,50 个神经元中的 20%将在训练的每次迭代中被随机忽略。
按照上述相同的方法,添加第二,第三和第四 LSTM 层。
##add 2nd lstm layer
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(rate = 0.2))##add 3rd lstm layer
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(rate = 0.2))##add 4th lstm layer
regressor.add(LSTM(units = 50, return_sequences = False))
regressor.add(Dropout(rate = 0.2))
注意最后一个 LSTM 层, return_sequences 是 False 由于我们不会添加更多的 LSTM 层。
最后,添加输出层。输出维度是 1,因为我们每次预测 1 个价格。
regressor.add(Dense(units = 1))
太好了!我们已经创建了一个基于 LSTM 的 RNN 模型🧨🧨.
4.模型编译
现在,让我们通过选择一个 SGD 算法和一个损失函数来编译 RNN。对于优化器,我们使用 Adam ,这是一个安全的选择。损失函数是实际值和预测值之间的均方误差。
regressor.compile(optimizer = ‘adam’, loss = ‘mean_squared_error’)
5.模型拟合
现在,让我们适合我们的 RNN。
regressor.fit(x = X_train, y = y_train, batch_size = 32, epochs = 100)
RNN 权重每 32 个股票价格更新一次,批量为 32 个。如果模型的损失没有收敛,请随意尝试更多的批次和时期。
太好了,现在让我们开始训练。最后,我们发现从损失 0.062 开始,我们在时期 50 得到损失0.0026*,到时期 100 损失0.0015*🎉🎉。**
6.模型预测
6.1 导入测试数据
使用第 2.1 节中的相同方法,读取测试数据。
**dataset_test = pd.read_csv(‘Google_Stock_Price_Test.csv’)real_stock_price = dataset_test.iloc[:, 1: 2].values**
6.2 数据处理
首先,我们需要连接用于预测的训练和测试数据集,因为我们使用前 60 天的股票价格来预测第二天的价格。换句话说,我们需要测试数据集中第一个日期之前 60 天的价格。
**dataset_total = pd.concat((dataset_train[‘Open’],dataset_test[‘Open’]), axis = 0)**
然后,为预测创建输入,从测试数据集中第一个日期之前 60 天的日期开始索引。
**inputs =
dataset_total[len(dataset_total)-len(dataset_test)- 60: ].values**
第三,改变输入的形状,使其只有一列。
**inputs = inputs.reshape(-1, 1)**
第四,使用由训练集设置的标度,对测试输入进行标度。
**inputs = sc.transform(inputs)**
最后,创建测试数据结构,如第 2.3 节所述。
**X_test = []
for i in range(60, len(inputs)):
X_test.append(inputs[i-60: i, 0])
X_test = np.array(X_test)
#make numpy array as 3D , adding num of indicator
X_test = np.reshape(X_test, newshape = (X_test.shape[0],
X_test.shape[1], 1))**
6.3 模型预测
现在, X_test 准备好预测了。
**predicted_stock_price = regressor.predict(X_test)**
别忘了,我们预测的是缩放后的值,所以我们需要反转预测。
**predicted_stock_price = sc.inverse_transform(predicted_stock_price)**
7.结果可视化
在最后一步中,让我们创建一个可视化图来轻松地检查预测。
**plt.plot(real_stock_price, color = ‘red’, label = ‘Real price’)
plt.plot(predicted_stock_price, color = ‘blue’, label = ‘Predicted price’)
plt.title(‘Google price prediction’)
plt.xlabel(‘Time’)
plt.ylabel(‘Price’)
plt.legend()
plt.show()**
如图 4 和图 5 所示,预测滞后于真实值,因为模型不能对非线性变化做出快速反应。但另一方面,模型对平滑变化反应良好。因此,我们得出结论,在包含峰值的预测部分,模型滞后于实际价格,但在包含平稳变化的部分,模型设法遵循向上和向下的趋势 ✨✨.
图 4 实际价格与预测价格
图 5 大时间尺度上的预测
太好了!这就是所有的旅程!如果需要源代码,请访问我的Github页面🤞🤞。
LSTM 梯度
LSTM 单元梯度的详细数学推导。
LSTM 或长短期记忆是复杂和最先进的神经网络结构的非常重要的构建块。这篇文章背后的主要思想是解释背后的数学。为了对 LSTM 有一个初步的了解,我推荐下面的博客。
[## 了解 LSTM 网络
2015 年 8 月 27 日发布人类不是每秒钟都从零开始思考。当你读这篇文章时,你…
colah.github.io](https://colah.github.io/posts/2015-08-Understanding-LSTMs/)
内容:
概念
- 介绍
- 说明
- 推导先决条件
B —推导
- LSTM 的产量
- 隐藏状态
- 输出门
- 细胞状态
- 输入门
- 忘记大门
- 对 LSTM 的投入
- 权重和偏差
C —随时间反向传播
D —结论
概念
介绍
图 1 : LSTM 细胞
上图是单个 LSTM 细胞的示意图。我知道这看起来很吓人😰,但是我们将一个接一个地浏览它,希望在文章结束时,它会变得非常清楚。
说明
基本上,一个 LSTM 细胞有 4 个不同的组成部分。忘记门、输入门、输出门和单元状态。我们将首先简要讨论这些部分的用法(详细解释请参考上面的博客),然后深入研究其中的数学部分。
忘门
顾名思义,这个部分负责决定最后一步要丢弃或保留哪些信息。这是由第一个乙状结肠层完成的。
图 2:蓝色标记的忘记门
基于 h_t-1(先前的隐藏状态)和 x_t(在时间步长 t 的当前输入),这为单元状态 C_t-1 中的每个值决定 0 和 1 之间的值。
图 3:忘记门和以前的细胞状态
对于所有的 1,所有的信息都保持原样,对于所有的 0,所有的信息都被丢弃,而对于其他值,它决定了有多少来自前一状态的信息将被携带到下一状态。
输入门
图 4:用蓝色标记的输入门
Christopher Olah 对输入门发生的事情有一个漂亮的解释。引用他的博客:
现在,这两个值,即 i_t 和 c~t 结合起来决定将什么新的输入馈送到单元状态。
单元格状态
图 5:蓝色标记的电池状态
细胞状态作为 LSTM 的记忆。这是他们在处理更长的输入序列时比香草 RNN 表现更好的地方。在每个时间步长,先前的单元状态(C_t-1)与遗忘门结合,以决定哪些信息将被结转,该信息又与输入门(i_t 和 c~t)结合,以形成新的单元状态或单元的新存储器。
图 6:新的细胞状态方程
输出门
图 7:标有蓝色的输出门
最后,LSTM 细胞必须给出一些输出。从上面获得的单元状态通过一个称为 tanh 的双曲线函数传递,以便在-1 和 1 之间过滤单元状态值。详情进入不同的激活功能,这个是个不错的博客。
现在,我希望 LSTM 单元的基本单元结构是清楚的,我们可以继续推导我们将在实现中使用的方程。
推导先决条件
- 要求:推导方程的核心概念是基于反向传播、成本函数和损失。如果你不熟悉这些,这几个链接将有助于更好地理解。本文还假设对高中微积分有基本的了解(计算导数和规则)。
了解神经网络最重要组成部分的具体细节
towardsdatascience.com](/understanding-backpropagation-algorithm-7bb3aa2f95fd) [## 寻找神经网络的成本函数
一步一步:神经网络背后的数学
towardsdatascience.com](/step-by-step-the-math-behind-neural-networks-490dc1f3cfd9)
2.变量:对于每个门,我们有一组权重和偏差,表示为:
- W_f,b_f->忘记门重和偏差
- W_i,b_i->输入门权重和偏置
- 候选小区状态权重和偏差
- W_o,b_o->输出门权重和偏置
W_v,b_v ->与 Softmax 层关联的权重和偏差。
f_t,i_t,c_tilede_t,o_t ->激活函数的输出
a_f,a_i,a_c,a_o ->激活函数的输入
j 是成本函数,我们将根据它来计算导数。注意(下划线(_)后的字符是下标)
3.正向推进方程式:
图 8:门方程
图 9:电池状态和输出方程
4.计算过程:让我们以忘记门为例来说明导数的计算。我们需要遵循下图中红色箭头的路径。
所以我们画出一条从 f_t 到成本函数 J 的路径,即
f_t →C_t →h_t →J。
反向传播恰好发生在同一步骤中,但方向相反
f_t ←C_t ←h_t ←J。
j 相对于 h_t 微分,h_t 相对于 _C_t 微分,C_t 相对于 f_t 微分。
因此,如果我们在这里观察,J 和 h_t 是单元格的最后一步,如果我们计算 dJ/dh_t,那么它可以用于类似 dJ/dC_t 的计算,因为:
dJ/dC_t = dJ/dh_t * dh_t/dC_t ( 链式法则)
类似地,将计算第 1 点中提到的所有变量的导数。
既然我们已经准备好了变量,也清楚了正向推进方程,是时候通过反向传播来推导导数了。我们将从输出方程开始,因为我们看到在其他方程中使用了相同的导数。这就是链式法则的用武之地。所以现在就开始吧。
衍生物
lstm的输出
输出有两个我们需要计算的值。
- Softmax:对于使用 Softmax 的交叉熵损失的导数,我们将直接使用最终方程。
详细的推导过程如下:
神经网络在多类分类问题中产生多个输出。但是,他们没有能力…
sefiks.com](https://sefiks.com/2017/12/17/a-gentle-introduction-to-cross-entropy-loss-function/#:~:text=Cross%20Entropy%20Error%20Function&text=If%20loss%20function%20were%20MSE,error%20function%20is%20cross%20entropy.&text=c%20refers%20to%20one%20hot,refers%20to%20softmax%20applied%20probabilities.)
隐藏状态
我们有 h_t 这样的隐藏态,h_t 对 w . r . t . j 求导,根据链式法则,推导可以在下图中看到。我们使用图 9 等式 7 中提到的 V_t 值,即:
v t = W v . h t+b v
输出门
相关变量:a_o 和 o_t。
o_t :下图显示了 o_t 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/dV_t * dV_t/dh_t * dh_t/dO_t
dJ/dV_t * dV_t/dh_t 可以写成 dJ/dh_t(我们从隐藏状态得到这个值)。
h_t 的值= o_t * tanh(c_t) ->图 9 等式 6。 所以我们只需要对 h_t w.r.t o_t. 进行区分,区分如下:-
a_o :同样,显示 a_o 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/dV _ t * dV _ t/DH _ t * DH _ t/dO _ t * dO _ t/da _ o
dJ/dV_t * dV_t/dh_t * dh_t/dO_t 可以写成 dJ/dO_t(上面 O_t 我们有这个值)。
o_t = sigmoid (a_o) ->图 8 等式 4。 ***所以我们只需要区分 o _ T w . r . T a _ o .***T他的区分将为:-
细胞状态
C_t 是单元的单元状态。除此之外,我们还在这里处理候选单元状态 a_c 和 c~_t。
**C_t:**C _ t 的推导非常简单,因为从 C _ t 到 J 的路径非常简单。C_t → h_t → V_t → J .由于我们已经有了 dJ/dh_t,所以直接微分 h_t w.r.t C_t。
h_t = o_t * tanh(c_t) ->图 9 等式 6。 所以我们只需要区分 h_t w.r.t C_t.
注意:单元状态 clubbed 会在文末解释。
c~_t :下图显示了 c~_t 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/dh_t * dh_t/dC_t * dC_t/dc~_t
dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(上面我们有这个值)。
C_t 的值如图 9 等式 5 所示(下图第 3 行最后一个 c_t 中缺少波浪号(~)符号->书写错误)。 所以我们只需要区分 C_t w.r.t c~_t.
a_c : 下图显示了 a_c 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/DH _ t * DH _ t/dC _ t * dC _ t/dC ~ _ t * dC ~ _ t/da _ c
dJ/dh_t * dh_t/dC_t * dC_t/dc~_t 可以写成 dJ/dc~_t(我们从上面有这个值)。
c \u t 的值如图 8 等式 3 所示。 所以我们只需要区分 c~_t w.r.t a_c 。
输入门
相关变量:i_t 和 a_i
i_t :下图显示了 i_t 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/dh_t * dh_t/dC_t * dC_t/di_t
dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(我们从 cell state 得到这个值)。所以我们只需要区分 C_t w.r.t i_t.
C_t 的值如图 9 等式 5 所示。因此,区别如下:-
a_i : 下图显示了 a_i 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/DH _ t * DH _ t/dC _ t * dC _ t/di _ t * di _ t/da _ I
dJ/dh_t * dh_t/dC_t * dC_t/di_t 可以写成 dJ/di_t(我们从上面有这个值)。所以我们只需要区分 i_t w.r.t a_i.
忘记大门
相关变量:f_t 和 a_f
f_t :下图显示了 f_t 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/dh_t * dh_t/dC_t * dC_t/df_t
dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(我们从 cell state 得到这个值)。所以我们只需要区分 C_t w.r.t f_t.
C_t 的值如图 9 等式 5 所示。因此,区别如下:-
a_f :下图显示了 f_t 和 J 之间的路径。根据箭头,微分的完整方程如下:
dJ/DH _ t * DH _ t/dC _ t * dC _ t/df _ t * df _ t/da _ t
dJ/dh_t * dh_t/dC_t * dC_t/df_t 可以写成 dJ/df_t(我们从上面有这个值)。所以我们只需要区分 f_t w.r.t a_f
Lstm 的输入
有 2 个变量与每个单元的输入相关联,即先前的单元状态 C_t-1 和与当前输入连接的先前的隐藏状态,即
[h_t-1,x_t] -> Z_t
C_t-1 : 这是 Lstm 细胞的记忆。图 5 显示了单元状态。C_t-1 的推导相当简单,因为只涉及 C_t-1 和 C_t。
Z_t :如下图所示,Z_t 进入 4 条不同的路径,a_f,a_i,a_o,a_c
Z_t → a_f → f_t → C_t → h_t → J . ->忘记门
Z_t → a_i→ i_t → C_t → h_t → J . ->输入门
Z_t → a_c → c~_t → C_t → h_t → J . ->候选细胞态
Z_t → a_o → o_t → C_t → h_t → J . ->输出门
权重和偏差
W 和 b 的推导非常简单。下面的推导是针对 Lstm 的输出门。对于其余的门,对权重和偏差进行类似的处理。
输入和遗忘门的权重和偏差
输出和输出门的权重和偏置
dJ/d_W_f = dJ/da_f . da_f / d_W_f ->忘记门
dJ/d_W_i = dJ/da_i . da_i / d_W_i ->输入门
dJ/d_W_v = dJ/dV_t . dV_t/ d_W_v ->输出
dJ/d_W_o = dJ/da_o . da_o / d_W_o ->输出门
最后我们完成了所有的推导。现在我们只需要澄清几点。
时间反向传播
到目前为止,我们所做的是一个单一的时间步骤。现在我们必须进行一次迭代。
因此,如果我们有总共 T 个时间步长,那么每个时间步长的梯度将在 T 个时间步长结束时相加,因此每次迭代结束时的累积梯度将为:
图 10:每次迭代结束时的累积梯度
现在这些将用于更新权重。
图 11:重量更新
结论
LSTMs 是非常复杂的结构,但是它们也工作得很好。主要有两种类型的 RNN 具有这种特征:LSTM 和格鲁
LSTMs 的训练也是一项棘手的任务,因为有许多超参数,正确组合通常是一项困难的任务。
所以,到现在为止,我希望 LSTM 的数学部分已经很清楚了,我建议你把手弄脏,以便更清楚、更好地理解它。以下是一些可能有帮助的链接:
[## 理解 LSTM 及其在情感分析 keras 中的快速实现。
towardsdatascience.com](/understanding-lstm-and-its-quick-implementation-in-keras-for-sentiment-analysis-af410fd85b47) [## Keras LSTM 教程-如何轻松建立一个强大的深度学习语言模型
在以前的帖子中,我介绍了用于构建卷积神经网络和执行单词嵌入的 Keras。的…
adventuresinmachinelearning.com](https://adventuresinmachinelearning.com/keras-lstm-tutorial/)
感谢你阅读这篇文章,希望你喜欢。
快乐学习😃!!!
LSTM 网络|详细解释
入门
LSTMs 的全面介绍
这篇文章解释了长短期记忆(LSTM)网络。我发现学习一个主题的最好方法是阅读许多不同的解释,所以我会在本文的最后链接一些我认为特别有用的资源。我强烈建议你去看看他们对 LSTMs 的不同观点和解释!
LSTM 图——这张图和下面所有的图片都是作者创作的
什么是 LSTMs,为什么有用?
LSTM 网络是专门设计来克服递归神经网络 RNNs 所面临的长期依赖性问题(由于消失梯度问题)。LSTMs 具有反馈连接,这使得它们不同于更传统的前馈神经网络。这一特性使得 LSTMs 能够处理整个数据序列(例如时间序列),而不用独立地处理序列中的每个点,而是保留关于序列中先前数据的有用信息,以帮助处理新数据点。因此,LSTMs 特别擅长处理数据序列,如文本、语音和一般时间序列。
例如,假设我们试图预测每月的冰淇淋销售额。正如人们所预料的,这种差异随着月份的不同而变化很大,12 月最低,6 月最高。
LSTM 网络可以学习这种每 12 个时间周期存在的模式。它不仅仅使用以前的预测,而是保留一个更长期的上下文,这有助于它克服其他模型面临的长期依赖问题。值得注意的是,这是一个非常简单的例子,但是当模式被更长的时间间隔分开时(例如,在很长的文本段落中),LSTMs 变得越来越有用。
LSTM 网络是如何工作的?
首先,在基本层面上,LSTM 在特定时间点的输出取决于三件事:
▹网络的当前长期记忆——被称为单元状态
▹前一时间点的输出——被称为前一隐藏状态
▹当前时间步的输入数据
LSTMs 使用一系列“门”来控制数据序列中的信息如何进入、存储和离开网络。典型的 LSTM 有三道门;忘记门,输入门和输出门。这些门可以被认为是过滤器,每一个都是它们自己的神经网络。我们将在这篇文章中详细探讨它们。
在下面的解释中,我们考虑下图所示的 LSTM 池。当查看本文中的图表时,想象从左向右移动。
LSTM 图
第一步
该过程的第一步是遗忘门。这里,我们将决定单元状态(网络的长期记忆)的哪些位是有用的,给定先前的隐藏状态和新的输入数据。
忘记大门
为此,先前的隐藏状态和新的输入数据被输入到神经网络中。该网络生成一个向量,其中每个元素都在区间[0,1]中(通过使用 sigmoid 激活来确保)。这个网络(在遗忘门内)被训练成当输入的一个分量被认为不相关时输出接近 0,而当相关时输出接近 1。将这个向量的每个元素看作一种过滤器/筛子是有用的,当值接近 1 时,它允许更多的信息通过。
这些输出值然后被发送并逐点乘以先前的单元状态。这种逐点乘法意味着被遗忘门网络视为不相关的单元状态的分量将被乘以一个接近 0 的数,因此对后续步骤的影响较小。
总之,遗忘门决定了给定序列中先前的隐藏状态和新的数据点,哪些长期记忆片段现在应该被遗忘(具有较小的权重)。
第二步
下一步涉及新存储网络和输入门。这一步的目标是在给定先前的隐藏状态和新的输入数据的情况下,确定什么新的信息应该被添加到网络的长期记忆(细胞状态)中。
输入门
新的记忆网络和输入门本身都是神经网络,并且都接受相同的输入,即先前的隐藏状态和新的输入数据。值得注意的是这里的输入实际上与遗忘门的输入相同!
-
新记忆网络是一个 tanh 激活的神经网络,它已经学会了如何将先前的隐藏状态和新的输入数据结合起来,以生成一个“新的记忆更新向量”。给定来自先前隐藏状态的上下文,该向量实质上包含来自新输入数据的信息。这个向量告诉我们,在给定新数据的情况下,网络的长期存储器(单元状态)的每个组件需要更新多少。
注意,我们在这里使用一个双曲正切值,因为它的值位于[-1,1]中,所以可以是负数。如果我们希望减少单元状态中组件的影响,这里负值的可能性是必要的。
-
然而,在上面的第 1 部分中,我们生成了新的内存向量,这里有一个大问题,它实际上并没有检查新的输入数据是否值得记忆。这就是输入门出现的地方。输入门是一个 sigmoid 激活的网络,它作为一个过滤器,识别“新记忆向量”的哪些成分值得保留。该网络将输出[0,1]中的值的向量(由于 sigmoid 激活),允许其通过逐点乘法充当过滤器。类似于我们在遗忘门中看到的,接近零的输出告诉我们,我们不想更新单元状态的该元素。
-
部分 1 和部分 2 的输出逐点相乘。这导致我们在第 2 部分中决定的新信息的大小被调整,并且如果需要的话被设置为 0。得到的组合向量然后被加到单元状态,导致网络的长期记忆被更新。
第三步
既然我们对网络长期记忆的更新已经完成,我们可以进入最后一步,输出门,决定新的隐藏状态。为了决定这一点,我们将使用三样东西;新更新的单元状态、先前的隐藏状态和新的输入数据。
有人可能认为我们可以只输出更新的单元状态;然而,这相当于有人在只被问及他们认为明天股市会涨还是会跌时,就把他们所知道的关于股市的一切都卸下来了!
为了防止这种情况发生,我们创建了一个滤波器,输出门,就像我们在遗忘门网络中所做的一样。输入是相同的(先前的隐藏状态和新数据),激活也是 sigmoid(因为我们希望从[0,1]中的输出获得滤波器属性)。
输出门
如前所述,我们希望将这个过滤器应用于新更新的单元格状态。这确保了只输出必要的信息(保存到新的隐藏状态)。但是,在应用过滤器之前,我们通过一个 tanh 传递单元格状态,以强制值进入区间[-1,1]。
这最后一步的逐步过程如下:
▹将双曲正切函数逐点应用于当前单元状态,以获得压扁的单元状态,其现在位于[-1,1]。
▹通过 sigmoid 激活的神经网络传递先前的隐藏状态和当前的输入数据以获得滤波器向量。
▹通过逐点乘法将该滤波器向量应用于压扁的单元状态。
▹输出新的隐藏状态!
一些澄清
虽然第 3 步是 LSTM 单元格中的最后一步,但是在我们的 LSTM 实际输出我们正在寻找的类型的预测之前,我们还需要考虑一些事情。
首先,上述步骤重复多次。例如,如果您试图根据前 30 天的定价数据预测未来几天的股票价格,那么这些步骤将重复 30 次。换句话说,你的模型将迭代产生 30 个隐藏状态来预测明天的价格。
但是输出还是隐藏状态。在上面的例子中,我们想要明天的价格,我们不能从明天的隐藏状态中赚钱!因此,要将隐藏状态转换为输出,我们实际上需要应用一个线性层,作为 LSTM 过程的最后一步。这种线性层步骤只在最末端发生一次,这就是为什么它通常不包括在 LSTM 单元图中的原因。
在许多其他参考资料中,根本没有提到这个线性层步骤,这最初让我感到困惑,所以希望这能为你们中的一些读者提供澄清!
如何用 Python 实现 LSTM?
如果您想查看如何在 Pytorch 中实现所有这些的示例,请查看我的另一篇文章!👇
[## 预测沃尔玛季度收入——py torch LSTM 示例
应用 LSTM 网络预测季节性时间序列数据
levelup.gitconnected.com](https://levelup.gitconnected.com/forecasting-walmart-quarterly-revenue-pytorch-lstm-example-b4e4b20862a7)
结论
感谢那些坚持到现在的人,我希望这篇文章对你理解 LSTM 网络有所帮助!如有任何反馈或问题,请随时发表评论。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@riandolphin/membership)
其他资源
其他一些观点可以在 Colah 的 Github 帖子、 Michael Phi 的帖子中找到,其中包含精彩的动画,以及 Stanford 的笔记。
基于 Pytorch 的 LSTM 文本分类
一步一步的指导你如何在 Pytorch 中建立一个双向 LSTM!
克里斯托夫·高尔在 Unsplash 上拍摄的照片
介绍
欢迎来到本教程!本教程将在几分钟内教你如何为文本分类构建一个双向【LSTM】。如果你还没有看过我之前关于 BERT 文本分类 的文章,这篇教程包含了和那篇类似的代码,但是包含了一些支持 LSTM 的修改。本文还解释了我是如何对两篇文章中使用的数据集进行预处理的,这是来自 Kaggle 的 真假新闻数据集 。
首先,什么是 LSTM,我们为什么要使用它?LSTM 代表长短期记忆网络,属于一个更大的神经网络类别,称为递归神经网络(RNN) 。与传统的 RNN 相比,它的主要优势在于,它能够通过复杂的架构更好地处理长期依赖性,该架构包括三个不同的门:输入门、输出门和遗忘门。这三个门共同决定在任意时间内 LSTM 细胞中哪些信息该记住,哪些该忘记。
LSTM 细胞
现在,我们对 LSTM 有了更多的了解,让我们集中在如何实现它的文本分类。本教程分为以下步骤:
- 预处理数据集
- 导入库
- 加载数据集
- 建立模型
- 培养
- 估价
在我们开始学习本教程之前,您可以在这里访问本文中的代码:
步骤 1:预处理数据集
原始数据集如下所示:
数据集概述
数据集包含任意的索引、标题、文本和相应的标签。
对于预处理,我们导入 Pandas 和 Sklearn,并为路径、训练验证和测试比率定义一些变量,以及用于将每个句子切割到第一个first_n_words
单词的trim_string
函数。修剪数据集中的样本不是必需的,但是它能够更快地训练较重的模型,并且通常足以预测结果。
接下来,我们将真实的转换为 0,将虚假的转换为 1,连接标题和文本以形成新列标题文本(我们使用标题和文本来决定结果),删除带有空文本的行,将每个样本修剪为first_n_words
,并根据train_test_ratio
和train_valid_ratio
分割数据集。我们将生成的数据帧保存到中。csv 文件,获取 train.csv 、 valid.csv 和 test.csv 。
步骤 2:导入库
我们导入 Pytorch 用于模型构建,torchText 用于加载数据,matplotlib 用于绘图,sklearn 用于评估。
步骤 3:加载数据集
首先,我们使用 torchText 为数据集中的标签创建一个标签字段,并为标题、文本和标题文本创建一个文本字段。然后,我们通过将 TabularDataset 指向包含 train.csv 、 valid.csv 和 test.csv 数据集文件的路径来构建 tabular dataset。我们创建加载数据的 train、valid 和 test 迭代器,最后,使用 train 迭代器构建词汇表(只计算最小频率为 3 的标记)。
步骤 4:构建模型
我们构造了继承自 nn 的 LSTM 类。模块。在 LSTM 内部,我们构建了一个嵌入层,然后是一个双 LSTM 层,最后是一个完全连接的线性层。在 forward 函数中,我们通过嵌入层传递文本 id 以获得嵌入,通过容纳变长序列的 LSTM 传递,从两个方向学习,通过完全连接的线性层传递,最后 sigmoid 以获得序列属于假的概率(为 1)。
第五步:培训
在训练之前,我们为检查点和指标构建保存和加载函数。对于检查点,保存模型参数和优化器;对于度量标准,将保存列车损失、有效损失和全局步骤,以便稍后可以轻松地重新构建图表。
我们用 10 个历元训练 LSTM,每当超参数设置实现最佳(最低)验证损失时,保存检查点和指标。以下是培训期间的输出:
整个训练过程在 Google Colab 上很快。训练了不到两分钟!
一旦我们完成了训练,我们可以加载之前保存的指标,并输出一个图表,显示整个时间内的训练损失和验证损失。
第六步:评估
最后,为了进行评估,我们选择之前保存的最佳模型,并根据我们的测试数据集对其进行评估。我们使用默认阈值 0.5 来决定何时将样本归类为假样本。如果模型输出大于 0.5,我们把那个新闻归类为假的;否则,真实的。我们输出分类报告,指出每个类别的精确度、召回率和 F1 值,以及总体精确度。我们还输出混淆矩阵。
我们可以看到,使用一层双 LSTM,我们可以在假新闻检测任务上实现 77.53%的准确率。
结论
本教程一步一步地解释了如何使用 Pytorch 实现你自己的文本分类 LSTM 模型。我们发现,双 LSTM 在假新闻检测方面达到了可接受的准确率,但仍有改进的空间。如果你想要更有竞争力的表现,可以看看我之前关于 BERT 文本分类 的文章!
文本分类是自然语言处理中的一项常见任务。我们应用 BERT,一个流行的变压器模型,对假新闻检测使用…
towardsdatascience.com](/bert-text-classification-using-pytorch-723dfb8b6b5b)
如果你想了解更多关于现代自然语言处理和深度学习的知识,请关注我的最新文章:)
参考
[1] S. Hochreiter,J. Schmidhuber,长短期记忆 (1997),神经计算
时间序列预测:使用 LSTM 模型预测股票价格
在这篇文章中,我将向你展示如何使用预测 LSTM 模型来预测股票价格
作者创作的人物。
1.介绍
1.1.时间序列和预测模型
传统上,大多数机器学习(ML)模型使用一些观察值(样本/实例)作为输入特征,但数据中没有时间 维度。
时间序列预测模型是能够根据先前 观测 值预测 未来值的模型。时间序列预测广泛用于非平稳数据。非平稳数据被称为统计属性(如平均值和标准偏差)不随时间保持不变,而是随时间变化的数据。
这些非平稳输入数据(用作这些模型的输入)通常被称为时间序列。时间序列的一些例子包括随时间变化的温度值、随时间变化的股票价格、随时间变化的房屋价格等。因此,输入是一个信号(时间序列),它是由在时间中连续获得的观察值定义的。
时间序列是按时间顺序进行的一系列观察。
时间序列的一个例子。作者用 Python 创作的情节。
观察:时序数据记录在离散时间刻度时间刻度上。
免责声明(在我们继续之前):已经有人尝试使用时间序列分析算法来预测股票价格,尽管它们仍然不能用于在真实市场中下注。这只是一篇教程文章,并不打算以任何方式“指导”人们购买股票。
——我的邮件列表只需 5 秒:https://seralouk.medium.com/subscribe
-成为会员支持我:https://seralouk.medium.com/membership
2.LSTM 模式
长短期记忆 ( LSTM )是一种用于深度学习领域的人工递归神经网络(RNN)架构。与标准的前馈神经网络不同,LSTM 有反馈连接。它不仅可以处理单个数据点(例如图像),还可以处理整个数据序列(例如语音或视频输入)。
LSTM 模型能够储存一段时间的信息。
换句话说,它们有记忆能力。记住,LSTM 代表长短期记忆模型。
当我们处理时间序列或顺序数据时,这个特性是非常有用的。当使用 LSTM 模型时,我们可以自由决定存储什么信息,丢弃什么信息。我们使用“门”来实现。对 LSTM 的深入理解超出了这篇文章的范围,但是如果你有兴趣了解更多,看看这篇文章末尾的参考资料。
如果你想在交互式路线图和活跃的学习社区的支持下自学数据科学,看看这个资源:【https://aigents.co/learn
3.获取股票价格历史数据
感谢雅虎财经我们可以免费获得的数据。使用以下链接获取特斯拉:https://finance.yahoo.com/quote/TSLA/history?的股价历史周期 1=1436486400 &周期 2=1594339200 &间隔=1d &过滤器=历史&频率=1d
您应该看到以下内容:
点击下载并保存**。csv** 文件本地保存在您的计算机上。
数据是从 2015 到现在( 2020 )!
4.Python 工作示例
所需模块:Keras,Tensorflow,Pandas,Scikit-Learn & Numpy
我们将构建一个多层 LSTM 递归神经网络来预测一系列值中的最后一个值,即本例中的特斯拉股票价格。
让加载数据数据和检查它们:
import math
import matplotlib.pyplot as plt
import keras
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from keras.layers import *
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from keras.callbacks import EarlyStoppingdf=pd.read_csv("TSLA.csv")
print(‘Number of rows and columns:’, df.shape)
df.head(5)
上述代码的输出
下一步是将数据分割成训练和测试集合,以避免过拟合,并能够调查我们模型的泛化能力。要了解更多关于过度拟合的信息,请阅读本文:
[## 你的模型是否过拟合?或者不合身?python 中使用神经网络的示例
过拟合,欠拟合,泛化能力,交叉验证。一切都简单解释了。我还提供了一个…
towardsdatascience.com](/is-your-model-overfitting-or-maybe-underfitting-an-example-using-a-neural-network-in-python-4faf155398d2)
要预测的目标值将是“收盘股价值。
training_set = df.iloc[:800, 1:2].values
test_set = df.iloc[800:, 1:2].values
在模型 拟合之前,归一化数据不失为一个好主意。这将提高性能。你可以在这里阅读更多关于最小-最大缩放器:
[## 关于 Python 中的最小-最大规范化,您需要知道的一切
在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它
towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79)
让我们构建具有 1 天滞后时间**(滞后 1)的输入要素:**
# Feature Scaling
sc = MinMaxScaler(feature_range = (0, 1))
training_set_scaled = sc.fit_transform(training_set)# Creating a data structure with 60 time-steps and 1 output
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-60:i, 0])
y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
#(740, 60, 1)
现在我们已经将数据整形为以下格式(#值、#时间步长、#1 维输出)。
**现在,该建立模型了。**我们将建立有 50 个神经元的 LSTM 和 4 个隐含层。最后,我们将在输出层分配 1 个神经元用于预测标准化的股票价格。我们将使用 MSE 损失函数和 Adam 随机梯度下降优化器。
注意:以下需要一些时间(~5min)。
model = Sequential()#Adding the first LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))
model.add(Dropout(0.2))# Adding a second LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))# Adding a third LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))# Adding a fourth LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50))
model.add(Dropout(0.2))# Adding the output layer
model.add(Dense(units = 1))
# Compiling the RNN
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Fitting the RNN to the Training set
model.fit(X_train, y_train, epochs = 100, batch_size = 32)
装配完成后,您应该会看到类似这样的内容:
准备测试数据(重塑它们):
# Getting the predicted stock price of 2017
dataset_train = df.iloc[:800, 1:2]
dataset_test = df.iloc[800:, 1:2]dataset_total = pd.concat((dataset_train, dataset_test), axis = 0)inputs = dataset_total[len(dataset_total) - len(dataset_test) - 60:].valuesinputs = inputs.reshape(-1,1)
inputs = sc.transform(inputs)
X_test = []
for i in range(60, 519):
X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))print(X_test.shape)
# (459, 60, 1)
使用测试集进行预测
predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
现在让我们来看看结果:
# Visualising the results
plt.plot(df.loc[800:, ‘Date’],dataset_test.values, color = ‘red’, label = ‘Real TESLA Stock Price’)
plt.plot(df.loc[800:, ‘Date’],predicted_stock_price, color = ‘blue’, label = ‘Predicted TESLA Stock Price’)
plt.xticks(np.arange(0,459,50))
plt.title('TESLA Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('TESLA Stock Price')
plt.legend()
plt.show()
5.结果
使用滞后 1(即一天的步长):
观察:2020 年 3 月因新冠肺炎封锁而大幅下跌!
我们可以清楚地看到,我们的模型表现得非常好。它能够准确地跟踪大多数不可接受的上涨/下跌,但是,对于最近的日期戳,我们可以看到,与股票价格的实际值相比,模型预期(预测)的值较低。
关于滞后的一个注记
本文中最初选择的延迟为 1,即使用 1 天的步长。这可以通过修改构建 3D 输入的代码来轻松改变。
示例:可以更改以下两个代码块:
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-60:i, 0])
y_train.append(training_set_scaled[i, 0])
和
X_test = []
y_test = []
for i in range(60, 519):
X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
采用以下新代码:
X_train = []
y_train = []
for i in range(60, 800):
X_train.append(training_set_scaled[i-50:i, 0])
y_train.append(training_set_scaled[i, 0])
和
X_test = []
y_test = []
for i in range(60, 519):
X_test.append(inputs[i-50:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))
在这种情况下,结果如下所示:
那都是乡亲们!希望你喜欢这篇文章!
看看我在另一篇文章中用来预测谷歌股价的脸书预言家模型。
使用可从《先知脸书》公开获得的预测模型预测股票价格
towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5)
也可以看看我最近用 ARIMA 模型写的文章:
在这篇文章中,我将向你展示如何使用预测 ARIMA 模型来预测特斯拉的股票价格
towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-an-arima-model-2e3b3080bd70)
参考
[1]https://colah.github.io/posts/2015-08-Understanding-LSTMs/
[2]https://en.wikipedia.org/wiki/Long_short-term_memory
敬请关注并支持这一努力
如果你喜欢这篇文章并且觉得它有用,关注我就可以看到我所有的新帖子。
有问题吗?把它们作为评论贴出来,我会尽快回复。
最新帖子
使用可从《先知脸书》公开获得的预测模型预测股票价格
towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5) [## 最佳免费数据科学资源:免费书籍和在线课程
最有用的免费书籍和在线课程,适合想了解更多数据科学知识的人。
medium.com](https://medium.com/@seralouk/the-best-free-data-science-resources-free-books-online-courses-9c4a2df194e5) [## 用新冠肺炎假设的例子解释 ROC 曲线:二分类和多分类…
在这篇文章中,我清楚地解释了什么是 ROC 曲线以及如何阅读它。我用一个新冠肺炎的例子来说明我的观点,我…
towardsdatascience.com](/roc-curve-explained-using-a-covid-19-hypothetical-example-binary-multi-class-classification-bab188ea869c) [## 支持向量机(SVM)解释清楚:分类问题的 python 教程…
在这篇文章中,我解释了支持向量机的核心,为什么以及如何使用它们。此外,我还展示了如何绘制支持…
towardsdatascience.com](/support-vector-machines-svm-clearly-explained-a-python-tutorial-for-classification-problems-29c539f3ad8) [## PCA 清楚地解释了——如何、何时、为什么使用它以及特性的重要性:Python 指南
在这篇文章中,我解释了什么是 PCA,何时以及为什么使用它,以及如何使用 scikit-learn 在 Python 中实现它。还有…
towardsdatascience.com](/pca-clearly-explained-how-when-why-to-use-it-and-feature-importance-a-guide-in-python-7c274582c37e) [## 关于 Python 中的最小-最大规范化,您需要知道的一切
在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它
towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79) [## Scikit-Learn 的标准定标器如何工作
在这篇文章中,我将解释为什么以及如何使用 scikit-learn 应用标准化
towardsdatascience.com](/how-and-why-to-standardize-your-data-996926c2c832)
和我联系
- LinkedIn:https://www.linkedin.com/in/serafeim-loukas/
- 研究之门:https://www.researchgate.net/profile/Serafeim_Loukas
- https://people.epfl.ch/serafeim.loukasEPFL简介 : 美国
- 堆栈溢出溢出:https://stackoverflow.com/users/5025009/seralouk
LSTM vs 伯特——推特情感分析的分步指南
最先进的 NLP 模型能比 RNN 更好地预测股票交易者情绪吗?
作者图片
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
在金融文本的情绪分析中看到 BERT 的竞争结果后,我对更非正式的文本进行了另一项初步研究,因为最终目标是除了新闻情绪之外,还分析交易员在电话和聊天中的声音。在这篇文章中,我让 LSTM 和伯特分析了 Stocktwit 的一些推文。
背景
与正式的金融文本不同,交易者的声音和聊天包含了迄今为止的非正式语言。在我过去的研究中,传统的基于规则的模型或简单的矢量化技术(如 BoW、Tfidf、word2vec)表现不佳,因为
- 一个词在不同的上下文中通常有不同的意思
- 拼写和句子远不是语法正确的语言
- 通过词干化、词汇化、停用词移除等来平衡单词分组。保持原来的形式是很困难的
- 对于基于规则的方法,字典必须专门建立在这种语言上,在这方面我没有足够的概括
LSTM 是自然语言处理中最著名的 RNN 模型之一,表现很好。这在很大程度上归功于这样一个事实
- 句子结构相当简单——简单地从左到右处理就足够了
- 每一个输入文本都很短,有利于记忆
- 这项任务相当简单的分类
另一方面,我在这里使用的 BERT 是在维基百科上训练的,那里的语言非常不同。由于资源的限制,从零开始训练 BERT 并不是一个好的选择。在这种情况下,让伯特获得比 LSTM 更好的表现还值得吗?
作为输入文本的推文
这里输入的文字取自 Stocktwits,作为这里交易者声音的类似语言。大约有一百万条推文被手工标记为 0(负面)到 4(正面),分别被加载为messages
和sentiments
列表。请注意,实际环境通常需要做更多的工作来准备输入,如声音识别、数据清理、流式传输。这篇文章跳过这些步骤,从数据加载的地方开始。
> ##### Sample input messages ######> print(messages)
["$AMZN sick! they’re running a prime flash sale on shares too!", "$AAPL has a good Piotroski-F score of 7.00\. This indicates a good health and profitability. https://www.chartmill.com/analyze.php?utm_source=stocktwits&utm_medium=FA&utm_content=PROFITABILITY&utm_campaign=social_tracking#/AAPL?r=fa&key=bb853040-a4ac-41c6-b549-d218d2f21b32", "$FB got rid of this trash today, i admit that bears were right", ...]> print(sentiments)
[4, 2, 0, ...]
1.预处理
在训练之前,输入文本需要进行预处理,如删除 URL、标记符号、@提及、符号等。在这里,我简单地删除了它们,因为它们在语音中不可用,但也有一些有趣的研究,关于如何利用表情符号和标签等信息,而不是删除它们,如果最终目标是分析推文文本的话。
预处理输入消息
现在输入已经被清理如下。
> ###### Input messages after preprocessing ######> print(preprocessed)
["sick they re running a prime flash sale on shares too", "has a good piotroski f score of this indicates a good health and profitability", "got rid of this trash today i admit that bears were right", ...]
2.标记化
下一步是标记文本。在这里,我使用 python NLTK 库,但也给出了使用不同方法的选项,以查看什么最适合输入。经过几次实验后,我决定使用 nltk.word_tokenize(),而不进行词汇化和停用词移除。
3.语料库和词汇库
一旦输入文本被标记化,我们就可以用下面的方式创建一个语料库和词汇库。词云或条形图是快速查看输入中的常用词的好方法。分布显示该标签不平衡,比其他情绪更中性。通过重采样(欠采样或过采样)来平衡数据是可能的,但这里按原样进行,因为这个比率将代表推文流中情感的实际发生。
文字云图像(由作者创建)
语料库中最常用的单词(由作者创建)
标签、字母和单词的分发(由作者创建)
分类模型
既然输入数据已经准备好了,就创建基于神经网络的模型,并为该模型标记化。
4.LSTM
使用 pytorch 创建一个基于 LSTM 的模型。该类扩展了 torch.nn.Module 并将层定义为嵌入→ lstm →丢弃→密集(全连接)→输出(softmax)。LSTM 的记号赋予器是将输入填充到右边或左边,直到指定的最大长度,如果输入超过最大长度,则截断,设计用于在每批的训练期间使用,而不是预处理所有输入。
5.伯特
这里我使用 BERT 的拥抱脸实现。只需使用他们的变压器和预先训练的模型和记号化器。
培训过程
6.资料组
为批处理创建数据集类和数据加载器。有许多不同的方法来定义它们,这只是一个非常简单的解决方案,与返回 torch.tensor 的已定义记号化器一起使用。
7.取样周期
根据不同输入大小的准确度、f1 和训练时间来测量性能。使用 scikit-learn 的分层混洗 Split,它可以根据给定的训练和测试大小,通过保留标签分布来执行欠采样。在每个循环中,通过 perf_counter()测量完成训练的持续时间。
此外,定义一个简单的函数来返回准确性和 F1 分数。
注意,模型参数是在实例化模型类时定义的,可以根据输入数据进行更新。
8.训练神经网络模型
如下定义培训流程:
- 循环训练批次
- 在整个数据的 1/5 处运行评估
- 一个时期完成后,显示结果
- 如果分数没有提高到超出忍耐限度,则结束,或者开始下一个纪元
AdamW 优化器和线性时间表与学习率预热一起使用,但这些可以根据需要与其他选项交换。
在每个训练批次循环中,将输入消息标记化并移动到 torch.tensor,执行前馈预测,计算损失并反向传播以更新权重。裁剪以避免在下一个批处理步骤之前爆发梯度问题。
在每个时期结束时,显示训练和验证数据的混淆矩阵和分数/损失。
火车!
最后:)
9.运行 LSTM 模型
在最小样本(n=1,000)的第一个时期之后,模型简单地将所有数据分类为“中性”,这是合理的,因为“中性”是多数类。
混淆矩阵(n=1,000,epoch=1)(由作者创建)
完成五个时代后,它看起来几乎是随机地对数据进行了分类。它从第三个时期(=验证周期= 10)开始过度拟合训练数据。
评估结果(n=1,000,epoch=5)(由作者创建)
最大的数据集(n=500,000)包含比第一个周期多 500 倍的数据。它表现得更好,现在可以正确分类大多数标签。从第四个周期开始超配,所以三个纪元会是最好的。
评估结果(n=500,000,epoch=5)(由作者创建)
10.运行伯特模型
三个时期的训练预训练的 BERT 花费的时间几乎与上述 LSTM 模型的五个时期相同。
BERT 显示了类似的结果,但是它在最大数据集(n = 500,000)的第三个时期开始过拟合。
评估结果(n=500,000,epoch=5)(由作者创建)
11.比较结果
如下所示,随着输入数据数量的增加,它的性能自然会更好,在大约 100k 的数据时达到 75%以上的分数。伯特的表现略好于 LSTM,但当模型接受相同时间的训练时,没有显著差异。
LSTM 与伯特的演奏比较(作者创作)
结论
在这篇文章中,来自 stockswits 的推文被清理、标记和分析,以通过 LSTM 模型和预训练的伯特模型预测情绪。
给定相同的资源和时间,预训练的 BERT 比 LSTM 稍好,但没有显著差异。
潜在地,对类似的推文从头训练 BERT 模型可以产生更好的结果,而所需的资源和成本超出了本研究的范围。
(可选)推文流上的推理
下面是一段代码,它使用上面训练好的模型,将 tweet 流作为输入进行处理,并输出带有置信度的情绪。
示例输出如下所示。
PyTorch 的 LSTMs
简单的解释
了解 LSTM 架构和数据流
大象永远不会忘记。LSTMs 呢?
让我猜猜… 你已经和 MLPs 和 CNN 完成了几个小项目,对吗?MLPs 让你开始理解梯度下降和激活函数。CNN 让你看到了计算机视觉的世界。它们的所有层次都有点难,但你最终会找到窍门的。
现在,你碰壁了。你在用头撞它。那座血淋淋、泪痕斑斑的建筑叫做伊斯特姆斯。
我感受到了你的痛苦,朋友。我是来帮忙的。
让我们从概念上熟悉 LSTMs,然后深入研究您的问题的具体难点:即定义网络架构,以及在数据流经网络的每一层时控制数据的形状。
RNNs 背后的理念
递归神经网络通常保持关于先前通过网络传递的数据的状态信息。普通 rnn 和 LSTMs 都是如此。这种所谓的“隐藏状态”随着数据点序列的每个新元素被传回网络。因此,网络的每个输出不仅是输入变量的函数,也是隐藏状态的函数,隐藏状态是网络过去所见的“记忆”。
普通 rnn 失败的地方
这有助于理解 LSTMs 填补传统 rnn 能力的空白。香草 RNN 遭受快速渐变消失或渐变爆炸。粗略地说,当链式法则应用于支配网络内“记忆”的方程时,会产生一个指数项。如果满足某些条件,该指数项可能会变得很大或很快消失。
LSTMs 不会(严重地)遭受消失梯度的问题,因此能够保持更长的“记忆”,使它们成为学习时态数据的理想选择。
PyTorch 中 LSTMs 的难点
现在,你可能已经知道了 LSTMs 背后的故事。你在这里是因为你很难将你的概念性知识转化为工作代码。
快速搜索 PyTorch 用户论坛会产生几十个问题,关于如何定义 LSTM 的架构,如何在数据从一层移动到另一层时塑造数据,以及当数据从另一端出来时如何处理。这些问题中有许多没有答案,而更多的问题的答案对于提问的初学者来说是难以理解的。
可以说,理解通过 LSTM 的数据流是我在实践中遇到的头号难题。似乎我并不孤单。
理解数据流:LSTM 层
在学习其他类型的网络之后,学习 LSTMs 时最难理解的一个概念可能是数据如何在模型的各层中流动。
这不是魔法,但看起来可能是。图片可能有所帮助:
作者配图。
- 一个 LSTM 层由一组 M 隐藏节点组成。该值 M 由用户在模型对象实例化时分配。很像传统的神经网络,虽然有指导方针,但这是一个有点武断的选择。
- 当长度为的单个序列 S 被传递到网络中时,序列 𝑆 的每个单独元素 s_i 通过每个隐藏节点。
- 每个隐藏节点为它看到的每个输入提供一个输出。这导致了形状 ( N , M ) 的隐藏层的整体输出
- 如果将小批量的 𝐵 序列输入到网络中,则会增加一个额外的维度,从而产生形状为 (𝐵、 N 、 M ) 的输出
了解数据流:全连接层
在 LSTM 层(或一组 LSTM 层)之后,我们通常会通过nn.Linear()
类向网络添加一个完全连接的层,用于最终输出。
- 最后一个
nn.Linear()
层的输入大小将总是等于它之前的 LSTM 层中隐藏节点的数量。 - 这个最终完全连接层的输出将取决于目标的形式和/或您使用的损失函数。
了解数据流:示例
我们将讨论两个定义网络架构和通过网络传递输入的示例:
- 回归
- 分类
示例 1a:回归网络架构
考虑一些时间序列数据,也许是股票价格。给定特定产品过去 7 天的股票价格,我们希望预测第 8 天的价格。在这种情况下,我们希望我们的输出是单个值。我们将使用 MSE 来评估这个单值的准确性,因此对于预测和性能评估,我们需要来自七天输入的单值输出。因此,我们将我们的网络架构定义为:
示例 1b:对层间数据进行整形
我告诉你一个小秘密,我的一个朋友曾经告诉过我:
这些天来,我对它有了一种理解【LSTM 数据流】如果我在做的时候看向别处,它就会起作用。
—亚历克
虽然他说的在某种意义上是对的,但我认为我们可以确定这台机器如何工作的一些细节。
- LSTM 层的输入必须是
(batch_size, sequence_length, number_features)
的形状,其中batch_size
是指每批序列的数量,number_features
是时间序列中变量的数量。 - 你的 LSTM 层的输出将会是
(batch_size, sequence_length, hidden_size)
的形状。再看一下我在上面创建的流程图。 - 我们的全连接
nn.Linear()
层的输入需要对应于前一 LSTM 层中隐藏节点数量的输入大小。因此,我们必须将我们的数据重塑为(batches, n_hidden)
形式。
重要提示: batches
与batch_size
不同,因为它们不是同一个数字。然而,想法是相同的,因为我们将 LSTM 层的输出分成batches
个片段,其中每个片段的大小为n_hidden
,即隐藏的 LSTM 节点的数量。
下面是一些模拟通过整个网络传递输入数据x
的代码,遵循上面的协议:
回想一下out_size = 1
,因为我们只希望知道一个值,这个值将使用 MSE 作为度量进行评估。
示例 2a:分类网络架构
在这个例子中,我们想要生成一些文本。一个模型在一大堆文本上被训练,也许是一本书,然后输入一系列字符。该模型将查看每个字符,并预测下一个字符应该出现。这一次我们的问题是分类而不是回归,我们必须相应地改变我们的架构。我制作了这张图表来勾画总体思路:
作者配图。
也许我们的模型训练的是由 50 个独特字符组成的数百万字的文本。这意味着当我们的网络得到一个字符时,我们希望知道接下来是 50 个字符中的哪一个。因此,对于单个字符,我们的网络输出将是 50 个概率,对应于 50 个可能的下一个字符中的每一个。
此外,我们将对文本字符串中的每个字符进行一次性编码,这意味着变量(input_size = 50
)的数量不再像以前那样是一个,而是一次性编码的字符向量的大小。
示例 2b:对层间数据进行整形
至于在各层之间形成数据,没有太大的区别。逻辑是相同的:
示例 2c:培训挑战
然而,这种情况提出了一个独特的挑战。因为我们正在处理分类预测,所以我们可能想要使用交叉熵损失来训练我们的模型。在这种情况下, 知道你的损失函数的要求是非常重要的。例如,看看 PyTorch 的nn.CrossEntropyLoss()
输入要求(强调我的,因为老实说有些文档需要帮助):
输入 应该包含每个类的原始的、未标准化的分数。 输入 必须是一个大小为(minibatch,C)… 的张量
这个准则 【交叉熵损失】 期望一个类索引在[0,C-1]范围内作为 的目标 为一个 的 1D 张量 的大小 minibatch 的每一个值。
好吧,无意冒犯 PyTorch,但那是狗屎。我不确定这是不是英语。我来翻译一下:
- 预测(上面称为输入,尽管有两个输入)应该是*(迷你批处理,C)** 的形式,其中 C 是可能的类的数量。在我们的例子
**C = 50**
中。* - 作为第二个输入的目标的大小应该是 (minibatch,1) 。换句话说,目标不应该被一键编码。但是,它应该是标签编码的。
这对你来说意味着你必须以两种不同的方式来塑造你的训练数据。输入x
将被一键编码,但是你的目标y
必须被标签编码。此外,x
的独热列应按照y
的标签编码进行索引。
离别的思绪
LSTMs 的实现可能很复杂。通过了解您试图解决的问题的个人需求,然后相应地调整您的数据,可以消除这种复杂性。
上面所有的代码都是未经测试的伪代码。如果你想看看上面两个例子的完整的 Jupyter 笔记本,请访问我的 GitHub:
我希望这篇文章有助于您理解通过 LSTM 的数据流!
其他资源:
- 拉兹万·帕斯卡努等论训练递归神经网络的难度,2013*https://arxiv.org/pdf/1211.5063.pdf*
- PyTorch 用户论坛:https://discuss.pytorch.org
照片致谢:
基于歌词的歌曲推荐,带有 Doc2Vec 嵌入和 Spotify 的 API
使用深度学习和自然语言处理理解歌词。
近 3000 首歌曲嵌入的二维表示,由艺术家着色。
单词嵌入和歌曲嵌入
单词嵌入对于自然语言处理来说是一个非常有用的工具。它们通常作为神经网络的参数被学习,并允许我们将单词映射到数字。更具体地说,它们允许我们将单词映射到高维向量。既然词向量用数字来表示信息,我们就可以利用它们之间的关系来理解它们所表示的词之间的关系。
如果我们可以嵌入单个单词,那么我们就可以嵌入句子、段落,甚至整个文档。事实证明,如果你能找到一种方法使它适合一个模型的架构,你可以为任何东西创建嵌入。
通过基于歌词训练歌曲嵌入,我们可以测量空间中点之间的关系,以理解歌曲之间的关系。
用例:歌曲推荐
如果我们已经训练了歌曲嵌入,那么我们将有一个对应于每首歌曲的 N 维向量。我们可以计算出从一首歌到其他每首歌的距离。那么,“最接近”的歌曲就是会被推荐的歌曲。
我们需要做的只是获取一些歌词,训练嵌入,然后构建一个可以测量距离并提供推荐的应用程序。
数据
我用的是 musiXmatch 数据集,这是百万首歌曲数据集的官方歌词集。我选择这个数据集是因为它包含 237,662 首歌曲,是可供研究的最大的干净歌词集。
由于版权问题阻止了完整的原创歌词的分发,数据以单词包的形式出现。这意味着我们不能按照单词出现的顺序来获取它们。取而代之的是,我们得到一个单词列表以及它们在每首歌中出现的次数。
单词袋格式可能会导致一些信息丢失,但这是一个很好的起点。Kaggle 上也有一些数据集包含了完整的歌词,也可以使用。
建模
我们建模的目标是学习数据集中歌曲的高维嵌入。这可以通过分布式单词包段落向量(PV-DBOW) 模型来完成,该模型以如下方式工作。
在我们的例子中,段实际上是一首歌。在训练的每次迭代中,对文本窗口进行采样以创建段落矩阵。然后,从该文本窗口中随机抽取一个单词。我们尝试使用段落矩阵作为输入来预测单词,并对模型权重进行更新。这些权重包括构成段落向量的权重。
如果我们有原始歌词,我们可以使用分布式内存段落向量(PV-DM)。这个模型可能会通过考虑单词出现的顺序来改善我们的结果。关于段落向量的更多信息可以在本文中找到。
Gensim 是我们将使用的工具。它是一个 python 库,使得实现上述 PV-DBOW 模型变得很容易。该笔记本包含用于训练和可视化 musiXmatch 数据集歌词嵌入的代码。
t-SNE 和可视化
t-分布式随机邻居嵌入(t-SNE) 是一种降维技术,对于可视化高维数据特别有用。它基于高维空间中的点的邻域来估计概率分布,并试图在低维空间中重建该分布。
t-SNE 的一个好处是它倾向于保持当地的关系。因此,我们可以在低维中绘制点,以了解高维空间中的关系。
当应用于 musiXmatch 数据集时,它看起来像这样。每个点代表一首歌,由艺术家上色。轴上的值本身没有意义,但它们有助于创建歌曲之间距离的概念。
艺术家之间的关系可以保证模型按预期工作。总的来说,我们应该期待看到相似艺术家的歌曲比不同流派艺术家的歌曲更接近。
三位艺术家的歌词嵌入
十位艺术家的歌词嵌入
构建应用程序
Flask 是一个用于构建 web 应用的 python 库。使用 Flask,我构建了一个应用程序,允许用户在 musiXmatch 数据集中搜索音乐,并与 Spotify 的 API 进行交互。幸运的是,我找到了一个很好的资源,而且不用重新发明轮子: Spotify-Flask 作者 mari-linhares 。
- 您可以通过此链接访问该应用:http://52.10.28.182:8081/
登录 Spotify 的认证流程并授予权限后,用户可以导航到一个页面,提示他们输入歌曲标题、艺术家和要返回的歌曲数量。如果可能的话,用户的顶级艺术家会被推荐给他们以获得灵感。
一旦选择了初始歌曲,通过测量嵌入之间的余弦相似度来找到相似的歌曲。相似的歌曲与 Spotify 的目录交叉引用,可用的歌曲将返回给用户。
如果用户喜欢返回的歌曲,他们可以将它们保存到 Spotify 播放列表中。如果没有,他们可以再试一次。
未来的工作
歌曲推荐只是歌词嵌入的众多应用之一。歌词向量可以用来揭示艺术家和他们的音乐之间的新关系。
另一方面,基于歌词的歌曲嵌入可能只是更大的推荐引擎的一小部分。当前的应用程序在搜索类似的歌曲时只使用歌词,但是当除了歌曲的内容之外还考虑歌曲的发音时,肯定会获得更好的推荐。
我将很高兴收到以上任何反馈。欢迎发表评论,或通过 areevesman@gmail.com 的Linkedin/电子邮件联系。
资源
该项目的相关资源包括如下。
链接到应用程序
代码
数据
Gensim 和段落向量
关于 t-SNE 的更多信息
网络应用
M5 预测-准确性
使用 Xgboost、Catboost、Lightgbm 进行预测比较
介绍
在本博客中,使用 R 对 M5 竞争数据进行探索性数据分析,使用 Xgboost、Catboost、Lightgbm、和脸书预言家预测 28 天的销量。通过比较 SMAPE 误差率和一个标准误差规则来选择最佳模型。
竞争背景:
Makridakis 竞赛(也称为 M 竞赛)是由预测研究员 Spyros Makridakis 领导的团队组织的一系列公开竞赛,旨在评估和比较不同预测方法的准确性。名为 M-Competition 的第一次比赛是在 1982 年举行的,当时只有 1001 个数据点,模型的复杂性和数据规模随着每次连续迭代而增加。
比赛链接:https://www.kaggle.com/c/m5-forecasting-accuracy
目标:
今年 3 月(2020 年),第五届迭代命名为 M5 竞赛举行。本次 m5 竞赛旨在预测未来 28 天(即截至 2016 年 5 月 22 日)的日销售额,并对这些预测进行不确定性估计。在这篇博客中,我只是要做预测,不确定性将在我的下一篇博客中用最佳选择的模型进行。
数据集:
所提供的数据集包含来自沃尔玛的 42,840 个分层销售数据。该数据集涵盖了美国三个州(加利福尼亚州、德克萨斯州和威斯康星州)的商店,包括从 2011 年 1 月 29 日到 2016 年 4 月 24 日这五年的商品级别、部门、产品类别和商店详细信息。此外,它还有解释变量,如价格、快照事件、星期几以及特殊事件和节日。
图 1:M5 系列数据组织方式概述
该数据包括在 3 个州的 10 家商店销售的 3 大类 7 个部门的 3049 件产品。分层聚合捕获了这些因素的组合,这使得执行自下而上的方法或自上而下的方法变得可行。例如,我们可以为所有销售创建一个时间序列,或者分别为每个州执行,等等。
假设
根据给出的数据,可能影响销售的一些因素如下:
- 日- 顾客购物的时间和支出大多取决于周末。许多顾客可能只喜欢在周末购物。
- **特殊活动/节假日:**根据活动和节假日的不同,客户的购买行为可能会发生变化。对于像复活节这样的节日,食品销售可能会上升,对于像超级碗决赛这样的体育赛事,家庭用品销售可能会上升。
- **产品价格:**销售受产品价格影响最大。大多数顾客在最终购买之前都会检查价格标签。
- **产品类别:**产品的类型很大程度上影响销售。例如,与食品销售相比,电视等家用产品的销售将会减少。
- 地点:地点在销售中也起着重要的作用。在像加利福尼亚这样的州,顾客可能会购买他们想要的产品而不考虑价格,而另一个地区的顾客可能对价格敏感。
在深入研究数据之前,先快速概述一下每个州的人口和收入中位数:
加利福尼亚
人口:3951 万
家庭年收入中位数:75277 美元
得克萨斯州
人口:2900 万
家庭年收入中位数:59570 美元
威斯康星州
人口 582.2 万
收入中位数:60733 美元
探索性数据分析是为了检验这些假设。
探索性数据分析
让我们开始数据分析,首先了解哪一个州的销售额最高,以及这三个州的各个部门的销售额。
探索商店的位置
本节旨在回答:
- 哪个州的销售额最高?
- 哪个部门的销售额最高?
- 表现最好的商店?
图二。每个州的总销售额
不出所料,食品部在这三个州都创下了最高的销售额。此外,从图 2 中可以看出,加州的总销售额最高。拥有 4 家商店和更多的人口可能是原因。令人惊讶的是,与德克萨斯州相比,人口密度较低的威斯康星州也创下了相同的销售额。为了更好地理解,绘制了每个商店的销售额。
图三。店内总销售额
因为与其他商店相比,ca3 的销售额几乎是两倍。CA_3 可能是一个更大的商店。人口密度和收入中位数也影响这些销售。
现在,我们已经了解了不同地点对销售的影响,现在让我们深入了解各个部门
探索价格和产品类别
本节旨在回答:
- 每个部门有多少不同的产品?
- 不同州所有可用产品的平均价格是多少?
- 哪个部门销售额最高最少?
图 4 可用产品总数
Food_3 部门的可用产品数量更多。因此,食品 3 部门可能包括日常消费的食品,如牛奶等。现在,让我们看看价格是否对销售有任何影响
图五。所有产品的平均价格
可以看出,爱好 _1 部门均价最高,美食 3 最低。尽管与德克萨斯州和威斯康星州相比,加利福尼亚州人口的平均家庭年收入更高,但三个州的平均价格几乎相似,这使得加利福尼亚州人口更能负担得起这些产品。现在让我们来看看每个产品在各州的销售情况。
图六。所有产品的总销售额
这里,平均价格最低的食品 3 部门销售额最高。更有趣的是,尽管爱好 1 的平均价格最高,几乎是爱好 2 的两倍,但爱好 1 的销售额也很高。家庭 1 销售额很高。这可能表明该产品部门拥有肥皂和洗涤剂等日常必需品。
如前所述,加利福尼亚州的销售量较高,其次是德克萨斯州和威斯康星州。与德克萨斯州相比,威斯康辛州的食品 1 和食品 2 类的销售额更高。因此,可以假设威斯康辛州的人口喜欢食物 1 和食物 2 部门。
我们能够证明一些与产品价格、位置和产品类别相关的论文陈述。现在,让我们进入时间序列分析,看看不同的工作日、月份和事件是如何影响销售的。
时间序列分析
本节旨在回答:
- 总销售额的每日季节性趋势
- 哪个月的销售额最高和最低?
- 在不同的州,人们更喜欢哪个工作日去杂货店购物?
绘制所有年份的时间序列,以观察不同部门所有 3 个州的季节性趋势。
图 7。部门的每日销售趋势
季节性趋势遵循相同的模式,并且在所有 3 个州都是平行的。最高的食品是销售额最高的部门,其次是爱好和家庭。为了更好地理解每日趋势,绘制了 2015 年的热图。
图 8。2015 年日历热图
沃尔玛似乎在圣诞节不营业。可以看出,在新年和感恩节这样的日子里,销售额很少。这是由于节日期间工作时间减少。此外,与平时相比,周末的销售额相对较高。
月度销售趋势
图九。全州每月销售趋势
令人惊讶的是,这三个州 5 年来的趋势都是一样的。可以看出,总销售额每年都在增加。这种趋势是因为沃尔玛每年都会推出新产品。此外,每年增加或减少的趋势模式几乎相似。为了更好地理解月度趋势,我们将一年中的所有月度销售额进行了分组,并绘制了图表。
图 10。类别月度销售趋势
可以看出,销售额每年都在增长,并在三月份达到顶峰。三月之后,销售额开始下降,直到五月,六月销售额骤降至全年最低。6 月份之后,销售额在两个月内逐渐增加,直到 11 月份才进一步下降。
每周趋势
图 11。全州每周销售趋势
不出所料,与正常工作日相比,周六和周日的总销售额更高。即使在这里,威斯康辛州也是一个例外,周六是销售高峰,而加州和德克萨斯州是周日。所以,也许威斯康辛州的居民更喜欢在周六去杂货店购物。
为了更好地观察工作日和月份的趋势,绘制了工作日和月份的总状态热图。
图 12。工作日与月份销售热图
这张销售热图有一个有趣的模式。可以观察到,每个月记录的销售数量都在增加。也就是说,如果在二月份的星期一记录了最高的销售额,我们可以看到在三月份星期二有更多的销售额。
假日和特殊活动的销售趋势:
本节旨在回答:
- 节日活动和节假日如何影响销售趋势?
- 哪个节日的销售额最高?
图 13。特殊活动的总销售额
超级碗体育赛事的销售额最高。国庆节那天,销售额很低。宗教节日当天的销售情况也是如此。为了观察销售趋势,绘制了 2015 年的季节性趋势图。
图 14。特殊活动的总销售趋势
观察结果:
- 在像新年和复活节这样的节日,由于营业时间减少,销售额很低。
- 圣诞节销售额为零,可能是因为沃尔玛关门了。
- 像 NBA 决赛这样的体育赛事显示了一个有趣的洞察力,赛事前一天的销售额很高,而赛事当天的销售额下降。
- 在父亲节、母亲节等特殊日子,销售额会下降。
- 国定假日和宗教节日对体育赛事也有类似的影响。
建模:
该竞赛旨在预测 28 天的销售情况。
涉及的步骤:
- 引入滞后和滚动平均值
- 训练/测试分流
- 数字编码
- 将数据转换成所需格式( data.matrix,LGB)。数据集,Cat.loadpool )
- 参数选择
- 模型训练/交叉验证
- 预测
- 型号对比的 SMAPE 误差
- 单标准误差规则
引入滞后和滚动平均值
由于缺乏计算能力,10%的数据是使用分层抽样选择的。分层随机抽样准确地反映了被研究的人群,因为它在应用随机抽样方法之前对整个人群进行了分层。简而言之,它确保人口中的每个亚群体在样本中得到适当的代表。
由于机器学习模型,我们使用的是具有滞后天数的时间序列,滚动平均值有助于改进模型,因此引入了新的滞后变量,分别用于 1 周、2 周、1 个月、2 个月的时变效应变量。有了更好的计算能力,也可以引入 1 年的滞后,因为每年的销售模式是相似的。引入了 1 周和 1 个月滞后变量的滚动平均值和滚动标准偏差。
对于不了解滞后的人来说,一个滞后是一段固定的流逝时间;时间序列中的一组观察值被绘制(滞后)在第二组数据之后。第 k 个滞后是发生在时间之前“k”个时间点的时间段
训练/测试分流
因为我们需要用 5 年的数据来预测 28 天。所有日期小于或等于 2016 年 3 月 27 日的数据都被视为训练数据。并将日期大于 2016 年 3 月 27 日且小于 2016 年 4 月 24 日的 28 天数据作为测试数据。最后 28 天用于验证。
数字编码:
由于许多机器学习模型无法读取字符类型数据,因此所有列都应转换为数字格式。我在 R 中使用了一个简单的命令
data%>%mutate_if(is.factor, as.integer)
为什么要组装模型?
集成方法通过组合多个模型来帮助改善机器学习结果。与单一模型相比,使用集合方法可以让我们做出更好的预测。因此,集成方法在许多著名的机器学习竞赛中排名第一,因此使用 sMAPE 错误率来比较不同的集成。
为什么是 sMape?
使用 sMAPE 误差率是因为它是 M3 预报中规定的评估指标。sMape 误差率或对称平均绝对百分比误差被列为重要的但不常见的预测误差测量方法之一。然而,它在计算上的复杂性和解释上的困难使它远远落后于最常见的 MAD 和 MAPE 预测误差计算。
sMape 误差计算如下
对于任何想了解所用模型以及一个模型相对于其他模型的优势的人,这里有一个链接指向一篇比较 Xgboost vs catboost vs Lightgbm 的文章。
Xgboost:
Xgboost 需要 xgb 格式的数据。用于预测的 DMatrix 格式,因此训练集和测试集都转换为 xgb。使用下面的命令。
train_set_xgb = xgb.DMatrix(data = data.matrix(train_data[,features]), label = data.matrix(train_labels))
test_set_xgb = xgb.DMatrix(data = data.matrix(test_data[,features]), label = data.matrix(test_labels))
为 Xgboost 选择的参数如下
params <- list(booster = "gbtree",
tree_method='gpu_hist', gpu_id=0,task_type = "GPU",
objective = "reg:tweedie", eta=0.4, gamma=0 nrounds = 20,
nthreads = 10,early_stopping_round = 10)
由于我们的数据包含大量零值,使用目标 as 回归没有给出预期的结果。在浏览了一些研究的文章之后,我们发现 Tweedie 是含有大量零的非负数据的最佳模型。因此 Tweedie 目标用于训练模型。
由于最新的 Xgboost 版本支持使用 GPU,因此使用 GPU 对模型进行训练。选择 RMSE 评估度量来训练模型。给出了 10 次的早期停止循环,因此如果模型 RMSE 在 10 次迭代中没有改进,模型将停止。并且将返回最佳 RMSE 值。
最佳 RMSE 值为 2.48
进行 3 重交叉验证是为了检查模型的一致性。为交叉验证返回的最佳 RMSE 值是 2.637。
定义一个函数来计算 sMAPE 值,如下所示:
smape_cal <- function(outsample, forecasts){
outsample <- as.numeric(outsample)
forecasts<-as.numeric(forecasts)
smape <- (abs(outsample-forecasts))/((abs(outsample)+abs(forecasts))/2)
return(smape)
}
Xgboost 的 SMAPE 值为 1.897968
Catboost:
catboost 需要 load_pool 格式的数据来进行预测,因此使用以下命令将训练集和测试集都转换为 load_pool 格式。
train_cat <- catboost.load_pool(data = data.matrix(train_data_cat[,features]), label = data.matrix(train_labels))
test_cat <- catboost.load_pool(data = data.matrix(test_data_cat[,features]), label = data.matrix(test_labels))
为 Catboost 选择的参数如下
params_cat <- list(iterations = 1500,
metric_period = 100,
tree_method='gpu_hist',task_type = "GPU",
loss_function = "RMSE",
eval_metric = "RMSE",
random_strength = 0.5,
depth = 7,
early_stopping_rounds = 100,
learning_rate = 0.18,
l2_leaf_reg = 0.1,
random_seed = 93)
RMSE 被用作损失函数和训练模型的评估度量。使用 Kaggle GPU 进行 1500 次迭代的计算时间约为 5 分钟。第一轮是 100 轮。
最佳 RMSE 值为 2.36541
执行 3 重交叉验证以检查模型一致性。为交叉验证返回的最佳 RMSE 值是 2.39741。
Catboost 的 sMAPE 值为 1.34523,,似乎比 xgboost 更好。
Lightgbm
lighgbm 需要 lgb_dataset 格式的数据进行预测,因此训练集和测试集都转换为 lgb。使用以下命令格式化数据集。
train_set_lgb <- lgb.Dataset(data=as.matrix(train_data[,features]), label = as.matrix(train_labels))
test_set_lgb <- lgb.Dataset(data=as.matrix(test_data[,features]), label =as.matrix(test_labels))
valids=list(train=train_set_lgb,test = test_set_lgb)
使用的参数如下
parameters =list(objective = "tweedie",
tweedie_variance_power=1.1,
metric ="rmse",
force_row_wise = TRUE,
num_leaves=90,
learning_rate = 0.03,
feature_fraction= 0.5,
bagging_fraction= 0.5,
max_bin=100,
bagging_freq = 1,
boost_from_average=FALSE,
lambda_l1 = 0,
lambda_l2 = 0,
nthread = 4)freeram()
Tweedie 用作目标函数,RMSE 用作训练模型的评估度量。
最佳 RMSE 值为 2.1967701
执行 3 重交叉验证以检查模型的一致性。为交叉验证返回的最佳 RMSE 值是 2.21。
Lgboost 模型的 sMAPE 值为 **1.14,**是所有 3 个模型中最好的。
图 15。LGB 模型的特征重要性
基于 sMape 误差,Lgb 是最好的模型。只是为了确认,一个标准误差适用于所有 3 个模型的交叉验证 RMSE 值。
一个标准误差规则:
对于那些不知道一个标准误差规则的人,在交叉验证中使用一个标准误差规则,其中我们采用最简单的模型,其误差在最佳模型(误差最小的模型)的一个标准误差内。
图 16。一个标准误差图
结论:
即使在这里,LGB 也是 RMSE 值最低的表现最好的车型。因为其他模型平均误差点不在 Lihtgbm 模型的标准差范围内。根据一个标准误差规则,Lightgbm 被选为最佳模型。
表现最好的模型的提交分数在 0.46 左右。
附录
所有绘图都是使用 r .中的 ggplot2 包制作的,因为代码非常大。我把我的 Kaggle 笔记本分享给任何想在比赛中使用代码的人。
ka ggle:https://www . ka ggle . com/jaswanthhbadvellu/cat-xgb-lgboost-prophet
数据集:【https://www.kaggle.com/c/m5-forecasting-accuracy/data
分层采样后的样本数据集如下所示
深度学习的 MacBook Pro?让我们试试。
它与英伟达 GPU 驱动的笔记本电脑相比如何?
我昨天买了一台 MacBook Pro。2019 款,13”带基础配置(后面会详细介绍)。作为一名数据科学家和深度学习爱好者,我一开始对整个苹果的想法有点怀疑,因为深度学习需要 GPU 在“合理”的时间内训练,而 GPU 不是 MAC 的主要卖点。
由 Ash Edmonds 在 Unsplash 上拍摄的照片
尽管如此,我还是决定尝试一下,因为我早就想要一台 MacBook 了。虽然我仍然不习惯键盘(布局方面),但对我来说,整个操作系统比 Windows 好得多。
我已经多次尝试了各种版本的 Linux ,但是所有的版本都感觉像是还在 alpha 测试之前,尽管事实并非如此(过热问题、睡眠问题、wifi 问题……)。
这篇文章针对的是那些面临着和我昨天一样的 MacBook 困境的数据科学家——买还是不买**。如果你没有时间通读整篇文章,简短的回答是是的——如果你有钱并且想要新的东西,就去买 Mac。**
您将不得不继续关注原因和性能比较。
这篇文章的结构如下:
- 硬件比较
- 使用的数据集和库
- 深度学习—性能比较
- 结论
现在,这不会是一个深度学习教程,因为我只会分享两台笔记本电脑在训练中的表现。如果您想了解这个数据集的完整概要,请告诉我。
无论如何,这个介绍比我预期的要长,所以让我们结束它,开始你来这里的目的。
硬件比较
直到昨天,我还没有 MacBook Pro,所以我已经在我的联想军团 Y540 笔记本电脑上完成了所有数据科学和深度学习的东西,规格如下:
- CPU:英特尔 I5 9300H
- GPU:英伟达 GeForce GTX 1650 4GB
- 内存:16GB DDR4
- 固态硬盘:512GB
虽然笔记本电脑的功能不是非常强大,但我发现它足以处理知名数据集的临时深度学习任务,甚至可以处理一些大型彩色图像。
只是我快速说明一下——我是用 CUDA 在 GPU 上训练模型,所以要记住这一点。
然后是Mac(13“2019。型号)具有以下规格:
- CPU:英特尔 I5 QC 1.4GHz
- GPU:英特尔 Iris Plus 645 1536MB
- 内存:8GB
- 固态硬盘:128GB
因此,仅从规格来看,它对 Mac 来说并不太好——但让我们在接下来的部分看看它的表现如何。
使用的数据集和库
最近在我的大学,我们处理了时尚-MNIST 数据集。如果你做过深度学习,我相信你对它很熟悉,但以防万一,这里有一点背景知识——来源: Kaggle 。
时尚-MNIST 是 Zalando 文章图像的数据集,由 60,000 个样本的训练集和 10,000 个样本的测试集组成。每个示例都是 28x28 灰度图像,与 10 个类别的标签相关联。[1]
更准确地说,我们有 10 类图像:
- 0: T 恤/上衣
- 1:裤子
- 2:套头衫
- 3:着装
- 4:外套
- 5:凉鞋
- 6:衬衫
- 7:运动鞋
- 8:袋子
- 9:短靴
好了,现在你已经有了数据集的一些基本信息。我唯一要做的就是说明我在使用哪个深度学习库。如果你读过我的任何帖子,你可能知道我是一个 PyTorch 用户,这篇文章也不会例外。
很好,现在我们知道了一切-让我们比较一下基本型号的 MacBook Pro 与支持 GPU 的 Windows 笔记本电脑之间的差异。
深度学习—性能比较
现在我已经开始在两台笔记本电脑上运行模型,看看 MacBook 会落后多少。在向您展示结果之前,您可能还会对模型架构感兴趣,如下图所示:
所以这里没什么特别的,我用 ReLU 作为隐藏层的激活函数,用对数 softmax 作为输出层。此外,我已经在内核大小为 2x2、步幅为 od 2 的两个卷积层之后执行了 MaxPooling 。是的,差点忘了——这个模型被训练了 15 个时期。
这是您的平均设置,将产生大约 150,000 个可训练参数(权重和偏差),神经网络需要针对这些参数进行优化。
现在到了你期待已久的部分——实际性能对比!这是图表:
联想:9 分 36 秒,MacBook: 10 分 13 秒
如你所见,联想笔记本电脑表现更好,但也好不了多少。我预计会有更严重的差异,主要是因为联想笔记本电脑有“像样的”GPU,而 MacBook 没有。
因为通风系统在联想笔记本电脑上无可挑剔,而在 Mac 上几乎不存在,Mac 确实变热了,所以这是你应该考虑的另一个方面。
由于这篇文章的唯一目标是研究 MacBooks 实际上能否处理深度学习,以及它们在这方面的表现如何,这里我将停止。
结论
我花了很长时间才决定买苹果电脑。我一直喜欢它的想法,总体来说操作系统似乎更好,但我只是担心它在数据科学和深度学习任务方面的表现会很糟糕。
我很高兴我已经做出了改变——只是希望我能早点做出改变。
感谢阅读,我希望你喜欢它。
喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
参考
[1]https://www.kaggle.com/zalando-research/fashionmnist
用 BERT 进行机器理解
使用深度学习进行问题回答
迈克尔·泽兹奇在 Unsplash 上的照片
在 Github 的资源库中可以找到 这里有 。本文将介绍如何设置它。预计时间:30 分钟以内。
机器(阅读)理解是 NLP 的领域,在这里我们教机器理解和回答使用非结构化文本的问题。
成为深度学习专家。掌握深度学习的基础,打入 AI。填满的星星填满的星星…
www.coursera.org](https://www.coursera.org/specializations/deep-learning?ranMID=40328&ranEAID=J2RDoRlzkk&ranSiteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&siteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&utm_content=2&utm_medium=partners&utm_source=linkshare&utm_campaign=J2RDoRlzkk)
2016 年,StanfordNLP 整合了 SQuAD(斯坦福问答数据集)数据集,该数据集由超过 10 万个根据维基百科文章制定的问题答案对组成。面临的挑战是训练一个机器学习模型来回答基于上下文文档的问题。当提供一个上下文文档(自由形式的文本)和一个问题时,模型将返回最有可能回答问题的文本子集。
来自小队数据集的示例条目
世界各地的顶级人工智能实践者解决了这个问题,但两年后,没有模型击败人类基准。然而,在 2018 年底,谷歌大脑的聪明人推出了 BERT(来自变压器的双向编码器表示),这是一种通用语言理解模型。通过一些微调,该模型能够在与小队测试集进行比较时超过人类基准。
来自 paper SQuAD: 100,000 多个用于机器理解文本的问题,这些是用于评估的指标:
**完全匹配。**此指标衡量与任何一个基本事实答案完全匹配的预测的百分比。
**(宏观平均)F1 得分。**此指标衡量预测和真实答案之间的平均重叠。我们将预测和基础事实视为一袋袋的令牌,并计算它们的 F1。我们对给定问题的所有基本事实答案取最大值 F1,然后对所有问题取平均值。
基于初始小队数据集:
- 人类注释者获得了 82.304% 的精确匹配分数和 91.221% 的 F1 分数
- 最初的 BERT 模型(在排行榜上排名第 11,主要被 BERT 的其他变体击败)获得了精确匹配分数 85.083% 和 F1 分数 91.835%
今天,我将向你展示如何使用 BERT 建立你自己的阅读理解系统。在 Github 仓库中可以找到 这里 。
要开始,你需要 Docker。🐳
设置 Docker
Docker 对于容器化应用程序很有用。我们将使用 Docker 使这项工作更有用,结果更具可重复性。按照这些说明在你的系统上安装 Docker。你还需要在 macos 和 windows 上自带 Docker 的docker-compose
。如果你用的是 Linux,你可以在这里安装。
从我的 Github Repo 本地保存代码
除了阵容数据和预先训练的重量,所有的代码和必要的依赖都在报告中。**注:**只有自己想训练模型才需要数据。如果没有,你可以使用我预先训练的重量。**另一个注意:**我不建议训练模型,除非你有强大的 GPU 或者大量的时间。
如果你想自己训练模特…
点击下载小队 2.0 数据集。将“训练集 2.0 版”和“开发集 2.0 版”保存到bert_QA/data
。
如果您想使用预先训练的重量…
我已经用 SQuAD 2.0 数据集训练了这个模型。你可以在这里下载。解压文件并将内容保存为bert_QA/weights
。
创建 Docker 容器
Docker 容器是使用 docker 映像中提供的指令构建的工作环境。我们需要一个docker-compose.yaml
配置文件来定义我们的容器的外观。
我为 Pytorch 变形金刚做了一个定制的 docker 图片,你可以在 dockerhub 上找到。出于本教程的目的,您不需要提取任何图像,因为配置文件已经这样做了。配置文件还将把我们的本地bert_QA
文件夹作为/workspace
挂载到容器中。
- 通过从终端/shell 运行根目录中的
docker-compose up -d
来启动我们的容器。第一次需要几分钟。 - 使用
docker ps
检查我们的容器是否启动并运行。
- 将 bash shell 附加到正在运行的容器:
docker exec -it <your_container_name> bash
训练模型
如果你使用我预先训练的重量,跳过这一步。我们将使用由 huggingface 提供的默认训练脚本来训练模型。
在 bash shell 中运行:
**注意:**如果没有 GPU,per_gpu_train_batch_size 不会做任何事情
这将训练并保存模型权重到weights
目录。
使用模型进行推理
现在让我们用这个模型来做一些很酷的东西。
在 shell 中启动一个 ipython 会话,并导入ModelInference
模块以从weights/
加载权重。将上下文文档作为参数传递给mi.add_target_text()
。摄取完语料库后,使用mi.evaluate()
提问。只有当模型确信答案存在于文本中时,模块才会返回答案。否则,模型将输出“未找到有效答案”。
结论
在过去的几年里,NLP 取得了长足的进步。预训练的 BERT 权重对 NLP 的影响类似于 AlexNet 对图像识别的影响。它实现了自然语言理解的许多新颖应用。
机器智能与企业
一个实用的外部视角——企业 ML/AI 成熟度
我在金融服务业工作了将近 20 多年。在那段时间里,我在不同的职能部门工作过,但我的工作总是与将交易与业务成果联系起来有关。随着时间的推移,我的工作标签发生了变化,从分析到分析到数据科学到机器学习到人工智能,但目标和高级方法保持不变。
在同样的 20 年里,计算和存储出现了爆炸式增长,并对我的工作产生了深远的影响。例如,任何数据科学家都可以很容易地询问交易+结果数据来导出链接。此外,这与数据科学家的短缺合谋创造了一个*雇佣军模型。*在这种情况下,很少有数据科学家会尝试将他们的工作与完整的业务环境和相关工作联系起来。
由于更容易的 ML/AI,企业最终形成了一大堆模型,如营销中的 RFM 模型(新近性、频率、货币化)、定价中的 LTV(生命时间价值)和需求模型保留模型运营中的等。现在缺少的是一个将模型纳入一个视图的系统,以供那些可以使用它来驱动企业战略或政策的人使用。
传统上,我们认为人工智能成熟度包括以下能力:(1) 计划工作 ( 基础水平);(2) E 执行工作 ( 称职等级);音阶作品 ( 顶级)。这种观点真的是“由内而外”的,而且有点短视,因为做大量的 ML/AI 显然不等同于超大的业务成果。然而,可悲的是,这是支持成熟度评估的潜在但普遍的观点。
在我们的专业领域内,当企业不愿意进行 ML/AI 投资和押注时,我们看到了这一点。有鉴于此,我认为我们需要考虑一个新的最高水平的成熟度(我会把这个水平称为“务实”,但我这一行的许多人可能会认为这是愤世嫉俗的——是的,他们这样做是正确的)。这个层次的企业能够综合定制的 AI/ML 模型,并将其翻译成商业语言:利润、增长和客户满意度。
只有当它驱动系统将模型带入单一视图时,ML/AI 的力量才能得到充分释放。这种观点可以帮助战略家或政策制定者理解对过去的业绩、不断变化的竞争格局、宏观指标等做出反应的“假设”行动。。…
在我的下一篇文章中会有更多的介绍。如果你很好奇,我下一篇文章的暂定标题是all ML的母亲(或 MOAML,是对印地语中“mamool”的致敬,我理解为“普通”的意思)。我们需要非常努力地工作,现在,让人工智能相关而不是时尚。这将要求我们让它说商业语言,从而让它从崇高变得简单。
机器学习单词嵌入
没有数学的介绍
单词是许多自然语言中的关键结构。它们被赋予了意义。往往因环境而大相径庭。拿 python 来说。这在计算机编程和生物学中意味着完全不同的东西。
要掌握一门语言,人和计算机都是从掌握关键词开始的。这篇文章试图解释计算机是如何掌握单词的。
用适合自然语言处理或信息检索(搜索)的形式来表示单词已经有很长的历史了。出现了两大类代表:本地和分布式。
这篇文章关注的是(I)分布式的和(ii)机器学习的表示。不熟悉本地或其他分布式表示的读者可能想先阅读自然语言处理中的单词和文本表示。
从这一点开始,我们转而使用术语单词嵌入。这是通常用来表示“机器学习的分布式单词表示”的术语。
为什么机器学习单词嵌入?
原因 1 。可以仅从丰富的文档语料库中学习单词的准确和丰富的表示。举个例子。从维基百科语料库中,我们可以机器学习数百万不同单词的好单词嵌入。对它们运行算法就行了。呈现出来。
原因二。领域特定的单词嵌入可以仅仅通过在领域特定的语料库上训练来学习。例如,从关于计算机编程的文档语料库中,嵌入单词的学习者可以了解 python 在计算机编程上下文中的含义。当然,这种含义与非编程环境中的含义完全不同。
想象一下,一个对某个领域一无所知的人,比如说计算机编程,要花多长时间才能理解它的词汇?即使是最基本的。
学习问题公式化
从高层次来看,很明显。我们想学习单词的“准确而丰富”的表达。不过有点太笼统了。我们如何知道算法是否(以及何时)学习得足够好?人们不断地与其他人互动,所以他们缺乏理解很快暴露出来。计算机还没有出现。因此,我们希望更具体地指定学习目标。
这个怎么样?我们想学习相似单词有相似表示法的表示法。嗯,这似乎也有点宽泛。事实上,我们已经获得了有用的特异性。
很容易构建成对单词的测试集,每对都标有“相似”或“不相似”。下面是一些例子
{lawyer, attorney} → similar
{computer, cat} → not-similar
标签可以被细化,例如,我们可以引入多个相似或相异的级别。
学习问题公式化:我们还没到那一步
熟悉机器学习的读者可能会倾向于认为前面提到的测试集也说明了机器学习问题。并非如此。我们来解释一下。
让我们看看,如果我们把测试集的形式作为学习问题的文字说明,我们会得到什么。我们得到:训练一个二元分类器,输入两个词,输出它们是否相似。
虽然这是一个值得解决的问题,但这不是我们的目标。我们希望输入是一个单个字。我们希望算法输出这个单词的准确而丰富的表示。测试集只是作为一种间接的手段来评估学习模型对这项任务有多好。
学习问题公式化:取两个
好吧,让我们重新开始
P1: We’d like to learn representations of words in which similar words have similar representations.
考虑将此重新表述为
P2: We’d like to learn representations of words that capture their context.
什么是“语境”?这个词经常出现在其他词的近旁。猫的上下文将包括胡须。但不是电脑
有理由认为,语境表征相似的词本身也是相似的。因此,解决 P2 问题也是解决 P1 问题的好办法。
我们取得了进展。我们之前的公式包括输入两个单词。这才一个!
嗯。我们如何获得(单词,上下文)对的训练集?在这一点上,我们甚至不知道如何将上下文的概念塞进一个变量中,这个变量可以作为我们的预测目标!
好吧,让我们先解决“将上下文填充到变量中”的问题。我们将一个单词的上下文建模为词典中单词的概率分布。以猫为例。胡须在猫的上下文中的概率应该很高。计算机在猫的上下文中的概率应该很低。
上下文向量
我们在本帖中描述的学习方法最好在神经网络环境中描述。神经网络喜欢在向量空间上操作。也就是说,它们将输入向量映射到输出向量(或标量),通常在两者之间会发生一些神奇的事情。
我们已经完成了输出。词典中单词的概率分布是空间中的向量,其维数是单词。(所以一百万单词词典的向量空间将有一百万个维度。)向量的一个分量的值就是相应单词的概率。
输入呢?这是一个特别的词。这也可以表示为同一空间中的概率向量。与单词相关联的维度的值为 1,其余为 0。
因此,我们当前的架构可以描述为
I ⇒ magic ⇒ O
I 和 O 是同一空间上的概率向量,而“魔术”是在它们之间发生的任何事情。
训练集?
为了学习,我们需要一个训练集(单词、上下文)对。不清楚如何建造。单词不会被贴上上下文的标签。
我们可以从具有代表性的文档语料库中估计单词的上下文向量。在这个词附近出现(足够频繁)的词是在它的上下文中,那些不在它的上下文中的词不是。
我们所说的“代表”是什么意思?我们指的是与我们试图学习的内容相匹配的语料库。学习计算机编程术语,我们的语料库应该由计算机编程文档组成。
训练集简化
建立上述训练集包括从语料库中学习各种单词的上下文向量。我们可以简化这个。相反,我们可以用一组足够接近的成对单词来训练,例如在同一个句子中。表示这样的一对( word1 , word2 )。我们将此解释为单词 2 出现在单词 1 的上下文中的实例。
这里有一个例子。
Sentence: the **dog** and **cat** are **black** Training Set: dog → cat, cat → dog, dog → black, black → dog, cat → black, black → cat
训练实例仅限于加粗的实例。(剩下的就当是停用词吧。)
将来自我们语料库中所有文档的所有句子的这种对流传送到学习算法将有效地向算法揭示每个单词的上下文向量。
这种简化对我们有两方面的好处。
首先,它简化了构建训练集的过程。我们可以独立处理每个句子。简单地发出由此产生的训练对。我们甚至可以在一个流动的,即连续学习的环境中做到这一点。想象一下新文档不断到达,就像 web 级搜索引擎的索引器一样。我们可以从他们那里即时流出新的训练实例。
第二,有利于学习算法。与输入相关联的目标是概率向量,其质量集中在一个单词上。这个目标比一个任意的概率向量更清晰。
好了,现在谈谈学习算法。我们只会看到一个。传达主要思想就足够了。也就是说,那些寻求从大型语料库中的大型词典上建立工业强度单词嵌入的人需要阅读更多。
连续词袋模型
这个描述相对于最初的描述有所简化,尽管对于我们在这篇文章中要解决的问题来说已经很好了。
这是一个只有一个隐藏层的神经网络。
I ⇒ H ⇒ O
好了,我们用 H 代替了魔法。确实神奇!
这两个符号下面发生了什么?这在下面描述。
H = W1*I O=probability_normalizer(W2*H)
让我们解释一下数据是如何从输入流向输出的。我们从输入向量 I 开始。我们用矩阵 W1 乘以 I 。这给了我们一个隐藏向量 H 。接下来,我们用矩阵 W2 乘以 H 。得到的向量还不一定是概率向量。我们对它应用概率规格化器,把它转换成一个。这就变成了我们的输出向量 O 。
一些问题仍然存在。首先,学习发生在哪里?第二,这个概率规格化器的概念有点抽象。
对第一个问题的回应。实际上,我们到目前为止描述的是输入到输出的数据流。我们将在一两分钟后开始实际的学习。我们将学习的参数是矩阵 W1 和 W2 中的值。
对第二个问题的回应。下面是两个概率规格化器的具体例子。两者都假设输入是一个具有非负值的向量。
第一个,姑且称之为简单,只是取每个值,除以所有值的和。第二个称为 softmax ,首先对值取幂,然后应用简单的规格化器。softmax 是在实践中使用的。为什么?在我们描述了实际的学习算法之后,我们将给出一些直觉。
以下是两个规格化函数的例子。
simple([1,3,5]) → [1/9,3/9,5/9]
softmax([1,3,5]) → simple([e¹,e³,e⁵])
在神经网络术语中,概率归一化器是一个矢量激活函数的实例。
更多要点
鉴于学习的过程将包括学习从 I 预测 O ,一旦我们学习得足够好,我们将只提取权重矩阵 W1。我们会扔掉 W2。
我们只关心从 I 到 H 的映射。 H 将作为由 I 表示的单词的表示。(也就是说,为了学习一个好的映射 I → H ,我们别无选择,只能解决完整的学习问题,因为我们没有关于 H 的目标,只有关于 O 的目标。)
另一个关键点是,我们会有意将 H 的维度限制为远小于 I 和 O 的维度。鉴于 I 和 O 可能有几百万个维度,我们将强制 H 有几百个,可能一千个,也可能更少。想法是迫使学习算法学习密集单词表示。
理由是这样的。首先,这是否可行?是的。单词有结构,否则一开始就不会有任何单词相似的概念。所以我们应该能够将 I 空间压缩到一个维度更低的空间。事实上,很难想象有超过 20 个描述单词的正交潜在属性!也许我们只是想象力不够丰富。所以让我们把这个乘以五倍。甚至更好,百倍。这还是在低几千!
好的,我们认为我们已经解决了可行性问题。接下来,我们为什么要这么做?(可行不代表是个好主意。)原因是密集表示更好地概括。直觉很简单:如果我们认为单词的潜在特征比它们的数量少得多,那么强迫学习者映射到低维空间将比试图学习映射到原始向量空间更好地概括。
最后,学习!
我们将通过一个简单的例子来集中传达直觉。没有数学。
我们的例子是在一个只有四个单词 A,B,C,d 的词典上。我们将 H 设为二维。我们将使用训练集
(A,B), (B,A), (C,D), (D,C)
我们将从空白状态开始学习,将 W1 和 W2 中的所有值随机初始化为较小的正值或负值。接下来,我们将呈现第一个训练实例的输入 A,其编码为 1000。所有可学习的权重都接近 0;所以 H 会是(0,0),W2* H 会是(0,0,0,0)。我们假设 probability_normalizer 激活函数将这个 H 映射到(、、、)。目标是 B,具体来说,是编码(0,1,0,0)。这个目标与预测大相径庭。所以我们需要学习。
接下来发生的事情最好用一张图来传达。
学习范例
在图中, T 表示目标输出。从 H 到 O 的圆弧上的+s 和-s 表示根据 O和 T 之间的差值改变重量的方向。我们看到 B 的产出的权重应该增加;其余减少。(这是因为 B 的产量太低;其余的产量太高了。)
我们还没完。我们还需要计算从 I 到 H 的权重调整。为什么?因为这些权重值也可能导致我们在输出端看到的误差。
这些调整是通过著名的反向传播算法计算的。正是这种算法,在这种隐藏的基于层的架构中利用适当选择的激活函数(在我们的情况下是概率归一化器),提供了魔力。
接下来发生的事情最容易用数字来描述。设 H 1 表示 H 的第一个分量。 H 1 的当前值为 0.1。考虑 B 的输出。它看到的错误是~ 1-=。在这种情况下,如果我们能够以某种方式在 H 1 上设置一个合理的目标,我们就会知道将重量从 I 移动到 H 1 的方向。如果 1 的目标值大于 0.1,我们会降低权重。如果 1 的目标值小于 0.1,我们会增加权重。
嗯,估计 1 的目标和估计 1 看到的误差是一样的。这一点我们可以估计如下。考虑一个特定的输出节点。它的误差是目标输出减去实际输出。我们首先通过 probability_normalizer 反向传播这个误差,然后通过从 H1 到这个输出节点的权重。这给了我们 H1 从这个输出节点看到的误差。输出节点上这些误差的总和。是 H1 认为的完全错误。
让我们一步一步地解决这个问题。三个输出都有错误,其中一个(B)有错误。想象一下,这些误差通过概率归一化器成比例地反向传播。(我们只是要求你去想象,而不是假设。)加上回想一下,从 H 1 到 O 的权重是随机的,幅度很小。考虑到这两个因素,在 H 1 处对这些误差求和将大致抵消它们,即产量接近 0。
同样,H2 看到的误差也将接近于 0。这令人不安吗?不。在这一点上, H 1 和 H 2 都不知道它想要成为什么。 H 1 和 H 2 误差虽然可能接近 0,但也可能不同。因此,从 T36 到 T37,H1 和 H2 的权重可能会经历至少略有不同的调整。这将导致 H1 和 H2 在他们所学的东西上产生分歧。在许多训练实例中,在我们的例子中,这意味着在相同的 4 个训练实例中的多次迭代, H 1 和 H 2 将学习从输出中挑选不同的东西。引发这一现象的现象被称为对称性破缺。
为什么选择 Softmax?
哦,我们忘了。我们答应解释这个。直觉告诉我们,我们想要鼓励学习区分。这样想。我们在隐藏层中有一个神经元池。起初,他们不知道他们应该做什么。如果我们不鼓励他们开始歧视,他们可能会保持不承诺。我们都知道会发生什么。有没有在一个没有人想脱颖而出的委员会里?
嗯,softmax 功能就像一位高管,推动人们探索自己舒适区以外的地方。softmax 中的幂运算具有放大差异的效果。于是轻微的赢家(输家)变成了强大的赢家(输家)。
延伸阅读
【https://arxiv.org/pdf/1411.2738.pdf】T2—word 2 vec 参数学习讲解
Mikolov,Sutskever,I .,Chen,k .,Corrado,G. S .,和 Dean,J. (2013b)。词和短语的分布式表示及其组合性。神经信息处理系统进展,3111-3119 页。