PDA

View Full Version : سوال: ایراد تابعی که نوشتم کجاست؟



mezood
پنج شنبه 02 مهر 1394, 05:53 صبح
پیشاپیش از مبتدیانه بودن سوال عذر می خواهم. تابع ریاضی سیگموید را به شکل زیر توشتم:
double sigmoid(double x){
double y=(1-exp(-x))/(1+exp(-x));
return y;
}



یک تابع ریاضی ساده است که صحت آن را نیز تست کرده ام. وقتی که از این تابع درون تابعی دیگر استفاده می کنم خروجی صفر را بر می گرداند این در حالی است که تابع سیگموید من تنها در صفر ، صفر می شود و من هیچ کدام از وزودی هایم صفر نیست. قسمتی از تابع سیگموید استفاده کردم به این صورت است:
for(j=0;j<present_layer_neuron;j++) {
Net[j]=sigmoid(Net[j]);
}
Net[j] را قبل از سیگموید و بعد از سیگموید چاپ کردم .اتفاقی که میفته اینه که تابع سیگموید یکسری اعداد غیر صفر را به صفر تبدبل می کنه. کل کد به این صورت است: #include <iostream>
#include <fstream>
#include <string>
#include <math.h>


using namespace std;


double sigmoid(double x)
{
double y=(1-exp(-x))/(1+exp(-x));
return y;
}




double* net_effected_by_sigmoid(double** x1,double** w2,int previous_layer_neuron,int pattern_num,int present_layer_neuron)
{
int i=0,j=0,k=0;
double net=0;
double* Net;
Net=new double[present_layer_neuron+1];
double* help=new double[present_layer_neuron+1];


for(k;k<present_layer_neuron;k++)
{
for(i=0;i<previous_layer_neuron+1;i++)
{
net=net+x1[i][pattern_num]*w2[k][i];
}
Net[k]=net;
}


for(j=0;j<present_layer_neuron;j++)
{
Net[j]=sigmoid(Net[j]);
}


for(i=0;i<present_layer_neuron;i++)
help[i+1]=Net[i];


//
Net[0]=1;
for(i=1;i<present_layer_neuron+1;i++)
Net[i]=help[i];
delete [] help;
return Net;
}






int main()
{
ifstream fin("tarining_table.txt");
ofstream fout("fout.txt");
int i=0,j=0,k=0;


//xL[N][P],,,,L for layer,,,N for neuron,,,P for pattern
double** x1;
x1=new double* [4];
x1[0]=new double [120*4];
for(i=0;i<4;i++)
x1[i]=&x1[0][i*120];




//yd[N][P],,,desired y, N for neuron,,,P for pattern
double** yd;
yd=new double* [2];
yd[0]=new double [120*2];
for(i=0;i<2;i++)
yd[i]=&yd[0][i*120];
//
//


for(i=0;i<120;i++)
{
for(j=0;j<4;j++)
{
fin>>x1[j][i];
}
for(k=0;k<2;k++)
{
fin>>yd[k][i];
}
}
fin.close();
//
//weighting
//wL[N][I],,,L for layer,,,N for neuron,,,I for input number
double** w2;
w2=new double* [7];
w2[0]=new double [7*4];
for(i=0;i<7;i++)
w2[i]=&w2[0][i*4];
//double w2[7][4];
double** w3;
w3=new double* [2];
w3[0]=new double [2*8];
for(i=0;i<2;i++)
w3[i]=&w3[0][i*8];
//double w3[2][8];
ifstream wfin("weight.txt");
//w2
for(i=0;i<7;i++)
{
for(j=0;j<4;j++)
{
wfin>>w2[i][j];
}
}
//w3
for(i=0;i<2;i++)
{
for(j=0;j<8;j++)
{
wfin>>w3[i][j];
}


}
wfin.close();
//checked
double *x2,*x3;


j=i=0;
while(i<120)


{


x2=net_effected_by_sigmoid(x1,w2,3,i,7);
i++;
}




delete [] x2;
delete [] x3;
delete [] x1[0];
delete [] x1;
delete [] yd[0];
delete [] yd;
delete [] w2[0];
delete [] w2;
delete [] w3[0];
delete [] w3;




return 0;
}



دو فایل تکزت ورودی هم برای اجرای کد لازم است که متوجه نشدم چطوری آپلود کنم. ممنون میشم جواب بدین؟

rahnema1
پنج شنبه 02 مهر 1394, 10:12 صبح
سلام
ببینید اگه می خواهید کار با اشاره گر را تمرین کنید خب مشکلی نیست (اگر چه می شه از تمرینهای ساده تر شروع کرد تا در اشاره گر مسلط تر بشید بعد تمرینهای مشکل تر را انجام بدید)
مثلا تو هر تابع که از new استفاده می کنید در همون جا هم delete انجام می شه
مثلا شما در یک حلقه صد بار new می کنید به همون اندازه هم باید delete کنید
الان دقیقا متوجه نشدم چیکار می خواد توی برنامه انجام بشه
در هر صورت پیشنهاد می کنم برای آرایه ها از vector استفاده کنید که دیگه دردسرهای اشاره گر و اشتباه برنامه پیش نیاد
مثلا نمونه برنامه زیر Mat آرایه دو بعدی و Vec می تونه آرایه یک بعدی ایجاد کنه
اینجا m ابعادش 10 در 20 میشه و مقادیر اولیه اش هم صفره و وارد یک تابع به نام func می کنیم و محتوای اون را تغییر می دهیم
حالا تابعهای دیگه هم برای vector مثل reserve و push_back و ... هم هست که
آموزشهای vector هم تو این سایت و هم سایتهای دیگه فراوونه و می تونید مراجعه کنید
حتی واسه کارهای جبری مثل ضرب ماتریس و .. هم کتابخانه هایی هست مثل armadillo که کار را از این هم راحت تر می کنه


#include <vector>
#include <iostream>
using namespace std;

typedef vector<double> Vec;
typedef vector<Vec> Mat;

void func(Mat& m)
{
int rows = m.size();
int cols = m[0].size();
for(int r = 0; r < rows; r++)
for(int c = 0; c < cols; c++)
m[r][c] = r * c;
}

int main()
{
int rows = 10;
int cols = 20;
Mat m(rows, Vec(cols));
func(m);
}

mezood
پنج شنبه 02 مهر 1394, 12:42 عصر
خیلی ممنون از راهنماییتون
اگر بخوام سوالم رو واضح تر بگم ، خط 40 رو اگر نگاه کنید یک ورودی غیر صفر به تابع سیگموید دادم و خروجی صفر می شه در صورتی که نباید اینطوری باشه. در مورد غیر صفر بودن ورودی هم صد درصد مطمئنم.

rahnema1
پنج شنبه 02 مهر 1394, 17:09 عصر
ببینید مشکل sigmoid نیست مشکل از جاهای دیگه هست
گفتم بهتره از vector استفاده کنید اما اگه می خواهید اشاره گر استفاده کنید یه نمونه می ذارم جاهای دیگه داخل تابع هم باز باید اصلاح بشه این متغیرهای i و j را خارج از حلقه تعذیف نکنید بهتره تو خود حلقه تعریف بشه

double** x1;
x1 = new double* [4];
for (int i = 0; i < 4; i++)
{
x[i] = new double[120];
}
for(int i = 0; i < 120; i++)
{
for(int j=0; j < 4; j++)
{
fin >> x1[j][i];
}
}
for (int i = 0; i < 4; i++)
{
delete[] x1[i];
}
delete[] x1;