⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cconditionaldistribution.cpp

📁 C人工智能游戏开发的一些实例源代码 C Game development in artificial intelligence source code of some examples
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		for(j=1;j<ulNumberOfInputs+1;j++)
		{
			dStimulus+=ppdwih[i][j]*pdInputs[j-1];
		}
		pdah[i]=1.0/(1.0+exp(-dStimulus));
	}
	double dTotalOutput=0.0;

	//Unlike the neural network in CMLP.cpp, the one used here has a special function to calculate the
	//activity of its outputs in order to guarantee that they sum to unity (as befits closed-world probabilities). 
	//This function is called "softmax" and is described more fully in books such as [Bishop95]
	for(i=0;i<ulNumberOfOutputs;i++)
	{
		dStimulus=ppdwho[i][0];
		for(j=1;j<ulNumberOfHiddenNodes+1;j++)
		{
			dStimulus+=ppdwho[i][j]*pdah[j-1];
		}

		//Translate this stimulation into the activity of the output neuron using the activation 
		//function:
		pdao[i]=exp(dStimulus);
		dTotalOutput+=pdao[i];
	}

	//Deallocate the temporary storage that was used for the hidden neuron activities
	delete []pdah;

	//Normalise the output neuron activities
	for(i=0;i<ulNumberOfOutputs;i++)
	{
		pdao[i]/=dTotalOutput;
	}

	//Remember that we're returning a pointer to "new"ed storage, so the calling function
	//must deallocate it to avoid memory leaks.
	return pdao;
}

//Generates a sample from the conditional distribution by selecting one of the distribution's bins in 
//accordance with their probabilities and generating a specific sample from within the bin
double CConditionalDistribution::dGetOutputs(
							const double * const pdInputs
							)
{
	//Use the neural network to calculate the bin probabilities as a function of the conditional distribution's inputs
	double *pdOutputs;
	pdOutputs=pdGetBinProbabilities(pdInputs);

	unsigned long ulCurrentBin;
	double dOutput;
	//This outer loop guarantees that events less likely than 1 in 100 do not occur. Though not strictly necessary
	//it helps to avoid samples that cannot be justified statistically on the basis of the model's training data.
	do
	{
		//The sampling mechanism in this inner loop is identical to that of the unconditional distribution
		ulCurrentBin=0;
		double dTargetProbability=double(rand())/double(RAND_MAX);
		double dAccumulator=pdOutputs[ulCurrentBin];
		while(dTargetProbability>dAccumulator)
		{
			ulCurrentBin++;
			dAccumulator+=pdOutputs[ulCurrentBin];
		}
	}
	while(pdOutputs[ulCurrentBin]<0.01);

	dOutput=double(ulCurrentBin)/double(ulNumberOfOutputs)+double(rand())/double(RAND_MAX)*(1.0/double(ulNumberOfOutputs));

	delete []pdOutputs;

	return dOutput;
}

double CConditionalDistribution::dGetPerformance(void)
{
	//dBestError is computed by a call to dGetPerformance
	return dBestError;
}

//This function measures the performance of the conditional distribution model - that is how consistent it is with 
//the exemplar data passed to this function. This consistency is measured as the mean log-probability with which 
//the distribution model "explains" the data.
double CConditionalDistribution::dGetPerformance(
								const unsigned long ulNumberOfPatterns,
								double ** const ppdInputs,
								double * const pdTargets
								)
{
	unsigned long i,j;

	//Storage for the error measure
	double dError=0.0;

	//Will store the neural network outputs (i.e. bin probabilities)
	double *pdOutputs;

	//Prepare some storage for the binary target vector (explained below)
	double *pdBinaryTargets=new double[ulNumberOfOutputs];
	
	//Go through each pattern (example) in the data set and
	for(i=0;i<ulNumberOfPatterns;i++)
	{
		//Compute the probabilities associated with each bin in the distribution for the current input
		pdOutputs=pdGetBinProbabilities(ppdInputs[i]);

		//Now, for each bin
		for(j=0;j<ulNumberOfOutputs;j++)
		{
			//This section of code translates the target output associated with the current example into a 
			//vector of length ulNumberOfOutputs, containing zeros in all positions but for a one corresponding to
			//the bin that actually contains target output specified in the current example. 

			//This vector can be thought of as a vector of target probabiltiies for the bins in the distribution model
			//and hence for the outputs of teh neural network: if the distribution predicted the examples perfectly 
			//then, for this pattern, all bins would have probability zero except for the one that actually contained
			//the example output.
			if(pdTargets[i]>=double(j)/double(ulNumberOfOutputs) 
				&& pdTargets[i]<double(j+1)/double(ulNumberOfOutputs))
			{
				pdBinaryTargets[j]=1.0;
			}
			else
			{
				pdBinaryTargets[j]=0.0;
			}

			//The actual error measure is derived below. This is the cross entropy function and can only be used
			//when the bin probabilities are constrained to sum to, at most, unity. (See [Bishop95].)
			dError-=pdBinaryTargets[j]*log(pdOutputs[j]);
		}
		//Deallocate the memory used to store the network outputs.
		delete []pdOutputs;
	}

	//Divide the error by the number of patterns to give the average error per sample - makes
	//the error measure independent of the number of samples and hence a little more 
	//interpretable.
	dError/=double(ulNumberOfPatterns);

	//Clean up allocated memory
	delete []pdBinaryTargets;

	//Return the computed error
	return dError;
}

