gpt1用于文本分类

揭秘大模型:从原理到实战中有代码:

class DecoderLayerGPT1(tf.keras.layers.Layer):

       def __init__(self, d_model, num_heads, dff, drop_rate=0.1):
          super(DecoderLayerGPT1, self).__init__()
          # 定义掩码多头注意力
          self.mha1 = MutilHeadAttention(d_model, num_heads)
          self.ffn = point_wise_feed_forward_network(d_model, dff)
          self.layernorm1 = LayerNormalization(epsilon=1e-6)
          self.layernorm2 = LayerNormalization(epsilon=1e-6)
          self.dropout1 = layers.Dropout(drop_rate)
          self.dropout2 = layers.Dropout(drop_rate)
       def call(self, inputs, training, look_ahead_mask):
          # 掩码多头注意力
          att1, att_weight1 = self.mha1(inputs, inputs, inputs, look_ahead_mask)
          att1 = self.dropout1(att1, training=training)
          out1 = self.layernorm1(inputs + att1)
          ffn_out = self.ffn(out1)
          ffn_out = self.dropout2(ffn_out, training=training)
          out2 = self.layernorm2(out1 + ffn_out)
          return out2, att_weight1


class GPT1(tf.keras.Model):
       def __init__(self, n_layers, d_model, n_heads, diff, target_vocab_size,
                  max_seq_len, fine_tuning_class_num,   drop_rate=0.1):
          super(GPT1, self).__init__()
          self.decoder = Decoder(n_layers, d_model, n_heads, diff,
                             target_vocab_size, max_seq_len, drop_rate)
          # 预训练阶段输出
          self.final_layer = tf.keras.layers.Dense(target_vocab_size)
          # 微调阶段输出
          self.fine_tuning_layer = tf.keras.layers.Dense(fine_tuning_class_num)
       def call(self, targets, training, look_ahead_mask):
          # 预训练阶段
          decode_out, att_weights = self.decoder(targets, training, look_ahead_mask)
          final_out = self.final_layer(decode_out)
          # 微调阶段
          fine_tuning_out = self.fine_tuning_layer(tf.keras.layers.Flatten()(final_out))
          return final_out, fine_tuning_out, att_weights


# 预训练阶段目标函数
    def loss_fun(y_ture, y_pred):
       mask = tf.math.logical_not(tf.math.equal(y_ture, 0))
       loss_ = loss_object(y_ture, y_pred)
       mask = tf.cast(mask, dtype=loss_.dtype)
       loss_ *= mask
       return tf.reduce_mean(loss_)
    # 微调阶段目标函数
    def loss_fun_fine_tuning(y_ture, y_pred):
       loss_ = loss_object_fine_tuning(y_ture, y_pred)
       return tf.reduce_mean(loss_)
    # 预训练阶段评估指标
    loss_object = tf.keras.losses.SparseCategoricalCrossentropy(
           from_logits=True, reduction='none')
    train_loss = tf.keras.metrics.Mean(name='train_loss')
    # 微调阶段评估指标
    loss_object_fine_tuning = tf.keras.losses.CategoricalCrossentropy(
           from_logits=True, reduction='none')
    train_loss_fine_tuning = tf.keras.metrics.Mean(name='train_loss_fine_tuning')
    train_accuracy_fine_tuning = tf.keras.metrics.CategoricalAccuracy(
           name='train_accuracy_fine_tuning')



