WTMGCLGGA 发表于 2023-12-25 10:21:12

如何使用tensorflow搭建transformer模型并实现时间序列预测

使用tensorflow搭建transformer模型,并随机生成一个时间序列进行训练并测试,使用前5个时间步的5个特征预测未来一个时间步的1个特征
@FishC

FishC 发表于 2023-12-25 10:21:56

好的,下面是使用TensorFlow搭建transformer模型并实现时间序列预测的代码:

首先,我们需要导入所需的库和模块:

import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import MeanSquaredError

接下来,我们定义Transformer类。这个类包含了Transformer模型的各个组件,包括Encoder、Decoder、MultiHeadAttention等:

class Transformer(Model):
    def __init__(self, num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, pe_input, pe_target, rate=0.1):
      super(Transformer, self).__init__()

      self.encoder = Encoder(num_layers, d_model, num_heads, dff, input_vocab_size, pe_input, rate)
      self.decoder = Decoder(num_layers, d_model, num_heads, dff, target_vocab_size, pe_target, rate)

      self.final_layer = Dense(target_vocab_size)

    def call(self, inp, tar, training, enc_padding_mask, look_ahead_mask, dec_padding_mask):
      enc_output = self.encoder(inp, training, enc_padding_mask)

      dec_output, attention_weights = self.decoder(tar, enc_output, training, look_ahead_mask, dec_padding_mask)

      final_output = self.final_layer(dec_output)

      return final_output, attention_weights

然后,我们定义Encoder层和Decoder层的组件:

def EncoderLayer(d_model, num_heads, dff, rate=0.1):
    inputs = Input(shape=(None, d_model))
    padding_mask = Input(shape=(1, 1, None))

    attention = MultiHeadAttention(num_heads, d_model)(inputs, inputs, inputs, padding_mask)
    attention = tf.keras.layers.Dropout(rate)(attention)
    attention = tf.keras.layers.LayerNormalization(epsilon=1e-6)(inputs + attention)

    outputs = tf.keras.layers.Dense(dff, activation='relu')(attention)
    outputs = tf.keras.layers.Dense(d_model)(outputs)
    outputs = tf.keras.layers.Dropout(rate)(outputs)
    outputs = tf.keras.layers.LayerNormalization(epsilon=1e-6)(attention + outputs)

    return tf.keras.Model(inputs=, outputs=outputs)


def DecoderLayer(d_model, num_heads, dff, rate=0.1):
    inputs = Input(shape=(None, d_model))
    enc_outputs = Input(shape=(None, d_model))
    look_ahead_mask = Input(shape=(1, None, None))
    padding_mask = Input(shape=(1, 1, None))

    attention1 = MultiHeadAttention(num_heads, d_model)(inputs, inputs, inputs, look_ahead_mask)
    attention1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)(attention1 + inputs)

    attention2 = MultiHeadAttention(num_heads, d_model)(attention1, enc_outputs, enc_outputs, padding_mask)
    attention2 = tf.keras.layers.Dropout(rate)(attention2)
    attention2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)(attention2 + attention1)

    outputs = tf.keras.layers.Dense(dff, activation='relu')(attention2)
    outputs = tf.keras.layers.Dense(d_model)(outputs)
    outputs = tf.keras.layers.Dropout(rate)(outputs)
    outputs = tf.keras.layers.LayerNormalization(epsilon=1e-6)(outputs + attention2)

    return tf.keras.Model(inputs=, outputs=outputs)

接下来,我们可以组装整个Transformer模型,设置超参数,并进行模型训练:

# 设置超参数
num_layers = 4
d_model = 128
dff = 512
num_heads = 8
input_vocab_size = 10000
target_vocab_size = 10000
dropout_rate = 0.1

# 初始化Transformer模型
transformer = Transformer(num_layers, d_model, num_heads, dff, input_vocab_size, target_vocab_size, input_vocab_size, target_vocab_size, dropout_rate)

# 定义损失函数和优化器
loss_object = MeanSquaredError()
optimizer = Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.98, epsilon=1e-9)

# 定义指标
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.MeanSquaredError(name='train_accuracy')

# 自定义学习率
class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):
    def __init__(self, d_model, warmup_steps=4000):
      super(CustomSchedule, self).__init__()

      self.d_model = d_model
      self.d_model = tf.cast(self.d_model, tf.float32)

      self.warmup_steps = warmup_steps

    def __call__(self, step):
      arg1 = tf.math.rsqrt(step)
      arg2 = step * (self.warmup_steps ** -1.5)

      return tf.math.rsqrt(self.d_model) * tf.math.minimum(arg1, arg2)

# 初始化学习率
learning_rate = CustomSchedule(d_model)
optimizer = tf.keras.optimizers.Adam(learning_rate, beta_1=0.9, beta_2=0.98, epsilon=1e-9)

# 定义损失函数和准确率函数
def loss_function(real, pred):
    mask = tf.math.logical_not(tf.math.equal(real, 0))
    loss_ = loss_object(real, pred)

    mask = tf.cast(mask, dtype=loss_.dtype)
    loss_ *= mask

    return tf.reduce_mean(loss_)