int CConditionalDistribution::Save(const char * const pFileName)
{
	unsigned long i,j;
	assert(pFileName);

	//Create the output stream to save the network to.
	ofstream *pOut=new ofstream(pFileName);

	//Make sure it was created and opened successfully.
	if(!pOut)
	{
		assert(false);
		return 0;
	}
	if(!pOut->is_open())
	{
		assert(false);
		delete pOut;
		return 0;
	}
	//Make sure we don't lose information.
	pOut->precision(15);

	//Save all the network info:
	//Its structure...
	*pOut<<ulNumberOfInputs;
	*pOut<<"\n";
	*pOut<<ulNumberOfHiddenNodes;
	*pOut<<"\n";
	*pOut<<ulNumberOfOutputs;
	*pOut<<"\n";

	//Its weights
	for(i=0;i<ulNumberOfHiddenNodes;i++)
	{
		for(j=0;j<ulNumberOfInputs+1;j++)
		{
			*pOut<<ppdwih[i][j];
			*pOut<<"\t";
		}
		*pOut<<"\n";
	}
	for(i=0;i<ulNumberOfOutputs;i++)
	{
		for(j=0;j<ulNumberOfHiddenNodes+1;j++)
		{
			*pOut<<ppdwho[i][j];
			*pOut<<"\t";
		}
		*pOut<<"\n";
	}

	//When training started...
	*pOut<<"Training started\t";
	*pOut<<pTrainingStartTime;
	*pOut<<"\t";
	*pOut<<pTrainingStartDate;
	*pOut<<"\n";

	//the current date and time...
	char *pTime=new char[256];
	*pOut<<"Current time\t\t";
	_strtime(pTime);
	*pOut<<pTime;
	*pOut<<"\t";
	_strdate(pTime);
	*pOut<<pTime;
	*pOut<<"\n";
	delete []pTime;

	//And how well the network currently performs.
	*pOut<<"Performance\t\t";
	*pOut<<dBestError;
	*pOut<<"\n";

	//Close the file and delete the stream.
	pOut->close();
	delete pOut;

	//Return that the save was successful.
	return 1;
}

int CConditionalDistribution::Load(const char * const pFileName)
{
	unsigned long i,j;
	assert(pFileName);

	//Create a stream to load the network from
	ifstream *pIn=new ifstream(pFileName,ios::nocreate);

	//Check to make sure that it was created and could be opened.
	if(!pIn)
	{
		assert(false);
		return 0;
	}
	if(!pIn->is_open())
	{
		assert(false);
		delete pIn;
		return 0;
	}

	//Since we're about to load a new network, we should delete the storage used by the
	//current one to prevent memory leaks.
	DeallocateMemory();

	//Load the structure of the new network
	*pIn>>ulNumberOfInputs;
	*pIn>>ulNumberOfHiddenNodes;
	*pIn>>ulNumberOfOutputs;

	//Allocate memory to store its weights
	AllocateMemory();

	//Reset its status so that it can be trained if necessary
	Reset();

	//Load in its weights
	for(i=0;i<ulNumberOfHiddenNodes;i++)
	{
		for(j=0;j<ulNumberOfInputs+1;j++)
		{
			*pIn>>ppdwih[i][j];
			ppdBestwih[i][j]=ppdwih[i][j];
		}
	}
	for(i=0;i<ulNumberOfOutputs;i++)
	{
		for(j=0;j<ulNumberOfHiddenNodes+1;j++)
		{
			*pIn>>ppdwho[i][j];
			ppdBestwho[i][j]=ppdwho[i][j];
		}
	}

	//Close and delete the stream.
	pIn->close();
	delete pIn;

	//Indicate that we've been successful.
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -