示例#1
0
s32 main()
{
    srand((u32)time(0));

    //setup data depending on which function will be run
    //TrainData will contain random values for teaching the network
    //TestData is for testing the network after it's trained
#if A
    const char *filename = "nn1a.csv";
    
    r32 TrainData[DataPointCount][2];
    r32 TestData[DataPointCount][2];
    
    for(u32 i = 0;
        i < ArrayCount(TrainData);
        ++i)
    {
        TrainData[i][0] = RandomBetween(-1,7);
        TrainData[i][1] = FunctionProblemOne(TrainData[i][0]);
        
        TestData[i][0] = RandomBetween(-1,7);
        TestData[i][1] = FunctionProblemOne(TrainData[i][0]);
    }

    u32 numLayers = 3;
    u32 lSz[3] = {1,25,1};
#endif
#if B
    const char *filename = "nn2a.csv";

    r32 TrainData[DataPointCount][3];
    r32 TestData[DataPointCount][3];
    
    for(u32 i = 0;
        i < ArrayCount(TrainData);
        ++i)
    {
        TrainData[i][0] = RandomBetween(-3,3);
        TrainData[i][1] = RandomBetween(-3,3);
        TrainData[i][2] = FunctionProblemTwo(TrainData[i][0], TrainData[i][1]);
        
        TestData[i][0] = RandomBetween(-3,3);
        TestData[i][1] = RandomBetween(-3,3);
        TestData[i][2] = FunctionProblemTwo(TrainData[i][0], TrainData[i][1]);
    }

    u32 numLayers = 4;
    u32 lSz[4] = {2,25,10,1};
#endif
#if C
    const char *filename = "nn1b.csv";
    
    r32 TrainData[DataPointCount][2];
    r32 TestData[DataPointCount][2];
    
    for(u32 i = 0;
        i < ArrayCount(TrainData);
        ++i)
    {
        TrainData[i][0] = RandomBetween(-1,7);
        TrainData[i][1] = FunctionProblemOneWithNoise(TrainData[i][0]);
        
        TestData[i][0] = RandomBetween(-1,7);
        TestData[i][1] = FunctionProblemOneWithNoise(TrainData[i][0]);
    }

    u32 numLayers = 3;
    u32 lSz[3] = {1,25,1};
#endif
#if D
    const char *filename = "nn2b.csv";
        
    r32 TrainData[DataPointCount][3];
    r32 TestData[DataPointCount][3];
    
    for(u32 i = 0;
        i < ArrayCount(TrainData);
        ++i)
    {
        TrainData[i][0] = RandomBetween(-3,3);
        TrainData[i][1] = RandomBetween(-3,3);
        TrainData[i][2] = FunctionProblemTwoWithNoise(TrainData[i][0], TrainData[i][1]);
        
        TestData[i][0] = RandomBetween(-3,3);
        TestData[i][1] = RandomBetween(-3,3);
        TestData[i][2] = FunctionProblemTwoWithNoise(TrainData[i][0], TrainData[i][1]);
    }

    u32 numLayers = 4;
    u32 lSz[4] = {2,25,10,1};
#endif

    //crash if I missed a number change
    Assert(numLayers == ArrayCount(lSz));
	
	r32 beta = 0.3f, alpha = 0.1f;
	u32 num_iter = 5000000;

	CBackProp *bp = new CBackProp(numLayers, lSz, beta, alpha);

    u32 DataPointSize = lSz[0] + lSz[numLayers - 1];

    //iterate up to the max iterations
    for (u32 IterationIndex = 0;
         IterationIndex < num_iter;
         ++IterationIndex)
	{
        r32 MeanSquareError = 0;
	
        for(u32 DataPointIndex = 0;
            DataPointIndex < DataPointCount;
            ++DataPointIndex)
        {
            //backpropogate the training data and caluculate the mse
            r32 *target = &TrainData[DataPointIndex][lSz[0]];
            bp->bpgt(TrainData[DataPointIndex], target);
            MeanSquareError += bp->mse(target);
        }

        //if average of MSE over the set of test data is below the threshold, end training
        MeanSquareError /= DataPointCount;
        if(MeanSquareError < Thresh)
        {
            printf("network trained, MSE: %f\n", MeanSquareError);
            break;
        }
        else
        {
            printf("training... MSE: %f\n", MeanSquareError);
        }
	}

#if 1

    //create ofs to create csvs of the data
    
    const char *path_prefix = "../data/";
    char OutputFilename[80];
    strcpy_s(OutputFilename, path_prefix);
    strcat_s(OutputFilename, filename);
    char TestDataFilename[80];
    strcpy_s(TestDataFilename, path_prefix);
    strcat_s(TestDataFilename, "test");
    strcat_s(TestDataFilename, filename);

    printf("%s\n%s\n", OutputFilename, TestDataFilename);
    
    std::ofstream NetworkOutput, TestDataOutput;
    NetworkOutput.open(OutputFilename, std::ofstream::out);
    TestDataOutput.open(TestDataFilename, std::ofstream::out);

    //iterate through each test data point, feed forward, and save out the results
	for (u32 i = 0 ; i < DataPointCount ; i++ )
	{
        r32 *DataPoint = TestData[i];
		bp->ffwd(DataPoint);
        r32 output = DataPoint[lSz[0]];
        r32 prediction = bp->Out(0);
        r32 reNormalized = (prediction * 10) - 5;

        for(u32 InputIndex = 0;
            InputIndex < lSz[0];
            ++InputIndex)
        {
            NetworkOutput << DataPoint[InputIndex] << ',';
            TestDataOutput << DataPoint[InputIndex] << ',';
        }
        NetworkOutput << reNormalized << std::endl;
        TestDataOutput << ((output*10)-5) << std::endl;
	}
#endif

    NetworkOutput.close();
    
    return 1;
}
示例#2
0
void TrainBackProp(TRAINING_TYPE type, const std::string& filename)
{
	// defining a net with 4 layers having 3,3,3, and 1 neuron respectively,
	// the first layer is input layer i.e. simply holder for the input parameters
	// and has to be the same size as the no of input parameters, in out example 3
	int numLayers = 3;
	int layerSize[3] = {10, 30, 1};

	switch (type)
	{
	case TRAINING_TYPE_FULL:
		break;
	case TRAINING_TYPE_SPEED:
		layerSize[1] = 30;
		break;
	case TRAINING_TYPE_STEER:
		layerSize[1] = 10;
		break;
	case TRAINING_TYPE_GEAR:
		layerSize[0] = 1;
		break;
	default:
		break;
	}

	// Learning rate - beta
	// momentum - alpha
	// Threshold - thresh (value of target mse, training stops once it is achieved)
	double beta = 0.0001, alpha = 0.5, Thresh =  0.2;

	std::vector<Car*> trainingData;
	bool success = loadCarData(filename, trainingData);

	if (!success)
		throw("Failed");

	std::cout << std::endl <<  "Now training the network...." << std::endl;

	CBackProp* bp = new CBackProp(numLayers, layerSize, beta, alpha);

	unsigned int size = trainingData.size();

	Car* car = NULL;
	int counter = 0;
	int iterations = 0;
	double error = 0;
	double percent = 0;

	bool trained = false;
	while (!trained)
	{
		int nrOfCorrect = 0;
		int total = 0;

		auto it_end = trainingData.cend();
		for (auto it = trainingData.cbegin(); it != it_end; it++)
		{
			int distance = std::distance(trainingData.cbegin(), it);
			car = (*it);

			double data[] = {
				car->speed, car->angle, car->distR, car->distFR, car->distFFR, 
				car->distF, car->distL, car->distFL, car->distFFL, car->clutch};

			double outputVal = 0.5;
			switch (type)
			{
			case TRAINING_TYPE_FULL:
				break;
			case TRAINING_TYPE_SPEED:
				if (car->accel > 0.0)
					outputVal = car->accel;
				else if(car->brake > 0.0)
					outputVal = car->brake;

				outputVal = 0.5 * (outputVal + 1.0);
				break;
			case TRAINING_TYPE_STEER:
				outputVal = 0.5 * (car->steer + 1.0);
				break;
			case TRAINING_TYPE_GEAR:
				outputVal = 0.5 * (car->gear + 1.0);
				break;
			default:
				break;
			}

			bp->bpgt(data, &outputVal);
		}
		double totalValue = 0.0;

		for (auto it = trainingData.cbegin(); it != it_end; it++)
		{
			int distance = std::distance(trainingData.cbegin(), it);
			car = (*it);

			double outputVal = 0.0;
			if (car->accel > 0.0)
				outputVal = car->accel;
			else if(car->brake > 0.0)
				outputVal = car->brake;

			double data[] = {
				car->speed, car->angle, car->distR, car->distFR, car->distFFR, 
				car->distF, car->distL, car->distFL, car->distFFL, car->clutch};

			bp->ffwd(data);

			double net_Out = bp->Out(0);

			double value = abs(net_Out - outputVal);
			totalValue += value;

			if (value < Thresh)
				nrOfCorrect++;

			total++;
		}
		error = totalValue / trainingData.size();
		percent = (double)((double)nrOfCorrect / (double)total);

		trained = error < Thresh || (1 - percent) < Thresh;

		counter++;
		if (trained || counter >= 1000)
		{
			iterations += counter;

			std::cout << std::endl
				<< "Iteration " << iterations << std::endl
				<< "Average Error " << error << std::endl
				<< "Percentage correct "<< percent << std::endl;

			counter = 0;
		}
	}

	std::cout << std::endl 
		<< "Iteration " << iterations << std::endl
		<< "Average Error " << error << std::endl
		<< "Percentage correct "<< percent << std::endl;


	switch (type)
	{
	case TRAINING_TYPE_SPEED:
		bp->WriteWeights("Bp_Speed.txt");
		break;
	case TRAINING_TYPE_STEER:
		bp->WriteWeights("Bp_Steer.txt");
		break;
	case TRAINING_TYPE_GEAR:
		bp->WriteWeights("Bp_Gear.txt");
		break;
	case TRAINING_TYPE_FULL:
	default:
		bp->WriteWeights("Bp_Full.txt");
		break;
	}

	std::cout << "Press Enter to quit" << std::endl;
	std::cin.ignore(1);

}