用C语言实现简单的神经元

用C语言实现简单的神经元

背景

工作之余研究一下时下大热的人工神经网络,因工作原因本人对C语言使用较为顺手于是用C撸了一个神经元

特点

本实现有以下特点

  1. 以基于对象的方式实现;
  2. 树突使用链表实现;
  3. 树突在连接两个神经元时自动创建。

代码

废话不多说,直接上代码

代码的使用,该部分用实现好的神经元模拟了与或非逻辑门

//main.c
#include <stdio.h>
#include <stdlib.h>
#include "neure.h" 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

//阶梯形隶属函数
double ladder(double x)
{
	return ((x>0)?1:0);
}
//sigmoid隶属函数
double sigmoid(double x)
{
	return (1/(1+exp(-x)));
}

int main(int argc, char *argv[]) 
{	
	double  d_x=1;
	double  d_y=1;
	 
	//简单模拟与逻辑门 
	neure_t* node1=creat_neure(1.5,ladder);//创建一个神经元 阀值为1.5 
	neure_connectIn(&d_x,node1,1);//连接到输入x 系数为1 
	neure_connectIn(&d_y,node1,1);//连接到输入y 系数为1 
	printf("%f and %f=%f\n",d_x,d_y,neure_output(node1)); //输出运算结果 
	//简单模拟或逻辑门 
	neure_t* node2=creat_neure(0.5,ladder);//创建一个神经元 阀值为0.5 
	neure_connectIn(&d_x,node2,1);//连接到输入x 系数为1 
	neure_connectIn(&d_y,node2,1);//连接到输入y 系数为1 
	printf("%f or %f=%f\n",d_x,d_y,neure_output(node2)); //输出运算结果
	//简单模拟非逻辑门 
	neure_t* node3=creat_neure(-0.5,ladder);//创建一个神经元 阀值为-0.5 
	neure_connectIn(&d_x,node3,-1);//连接到输入x 系数为-1  
	printf("%f not =%f\n",d_x,neure_output(node3)); //输出运算结果
	//连接与门和非门模拟与非门 
	neure_connect(node1,node3,-1);//连接两个神经元系数为-1 
	printf("%f andnot %f =%f\n",d_x,d_y,neure_output(node3)); //输出运算结果
	return 0;
}

neure.h是接口

//neure.h
#ifndef _FILE_NEURE_H_
#define _FILE_NEURE_H_

typedef double (*transferFunc_t)(double);
typedef struct neure neure_t;
//typedef struct input input_t;

/*功能:创建神经元,无树突,树突在连接两个神经元或连接神经元与输入时自动创建
  参数:v阀值 pf_tsf隶属函数
  返回值:指向被创建的神经元的指针 */ 
neure_t* creat_neure(double v,transferFunc_t pf_tsf); 

//连接两个神经元,并设置系数 
int neure_connect(neure_t* pNeureFirst,neure_t* pNeureNext,double w);

//连接神经元到输入,并设置系数 
int neure_connectIn(double* pd_x,neure_t* pNeureNext,double w);

//计算神经元的输出 该函数自动调用所依赖的前置神经元 
float neure_output(neure_t *pNeure); 

#endif

重点来了neure.c部分是实现

//neure.c
//author :1084541514@qq.com
#include <stdio.h>
#include <stdlib.h> 
#include "neure.h"

typedef struct input input_t;
//创建输入节点 
input_t* creat_input(neure_t* pLastNeure,double* pd_x,double w);

typedef double (*transferFunc_t)(double);
//神经元 
struct neure
{
 input_t* inputHead;//树突链表 ,因树突个数不定所以用链表实现 
 double v;		   //阀值	
 transferFunc_t tsf;//传递函数 ,隶属函数 
};

