Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何初始化依赖于以前条目的可变模板?_C++_Variadic Templates - Fatal编程技术网

C++ 如何初始化依赖于以前条目的可变模板?

C++ 如何初始化依赖于以前条目的可变模板?,c++,variadic-templates,C++,Variadic Templates,我正在尝试实现一个神经网络。为此,我想我可以对大多数超参数使用模板参数。开始变得困难了,我怀疑这可能不可能实现我想要的 我有一个基本的神经元类 class NeuronBase { /* virtual output method */ }; 由此我有了一个输入神经元 class InputNeuron : public NeuronBase { /* overrides output */ }; 以及大多数层中使用的适当神经元类型 template<std::size_t NumIn

我正在尝试实现一个神经网络。为此,我想我可以对大多数超参数使用模板参数。开始变得困难了,我怀疑这可能不可能实现我想要的

我有一个基本的神经元类

class NeuronBase { /* virtual output method */ };
由此我有了一个输入神经元

class InputNeuron : public NeuronBase { /* overrides output */ };
以及大多数层中使用的适当神经元类型

template<std::size_t NumInputs>
class Neuron : public NeuronBase
{
public:

    Neuron(std::array<NeuronBase*,NumInputs> prevLayer)
    :
        m_inputLayer(prevLayer)
    {}

    /* override output method */

protected:
    std::array<NeuronBase*,NumInputs> m_inputLayer;
};
模板
类神经元:公共神经元库
{
公众:
神经元(标准::数组层)
:
m_输入层(前置层)
{}
/*重写输出方法*/
受保护的:
std::阵列m_输入层;
};
它们包含在一个层中:

template<std::size_t NumNeurons>
class Layer
{
public:
    typedef std::array<NeuronBase*,NumNeurons> NeuronArray;

    Layer(NeuronArray neurons)
    :
        m_neurons(neurons)
    {}

    NeuronArray& GetNeurons() const { return m_neurons; }

protected:
    NeuronArray m_neurons;
};
模板
类层
{
公众:
typedef std::数组和数组;
层(神经元阵列)
:
m_神经元(神经元)
{}
NeuronArray&GetNeurons()常量{返回m_neurons;}
受保护的:
神经元阵列;
};
这些层由网络封装:

template<std::size_t NumInputs, std::size_t NumOutputs, std::size_t... HiddenSizes>
class NeuralNetwork
{
public:
    NeuralNetwork()
    :
        m_hiddenLayers(/* WTF do I do?? */)
    {
    }

protected:
    std::array<InputNeuron,NumInputs> m_inputLayer;
    Layer<NumOutputs> m_outputLayer;
    std::tuple<Layer<HiddenSizes>...> m_hiddenLayers;
};
模板
类神经网络
{
公众:
神经网络
:
m_隐藏层(/*我该怎么办?*/)
{
}
受保护的:
std::阵列m_输入层;
层m_输出层;
std::元组m_隐藏层;
};
将创建如下内容:

int main()
{
    NeuralNetwork<126,7,252,63> nn;

    return 0;
}
intmain()
{
神经网络;
返回0;
}
这就形成了一个包含126个输入、7个输出和两个隐藏层的网络,第一个隐藏层252,第二个隐藏层63个神经元

我推荐了一些你通常会在神经网络中看到的东西

我遇到的问题是初始化网络中的层。
m_hiddenLayers
需要使用引用输入层的第一个元素初始化,其余元素使用
std::tuple
中的前一项初始化,并且还需要使用正确的类型创建它们,即
Neuron
而不是
NeuronBase

我怎样才能做到这一点呢?

我现在希望有一个。。。钥匙这应该满足您的需求:

template<std::size_t NumInputs, std::size_t NumOutputs, std::size_t... HiddenSizes>
class NeuralNetwork
{
public:
    NeuralNetwork()
    : m_hiddenLayers{makeHiddenLayers()}
    , m_outputLayer{makeOutputLayer()}
    {
    }

private:

    // Creates an array of pointers to each neuron of the input layer
    template <std::size_t LayerSize, std::size_t... LayerIdx>
    auto makeLayerPtrs(
        std::array<InputNeuron, LayerSize> &inputLayer,
        std::index_sequence<LayerIdx...>
    ) {
        return std::array<NeuronBase *, LayerSize>{&inputLayer[LayerIdx]...};
    }

