# 基于C 语言实现 LSTM 算法
## 1.LSTM 算法简介
LSTM 全称是 "Long Short-Term Memory",一种用来学习大量时序序列中隐含的相关性并用于预测其可能的趋势的机器学习算法。它的应用范围包括但不局限于价格走势预测、估计剩余寿命、分析语言的情感趋向、自动写作和语音合成。
算法描述了一个用于计算的工作单元,它按照时间顺序接受自然数作为输入,通过计算得到对应的输出。当一系列输入计算完成时,也就得到了对应的一个输出序列。单个 LSTM 单元的学习能力是有限的,可以将输出的序列作为输入序列给另外一个 LSTM 作为输入,通过这种方式利用多个 LSTM 单元的组合提高整体学习能力。
## 2.LSTM 的计算过程
作为机器学习算法的一种,LSTM 的应用包括利用大量数据进行训练和根据训练得到的参数预测两个步骤。其预测过程使用正向传播算法,训练过程采用误差反向传播算法。
### 2.1LSTM 的正向传播算法
一个处理 1 维序列的 LSTM 单元有 12 个参数。这里将这 12 个参数表示为:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/aae15fce2805e2a38b684c372d4fdec4.writebug)
假设输入序列 `x` 和输出序列 `h` 分别有 n 个元素,表示为:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/640feef6e1426ef511d1658b820f3a7b.writebug)
每次计算中还会产生以下的临时变量:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/8face2178b0e1fbd85e94dc28805f9a6.writebug)
最后 LSTM 的计算可以表示为:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/1b11ff1bfca0f0a30067c8b1a4ba7d7b.writebug)
里面的一个函数符号表示 Sigmoid 函数:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/2a18c9485888beaf4c50ede770a1b62f.writebug)
### 2.2LSTM 的误差反向传播算法
假设期望输出为:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/caa97ab4c6c9606d86a281f00b932bee.writebug)
采用均方误差(MSE,Mean Squard Error)来评估实际输出与期望输出的误差:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/8cea79315d25bb63fdf1c64a8ba188a4.writebug)
那么在一次正向传播后,LSTM 输出序列 h 的每个元素对 E 的影响可以用下面的一阶偏导数表示:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/f174d797eead35f3811a9bc34a9864fd.writebug)
进行误差反向传播需要使用 E 对 12 个参数的每一个的偏导数。与普通的神经网络算法不同的是,LSTM 利用 C(t-1) 和 h(t-1) 参与第 t 次的计算,使得第 t 次之前的计算结果会对第 t 次的输出 h(t) 产生影响。
由于:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/23e282fc5393ed6e6185c4c31040b76d.writebug)
所以 t = 1 时:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/b6da16a324e27676ef94fea3fc3218ac.writebug)
当 t > 1 时:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/dac19b95493d47a2ef1479888dac678c.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/b4a90978c2951676b797b59c8359d144.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/ac3d07c8e31cad5f06999d746f351fa3.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/2b812839f63852fa4c9798ccedb5fbd3.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/97beae433d12e2552771ce1dc72af748.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/dc2c651f2ca07a5489331ebafdf2efd5.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/09f856386b6be9ba4ff6838185f6d62e.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/2c039fc5e93d36c2777054e6bb00e734.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/3e052cb6672f75253cdbf8ed3dc197c4.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/04c7d6adb7f8726db3030895c3586b2a.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/6b876255f71950174f31a3ec61fc8e5d.writebug)
![](https://www.writebug.com/myres/static/uploads/2021/10/29/5b92f67cf9ddb0ba512c2067cdd42971.writebug)
为方便计算,激活函数导数可取:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/ac7bc640d5828f0e16663c9d3317e5c2.writebug)
最后:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/8b8d29e81179a9388fdef56656180b1f.writebug)
一般情况下学习率取值:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/21c10d9758ba76c3b46b87c05da5f9de.writebug)
采用简单的梯度下降,可以在正向传播后修正参数:
![](https://www.writebug.com/myres/static/uploads/2021/10/29/e9aca0fd477368050ea350f59dedcfb1.writebug)
## 3.C 实现方法
用结构体来保存计算过程所需的变量,并提供一个函数用来初始化并返回这个结构体。后续提供一系列的函数用于操作这个结构体。
### 3.1数据结构
结构体中变量名称和算法的参数之间的对应关系是:
<table>
<tr><th>结构体变量</th><th>定义</th><th>对应算法中的变量</th></tr>
<tr><td>整数 length</td><td>int length;</td><td>表示 LSTM 计算序列长度</td></tr>
<tr><td>浮点数指针 x</td><td>double *x;</td><td>输入序列 x</td></tr>
<tr><td>浮点数指针 h</td><td>double *h;</td><td>输出序列 h</td></tr>
<tr><td>浮点数指针 f</td><td>double *f;</td><td>中间变量序列 f</td></tr>
<tr><td>浮点数指针 i</td><td>double *i;</td><td>中间变量序列 i</td></tr>
<tr><td>浮点数指针 tilde_C</td><td>double *tilde_C;</td><td>中间变量序列 <img src="images/lstm-tilde-c.png"/></td></tr>
<tr><td>浮点数指针 C</td><td>double *C;</td><td>中间变量序列 C</td></tr>
<tr><td>浮点数指针 o</td><td>double *o;</td><td>中间变量序列 o</td></tr>
<tr><td>浮点数指针 hat_h</td><td>double *hat_h;</td><td>期望输出序列 <img src="images/lstm-hat-h.png"/></td></tr>
<tr><td>浮点数 W_fh</td><td>double W_fh;</td><td>参数 <img src="images/lstm-wfh.png"/></td></tr>
<tr><td>浮点数 W_fx</td><td>double W_fx;</td><td>参数 <img src="images/lstm-wfx.png"/></td></tr>
<tr><td>浮点数 b_f</td><td>double b_f;</td><td>参数 <img src="images/lstm-bf.png"/></td></tr>
<tr><td>浮点数 W_ih</td><td>double W_ih;</td><td>参数 <img src="images/lstm-wih.png"/></td></tr>
<tr><td>浮点数 W_ix</td><td>double W_ix;</td><td>参数 <img src="images/lstm-wix.png"/></td></tr>
<tr><td>浮点数 b_i</td><td>double b_i;</td><td>参数 <img src="images/lstm-bi.png"/></td></tr>
<tr><td>浮点数 W_Ch</td><td>double W_Ch;</td><td>参数 <img src="images/lstm-wCh.png"/></td></tr>
<tr><td>浮点数 W_Cx</td><td>double W_Cx;</td><td>参数 <img src="images/lstm-wCx.png"/></td></tr>
<tr><td>浮点数 b_C</td><td>double b_C;</td><td>参数 <img src="images/lstm-bC.png"/></td></tr>
<tr><td>浮点数 W_oh</td><td>double W_oh;</td><td>参数 <img src="images/lstm-woh.png"/></td></tr>
<tr><td>浮点数 W_ox</td><td>double W_ox;</td><td>参数 <img src="images/lstm-wox.png"/></td></tr>
<tr><td>浮点数 b_o</td><td>double b_o;</td><td>参数 <img src="images/lstm-bo.png"/></td></tr>
</table>
下面的参数不是算法必须的,但是实现时会使用:
<table>
<tr><th>结构体变量</th><th>定义</th><th>说明</th></tr>
<tr><td>整数 error_no</td><td>int error_no;</td><td>错误号,无错误默认0。用于记录最后一次程序发生的错误。</td></tr>
<tr><td>字符指针 error_msg</td><td>char *error_msg;</td><td>发生的错误的文字说明,默认无错误,内容为指向字符串"\0"的指针。</td></tr>
</table>
### 3.2错误编号和错误信息
<table>
<tr><th>错误号</th><th>信息</th><th>说明</th></tr>
<tr><td>0</td><td>"\0"</td><td>无错误。</t
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
100013009-基于C 语言实现 LSTM 算法.zip (71个子文件)
lstmmaster
src
test_rectangle_cos_pre.c 768B
test.c 1KB
test_up_frequence_and_yx_pre.c 672B
test_save.c 551B
test_lstmslib.c 939B
test_params_change.c 891B
test_run.c 762B
lstmslib.h 773B
test_up_frequence_pre.c 648B
test_create.c 1KB
test_random.c 566B
test_random_pre.c 633B
test_sin_cos_pre.c 1KB
lstmlib.h 899B
lstmlib.c 25KB
test_up_frequence.c 579B
test_mse.c 328B
lstmslib.c 2KB
test_fitunit.c 1010B
test_sin_cos.c 572B
LICENSE 1KB
temp.c 519B
test.sh 1KB
.gitignore 40B
images
lstm-bi.png 586B
lstm-hope-outputs.png 2KB
test_rectangle_cos_pre.png 42KB
lstm-hat-h.png 642B
test_sin_cos_pre_noise_2.png 140KB
lstm-t2-wch.png 40KB
lstm-dedh.png 5KB
lstm-t2-woh.png 39KB
lstm-bC.png 704B
test_params_change.png 56KB
lstm-woh.png 984B
lstm-error-function.png 3KB
test_sin_cos_pre_noise_1.png 123KB
lstm-main.png 17KB
lstm-t2-wix.png 46KB
lstm-wfh.png 971B
lstm-t2-wfh.png 48KB
lstm-tilde-c.png 650B
lstm-t2-wox.png 38KB
test_sin_cos_pre.png 42KB
lstm-t2-bf.png 37KB
lstm-t2-wih.png 38KB
lstm-zero.png 2KB
lstm-params.png 4KB
lstm-t2-wfx.png 38KB
lstm-sigmoid.png 2KB
lstm-wfx.png 945B
lstm-bf.png 692B
test_sin_cos_pre_noise_3.png 138KB
lstm-wCh.png 1KB
lstm-bo.png 652B
lstm-dedall.png 42KB
lstm-bp.png 30KB
lstm-wCx.png 977B
lstm-t2-bi.png 36KB
lstm-wox.png 956B
lstm-lr.png 2KB
lstm-t2-bc.png 37KB
lstm-d-zero.png 35KB
lstm-wix.png 909B
lstm-inputs-outputs.png 4KB
lstm-t2-bo.png 35KB
lstm-t2-wcx.png 46KB
lstm-activity-d.png 4KB
lstm-temp-params.png 5KB
lstm-wih.png 957B
README.md 11KB
共 71 条
- 1
资源评论
- wnt139804310102023-10-21资源有很好的参考价值,总算找到了自己需要的资源啦。
神仙别闹
- 粉丝: 2705
- 资源: 7641
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功