从零开始构建简易AI问答系统
本帖最后由 恋丶你的语 于 2023-3-24 23:14 编辑一、非正文部分
现在ChatGPT特别火爆,他可以帮助我们的工作带来许多的便捷。在此之前我很早就想拥有自己的AI,哪怕是最简单的那种,奈何,大学我选了财务管理专业(高风险低收益{:1_908:} ),在梦想的道路上越跑越远。{:1_889:} 。在大二偶然之间了解到了财务数据分析这块的知识,然后我开始的我得Python半吊子学习,啥都学学,如今我已大四,还有几个月就要毕业,对未来挺焦虑的,于是我静下心来,用自己这段时间所学的知识来尝试完成自己的小愿望,于是就有了这篇文章。大佬勿喷,业余学习
二、基本思路
我的想法是一个可以能够自我学习会计知识并可以问答的程序,但是我没有那么多时间去整理这些相关的资料,于是让他直接获取百度百科的数据。基本思路如下:
1、爬取百度百科相关词条的网页内容,可以使用Python中的爬虫框架,例如Scrapy或BeautifulSoup等。
2、对网页内容进行自然语言处理和数据清洗,将有用的信息提取出来,并存储在数据库或本地文件中。
3、使用机器学习算法,如神经网络、随机森林等对得到的数据进行训练。
4、开发一个问答系统,将用户问题输入进去,然后将输入的问题与训练好的模型匹配,以便回答用户问题。
当然,这个项目具体实现上还有很多需要考虑的细节,比如如何避免数据爬取被反爬虫,如何处理查询不到的问题等等,不过这个只是一个简易的AI就不考虑那么多,而且我知识量也不够。
三、代码部分
3.1然后根据思路写出基本的代码,然后在根据思路进行调整:
# 导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
from gensim.models.word2vec import Word2Vec
import numpy as np
import pandas as pd
from sklearn.svm import SVC
from sklearn.metrics.pairwise import cosine_similarity
# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
url = 'https://baike.baidu.com/item/' + keyword
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
content = soup.find_all(class_="para")
content_list = []
for para in content:
para = para.get_text().strip()
if para:
content_list.append(para)
full_content = ''.join(content_list)
return full_content
# 分词和向量化部分:使用jieba对爬取的数据进行分词,然后使用Word2Vec模型将分词结果转化为词向量
class Word2VecVectorizer:
def __init__(self):
self.word2vec = None
def fit(self, sentences):
w2v = Word2Vec(sentences=sentences, size=256, min_count=5, workers=4)
self.word2vec = dict(zip(w2v.wv.index2word, w2v.wv.vectors))
def transform(self, sentences):
vectors = []
for sentence in sentences:
sentence_vec = []
for word in sentence:
if word in self.word2vec:
sentence_vec.append(self.word2vec)
if len(sentence_vec) > 0:
sentence_vec = np.mean(sentence_vec, axis=0)
else:
sentence_vec = np.zeros(256)
vectors.append(sentence_vec)
return np.array(vectors)
# 机器学习部分:使用SVM算法对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
def __init__(self):
self.vectorizer = None
self.clf = None
self.question_vectors = None
self.answer_vectors = None
self.df = None
def fit(self, questions, answers):
self.vectorizer = Word2VecVectorizer()
self.vectorizer.fit(questions)
self.question_vectors = self.vectorizer.transform(questions)
self.answer_vectors = self.vectorizer.transform(answers)
self.clf = SVC(kernel='linear', probability=True)
self.clf.fit(self.question_vectors, range(len(questions)))
def ask(self, question, n=5):
question = list(jieba.cut(question))
question_vec = self.vectorizer.transform()
probas = self.clf.predict_proba()
top_n = np.argsort(probas)[-n:]
sims = cosine_similarity(, self.question_vectors)
best_match = np.argmax(sims)
return self.df.iloc]['answer']
# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
# 爬取需要用到的数据
wiki_content = get_wiki_content('会计')
# 对数据进行预处理
questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
# 训练问答系统
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})
# 进行测试
while True:
question = input('请输入你的问题:')
if question == 'bye':
break
answer = qas.ask(question)
print('答案为:', answer)
3.2 加入神经网络模型
我们可以发现他只能回答一些基础的问题。然后我们在此基础上加入神经网络模型进一步完善它。于是我使用预训练的语言模型(如BERT)来对问题和答案进行编码,然后将编码后的结果输入到一个神经网络中进行分类。代码如下,其中使用Hugging Face库来加载BERT模型。
#导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
import torch
from transformers import BertTokenizer, BertModel
from torch.utils.data import TensorDataset, DataLoader
import torch.nn.functional as F
# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
url = 'https://baike.baidu.com/item/' + keyword
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
content = soup.find_all(class_="para")
content_list = []
for para in content:
para = para.get_text().strip()
if para:
content_list.append(para)
full_content = ''.join(content_list)
return full_content
# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
def __init__(self):
self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
self.model = BertModel.from_pretrained('bert-base-chinese')
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
def encode(self, sentence):
input_ids = torch.tensor(, dtype=torch.long).to(self.device)
with torch.no_grad():
outputs = self.model(input_ids)
encoded = outputs[:, 0, :].cpu().numpy()
return encoded
# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
def __init__(self):
self.encoder = None
self.clf = None
self.question_vectors = None
self.answer_vectors = None
self.df = None
def fit(self, questions, answers):
self.encoder = BertEncoder()
self.question_vectors = self.encoder.encode(questions)
self.answer_vectors = self.encoder.encode(answers)
self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256),
torch.nn.ReLU(),
torch.nn.Linear(256, len(questions)),
torch.nn.Softmax())
self.clf.to(self.encoder.device)
train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))
train_loader = DataLoader(train_data, batch_size=32)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)
num_epochs = 5
for epoch in range(num_epochs):
for inputs, labels in train_loader:
inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)
outputs = self.clf(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
def ask(self, question, n=5):
question_vec = self.encoder.encode(question)
inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)
outputs = self.clf(inputs)
probas = F.softmax(outputs, dim=1).detach().cpu().numpy()
top_n = np.argsort(probas)[-n:]
sims = cosine_similarity(, self.question_vectors)
best_match = np.argmax(sims)
return self.df.iloc]['answer']
# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
# 爬取需要用到的数据
wiki_content = get_wiki_content('会计')
# 对数据进行预处理
questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
# 训练问答系统
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})
# 进行测试
while True:
question = input('请输入你的问题:')
if question == 'bye':
break
answer = qas.ask(question)
print('答案为:', answer)
我们利用BERT模型来对问题和答案进行编码,然后使用全连接层对编码后的文本向量进行分类。这样的神经网络效果较好,可以更准确地回答问题。但是,由于BERT模型比较复杂,因此训练和推断速度都比较慢,需要耐心等待。
3.3 添加将训练结果保存到excel文件中的功能
为了实现将训练结果保存到Excel文件中的功能,我们可以使用pandas库。在下面的代码中,我们对问答系统类(QuestionAnswerSystem)进行一些改进,添加了一个新的方法 save_result_to_excel。这个方法接受一个Excel文件名作为参数,并将问题和答案保存到该文件中。在方法中,我们将DataFrame类型的数据转换为Excel文件,并将其保存在指定的文件名中。下面是修改后的代码:
# 导入需要用到的库
import requests
from bs4 import BeautifulSoup
import jieba
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
import torch
from transformers import BertTokenizer, BertModel
from torch.utils.data import TensorDataset, DataLoader
import torch.nn.functional as F
# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
url = 'https://baike.baidu.com/item/' + keyword
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
content = soup.find_all(class_="para")
content_list = []
for para in content:
para = para.get_text().strip()
if para:
content_list.append(para)
full_content = ''.join(content_list)
return full_content
# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
def __init__(self):
self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
self.model = BertModel.from_pretrained('bert-base-chinese')
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
def encode(self, sentence):
input_ids = torch.tensor(, dtype=torch.long).to(self.device)
with torch.no_grad():
outputs = self.model(input_ids)
encoded = outputs[:, 0, :].cpu().numpy()
return encoded
# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
def __init__(self):
self.encoder = None
self.clf = None
self.question_vectors = None
self.answer_vectors = None
self.df = None
def fit(self, questions, answers):
self.encoder = BertEncoder()
self.question_vectors = self.encoder.encode(questions)
self.answer_vectors = self.encoder.encode(answers)
self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256),
torch.nn.ReLU(),
torch.nn.Linear(256, len(questions)),
torch.nn.Softmax())
self.clf.to(self.encoder.device)
train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))
train_loader = DataLoader(train_data, batch_size=32)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)
num_epochs = 5
for epoch in range(num_epochs):
for inputs, labels in train_loader:
inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)
outputs = self.clf(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
def ask(self, question, n=5):
question_vec = self.encoder.encode(question)
inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)
outputs = self.clf(inputs)
probas = F.softmax(outputs, dim=1).detach().cpu().numpy()
top_n = np.argsort(probas)[-n:]
sims = cosine_similarity(, self.question_vectors)
best_match = np.argmax(sims)
return self.df.iloc]['answer']
# 新增方法:将问答结果保存到Excel文件中
def save_result_to_excel(self, filename='qa_result.xlsx'):
df_result = self.df.copy()
df_result.columns = ['Question', 'Answer']
df_result.to_excel(filename, index=False)
# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
# 爬取需要用到的数据
wiki_content = get_wiki_content('会计')
# 对数据进行预处理
questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
# 训练问答系统
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})
# 将结果保存到Excel文件中
qas.save_result_to_excel('qa_result.xlsx')
# 进行测试
while True:
question = input('请输入你的问题:')
if question == 'bye':
break
answer = qas.ask(question)
print('答案为:', answer)
在主程序部分中,新增了一行代码 qas.save_result_to_excel('qa_result.xlsx'),将问答结果保存到Excel文件中。可以将文件名设置为自己喜欢的名称,并在文件保存位置执行该代码。执行完毕后,在指定的文件夹中会生成一个名为 qa_result.xlsx 的文件,其中包含了训练结果的问题和答案。
3.4 想要更好的学习,我们需要对该程序在对话过程中就对数据进行数据标注和检验
实现问答系统的数据标注和检验功能,我们需要对 QuestionAnswerSystem 进行一些改进。
首先,为了方便用户对答案进行标注,我们需要在 ask 方法中添加一个新参数 is_correct,用于接收用户对答案是否正确的标注。我们还需要将问题、答案和标注组成的列表存储到 df 属性中,以便后续使用。
其次,我们可以新增一个方法 check_accuracy,用于计算问答系统的准确率。该方法会基于已标注数据计算平均准确率,并将准确率打印出来。同时,我们也可以通过 save_result_to_excel 方法保存标注后的结果到Excel文件中。下面是修改后的代码:
# 导入需要用到的库
import requests# 发送网络请求的模块
from bs4 import BeautifulSoup# 从bs4模块中导入BeautifulSoup类,用于解析HTML文档
import jieba# 中文分词库
import numpy as np# 用于科学计算的库
import pandas as pd# 用于数据处理和分析的库
from sklearn.metrics.pairwise import cosine_similarity# 余弦相似度计算函数
import torch# PyTorch深度学习框架
from transformers import BertTokenizer, BertModel# 预训练的BERT模型和分词器
from torch.utils.data import TensorDataset, DataLoader# 数据集和数据加载器
import torch.nn.functional as F# 神经网络相关的函数和工具
# 爬虫部分:爬取百度百科的网页内容,并进行数据清洗和预处理
def get_wiki_content(keyword):
url = 'https://baike.baidu.com/item/' + keyword# 构造百度百科的URL链接
response = requests.get(url)# 发送GET请求并获取响应对象
soup = BeautifulSoup(response.text, 'html.parser')# 用html.parser解析HTML文档
content = soup.find_all(class_="para")# 查找class属性为"para"的标签
content_list = []
for para in content:
para = para.get_text().strip()# 获取标签中的文本内容
if para: # 如果文本内容非空
content_list.append(para)# 将其添加到列表中
full_content = ''.join(content_list)# 将列表中的所有段落合并成一个完整的字符串
return full_content# 返回完整的百科内容
# 编码器部分:使用预训练的BERT模型来对文本进行编码
class BertEncoder:
def __init__(self):
self.tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') # 调用BERT分词器
self.model = BertModel.from_pretrained('bert-base-chinese')# 调用BERT模型
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 判断是否可用GPU
def encode(self, sentence):# 对句子进行编码
input_ids = torch.tensor(, dtype=torch.long).to(self.device)# 将句子转换成ID序列,并放到GPU上
with torch.no_grad(): # 关闭梯度计算,以节省内存和加速计算
outputs = self.model(input_ids)# 输入句子,得到BERT模型输出
encoded = outputs[:, 0, :].cpu().numpy()# 取第1个输出,取第1行,即CLS对应的向量,将其从GPU上取回并转换为NumPy数组
return encoded
# 神经网络部分:使用全连接层对文本向量训练模型,并使用余弦相似度计算输入问题与已知问题的相似度
class QuestionAnswerSystem:
def __init__(self):
self.encoder = None
self.clf = None
self.question_vectors = None
self.answer_vectors = None
self.df = None# 保存问答结果的DataFrame
def fit(self, questions, answers): # 训练神经网络模型
self.encoder = BertEncoder()# 初始化编码器
self.question_vectors = self.encoder.encode(questions)# 编码所有问题
self.answer_vectors = self.encoder.encode(answers)# 编码所有答案
self.clf = torch.nn.Sequential(torch.nn.Linear(768, 256), # 全连接层1,输入大小为768,输出大小为256
torch.nn.ReLU(),# ReLU激活函数
torch.nn.Linear(256, len(questions)),# 全连接层2,输入大小为256,输出大小为问题数量
torch.nn.Softmax()) # Softmax函数,用于分类
self.clf.to(self.encoder.device)# 将模型放到GPU上
train_data = TensorDataset(torch.tensor(self.answer_vectors, dtype=torch.float32), torch.tensor(range(len(questions)), dtype=torch.long))# 构造训练数据集
train_loader = DataLoader(train_data, batch_size=32)# 构造数据加载器,每次读取32个样本
criterion = torch.nn.CrossEntropyLoss() # 定义损失函数为交叉熵
optimizer = torch.optim.Adam(self.clf.parameters(), lr=1e-3)# 使用Adam优化器,并设置学习率为0.001
num_epochs = 5# 训练轮数为5轮
for epoch in range(num_epochs):# 进行多轮训练
for inputs, labels in train_loader: # 按批次读取数据
inputs, labels = inputs.to(self.encoder.device), labels.to(self.encoder.device)# 将数据放到GPU上
outputs = self.clf(inputs) # 输入数据,得到模型输出结果
loss = criterion(outputs, labels) # 计算损失值
optimizer.zero_grad() # 将梯度清零,以免累加影响下一次更新
loss.backward()# 反向传播计算梯度
optimizer.step() # 更新权重
def ask(self, question, n=5, is_correct=None): # 回答问题
question_vec = self.encoder.encode(question)# 对输入问题进行编码
inputs = torch.tensor(question_vec, dtype=torch.float32).to(self.encoder.device)# 将编码后的问题放到GPU上
outputs = self.clf(inputs)# 输入问题向量,得到模型输出结果
probas = F.softmax(outputs, dim=1).detach().cpu().numpy()# 对输出结果进行softmax处理,并将其从GPU上取回并转换为NumPy数组
top_n = np.argsort(probas)[-n:]# 取最大的n个概率对应的下标
sims = cosine_similarity(, self.question_vectors)# 计算输入问题与已知问题的相似度
best_match = np.argmax(sims)# 找到最相似的问题
if is_correct is not None: # 如果需要记录问答结果
self.df = self.df.append({'question': question, 'answer': self.df.iloc]['answer'], 'is_correct': bool(is_correct)}, ignore_index=True)# 将记录添加到DataFrame中
return self.df.iloc]['answer']# 返回最匹配的答案
# 新增方法:将问答结果保存到Excel文件中
def save_result_to_excel(self, filename='qa_result.xlsx'):
df_result = self.df.copy() # 复制一份问答结果
df_result.columns = ['Question', 'Answer', 'Is Correct']# 重命名列名
df_result.to_excel(filename, index=False)# 将结果保存到Excel文件中,不保存索引
# 新增方法:检验问答系统的准确率
def check_accuracy(self):
accuracy = self.df['is_correct'].mean() # 计算平均准确率
print('问答系统的准确率为: {:.2f}%'.format(accuracy*100))# 输出准确率
# 主程序部分:调用以上函数完成问答系统的搭建
if __name__ == '__main__':
# 爬取需要用到的数据
wiki_content = get_wiki_content('会计')
# 对数据进行预处理
questions = ['什么是会计', '什么是账户', '什么是分录', '什么是财务报表']
answers = ['会计是什么', '账户是什么', '分录是什么', '财务报表是什么']
# 训练问答系统
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})
# 进行测试
while True:
question = input('请输入你的问题:')
if question == 'bye':
break
is_correct = input('答案是否正确?(y/n)')
if is_correct.lower() == 'y':
is_correct = True
elif is_correct.lower() == 'n':
is_correct = False
else:
is_correct = None
answer = qas.ask(question, is_correct=is_correct)
print('答案为:', answer['answer'])
# 检验准确率并保存标注后的数据到Excel文件中
qas.check_accuracy()
qas.save_result_to_excel('qa_result.xlsx')
在主程序部分中,我们新增了两个输入提示,以便用户标注答案是否正确,同时也新增了两行代码来调用 check_accuracy 和 save_result_to_excel 方法,以检验问答系统的准确率,并将标注后的结果保存到Excel文件中。现在,当运行程序并回答每个问题时,程序会提示你输入答案是否正确,你可以输入 "y" 或 "n" 来对答案进行标注。程序会将问题、答案和标注组成的记录存储到 df 属性中,并在每次执行 ask 方法时更新 df。执行 check_accuracy 方法时,程序将基于已标注数据计算准确率,并将其打印出来。执行 save_result_to_excel 方法时,程序将标注后的数据写入到Excel文件中以便后续使用。到此为止,我们的程序的一些功能也就基本实现了。当然还存在许多的问题,希望大家可以一起学习,一起进步。
四、最后的最后
为了更好的让他学习方便,于是最后增加一个适配的Webj界面。要将该程序适配为web界面,需要使用web框架来搭建一个网站,并将问答系统集成到网站中。可以使用Python中的Flask框架。以下是实现步骤:
1、导入Flask和其他需要用到的库:
from flask import Flask, render_template, request
import pandas as pd
from qa_system import QuestionAnswerSystem
其中qa_system.py文件是之前所提到的问答系统代码。
2、创建Flask应用:
app = Flask(__name__)
3、加载问答系统:
qas = QuestionAnswerSystem()
qas.fit(questions, answers)
qas.df = pd.DataFrame({'question': questions, 'answer': answers})
其中,questions和answers是之前已经定义过的问题列表和答案列表。
4、创建路由函数:
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
question = request.form.get('question')
is_correct = request.form.get('is_correct')
if is_correct.lower() == 'y':
is_correct = True
elif is_correct.lower() == 'n':
is_correct = False
else:
is_correct = None
answer = qas.ask(question, is_correct=is_correct)
return render_template('index.html', answer=answer['answer'])
return render_template('index.html')
这个路由函数包含了两个请求方法:GET和POST。当用户访问网页时,会发送一个GET请求,会渲染index.html页面;当用户提交问题时,会发送一个POST请求,会通过问答系统获取答案,并将答案渲染到页面中。question和is_correct是从表单中获取的参数。
5、编写HTML模板:
这里写了一个简单的模板作为参考,可以根据需求进行修改。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>问答系统</title>
</head>
<body>
<form method="post">
<input type="text" name="question" placeholder="请输入你的问题" required>
<input type="radio" name="is_correct" value="y" required>
<label for="y">正确</label>
<input type="radio" name="is_correct" value="n" required>
<label for="n">错误</label>
<button type="submit">提交</button>
</form>
{% if answer %}
<p>{{ answer }}</p >
{% endif %}
</body>
</html>
这个模板包含了一个表单,用户可以在这里输入问题。表单中还包含了两个单选框,用户在回答问题后可以选择是否正确。如果问答系统能够成功获取到答案,就会将答案渲染到页面中。
6、运行Flask应用:
if __name__ == '__main__':
app.run()
7、运行这个应用之后,通过浏览器访问网址http://127.0.0.1:5000/,即可看到刚才编写的页面。最终大功告成,最后希望大佬勿喷。
2023/3/24 23:10 重新编辑了下,新增内容就是每行都添加了注释,可以行大家更好的学习、理解和修改我创造的BUG(坏笑ing) 真厉害啊 学到了 hijackking 发表于 2023-3-21 20:57
大神问下;
Traceback (most recent call last):
File "D:\studyddd\dddd.py", line 106, in
这段代码报错的原因是在 Torch 的 TensorDataset 构造函数中,两个 tensor 的第一维大小不一致导致的。具体来说,代码的第 60 行中,使用了一个名为 answer_vectors 的成员变量构造了一个 torch.Tensor 对象,然后将这个对象和一个 long 类型的 torch.Tensor 对象构造成了一个 TensorDataset 对象。其中,第一个 tensor 的第一维大小为 self.answer_vectors 的行数,第二个 tensor 的第一维大小为 questions 的长度。由于这两个 tensor 的第一维大小不相等,所以就会报出 "Size mismatch between tensors" 的错误。
为了解决这个问题,你需要检查 self.answer_vectors 和 questions 的行数是否相等。如果不相等,你需要将它们转化为相同的大小。你可以使用 numpy 的 resize 函数来改变 self.answer_vectors 的大小,或者使用 pandas 的 DataFrame 类型将 questions 和 answers 整合在一起,然后再将它们转化为 tensor 类型。 太强大了,收藏学习!!! 收藏学习! 感谢,能打包一系列源码部署就好了 被你的介绍感动到了,太厉害了{:1_893:} 学习学习,我也正在学习 感谢分享!如果能够对代码做更详细的解释那就更适合新手学习了。 学习了,楼主真棒!