# 创建GPT-1模型
    gpt1 = GPT1(num_layers, d_model, num_heads, dff, target_vocab_size,
              max_seq_len, n_class, dropout_rate)
    # 创建ckpt管理器
    checkpoint_path = './checkpoint/train_cat'
    ckpt = tf.train.Checkpoint(gpt1=gpt1, optimizer=optimizer)
    ckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=3)
    if ckpt_manager.latest_checkpoint:
       ckpt.restore(ckpt_manager.latest_checkpoint)
    # 定义训练过程
    def train_step(targets):
       tar_inp = targets['title'][:, :-1]
       tar_real = targets['title'][:, 1:]
       cat_name = targets['cat']
       combined_mask = create_mask(tar_inp)
       with tf.GradientTape() as tape:
          predictions, predict_fine_tuning, _ = gpt1(tar_inp, True, combined_mask)
          loss = loss_fun(tar_real, predictions)
          loss_fine_tuning = loss_fun_fine_tuning(cat_name, predict_fine_tuning)
          loss_combine = loss + loss_fine_tuning
        # 求梯度
        gradients = tape.gradient(loss_combine, gpt1.trainable_variables)
        # 反向传播
        optimizer.apply_gradients(zip(gradients, gpt1.trainable_variables))
        # 记录损失值和准确率
        train_loss(loss)
        train_accuracy(tar_real, predictions)
        train_loss_fine_tuning(loss_fine_tuning)
        train_accuracy_fine_tuning(cat_name, predict_fine_tuning)


# 训练多个轮次
    for epoch in range(EPOCHS):
       train_loss.reset_states()
       train_accuracy.reset_states()
       train_loss_fine_tuning.reset_states()
       train_accuracy_fine_tuning.reset_states()
       for batch, all_inputs in enumerate(train_dataset):
          train_step(all_inputs)
          if batch % 1000 == 0:
             loss = train_loss.result()
             loss_fine_tuning = train_loss_fine_tuning.result()
    epoch 20, batch 0, loss:3.8556, loss_fine:0.5126, acc:0.8906
    epoch 20, batch 1000, loss:3.6283, loss_fine:0.2713, acc:0.9259
    epoch 20, batch 2000, loss:3.6260, loss_fine:0.2715, acc:0.9256
    epoch 20, batch 3000, loss:3.6289, loss_fine:0.2736, acc:0.9248
    epoch 20, batch 4000, loss:3.6265, loss_fine:0.2719, acc:0.9251
    epoch 20, save model at ./checkpoint/train_cat/ckpt-10		


# 预测函数实现
    def predict_func(inp_sentence):
       start_token = [tokenizer_title.vocab_size]
       end_token = [tokenizer_title.vocab_size + 1]
       inp_sentence = start_token + tokenizer_title.encode(inp_sentence) + end_token
       n = MAX_LENGTH - len(inp_sentence)
       inp_sentence = inp_sentence + [0 for k in range(n)]
       inp_sentence = inp_sentence[:-1]
       inp_sentence = tf.expand_dims(inp_sentence, 0)
       combined_mask = create_mask(inp_sentence)
       predictions, predict_fine_tuning, _ = gpt1(inp_sentence, False, combined_mask)
       predicted_id = tf.cast(tf.argmax(predict_fine_tuning, axis=-1), tf.int32)
       return predicted_id
    # 根据predicted_id获取类别
    def get_cat_name(sentence, plot=''):
       result = predict_func(sentence)[0]
       result = cat_name_all[result]
       print('输入: {}'.format(sentence).replace(" ", ""))
       print('预测输出: {}'.format(result))
    # 获取真实的类别
    def get_real_cat(label):
       index = label.index(1)
       return cat_name_all[index]
    s = "文明的坐标|乌镇融合“古韵与现代”"
    s = " ".join(jieba.cut(s))
    get_cat_name(s)
    print("==============================================================")
    s = "2030年的未来科技预测:20项技术改变世界"
    s = " ".join(jieba.cut(s))
    get_cat_name(s)
    print("==============================================================")
    s = "糖醋汁怎样调?牢记黄金比例"54321",按照这个配方,一次成功"
    s = " ".join(jieba.cut(s))
    get_cat_name(s)
    输入:文明的坐标|乌镇融合"古韵与现代"
    预测输出:文化
    ==============================================================
    输入:2030年的未来科技预测:20项技术改变世界
    预测输出:科技
    ==============================================================
    输入:糖醋汁怎样调?牢记黄金比例"54321",按照这个配方,一次成功
    预测输出:美食	

  

 

你看看上面gpt1用于文本分类的代码 预训练是自己做的嘛?
 
 
GPT-5
 

