# lstm-torch **Repository Path**: hymagic/lstm-torch ## Basic Information - **Project Name**: lstm-torch - **Description**: 晚点在写,作者比较懒 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2022-12-05 - **Last Updated**: 2024-12-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README LSTM使用Keras Python包构建,以预测时间序列步骤和序列。中证500股市数据。 一、环境要求 * Python~=3.10.x * TensorFlow~=2.11.0 * numpy~=1.23.5 * keras~=2.11.0 * pandas~=1.5.2 * matplotlib~=3.6.2 * akshare~=1.8.15 二、安装命令 `pip install -r requirements.txt ` 三、数据获取 数据来akshare,存储方式分为csv和mysql两种 以获取中证500为例 csv方式: data_acquisition_akshare.py-》 `download_500etf_fund() ` mysql方式: data_daily_akshare.py 基于akShare获取行情数据 data_finance_akshare.py 基于akShare获取财务数据 需要在电脑上装MySQL8 四、工程说明 core --data_acquisition_akshare 获取数据工具 --data_processor 用于加载和转换lstm模型数据的类 --model 模型构建 --pyplot_utils 画图工具 --utils 工具 data --原始数据 saved_models --训练模型 config.json --数据参数 run_model.py --训练预测图输出 run() resource db_sql.sql sql脚本 五、扩展 循环层 RNN(Recurrent neural network,递归神经网络) 用于处理序列数据——从科学仪器的时间序列测量到自然语言句子再到 DNA 核苷酸,无所不包。RNN 通过保持一种 隐藏状态 来实现这一功能,这种隐藏状态就像一种记忆,记录了它迄今为止在序列中看到的内容。 RNN 层或其变体 LSTM(long short-term memory,长短期记忆)和 GRU(gated recurrent unit,门控循环单元)的内部结构非常复杂,超出了本视频的讨论范围,但我们将向您展示基于 LSTM 的语音部分标记(一种分类器,能告诉您一个词是名词还是动词等)的实际效果: class LSTMTagger(torch.nn.Module): def __init__(self, embedding_dim, hidden_dim, vocab_size, tagset_size): super(LSTMTagger, self).__init__() self.hidden_dim = hidden_dim self.word_embeddings = torch.nn.Embedding(vocab_size, embedding_dim) # The LSTM takes word embeddings as inputs, and outputs hidden states # with dimensionality hidden_dim. self.lstm = torch.nn.LSTM(embedding_dim, hidden_dim) # The linear layer that maps from hidden state space to tag space self.hidden2tag = torch.nn.Linear(hidden_dim, tagset_size) def forward(self, sentence): embeds = self.word_embeddings(sentence) lstm_out, _ = self.lstm(embeds.view(len(sentence), 1, -1)) tag_space = self.hidden2tag(lstm_out.view(len(sentence), -1)) tag_scores = F.log_softmax(tag_space, dim=1) return tag_scores 这个构造函数有四个参数: vocab_size 是输入词汇的字数。每个单词都是 vocab_size 维空间中的独热(one-hot)向量(或单位向量)。 tagset_size 是输出集合中标签的数量。 embedding_dim 是词汇 嵌入(embedding) 空间的大小。嵌入空间将词汇映射到一个低维空间中,在这个空间中,词义相近的词会靠得很近。 hidden_dim 是 LSTM 内存的大小。 输入将是一个句子,其中的单词表示为独热向量的索引。然后,嵌入层会将这些词映射到一个 embedding_dim 维空间。LSTM 获取嵌入序列并对其进行迭代,得到长度为 hidden_dim 的输出向量。最后的线性层充当分类器,对最后一层的输出应用 log_softmax(),可将输出转换为一组归一化的估计概率,表示指定单词映射到指定标签的概率。 如果您想看看这个网络的实际应用,请查看 pytorch.org 上的序列模型和 LSTM 网络教程。 变换器 变换器(Transformer) 是一种多用途网络,它与 BERT 等模型一起,称霸了 NLP 技术领域。讨论变换器架构超出了本视频的范围,但 PyTorch 有一个 Transformer 类,可以定义变换器模型的整体参数——注意力头的数量、编码器和解码器层的数量、随机失活(dropout)和激活函数等(甚至可以通过正确的参数用这个类来构建 BERT 模型!)。torch.nn.Transformer 类还封装了各个组件(TransformerEncoder、TransformerDecoder)和子组件(TransformerEncoderLayer、TransformerDecoderLayer)的类。有关详细信息,请查阅有关变换器类的文档以及 pytorch.org 上的相关教程。 其他层和函数 数据操作层 还有其他一些类型的层在模型中起重要作用,但它们本身并不参与学习过程。 最大池化(和它兄弟,最小池化)通过合并单元来减少张量,并将输入单元的最大值分配给输出单元(我们看到过这个)。例如 my_tensor = torch.rand(1, 6, 6) print(my_tensor) maxpool_layer = torch.nn.MaxPool2d(3) print(maxpool_layer(my_tensor)) 输出: tensor([[[0.5036, 0.6285, 0.3460, 0.7817, 0.9876, 0.0074], [0.3969, 0.7950, 0.1449, 0.4110, 0.8216, 0.6235], [0.2347, 0.3741, 0.4997, 0.9737, 0.1741, 0.4616], [0.3962, 0.9970, 0.8778, 0.4292, 0.2772, 0.9926], [0.4406, 0.3624, 0.8960, 0.6484, 0.5544, 0.9501], [0.2489, 0.8971, 0.7499, 0.1803, 0.9571, 0.6733]]]) tensor([[[0.7950, 0.9876], [0.9970, 0.9926]]]) 如果仔细观察上面的值,就会发现已最大池化的输出中每个值都是 6x6 输入的各象限最大值。 归一化层会将一层的输出重新居中并归一化,然后再输入到另一层。将中间张量居中和缩放有很多好处,比如可以让您使用更高的学习率,而不会导致梯度爆炸/消失。 my_tensor = torch.rand(1, 4, 4) * 20 + 5 print(my_tensor) print(my_tensor.mean()) norm_layer = torch.nn.BatchNorm1d(4) normed_tensor = norm_layer(my_tensor) print(normed_tensor) print(normed_tensor.mean()) 输出: tensor([[[ 7.7375, 23.5649, 6.8452, 16.3517], [19.5792, 20.3254, 6.1930, 23.7576], [23.7554, 20.8565, 18.4241, 8.5742], [22.5100, 15.6154, 13.5698, 11.8411]]]) tensor(16.2188) tensor([[[-0.8614, 1.4543, -0.9919, 0.3990], [ 0.3160, 0.4274, -1.6834, 0.9400], [ 1.0256, 0.5176, 0.0914, -1.6346], [ 1.6352, -0.0663, -0.5711, -0.9978]]], grad_fn=) tensor(3.3528e-08, grad_fn=) 运行上面的单元格时,我们为输入张量添加了一个较大的缩放因子和偏移量,您应该看到输入张量的 mean() 在 15 左右。在通过归一化层运行后,您可以看到数值变小了,并聚集在零附近——事实上,平均值应该非常小(> 1e-8)。 这样做是有好处的,因为许多激活函数(下面会讨论)在 0 附近的梯度最大,但有时把输入推远离 0 会出现梯度消失或爆炸。将数据保持在梯度最陡峭区域的中心,往往意味着更快更好的学习和更高的可行学习率。 随机失活(Dropout)层是模型中一种鼓励 稀疏表示 的工具,即让模型用更少的数据进行推理。 随机失活层的工作原理是在 训练过程中 随机设置输入张量的一部分——随机失活层在推理时始终处于关闭状态。这就迫使模型根据这种被屏蔽或减少的数据集进行学习。例如: my_tensor = torch.rand(1, 4, 4) dropout = torch.nn.Dropout(p=0.4) print(dropout(my_tensor)) print(dropout(my_tensor)) 输出: tensor([[[0.8869, 0.6595, 0.2098, 0.0000], [0.5379, 0.0000, 0.0000, 0.0000], [0.1950, 0.2424, 1.3319, 0.5738], [0.5676, 0.8335, 0.0000, 0.2928]]]) tensor([[[0.8869, 0.6595, 0.2098, 0.2878], [0.5379, 0.0000, 0.4029, 0.0000], [0.0000, 0.2424, 1.3319, 0.5738], [0.0000, 0.8335, 0.9647, 0.0000]]]) 从上面,您可以看到样本张量应用随机失活的效果。您可以使用可选的 p 参数设置单个权重失活的概率,如果不使用,默认值为 0.5。 激活函数 激活函数使得深度学习成为可能。神经网络实际上是一个带有许多参数的程序,用于 模拟数学函数。如果我们只是反复将张量乘以层权重,那么我们只能模拟 线性函数,另外没有必要使用多层,因为整个网络可以简化为一次矩阵乘法。在层之间插入非线性激活函数允许深度学习模型模拟任何函数,而不仅仅是线性函数。 torch.nn.Module 中包含封装了所有主要激活函数的对象,包括 ReLU 及其许多变种、Tanh、Hardtanh、sigmoid 等。它还包括其他在模型输出阶段最有用的函数,例如 Softmax。 损失函数 损失函数告诉我们一个模型的预测离正确答案有多远。PyTorch 包含多种损失函数,包括常见的 MSE(均方误差 = L2 范数)、交叉熵损失和负对数似然损失(适用于分类器)等。 keras model.fit()参数介绍。 fit( x=None, #输入的x值 y=None, #输入的y标签值 batch_size=None, #整数 ,每次梯度更新的样本数即批量大小。未指定,默认为32。 epochs=1, #迭代次数 verbose=1, #整数,代表以什么形式来展示日志状态 callbacks=None, #回调函数,这个list中的回调函数将会在训练过程中的适当时机被调用,参考回调函数 validation_split=0.0, #浮点数0-1之间,用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。 validation_data=None, #这个参数会覆盖 validation_split,即两个函数只能存在一个,它的输入为元组 (x_val,y_val),这作为验证数据。 shuffle=True, #布尔值。是否在每轮迭代之前混洗数据 class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, #一个epoch包含的步数(每一步是一个batch的数据送入),当使用如TensorFlow数据Tensor之类的输入张量进行训练时,默认的None代表自动分割,即数据集样本数/batch样本数。 validation_steps=None, #在验证集上的step总数,仅当steps_per_epoch被指定时有用。 validation_freq=1, #指使用验证集实施验证的频率。当等于1时代表每个epoch结束都验证一次 max_queue_size=10, workers=1, use_multiprocessing=False ) ![img.png](img.png) ![img_1.png](img_1.png)