//树突 
struct input 
{
	neure_t * pNeure;//输入神经元
	double* pd_x; //输入值指针,未连接神经元时值要外部设置 
	double w;//权重 
	input_t * next;//下一输入项 
};
//连接两个神经元,如果后置的神经元没有树突则自动创建 
int neure_connect(neure_t* pNeureFirst,neure_t* pNeureNext,double w)
{
	input_t* pNextInput=NULL;
	input_t* pLastInput=NULL;
	if((pNeureFirst==NULL)||(pNeureNext==NULL))
	{
		return -1;
	}
	pLastInput=pNeureNext->inputHead;
	pNextInput=pNeureNext->inputHead;
	while(NULL!=pNextInput)//遍历树突 
	{
		if(NULL==pNextInput->pNeure)//判断树突是否空闲 
		{
			pNextInput->pNeure=pNeureFirst;
			pNextInput->w=w;
			return 0;//连接成功 
		}
		pLastInput=pNextInput;
		pNextInput=pNextInput->next;//查看下个树突 
	}
	
	if(NULL==pNeureNext->inputHead)//没有树突 
	{
		pNeureNext->inputHead=creat_input(pNeureFirst,NULL,w);
		if(NULL==pNeureNext->inputHead)return -2;//创建新树突分配内存失败 
	} 
	else //有树突但没有空闲树突 
	{
		pLastInput->next=creat_input(pNeureFirst,NULL,w);
		if(NULL==pNeureNext->inputHead)return -2;//创建新树突分配内存失败 
	} 
}

int neure_connectIn(double* pd_x,neure_t* pNeureNext,double w)
{
	input_t* pNextInput=NULL;
	input_t* pLastInput=NULL;
	if((pd_x==NULL)||(pNeureNext==NULL))
	{
		return -1;
	}
	pLastInput=pNeureNext->inputHead;
	pNextInput=pNeureNext->inputHead;
	while(NULL!=pNextInput)//遍历树突 
	{
		if(NULL==pNextInput->pNeure)//判断树突是否空闲 
		{
			if(NULL==pNextInput->pd_x)
			{
				pNextInput->pd_x=pd_x;
				pNextInput->w=w;
				return 0;//连接成功 
			}
			
		}
		pLastInput=pNextInput;
		pNextInput=pNextInput->next;//查看下个树突 
	}
	
	if(NULL==pNeureNext->inputHead)//没有树突 
	{
		pNeureNext->inputHead=creat_input(NULL,pd_x,w);
		if(NULL==pNeureNext->inputHead)
			return -2;//创建新树突分配内存失败 
		return 0;
	} 
	else //有树突但没有空闲树突 
	{
		pLastInput->next=creat_input(NULL,pd_x,w);
		if(NULL==pNeureNext->inputHead)
			return -2;//创建新树突分配内存失败 
		return 0;
	}	
}
//神经元输出计算函数 
float neure_output(neure_t *pNeure)
{ 
	double sum=0;
	input_t*  pNextInput=pNeure->inputHead;
	//求输入和
	while(NULL!=pNextInput)
	{
		if(NULL!=pNextInput->pNeure)//输入神经元非空 
		{ 
			sum+=neure_output(pNextInput->pNeure)*(pNextInput->w);//递归计算前神经元的输出 
		}
		else//输入没有接神经元 
		{
			sum+=*(pNextInput->pd_x)*pNextInput->w;//debug
		} 
		
		pNextInput=pNextInput->next;
	} 
	return(pNeure->tsf(sum-pNeure->v));//使用隶属函数计算输出 
}

//创建无树突的神经元 
neure_t* creat_neure(double v,transferFunc_t pf_tsf)
{
	neure_t* pNeure=(neure_t*)malloc(sizeof(neure_t));
	if(pNeure==NULL)return NULL;//内存分配错误
	pNeure->inputHead=NULL;//新创建的神经元没有树突 
	pNeure->v=v;
	pNeure->tsf=pf_tsf;		
	return pNeure; 
	
}

//创建树突
input_t* creat_input(neure_t* pLastNeure,double* pd_x,double w)
{
	input_t * pInput=(input_t*)malloc(sizeof(input_t));
	if(NULL==pInput)return NULL;
	
	pInput->pNeure=pLastNeure;
	pInput->w=w;
	pInput->pd_x=pd_x;
	pInput->next=NULL;
	return pInput;
}

代码未完善,未实现删除。
代码未经充分测试仅供参考
谢谢

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值