c++ 在人工智能中实现一个数据结构节点是可能的吗?

de90aj5v  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(178)

我正在做一个项目,必须使用人工智能进行图像预测,

这是图像,你可以看到节点是相互连接的,先对图像进行编码,然后是隐藏层,最后是解码层。
我的问题是,自动编码器的真实的实现是非常难以理解的,是否有可能像我们通常在数据结构中所做的那样对自动编码器节点进行编码,以创建链表节点、BST节点等?
我希望代码看起来容易理解。
就像...

#include <iostream>
using namespace std;
struct node
{
    double data[100][100];
    struct node *next;
};
class autoencoder
{
    struct node *head;
    struct node *temp; // to traverse through the whole list
public:
    LinkedList()
    {
        head = NULL;
    }
        void insert()
    {
        node *NewNode = new node;
        cout << "Enter data :: ";
        cin >> NewNode->data[100][100];
        NewNode->next = 0;
        if (head == 0)
        {
            head = temp = NewNode;
        }
        else
        {
            temp->next = NewNode;
            temp = NewNode; // temp is treversing to newnode
        }
    }

        void activation() // some activation function
        void sigmoid fucntion // some sigmoid function 
}
int main()
{
    autoencoder obj;
    obj.insertnode()
    obj.activation()
    obj.sigmoid()
}

这是sudo代码类型。我的问题是真实的的自动编码器实现包括这么多的库和其他东西是不可理解的,它是否可能实现自动编码器的节点,如图所示?
我已经搜索了很多,但没有找到任何解决方案。如果可以的话,请让我知道指导。如果没有,请让我知道,这样我就浪费我的时间在搜索这个。

zyfwsgd6

zyfwsgd61#

是的,使用通用的数据结构来实现神经网络是完全可能的。对于现代神经网络,顶层的数据结构不是链表,而是Graph -链表是最简单的Graph类型(只是线性的)。更复杂的网络(例如ResNet)有不止一条路径。
你应该做的一件关键的事情是保持权重和输入的分离。double data[100][100]对我来说是不清楚的。这些是权重,还是你正在处理的图像数据?此外,它是一个自动编码器。这些维度应该在不同的层中变化,如你的图片所示。(在真实的世界中,我们选择像64或128这样的好整数)
请注意,从数据 * 结构 * 的Angular 来看,自动编码器并不特别,它们只是一组层。自动编码器的关键是如何训练它们,而这在结构中是不可见的。

hgc7kmma

hgc7kmma2#

节点的核心相当简单:

struct Node {
  double value;
  double bias = 0;
  std::vector<std::pair<Node*, float>> connections;

  double compute() {
    value = bias;
    for (auto&& [node, weight] : connections) {
      value += node->value * weight;
    }

    return value;
  }
};

层是一组节点:

using Layer = std::vector<Node>;

网络是由许多层组成的,我们假设每一层都是完全连接的:

struct Network {
  std::vector<Layer> layers;

  void addFCLayer(int size) {
    Layer newLayer(size);
    if (!layers.empty()) {
      Layer& prevLayer = layers.back();
      for (auto& newNode: newLayer) {
        for (auto& prevNode: prevLayer) {
          newNode.connections.emplace_back(&prevNode, rand());
        }
      }
    }
    layers.push_back(std::move(newLayer));
  }

最后,正向传播只是逐层调用compute层,跳过第一个(输入)层。

void forwardProp() {
    for (auto it = ++layers.begin(); it != layers.end(); it++) {
      for (auto& node: *it) {
        node.compute();
      }
    }
  }
};

当然,还有很多“留给读者的练习”:

  • 使用预定义的权重和偏差而不是使用rand()
  • 使用不同的激活函数
  • 一些很好的脚手架,这样你就可以输入一个图像,而不是设置几百个节点的值并将它们读回来。
  • 实际训练/测试网络并更新权重

相关问题