不到100行代码,用C++创建生成式AI模型
不到100行代码,用C++创建生成式AI模型
近年来,AI技术迅速发展,其中生成式AI尤为引人注目。本文将介绍如何用不到100行C++代码创建一个简单的生成式AI模型,让开发者快速入门AI开发领域。
什么是AI?
人工智能(Artificial Intelligence)又称AI,是指在机器中模拟人类智能,通过编程使其看起来像人类一样思考并模仿人类行为。这个术语也可用于任何表现出与人类思维相关的特征(如学习和解决问题)的机器。
什么是生成式AI?
生成式AI(Generative AI、GenAI或GAI)是一种AI技术,通过生成模型来生成文本、图像、视频或其他数据。生成式AI模型通过接受给定的输入(比如文本、图像或数据集)进行学习,然后用生成式模型对这些输入进行训练,进而生成新的输出示例,甚至可以在没有任何人类指示的情况下生成新的内容。
一般来说,用户给出简单的指令(即“提示”),然后它就会根据这些指令和训练好的数据集生成一个新的样本。下面是一个简单的生成式AI模型的示例。
有一些生成式AI模型包括:生成对抗网络(GANs)、变分自编码器(VAEs)、自回归模型和变换器(Transformer)。
如何用C++创建简单的生成式AI模型?
首先,我们来创建一个简单的生成式AI,它可以通过给定的文本输入进行训练并从中学习。然后,我们可以创建一个生成模型来生成新的句子。在这里,我们将会有一个拥有映射的类,而该映射将保存字符串以及与每个字符串相关的字符串。下面,让我们来定义类和映射。
class GenerativeAI
{
private:
std::map<std::string, std::vector<std::string>> wordRel; // map to world releation
public:
}
我们可以通过将它们添加到字符串向量中来教授单词之间的关系。请注意,这是一个非常简单的学习示例,在真正的生成式AI模型中,你应该考虑更多细节,并且可以通过不同激活函数模型中的权重进行训练。更复杂的专业模型有更多层、偏置、隐藏神经元、过滤器、变换器(Transformer)、张量模型等。
接下来,让我们创建一个可以从给定文本中学习字符串类型的方法。例如,下面就是一个可以添加到公共部分.learn_fromstring()
中的方法。
// Method to learn word relations from a given string
void learn_fromstring(const std::string &sentence)
{
std::istringstream iss(sentence);
std::vector<std::string> tokens{ std::istream_iterator<std::string>{iss},
std::istream_iterator<std::string>{} };
for (size_t i = 0; i < tokens.size() - 1; ++i) {
wordRel[tokens[i]].push_back(tokens[i + 1]);
}
}
在上述方法中,我们先将句子转换为istringstream
,然后从这个stream创建一个单词(token)向量。然后我们处理每个单词,并将下一个单词推到其映射的顺序中。例如,如果我们训练“I am”、“I was”、“I have”这类句子,它会把“I”映射和“am”、“was”、“have”添加到这个向量中。换句话说,它存储了“I”后面可能出现的下一个单词。实际上,这些关系是通过单词索引、权重、激活函数等建立起来的。例如,“am”通常与“I”搭配使用,因此它们之间的关系更密切,权重系数也应该更高。举一个简单的例子,我们先不考虑权重和激活函数。
现在,我们需要一个公共部分(public section)下的句子生成器,它可以通过考虑单词之间的关系来生成随机文本。首先,让我们举例说明生成模型,然后再进行解释。
// Method to generate a sequence of words based on learned relations
std::string sentence_generator(const std::string &startWord, int length)
{
std::string currentWord = startWord;
std::string sequence = currentWord;
for (int i = 0; i < length - 1; ++i)
{
if (wordRel.find(currentWord) == wordRel.end()) break;
std::vector<std::string> nextWords = wordRel[currentWord];
std::uniform_int_distribution<int> distribution(0, nextWords.size() - 1);
currentWord = nextWords[distribution(generator)];
sequence += " " + currentWord;
}
return sequence;
}
在上面的sentence_generator()
方法中,我们先定义第一个单词(你可以选择将第一个使用的单词存储在一个仓库中,也可以随机选择)以及要生成的句子长度。然后,我们在循环中生成句子的中间单词。最后,它将返回新生成的序列句子。
就是这样,非常简单!
为了理解这个映射内部发生了什么,我们可以创建另一个方法来揭示单词之间的关系,如下所示。
// print the word releations
void print_word_relations()
{
std::cout << "Word Relations:" << std::endl;
for (const auto &pair : wordRel)
{
std::cout << pair.first << ":";
for (const auto &word : pair.second)
{
std::cout << " " << word;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
现在我们可以开发主函数了。从这个类中创建一个新的生成式AI对象,用learn_fromstring()
方法训练一些句子。根据给定的句子,输出训练后的单词关系,我们就可以创建许多新句子了,还可以在每个循环中用sentence_generator()
方法创建一个新的字符串。下面是我训练了一些句子并生成10个新句子作为输出的过程。
int main()
{
GenerativeAI generator;
// Learn from sentences
generator.learn_fromstring("I am generative AI test example");
generator.learn_fromstring("I was a code");
generator.learn_fromstring("I can develop applications in C++");
generator.learn_fromstring("I have a generative code example");
generator.learn_fromstring("I should generate different sentences");
generator.learn_fromstring("I am easy with LearnCPlusPlus.org");
// Print word releations that learnt
generator.print_word_relations();
// Generate new sentences
for (int i = 0; i < 10; ++i)
{
std::cout << "Generated Sentence " << i + 1 << ": " << generator.sentence_generator( "I", 4+rnd()%2 ) << std::endl;
}
system("pause");
return 0;
}
有没有用C++编写的简单生成式AI模型的完整示例?
有的,下面就是一个用C++写的生成式AI的完整示例。
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <random>
std::random_device rnd;
std::mt19937 generator(rnd());
class GenerativeAI
{
private:
std::map<std::string, std::vector<std::string>> wordRel; // map to world releation
public:
// Method to learn word relations from a given string
void learn_fromstring(const std::string &sentence)
{
std::istringstream iss(sentence);
std::vector<std::string> tokens{ std::istream_iterator<std::string>{iss},
std::istream_iterator<std::string>{} };
for (size_t i = 0; i < tokens.size() - 1; ++i) {
wordRel[tokens[i]].push_back(tokens[i + 1]);
}
}
// Method to generate a sequence of words based on learned relations
std::string sentence_generator(const std::string &startWord, int length)
{
std::string currentWord = startWord;
std::string sequence = currentWord;
for (int i = 0; i < length - 1; ++i)
{
if (wordRel.find(currentWord) == wordRel.end()) break;
std::vector<std::string> nextWords = wordRel[currentWord];
std::uniform_int_distribution<int> distribution(0, nextWords.size() - 1);
currentWord = nextWords[distribution(generator)];
sequence += " " + currentWord;
}
return sequence;
}
// print the word releations
void print_word_relations()
{
std::cout << "Word Relations:" << std::endl;
for (const auto &pair : wordRel)
{
std::cout << pair.first << ":";
for (const auto &word : pair.second)
{
std::cout << " " << word;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
};
int main()
{
GenerativeAI generator;
// Learn from sentences
generator.learn_fromstring("I am generative AI test example");
generator.learn_fromstring("I was a code");
generator.learn_fromstring("I can develop applications in C++");
generator.learn_fromstring("I have a generative code example");
generator.learn_fromstring("I should generate different sentences");
generator.learn_fromstring("I am easy with LearnCPlusPlus.org");
// Print word releations that learnt
generator.print_word_relations();
// Generate new sentences
for (int i = 0; i < 10; ++i)
{
std::cout << "Generated Sentence " << i + 1 << ": " << generator.sentence_generator( "I", 4+rnd()%2 ) << std::endl;
}
system("pause");
return 0;
}
结果如下:
最后需要说明一点:为了尽可能让大家易于理解和便于编码,我试着制作了大约20个不同的示例(包括一些来自Copilot的支持)并尽量将其简化,所以这应该是最简单易行的生成式AI模型了。