    // Creates an array of pointers to each neuron of the input layer
    template <std::size_t LayerSize>
    auto makeLayerPtrs(std::array<InputNeuron, LayerSize> &inputLayer) {
        return makeLayerPtrs(inputLayer, std::make_index_sequence<LayerSize>{});
    }

    // Creates an array of pointers to each neuron of the given layer
    template <std::size_t LayerSize, std::size_t... LayerIdx>
    auto makeLayerPtrs(Layer<LayerSize> &layer, std::index_sequence<LayerIdx...>) {
        return std::array<NeuronBase *, LayerSize>{layer.GetNeurons()[LayerIdx].get()...};
    }

    // Creates an array of pointers to each neuron of the given layer
    template <std::size_t LayerSize>
    auto makeLayerPtrs(Layer<LayerSize> &layer) {
        return makeLayerPtrs(layer, std::make_index_sequence<LayerSize>{});
    }

    // Creates an array of pointers to each neuron of the given layer
    template <std::size_t LayerNumber>
    auto makeLayerPtrs() {
        if constexpr (LayerNumber == 0) {
            return makeLayerPtrs(m_inputLayer);
        } else {
            return makeLayerPtrs(std::get<LayerNumber - 1>(m_hiddenLayers));
        }
    }

    // Creates a Neuron with the given array of pointers to the previous layer
    template <auto Dummy, std::size_t LayerSize>
    auto makeNeuron(std::array<NeuronBase *, LayerSize> const &previousLayerPtrs) {
        return std::make_unique<Neuron<LayerSize>>(previousLayerPtrs);
    }

    // Creates one hidden layer
    template <std::size_t LayerNumber, std::size_t LayerSize, std::size_t... LayerIdx>
    auto makeHiddenLayer(std::index_sequence<LayerIdx...>) {
        // Implicit shift to 1-based indexing of hidden layers
        auto const previousLayerPtrs = makeLayerPtrs<LayerNumber>();
        return Layer<LayerSize>{{makeNeuron<LayerIdx>(previousLayerPtrs)...}};
    }

    // Creates all of the hidden layers
    template <std::size_t... HiddenLayersIdx>
    auto makeHiddenLayers(std::index_sequence<HiddenLayersIdx...>) {
        return std::tuple{
            makeHiddenLayer<HiddenLayersIdx, HiddenSizes>(
                std::make_index_sequence<HiddenSizes>{}
            )...
        };
    }

    // Creates all of the hidden layers
    auto makeHiddenLayers() {
        return makeHiddenLayers(std::make_index_sequence<sizeof...(HiddenSizes)>{});
    }

    // Creates the output layer
    template <std::size_t... LayerIdx>
    auto makeOutputLayer(std::index_sequence<LayerIdx...>) {
        auto const lastHiddenLayerPtrs = makeLayerPtrs<sizeof...(HiddenSizes)>();
        return Layer<NumOutputs>{{makeNeuron<LayerIdx>(lastHiddenLayerPtrs)...}};
    }

    // Creates the output layer
    auto makeOutputLayer() {
        return makeOutputLayer(std::make_index_sequence<NumOutputs>{});
    }

protected:
    // Caution : reordered members
    std::array<InputNeuron,NumInputs> m_inputLayer;
    std::tuple<Layer<HiddenSizes>...> m_hiddenLayers;
    Layer<NumOutputs> m_outputLayer;
};
模板
类神经网络
{
公众:
神经网络
:m_hiddenLayers{makeHiddenLayers()}
,m_outputLayer{makeOutputLayer()}
{
}
私人:
//创建指向输入层每个神经元的指针数组
模板
自动生成图层器(
std::阵列和输入层,
std::index_序列
) {
返回std::数组{&inputLayer[LayerIdx]…};
}
//创建指向输入层每个神经元的指针数组
模板
自动生成层rpter(标准::数组和输入层){
返回makelayerpters(inputLayer,std::make_index_sequence{});
}
//创建指向给定层的每个神经元的指针数组
模板
自动生成图层器(图层和图层,标准::索引顺序){
返回std::数组{layer.GetNeurons()[LayerIdx].get()…};
}
//创建指向给定层的每个神经元的指针数组
模板
自动生成图层器(图层和图层){
返回makelayerpters(layer,std::make_index_sequence{});
}
//创建指向给定层的每个神经元的指针数组
模板
自动生成图层器(){
如果constexpr(LayerNumber==0){
返回MakeLayerPters(m_inputLayer);
}否则{
返回makelayerpters(std::get(m_hiddenLayers));
}
}
//使用指向上一层的给定指针数组创建神经元
模板