keras 简单 lstm例子(基于one-hot编码)

简单的LSTM问题,能够预测一句话的下一个字词是什么

固定长度的句子,一个句子有3个词。

使用one-hot编码

 

各种引用

import keras
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
import numpy as np

数据预处理

data = 'abcdefghijklmnopqrstuvwxyz'

data_set = set(data)

word_2_int = {b:a for a,b in enumerate(data_set)}
int_2_word = {a:b for a,b in enumerate(data_set)}

word_len = len(data_set)

print(word_2_int)
print(int_2_word)

一些辅助函数

def words_2_ints(words):
    ints = []
    for itmp in words:
        ints.append(word_2_int[itmp])
    return ints

print(words_2_ints('ab'))

def words_2_one_hot(words, num_classes=word_len):
    return keras.utils.to_categorical(words_2_ints(words), num_classes=num_classes)
print(words_2_one_hot('a'))
def get_one_hot_max_idx(one_hot):
    idx_ = 0
    max_ = 0
    for i in range(len(one_hot)):
        if max_ < one_hot[i]:
            max_ = one_hot[i]
            idx_ = i
    return idx_

def one_hot_2_words(one_hot):
    tmp = []
    for itmp in one_hot:
        tmp.append(int_2_word[get_one_hot_max_idx(itmp)])
    return "".join(tmp)

print( one_hot_2_words(words_2_one_hot('adhjlkw')) )

 

构造样本

time_step = 3 #一个句子有3个词

def genarate_data(batch_size=5, genarate_num=100):
    #genarate_num = -1 表示一直循环下去,genarate_num=1表示生成一个batch的数据,以此类推
    #这里,我也不知道数据有多少,就这么循环的生成下去吧。
    #入参batch_size 控制一个batch 有多少数据,也就是一次要yield进多少个batch_size的数据
    '''
    例如,一个batch有batch_size=5个样本,那么对于这个例子,需要yield进的数据为:
    abc->d
    bcd->e
    cde->f
    def->g
    efg->h
    然后把这些数据都转换成one-hot形式,最终数据,输入x的形式为:
    
    [第1个batch]
    [第2个batch]
    ...
    [第genarate_num个batch]
    
    每个batch的形式为:
    
    [第1句话(如abc)]
    [第2句话(如bcd)]
    ...
    
    
    每一句话的形式为:
    
    [第1个词的one-hot表示]
    [第2个词的one-hot表示]
    ...
    
    '''
    cnt = 0
    batch_x = []
    batch_y = []
    sample_num = 0
    while(True):
        for i in range(len(data) - time_step):
            batch_x.append(words_2_one_hot(data[i : i+time_step]))
            batch_y.append(words_2_one_hot(data[i+time_step])[0]) #这里数据加[0],是为了符合keras的输出数据格式。 因为不加[0],表示是3维的数据。 你可以自己尝试不加0,看下面的test打印出来是什么
            sample_num += 1
            #print('sample num is :', sample_num)
            if len(batch_x) == batch_size:
                yield (np.array(batch_x), np.array(batch_y))
                batch_x = []
                batch_y = []
                if genarate_num != -1:
                    cnt += 1

                if cnt == genarate_num:
                    return
            
for test in genarate_data(batch_size=3, genarate_num=1):
    print('--------x:')
    print(test[0])
    print('--------y:')
    print(test[1])

搭建模型并训练

model = Sequential()

# LSTM输出维度为 128
# input_shape控制输入数据的形态
# time_stemp表示一句话有多少个单词
# word_len 表示一个单词用多少维度表示,这里是26维

model.add(LSTM(128, input_shape=(time_step, word_len)))
model.add(Dense(word_len, activation='softmax')) #输出用一个softmax,来分类,维度就是26,预测是哪一个字母

model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

model.fit_generator(generator=genarate_data(batch_size=5, genarate_num=-1), epochs=50, steps_per_epoch=10)
#steps_per_epoch的意思是,一个epoch中,执行多少个batch
#batch_size是一个batch中,有多少个样本。
#所以,batch_size*steps_per_epoch就等于一个epoch中,训练的样本数量。(这个说法不对!再观察看看吧)
#可以将epochs设置成1,或者2,然后在genarate_data中打印样本序号,观察到样本总数。

使用训练后的模型进行预测:

result = model.predict(np.array([words_2_one_hot('bcd')]))
print(one_hot_2_words(result))

可以看到,预测结果为

e

