【ChatGPT】ChatGPT是如何训练得到的?

前言

ChatGPT是一种基于语言模型的聊天机器人,它使用了GPT(Generative Pre-trained Transformer)的深度学习架构来生成与用户的对话。GPT是一种使用Transformer编码器和解码器的预训练模型,它已被广泛用于生成自然语言文本的各种应用程序,例如文本生成,机器翻译和语言理解。

 

在本文中,我们将探讨如何使用Python和PyTorch来训练ChatGPT,以及如何使用已经训练的模型来生成对话。

 1.准备数据

在训练ChatGPT之前,我们需要准备一个大型的对话数据集。这个数据集应该包含足够的对话,覆盖各种主题和领域,以及各种不同的对话风格。这个数据集可以是从多个来源收集的,例如电影脚本,电视节目,社交媒体上的聊天记录等。

在本文中,我们将使用Cornell Movie Dialogs Corpus,一个包含电影对话的大型数据集。这个数据集包含超过22,000个对话,涵盖了多个主题和风格。

我们可以使用以下代码下载和解压缩Cornell Movie Dialogs Corpus,这个数据集也可以从[这里](https://www.cs.cornell.edu/~cristian/Cornell_Movie-Dialogs_Corpus.html)手动下载。

import os
import urllib.request
import zipfileDATA_URL = 'http://www.cs.cornell.edu/~cristian/data/cornell_movie_dialogs_corpus.zip'
DATA_DIR = './cornell_movie_dialogs_corpus'
DATA_FILE = os.path.join(DATA_DIR, 'cornell_movie_dialogs_corpus.zip')if not os.path.exists(DATA_DIR):os.makedirs(DATA_DIR)if not os.path.exists(DATA_FILE):print('Downloading data...')urllib.request.urlretrieve(DATA_URL, DATA_FILE)print('Extracting data...')
with zipfile.ZipFile(DATA_FILE, 'r') as zip_ref:zip_ref.extractall(DATA_DIR)

 2.数据预处理

在准备好数据集之后,我们需要对数据进行预处理,以便将其转换为模型可以处理的格式。在本教程中,我们使用了一个简单的预处理步骤,该步骤包括下列几步:

  • 将数据拆分成句子pairs(上下文,回答)
  • 去除标点符号和特殊字符
  • 将所有的单词转换成小写
  • 将单词映射到一个整数ID
  • 将句子填充到相同的长度
下面是用于预处理数据的代码:
import re
import random
import numpy as np
import torchdef load_conversations():id2line = {}with open(os.path.join(DATA_DIR, 'movie_lines.txt'), errors='ignore') as f:for line in f:parts = line.strip().split(' +++$+++ ')id2line[parts[0]] = parts[4]inputs = []outputs = []with open(os.path.join(DATA_DIR, 'movie_conversations.txt'), 'r') as f:for line in f:parts = line.strip().split(' +++$+++ ')conversation = [id2line[id] for id in parts[3][1:-1].split(',')]for i in range(len(conversation) - 1):inputs.append(conversation[i])outputs.append(conversation[i+1])return inputs, outputsdef preprocess_sentence(sentence):sentence = re.sub(r"([?.!,])", r" \1 ", sentence)sentence = re.sub(r"[^a-zA-Z?.!,]+", r" ", sentence)sentence = sentence.lower()return sentencedef tokenize_sentence(sentence, word2index):tokenized = []for word in sentence.split(' '):if word not in word2index:continuetokenized.append(word2index[word])return tokenizeddef preprocess_data(inputs, outputs, max_length=20):pairs = []for i in range(len(inputs)):input_sentence = preprocess_sentence(inputs[i])output_sentence = preprocess_sentence(outputs[i])pairs.append((input_sentence, output_sentence))word_counts = {}for pair in pairs:for sentence in pair:for word in sentence.split(' '):if word not in word_counts:word_counts[word] = 0word_counts[word] += 1word2index = {}index2word = {0: '<pad>', 1: '<start>', 2: '<end>', 3: '<unk>'}index = 4for word, count in word_counts.items():if count >= 10:word2index[word] = indexindex2word[index] = wordindex += 1inputs_tokenized = []outputs_tokenized = []for pair in pairs:input_sentence, output_sentence = pairinput_tokenized = [1] + tokenize_sentence(input_sentence, word2index) + [2]output_tokenized = [1] + tokenize_sentence(output_sentence, word2index) + [2]if len(input_tokenized) <= max_length and len(output_tokenized) <= max_length:inputs_tokenized.append(input_tokenized)outputs_tokenized.append(output_tokenized)inputs_padded = torch.nn.utils.rnn.pad_sequence(inputs_tokenized, batch_first=True, padding_value=0)outputs_padded = torch.nn.utils.rnn.pad_sequence(outputs_tokenized, batch_first=True, padding_value=0)return inputs_padded, outputs_padded, word2index, index2word

 3.训练模型

在完成数据预处理之后,我们可以开始训练ChatGPT模型。对于本文中的示例,我们将使用PyTorch深度学习框架来实现ChatGPT模型。

首先,我们需要定义一个Encoder-Decoder模型结构。这个结构包括一个GPT解码器,它将输入的上下文句子转换为一个回答句子。GPT解码器由多个Transformer解码器堆叠而成,每个解码器都包括多头注意力和前馈神经网络层。


import torch.nn as nn
from transformers import GPT2LMHeadModelclass EncoderDecoder(nn.Module):def __init__(self, num_tokens, embedding_dim=256, hidden_dim=512, num_layers=2, max_length=20):super().__init__()self.embedding = nn.Embedding(num_tokens, embedding_dim)self.decoder = nn.ModuleList([GPT2LMHeadModel.from_pretrained('gpt2') for _ in range(num_layers)])self.max_length = max_lengthdef forward(self, inputs, targets=None):inputs_embedded = self.embedding(inputs)outputs = inputs_embeddedfor decoder in self.decoder:outputs = decoder(inputs_embedded=outputs)[0]return outputsdef generate(self, inputs, temperature=1.0):inputs_embedded = self.embedding(inputs)input_length = inputs.shape[1]output = inputs_embeddedfor decoder in self.decoder:output = decoder(inputs_embedded=output)[0][:, input_length-1, :]output_logits = output / temperatureoutput_probs = nn.functional.softmax(output_logits, dim=-1)output_token = torch.multinomial(output_probs, num_samples=1)output_token_embedded = self.embedding(output_token)output = torch.cat([output, output_token_embedded], dim=1)return output[:, input_length:, :]

然后,我们需要定义一个训练函数,该函数将使用梯度下降方法优化模型参数,并将每个epoch的损失和正确率记录到一个日志文件中。


def train(model, inputs, targets, optimizer, criterion):model.train()optimizer.zero_grad()outputs = model(inputs, targets[:, :-1])loss = criterion(outputs.reshape(-1, outputs.shape[-1]), targets[:, 1:].reshape(-1))loss.backward()optimizer.step()return loss.item()def evaluate(model, inputs, targets, criterion):model.eval()with torch.no_grad():outputs = model(inputs, targets[:, :-1])loss = criterion(outputs.reshape(-1, outputs.shape[-1]), targets[:, 1:].reshape(-1))return loss.item()def train_model(model, inputs, targets, word2index, index2word, num_epochs=10, batch_size=64, lr=1e-3):device = torch.device('cuda' if torch.cuda.is_available() else 'cpu

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端知识】React 基础巩固(四十)——Navigate导航

React 基础巩固(四十)——Navigate导航 一、Navigate的基本使用 新建Login页面&#xff0c;在Login中引入Navigate&#xff0c;实现点击登陆按钮跳转至/home路径下&#xff1a; import React, { PureComponent } from "react"; import { Navigate } from "reac…

HTML5 API 多端通信桥 MessageChannel 技术

这个特别有意思&#xff0c;可以将其理解为通信桥的概念&#xff0c;桥有两个端&#xff08;port1&#xff0c;port2&#xff09;只要将port1&#xff0c;port2指定到任意两个进程&#xff0c;无论是iframe-iframe&#xff0c;iframe-worker&#xff0c;parent-child-iframe&am…

【数据结构】图文并茂,通过逻辑图带你轻松拿捏链表,实现各种接口功能

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我们接着之前讲过的顺序表来继续介绍初阶数据结构的内容&#xff0c;今天给大家带来的是有关链表的基本知识和各种接口功能的实现 好了&#xff0c;废话不多说&#x…

LeetCode 周赛上分之旅 # 36 KMP 字符串匹配殊途同归

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

day50-Insect Catch Game(捉虫游戏)

50 天学习 50 个项目 - HTMLCSS and JavaScript day50-Insect Catch Game&#xff08;捉虫游戏&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport"…

codeblocks编译lvgl报错

codeblocks编译lvgl报错 1.报错内容2.解决方案3.lvgl本身代码报错 1.报错内容 error: unknown type name _In_opt_ ...2.解决方案 官网下载&#xff1a; 这里的Compiler’s installation directory 选择自带的 3.lvgl本身代码报错 undefined reference to _lv_utils_bse…

面试总结-Redis篇章(九)——Redis主从复制、主从数据同步原理

Redis其他面试问题 主从复制单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离主节点主要进行客户端的写操作&#xff0c;从节点进行客户端的读操作&#xff0c;因为Redis一直都是读多写少&…

UE5.1.1 创建C++项目失败

因一直使用Unity开发环境&#xff0c;安装Unreal后&#xff0c;并未详细配置过其开发环境&#xff0c;默认创建蓝图工程无异常&#xff0c;但创建UE C项目时总共遇到两个错误&#xff1a; 错误一 Running /Epic/UE/UE_5.1/Engine/Build/BatchFiles/Build.bat -projectfiles -…

<C++>二、类和对象-构造函数

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生…

【Linux多线程】死锁问题介绍

死锁 &#x1f96d;什么是死锁&#x1f965;死锁产生的条件&#x1f95d;如何避免死锁&#x1f345; 避免死锁算法 &#x1f96d;什么是死锁 死锁是多线程或多进程编程中的一种常见问题&#xff0c;指的是两个或多个线程&#xff08;或进程&#xff09;相互等待对方持有的资源&…

搜索二叉树_SearchBinaryTree

目录 搜索二叉树的原理 搜索二叉树的搜索时间复杂度 二叉搜索树实现_key 模型 节点 构造函数 查找 中序遍历 插入 循环 递归 删除 循环 1.删除叶子节点 2.删除有一个孩子的节点 3.左右孩子都不为空 递归 析构函数 拷贝构造 operator key_value 模型 节点 …

Mysql触发器

1.触发器 触发器是与表有关的数据库对象&#xff0c;指在 insert / update / delete 之前或之后&#xff0c;触发并执行触发器中定义的SL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&#xff0c;数据校验等操作。 使用别名 OLD 和 …

mysql安装教程保姆级

MySQL免安装本地运行 1.下载MySQL2.创建install.bat3.init.sql 初始创建4.环境变量配置5.运行 install.bat 管理员权限运行6.连接成功遇到的问题 1.下载MySQL ①地址&#xff1a;https://downloads.mysql.com/archives/community/ ②解压 2.创建install.bat 放在mysql>b…

算法综合篇专题一:双指针问题

"就算没有看清那株灿烂的花蕊&#xff0c;也应该放声歌颂赞美鲜红的玫瑰" 1、移动零 (1) 题目解析 (2) 算法原理 class Solution { public:void moveZeroes(vector<int>& nums) {for(int cur0,dest-1;cur<nums.size();cur){if(nums[cu…

java设计模式-建造者(Builder)设计模式

介绍 Java的建造者&#xff08;Builder&#xff09;设计模式可以将产品的内部表现和产品的构建过程分离开来&#xff0c;这样使用同一个构建过程来构建不同内部表现的产品。 建造者设计模式涉及如下角色&#xff1a; 产品&#xff08;Product&#xff09;角色&#xff1a;被…

前端工程化最佳实践:项目结构、代码规范和文档管理

文章目录 前端工程化最佳实践项目结构设计与组织文档管理和注释规范国际化和本地化实践 前端工程化的未来发展趋势前端工程化领域的最新技术和工具WebAssembly 和前端性能优化可持续性和可访问性的趋势 总结前端工程化的关键知识点前端工程化对项目和团队的价值 前端工程化最佳…

《golang设计模式》第一部分·创建型模式-01-单例模式(Singleton)

文章目录 1. 概述1.1 目的1.2 实现方式 2. 代码示例2.1 设计2.2 代码 1. 概述 1.1 目的 保证类只有一个实例有方法能让外部访问到该实例 1.2 实现方式 懒汉式 在第一次调用单例对象时创建该对象&#xff0c;这样可以避免不必要的资源浪费 饿汉式 在程序启动时就创建单例对象…

卷积神经网络

目录 注意&#xff1a;有参数计算的才叫层 1.应用 1.1分类和检索 1.2超分辨率重构 1.3医学任务 1.4无人驾驶 1.5人脸识别 2.卷积 2.1卷积神经网络和传统网络的区别 2.2整体框架 2.3理解卷积&#xff08;重点&#xff09; 2.4为何要进行多层卷积 2.5卷积核的参数 2.6…

C++STL库中的list

文章目录 list的介绍及使用 list的常用接口 list的模拟实现 list与vector的对比 一、list的介绍及使用 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向带头循环链表结构&#xff0c;双向带头循…

基于ssm+mysql+jsp高校疫情防控出入信息管理系统

基于ssmmysqljsp高校疫情防控出入信息管理系统 一、系统介绍二、功能展示1.登陆2.教师管理3.学生管理4.打卡记录管理5.学生申请通行证6.通行证管理7.留言信息管理8.公告类型管理9.公告管理 四、获取源码 一、系统介绍 学生 : 个人中心、打卡记录管理、学生申请通行证、通行证管…