📄 cmac.cpp
字号:
tiles[i].e=0;
}
}
CMAC::Tiling::~Tiling(){
delete [] origin;
delete [] IndCoef;
delete [] tiles;
delete [] n;
delete [] h;
}
CMAC::CMAC(char* fileName){
int TilingsNumber;
int** TilesNumber=NULL;
setCmacStructure(fileName, TilingsNumber, &TilesNumber);
if (TilesNumber==NULL){
cout << "Something is wrong with reading CMAC structure from file" << fileName << endl;
exit(EXIT_FAILURE);
}
createCMAC(TilingsNumber, TilesNumber);
int i;
for (i=0; i<TilingsNumber; i++)
delete [] TilesNumber[i];
delete [] TilesNumber;
}
void CMAC::createCMAC(int t, int** n){
/* General constructor.
Parameters:
t : number of tiles
n : array that indicates number of tiles along each dimension for each tile
*/
int i;
tilings = new Tiling[t];
T=t;
ALPHA_SCHEDULE=VISITATION;
ALPHA_DECREASE_FREQUENCY=100;
ALPHA_DECREASE_FACTOR=2.0;
ExamplesNumber=0;
NumberOfParameters=0;
MaxParameterChange=0;
NumberParametersChanged=0;
for(i=0; i<t; i++){
Tiling* til = new Tiling(n[i]);
tilings[i] = (*til);
NumberOfParameters=NumberOfParameters+tilings[i].getSize();
}
CMAC::Tiling::setTraceDecay(0.0);
}
int CMAC::getSize(){
/* Returns total number of parameters in this camc architecture
*/
return NumberOfParameters;
}
void CMAC::setInputBounds(const double* left, const double* right){
/* Sets bounds on input variables
*/
CMAC::Tiling::setBounds(left, right);
}
void CMAC::deleteInputBounds(){
CMAC::Tiling::deleteBounds();
}
void CMAC::predict(const State& s, double& output)
/* Predicts an output value for a given input.
Parameters:
s : reference to the input (state)
output : returned value of the predicted output
*/
{ int i, ind;
double w;
output=0;
for(i=0; i<T; i++){
tilings[i].getActiveParameter(s, w, ind);
output=output+w;
}
#ifdef DEBUG
cout << "Input: " << endl;
for(i=0; i<State::dimensionality; i++)
cout << s.x[i] << " ";
cout << endl;
cout << "Output: " << output << endl;
#endif
}
void CMAC::learn(const State& s, const double target)
/* Learns an input-output pair.
Used when learning according to MSE criteria
Parameters:
s : input (state)
target: target output value
*/
{
int i;
double w_update, PredictedValue;
ExamplesNumber++;
predict(s, PredictedValue);
w_update=(target-PredictedValue);
for(i=0; i<T; i++)
tilings[i].updateParameters(s, w_update, MaxParameterChange, NumberParametersChanged); //this is a function that uses eleigibility traces. It is assumed that the user of this class sets eligibility traces using appropriate functions.
if (ALPHA_SCHEDULE==DECREASE){
if ((ExamplesNumber%ALPHA_DECREASE_FREQUENCY)==0)
for(i=0; i<T; i++)
tilings[i].decreaseAlpha(ALPHA_DECREASE_FACTOR);
}
else
if (ALPHA_SCHEDULE==VISITATION)
for(i=0; i<T; i++)
tilings[i].decreaseAlpha(s);
}
void CMAC::computeGradient(const State& s, double* GradientVector)
/* Compute the gradient w.r.t. architecture parameters
at input s
*/
{
int i, j, ind, N, I;
double par;
I=0;
for (i=0; i<T; i++){
N=tilings[i].getSize();
tilings[i].getActiveParameter(s, par, ind);
for (j=0; j<N; j++){
if (j==ind)
GradientVector[I+j]=1;
else
GradientVector[I+j]=0;
}
I=I+N;
}
}
void CMAC::updateParameters(double* delta)
/* Increase parameters by amounts in delta array
multiplied by appropriate learning step for each parameter
*/
{
int i, N, I;
ExamplesNumber++;
I=0;
for (i=0; i<T; i++){
N=tilings[i].getSize();
//cout << "Tiling " << i << endl;
tilings[i].updateParameters(&(delta[I]), MaxParameterChange, NumberParametersChanged);
I=I+N;
}
if (ALPHA_SCHEDULE==DECREASE){
if ((ExamplesNumber%ALPHA_DECREASE_FREQUENCY)==0)
for(i=0; i<T; i++)
tilings[i].decreaseAlpha(ALPHA_DECREASE_FACTOR);
}
else
if (ALPHA_SCHEDULE==VISITATION)
for(i=0; i<T; i++)
tilings[i].decreaseAllAlpha();
}
void CMAC::replaceTraces(const State& s, double replace)
/* Replace traces of parameters, activated by input state s to value replace
*/
{
int i;
for(i=0; i<T; i++)
tilings[i].replaceTrace(s, replace);
}
void CMAC::decayTraces(double factor){
int i;
for(i=0; i<T; i++)
tilings[i].decayTraces(factor);
}
void CMAC::accumulateTraces(const State& s, double amount){
int i;
for(i=0; i<T; i++)
tilings[i].accumulateTraces(s, amount);
}
void CMAC::setArchitectureParameters(int argc, char *argv[])
/* Loads parameters of the architecture.
Parameters:
argc : number of supplied arguments
argv : array of arguments
In this case 1 argument is expected (argc=1) and
argv[0] is the name of the file from which parameters are
to be read
*/
{ int i;
if (argc==0){
cout << "No file name to read data." << endl;
exit(EXIT_SUCCESS);
}
ifstream file(argv[0]);
if (file.fail()){
cout << "Error (cmac): cannot open file " << argv[0] << endl;
exit(EXIT_FAILURE);
}
char buffer[40];
file.get(buffer, strlen("Number of tilings: ")+1);
if (file.fail()){
cout << "Error (cmac): input failed (1)" << endl;
exit(EXIT_FAILURE);
}
int t;
file >> t;
if (file.fail()){
cout << "Error (cmac): input failed (2)" << endl;
exit(EXIT_FAILURE);
}
if (t!=T){
delete [] tilings;
T=t;
tilings = new Tiling[T];
}
for(i=0; i<T; i++){
int j;
char c;
file.get(c);
if (file.fail()){
cout << "Error (cmac): input failed (2-3) " << endl;
exit(EXIT_FAILURE);
}
file.get(buffer, strlen("Tiling ")+1);
if (file.fail()){
cout << "Error (cmac): input failed (3) " << endl;
exit(EXIT_FAILURE);
}
file >> j;
if (file.fail()){
cout << "Error (cmac): input failed (4) " << endl;
exit(EXIT_FAILURE);
}
tilings[i].setParameters(file);
}
file.close();
}
void CMAC::saveArchitectureParameters(int argc, char *argv[])
/* Saves parameters of the architecture.
Parameters:
argc : number of supplied arguments
argv : array of arguments
In this case 1 argument is expected (argc=1) and
argv[0] is the name of the file to which parameters
are to be saved
*/
{ int i;
if (argc==0){
cout << "No file name to save data." << endl;
exit(EXIT_SUCCESS);
}
ofstream file(argv[0]);
if (file.fail()){
cout << "Error (cmac): cannot open file " << argv[0] << endl;
exit(EXIT_FAILURE);
}
file << "Number of tilings: " << T << endl;
if (file.fail()){
cout << "Error (cmac): disk is full " << endl;
exit(EXIT_FAILURE);
}
for(i=0; i<T; i++){
file << "Tiling " << i << endl;
if (file.fail()){
cout << "Error (cmac): disk is full " << endl;
exit(EXIT_FAILURE);
}
tilings[i].saveParameters(file);
}
file.close();
}
void CMAC::setLearningParameters(int argc, char *argv[])
/* Sets learning parameters.
Parameters:
argc : number of supplied arguments
argv : array of arguments
*/
{
int i, j;
double alpha=0;
double decay=0;
double v=0;
bool alphaSet=false;
for (i=0; i<argc; i++){
if (strncmp(argv[i],"?",1)==0){
cout << "CMAC learning parammeters:" << endl;
cout << "schedule= (possible values: constant, decrease, visitation)" << endl;
cout << "alpha= (constant if using constant schedule, or initial value if using other schedules)" << endl;
cout << "f= (decrease frequency, if using decrease schedule)" << endl;
cout << "d= (decrease factor, if using decrease schedule)" << endl;
cout << "v= (visitation factor for alpha)" << endl;
return;
}
if (strncmp("schedule=", argv[i], 9)==0){
if (strncmp("schedule=constant", argv[i], 17)==0)
ALPHA_SCHEDULE=CONSTANT;
if (strncmp("schedule=decrease", argv[i], 17)==0)
ALPHA_SCHEDULE=DECREASE;
if (strncmp("schedule=visitation", argv[i], 19)==0)
ALPHA_SCHEDULE=VISITATION;
}
if (strncmp("alpha=", argv[i], 6)==0){
alpha=atof(&(argv[i][6]));
if ((alpha<=0) || (alpha>1)){
cout << "Error (cmac): learning step must be in (0,1]" << endl;
exit(EXIT_FAILURE);
}
alphaSet=true;
}
if (strncmp("f=", argv[i], 2)==0)
ALPHA_DECREASE_FREQUENCY=atoi(&(argv[i][2]));
if (strncmp("ph=", argv[i], 3)==0){
SaveParameterHistory=atoi(&(argv[i][3]));
if ((SaveParameterHistory!=true)&&(SaveParameterHistory!=false)){
cout << "Error (cmac): invalid entry for save parameter history option" << endl;
exit(EXIT_FAILURE);
}
}
if (strncmp("d=", argv[i], 2)==0){
ALPHA_DECREASE_FACTOR=atof(&(argv[i][2]));
if (ALPHA_DECREASE_FACTOR<=1){
cout << "Error (camc): invalid setting of alpha decrease factor" << endl;
exit(EXIT_FAILURE);
}
}
if (strncmp("v=", argv[i], 2)==0){
v=atof(&(argv[i][2]));
if (v<1){
cout << "Error (camc): invalid setting of alpha visitation factor" << endl;
exit(EXIT_FAILURE);
}
for(j=0; j<T; j++)
tilings[j].setVisitationFactor(v);
}
if (strncmp("decay=", argv[i], 6)==0){
decay=atof(&(argv[i][6]));
if ((decay<0) || (decay>1)){
cout << "Error (cmac): trace decay must be in [0,1]" << endl;
exit(EXIT_FAILURE);
}
CMAC::Tiling::setTraceDecay(decay);
}
}
if (alphaSet==true){
if (alpha==0){
cout << "Please specify learning step from (0,1]" << endl;
cin >> alpha;
if (alpha<=0) {
cout << "Invalid entry" << endl;
exit(EXIT_SUCCESS);
}
}
for(j=0; j<T; j++)
tilings[j].setAlpha(alpha);
}
}
CMAC::~CMAC(){
delete [] tilings;
}
void CMAC::helpLearningParameters(){
cout << "CMAC learning parammeters:" << endl;
cout << "schedule=value : type of the schedule for decreasing learning steps (possible values: constant, decrease, visitation)" << endl;
cout << "alpha=value : learning step (constant if using constant schedule, or initial value if using other schedules)" << endl;
cout << "f=value : decrease frequency, if using decrease schedule" << endl;
cout << "d=value : decrease factor, if using decrease schedule" << endl;
cout << "v=value : constant used in the visitation schedule rule to decrease learning steps: v/(v+number of visits to the tile)." << endl;
cout << "decay=value : trace decay factor" << endl;
return;
}
void CMAC::setCmacStructure(char* fileName, int& TilingsNumber, int*** TileNumbers){
/*This function reads configuration of the cmac architecture from a file
*/
char buffer[40], c;
int i,j;
ifstream cmacFile(fileName);
if (cmacFile.fail()){
cout << "Error: can not open file to read cmac configuration" << endl;
exit(EXIT_FAILURE);
}
cmacFile.get(buffer, strlen("TilingsNumber =")+1);
if (cmacFile.fail()){
cout << "Error: input failed (1)" << endl;
exit(EXIT_FAILURE);
}
cmacFile >> TilingsNumber;
if (cmacFile.fail()){
cout << "Error: input failed (2)" << endl;
exit(EXIT_FAILURE);
}
*TileNumbers = new int*[TilingsNumber];
cmacFile.get(c);
if (cmacFile.fail()){
cout << "Error: input failed (3)" << endl;
exit(EXIT_FAILURE);
}
cmacFile.get(buffer, strlen("Number of tiles along each dimension:")+1);
if (cmacFile.fail()){
cout << "Error: input failed (4)" << endl;
exit(EXIT_FAILURE);
}
for(i=0; i<TilingsNumber; i++){
(*TileNumbers)[i] = new int[State::dimensionality];
cmacFile.get(c);
if (cmacFile.fail()){
cout << "Error: input failed (4-5)" << endl;
exit(EXIT_FAILURE);
}
cmacFile.get(buffer, strlen("Tiling ")+1);
if (cmacFile.fail()){
cout << "Error: input failed (5)" << endl;
exit(EXIT_FAILURE);
}
cmacFile >> j;
if (cmacFile.fail()){
cout << "Error: input failed (6) tiling" << i << endl;
exit(EXIT_FAILURE);
}
for (j=0; j<State::dimensionality; j++){
cmacFile >> (*TileNumbers)[i][j];
if (cmacFile.fail()){
cout << "Error: input failed (7)" << endl;
exit(EXIT_FAILURE);
}
}
}
cmacFile.close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -