我一直在努力学习神经网络,我在互联网上看到的所有例子都提供了模拟逻辑门的示例,即XOR门。但我想要做的是创建一个可以训练模拟x^2
或e^x
等功能的网络。这可能吗?我需要对网络进行哪些更改?
这是我的神经网络代码,包括1个输入节点,一个由3个节点组成的隐藏层和一个输出节点。
#include <iostream.h>
#include <fstream.h>
#include <math.h>
#include <time.h>
const double eeta=0.9;
const int n=5;
struct Net_elem
{
double weights1[3];
double weights2[3];
double bias1,bias2;
};//structure to store network paramenters
Net_elem net_elem;
double sigma(double input)
{
return 1/(1+exp(-input));
}
void show_net_elem()
{
cout.precision(15);
for(int i=0;i<3;i++)
{
cout<<"weights1["<<i<<"]="<<net_elem.weights1[i];
cout<<endl;
}
for(int i=0;i<3;i++)
{
cout<<"weights2["<<i<<"]="<<net_elem.weights2[i];
cout<<endl;
}
cout<<"bias1="<<net_elem.bias1<<" bias2="<<net_elem.bias2<<endl;
system("pause");
system("cls");
}
//function to train the network
void train(double input,double expected)
{
double Output,output[3],Delta,delta[3],delta_bias1,delta_bias2;
//Propogate forward
double sum=0;
for(int i=0;i<3;i++)
output[i]=sigma(input*net_elem.weights1[i]+net_elem.bias1);
sum=0;
for(int i=0;i<3;i++)
sum=sum+output[i]*net_elem.weights2[i];
Output=sigma(sum+net_elem.bias2);
cout<<"Output="<<Output<<endl;
//Backpropogate
Delta=expected-Output;
for(int i=0;i<3;i++)
delta[i]=net_elem.weights2[i]*Delta;
delta_bias2=net_elem.bias2*Delta;
//Update weights
for(int i=0;i<3;i++)
net_elem.weights1[i]=net_elem.weights1[i]+eeta*delta[i]*output[i]*(1-output[i])*input;
for(int i=0;i<3;i++)
net_elem.weights2[i]=net_elem.weights2[i]+eeta*Delta*Output*(1-Output)*output[i];
net_elem.bias2=net_elem.bias2+eeta*delta_bias2;
double sum1=0;
for(int i=0;i<3;i++)
sum1=sum1+net_elem.weights1[i]*delta[i];
net_elem.bias1=net_elem.bias1+eeta*sum1;
show_net_elem();
}
void test()
{
cout.precision(15);
double input,Output,output[3];
cout<<"Enter Input:";
cin>>input;
//Propogate forward
double sum=0;
for(int i=0;i<3;i++)
output[i]=sigma(input*net_elem.weights1[i]+net_elem.bias1);
for(int i=0;i<3;i++)
sum=sum+output[i]*net_elem.weights2[i];
Output=sigma(sum+net_elem.bias2);
cout<<"Output="<<Output<<endl;
}
我试图运行它来模拟平方根函数。但输出只是在0和1之间跳跃,交替。
主:
int main()
{
net_elem.weights1[0]=(double)(rand()%100+0)/10;
net_elem.weights1[1]=(double)(rand()%100+0)/10;
net_elem.weights1[2]=(double)(rand()%100+0)/10;
net_elem.weights2[0]=(double)(rand()%100+0)/10;
net_elem.weights2[1]=(double)(rand()%100+0)/10;
net_elem.weights2[2]=(double)(rand()%100+0)/10;;
net_elem.bias1=(double)(rand()%100+0)/10;
net_elem.bias2=(double)(rand()%100+0)/10;
double output[n],input[n];
int ch;
for(int i=1;i<n;i++)
{
input[i]=100;
output[i]=sqrt(input[i]);
}
do
{
cout<<endl<<"1. Train"<<endl;
cout<<"2. Test"<<endl;
cout<<"3. Exit"<<endl;
cin>>ch;
switch(ch)
{
case 1:for(int i=1;i<n;i++)
{
train(input[i],output[i]);
}
break;
case 2:test();break;
case 3:break;
default:cout<<"Enter Proper Choice"<<endl;
}
}while(ch!=3);
}
答案 0 :(得分:0)
我认为你错过了使用神经网络的重点。神经网络不会模仿已知的功能。它们将未知向量空间中的区域分开。 XOR问题通常作为一个例子,因为它是最小的非线性可分问题:一个简单的感知器只是一个分隔你问题中两个区域的线
在这种情况下,可以使用简单的线条将蓝点与红点分开(问题是可线性分离)。但是,在XOR问题中,点的位置如下:
这里,单行(感知器)是不够的。然而,多层感知器(很可能是您正在使用的神经网络的类型)可以使用多个感知器(在这种情况下为两个)来分离蓝色和红色点。以类似的方式,神经网络可以分离任何空间。
然而,XOR问题产生两种类型的输出,我们使用神经网络来分离它们。另一方面,x ^ 2产生连续的点线,因此无需分离。另外,请记住,模仿XOR函数是作为此类问题的一个例子。在实践中,没有人使用神经网络来取代XOR功能。如果你想使用一个函数,只需使用它,而不是构建一个近似它的东西。
PS:如果您仍想模拟练习的x ^ 2功能,则需要回归。你正在做的是分类(因为你在输出中使用了sigma函数)。但是,练习你最好坚持分类问题。它们更为常见。另外,对于这样的问题,请尝试使用Matlab,或者,如果您想用C ++编写,请使用一些线性代数库(例如EIGEN 3),以便在没有一千个循环的情况下更容易编写。