很棒,你的问题非常关键!你在问的其实是——这个 GPT1 模型的“预训练”阶段到底是不是它自己做的?
我们可以从你贴的代码结构来仔细分析。
答案是:👉 这个代码的“预训练阶段”不是基于已有的 GPT-1 预训练权重完成的,而是从零自训练(即自定义的、伪预训练)结构。


🔍 我们先看模型结构

你定义的类:

python
 
class GPT1(tf.keras.Model):

本质上是一个 Transformer Decoder 堆叠 模型,用了:

  • 多层 DecoderLayerGPT1
  • 每一层里有 Masked Multi-Head Attention(掩码多头注意力)
  • 加上 前馈层(feed forward network)
  • 最后有两个输出:
    1. final_layer:词预测用的(语言建模任务)
    2. fine_tuning_layer:文本分类用的(下游任务)

也就是说,你完全自定义了 GPT-1 的结构(并没有加载外部大模型权重),
💡 这是一个从零搭建的 GPT-like 模型。


🔬 再看“预训练阶段”的任务逻辑

在 train_step() 里有两部分 loss:

python
 
predictions, predict_fine_tuning, _ = gpt1(tar_inp, True, combined_mask)
loss = loss_fun(tar_real, predictions)
loss_fine_tuning = loss_fun_fine_tuning(cat_name, predict_fine_tuning)
loss_combine = loss + loss_fine_tuning

  

 
我们可以这样理解:
  • loss_fun(tar_real, predictions) → 是 语言模型任务(LM) 的损失
    相当于 “给定前文预测下一个词”。
  • loss_fun_fine_tuning(...) → 是 文本分类任务(微调) 的损失
    相当于预测句子的类别,比如 “科技 / 美食 / 文化”等。

并且这两部分是联合训练的,也就是边预测下一个词边学分类。


🧠 所以,这段代码的“预训练”是什么意思?

这里的所谓 “预训练阶段” 是指:

在同一个自建模型中,让它先学会语言模式(预测下一个词),
再同时做分类任务。

换句话说:

  • 它模拟了 GPT 模型的预训练范式;
  • 但并没有使用 GPT-1 真实的预训练权重或语料;
  • 所以严格来说,这是一个自定义的从零训练的 GPT-like 模型。

📊 真正的 GPT 预训练一般是什么样?

真正 GPT(比如 OpenAI GPT-1):

  • 使用了大规模无监督文本(BooksCorpus 等)。

  • 目标函数是 “自回归语言建模”:

P(xt∣x<t)P(xtx<t)
  • 训练好后才加载到下游任务(如文本分类、摘要等)上进行 fine-tuning。

而你的版本做的是:

  • 结构和 GPT 类似;
  • 训练数据和任务是你自己定义的;
  • 没有加载外部“预训练好的模型参数”;
  • 所以“预训练”只是概念上的、任务上的隔离,并非真正的外部预训练。

✅ 结论总结

表格
 
项目你当前的代码真正的 GPT 预训练
模型结构 GPT-like Transformer Decoder GPT Transformer Decoder
权重来源 随机初始化(从零训) 大规模语料预训练
任务 语言建模 + 分类(联合训练) 语言建模(自回归预测下一个词)
预训练语料 你自己的分类语料 通用大规模文本数据
微调阶段 分类任务使用 fine_tuning_layer 分任务(例如情感分析)

👉 所以答案是:

这段代码的“预训练”部分不是预加载模型,而是在你自己的训练脚本里自定义模拟的预训练机制。也就是说,这个 GPT1 是你自己从零开始训练的模型。


如果你希望它更接近真正的 GPT 预训练模型(例如加载已有 GPT-2 / GPT-Neo / ChatGLM 权重),我可以帮你:

  • 用 transformers 库直接调用;
  • 或者改造你的代码以支持从预训练 checkpoint 加载参数。
 
 
posted @ 2025-11-18 11:50  bonelee  阅读(2)  评论(0)    收藏  举报