<think>嗯,用户想了解LSTM中的数值编码方法和实现。首先,我需要明确什么是数值编码。数值编码通常指将原始数据转换为适合神经网络处理的数值形式,比如归一化、标准化、序列化等。对于时间序列数据,这可能还涉及滑动窗口处理或特征工程。 接下来,我得回忆LSTM的结构和处理流程。LSTM擅长处理序列数据,所以输入通常是三维的(样本数、时间步长、特征数)。数值编码需要确保数据符合这个结构。可能需要提到如何将原始数据转换成这样的形状,比如使用滑动窗口生成时间步。 然后,考虑用户可能需要的具体方法。比如归一化和标准化是常见的数据预处理步骤,可以避免不同量纲的影响。另外,时间序列的分段和填充也是关键,特别是处理变长序列时。还有特征工程,比如添加统计特征或滞后特征,可能提升模型性能。 关于实现部分,用户可能想知道如何在代码中应用这些方法。比如使用Python的sklearn库进行标准化,使用Keras的TimeseriesGenerator生成时间序列数据,或者手动构建滑动窗口。此外,可能需要提到如何处理缺失值,比如插值或删除。 还需要考虑LSTM模型的结构对编码的影响。比如,输入层的形状设置,是否需要嵌入层(虽然嵌入层通常用于类别数据,但数值数据可能不需要)。引用中提到的TimeDistributed层和Dropout层可能在模型构建中使用,但用户的问题更关注输入数据的编码,所以可能不需要深入这些层。 用户提供的引用里提到LSTM和BiLSTM的结构,以及自编码器中使用LSTM例子。可能需要参考这些内容,比如引用[4]中提到用LSTM进行数据转换,说明数值编码后输入LSTM进行处理。引用[2]提到解码器使用LSTM层,可能涉及输出序列的处理,但用户问题主要关注输入编码。 最后,要确保回答结构清晰,分步骤说明方法和实现,并附上代码示例。可能的问题包括数据预处理的步骤、如何处理不同时间步长的数据、特征工程的具体方法等。需要检查引用是否正确应用,比如引用[1]关于模型超参数设置可能和数据预处理相关,而引用[4]则涉及LSTM架构的应用。 总结,回答应涵盖数据标准化、序列生成、特征工程、实现代码示例,以及相关引用。确保每个步骤有解释和示例代码,帮助用户理解如何实际应用这些方法。</think>### LSTM数值编码方法及实现 LSTM(Long Short-Term Memory)中数值编码的核心在于将原始数据转换为适合时间序列模型处理的**三维张量结构**$(\text{样本数}, \text{时间步长}, \text{特征数})$,并解决数值尺度差异问题。以下是关键步骤: --- #### 一、数值编码方法 1. **数据标准化/归一化** - 使用$Z$-score标准化或Min-Max归一化消除量纲差异: $$x_{\text{normalized}} = \frac{x - \mu}{\sigma} \quad \text{或} \quad x_{\text{scaled}} = \frac{x - x_{\min}}{x_{\max} - x_{\min}}}$$ - 避免梯度爆炸/消失问题,加速模型收敛[^1] 2. **时间序列分段与填充** - 对变长时间序列采用滑动窗口分割: $$S = [s_{t}, s_{t+1}, ..., s_{t+n}] \rightarrow \text{窗口长度}=n$$ - 使用零填充或前向填充处理不等长序列 3. **特征工程扩展** - 添加滞后特征(Lag Features):$x_{t-1}, x_{t-2}$ - 统计特征:滑动窗口均值、方差、极值等 --- #### 二、代码实现示例 ```python import numpy as np from sklearn.preprocessing import StandardScaler from keras.preprocessing.sequence import TimeseriesGenerator # 1. 数据标准化 scaler = StandardScaler() scaled_data = scaler.fit_transform(raw_data) # raw_data形状=(样本数, 特征数) # 2. 构建时间序列样本 sequence_length = 10 # 时间步长 n_features = scaled_data.shape[1] generator = TimeseriesGenerator( scaled_data, targets=scaled_data[:,0], # 假设预测第一个特征 length=sequence_length, batch_size=32 ) # 3. LSTM模型输入层设置 from keras.models import Sequential from keras.layers import LSTM, Dense model = Sequential() model.add(LSTM(64, input_shape=(sequence_length, n_features), return_sequences=True)) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') ``` --- #### 三、高级编码技术 1. **多变量编码** - 对混合类型数据(数值+类别)分别处理,最后拼接: ```python numerical_encoder = StandardScaler() categorical_encoder = OneHotEncoder() combined_features = np.hstack([numerical_encoder.fit_transform(X_num), categorical_encoder.fit_transform(X_cat)]) ``` 2. **自编码器架构** 通过LSTM编码-解码器实现特征压缩: ```python # 编码器 encoder_input = Input(shape=(None, n_features)) encoder_lstm = LSTM(32, return_state=True) _, state_h, state_c = encoder_lstm(encoder_input) encoder_states = [state_h, state_c] # 解码器 decoder_input = Input(shape=(None, n_features)) decoder_lstm = LSTM(32, return_sequences=True, return_state=True) decoder_output, _, _ = decoder_lstm(decoder_input, initial_state=encoder_states) decoder_dense = Dense(n_features) output = decoder_dense(decoder_output) autoencoder = Model([encoder_input, decoder_input], output) ``` 该方法可提取深层时序特征[^4] ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值