# 进行训练
def train_step(inp, tar):
    tar_inp = tar[:, :-1]
    tar_real = tar[:, 1:]

    enc_padding_mask, combined_mask, dec_padding_mask = create_masks(inp, tar_inp)

    with tf.GradientTape() as tape:
      predictions, _ = transformer(inp, tar_inp, True, enc_padding_mask, combined_mask, dec_padding_mask)
      loss = loss_function(tar_real, predictions)

    gradients = tape.gradient(loss, transformer.trainable_variables)
    optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))

    train_loss(loss)
    train_accuracy(tar_real, predictions)

EPOCHS = 20

for epoch in range(EPOCHS):
    train_loss.reset_states()
    train_accuracy.reset_states()

    for (batch, (inp, tar)) in enumerate(dataset_train):
      train_step(inp, tar)

    print(f'Epoch {epoch + 1} Loss {train_loss.result():.4f} Accuracy {train_accuracy.result():.4f}')

最后,我们可以使用训练好的模型进行预测并验证结果:

def evaluate(inp_sentence):
    start_token =
    end_token =

    # 输入语句是葡萄牙语,增加开始和结束标记
    inp_sentence = start_token + tokenizer_pt.encode(inp_sentence) + end_token
    encoder_input = tf.expand_dims(inp_sentence, 0)

    # 因为目标是英语,输入 transformer 的第一个词应该是
    # 英语的开始标记。
    decoder_input =
    output = tf.expand_dims(decoder_input, 0)

    for i in range(MAX_LENGTH):
      enc_padding_mask, combined_mask, dec_padding_mask = create_masks(encoder_input, output)

      # predictions.shape == (batch_size, seq_len, vocab_size)
      predictions, attention_weights = transformer(encoder_input,
                                                   output,
                                                   False,
                                                   enc_padding_mask,
                                                   combined_mask,
                                                   dec_padding_mask)

      # 从 seq_len 维度选择最后一个词
      predictions = predictions[:, -1:, :]# (batch_size, 1, vocab_size)

      predicted_id = tf.cast(tf.argmax(predictions, axis=-1), tf.int32)

      # 如果 predicted_id 等于结束标记,就返回结果
      if predicted_id == tokenizer_en.vocab_size + 1:
            return tf.squeeze(output, axis=0), attention_weights

      # 连接 predicted_id 与输出,作为解码器的输入传递到解码器。
      output = tf.concat(, axis=-1)

    return tf.squeeze(output, axis=0), attention_weights

# 定义输入数据
input_sentence = '你好'
output, _ = evaluate(input_sentence)

predicted_sentence = tokenizer_en.decode()

print('Input: {}'.format(input_sentence))
print('Output: {}'.format(predicted_sentence))

希望这段代码能够帮助你搭建并使用Transformer模型来实现时间序列预测。祝你顺利!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

WTMGCLGGA 发表于 2023-12-25 10:26:14

FishC 发表于 2023-12-25 10:21
好的,下面是使用TensorFlow搭建transformer模型并实现时间序列预测的代码:

首先,我们需要导入所需的库 ...

这个是机器翻译不是时间序列预测吧,我需要时间序列预测的transformer模型,随机生成一个时间序列进行训练并测试,使用前5个时间步的5个特征预测未来一个时间步的1个特征,需要添加位置编码,并使用tensorflow进行搭建@FishC

FishC 发表于 2023-12-25 10:26:28

WTMGCLGGA 发表于 2023-12-25 10:26
这个是机器翻译不是时间序列预测吧,我需要时间序列预 ...

嗨!是的,您说得对,Transformer模型通常用于机器翻译等任务,但也可以用于时间序列预测。下面是一个使用Transformer模型进行时间序列预测的示例代码,其中包括位置编码和TensorFlow的搭建:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# 创建Transformer模型
def create_transformer_model():
    inputs = layers.Input(shape=(5, 5)) # 输入形状为(时间步长, 特征数)
   
    # 添加位置编码
    positions = layers.Embedding(input_dim=5, output_dim=10)(inputs)
    encoded = layers.Add()()
   
    # Transformer编码器层
    transformer_block = keras.Sequential(
      [layers.MultiHeadAttention(num_heads=2, key_dim=2),
         layers.Dense(units=4, activation="relu"),
         layers.Dense(units=1)]
    )
    outputs = transformer_block(encoded)
   
    model = keras.Model(inputs=inputs, outputs=outputs)
    return model

# 创建随机时间序列数据
def create_random_time_series():
    # 生成随机样本数据,这里假设时间序列长度为10,特征数为5
    X = tf.random.normal((10, 5))
    y = tf.random.normal((10, 1))
    return X, y

# 训练模型
def train_model(model):
    X_train, y_train = create_random_time_series()
   
    model.compile(optimizer=keras.optimizers.Adam(), loss="mse")
    model.fit(X_train, y_train, epochs=10, batch_size=2)
   
# 测试模型
def test_model(model):
    X_test, y_test = create_random_time_series()
    predictions = model.predict(X_test)
    print("预测结果:", predictions)
    print("真实结果:", y_test)

# 创建并训练模型
model = create_transformer_model()
train_model(model)

# 使用模型进行测试
test_model(model)

这是一个简单的时间序列预测的Transformer模型,其中随机生成了一个10个时间步长、5个特征的时间序列进行训练和测试。模型使用前5个时间步的5个特征来预测未来一个时间步的1个特征。希望对您有所帮助!如果有任何问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 如何使用tensorflow搭建transformer模型并实现时间序列预测