105{
106 unsigned short nclass=trainingFeatures.size();
107 unsigned int ntraining=0;
108 unsigned int ntest=0;
109 for(int iclass=0;iclass<nclass;++iclass){
110 ntraining+=m_nctraining[iclass];
111 ntest+=m_nctest[iclass];
112 }
113 if(ntest)
114 assert(!m_cv);
115 if(!m_cv)
116 assert(ntest);
117 unsigned short nFeatures=trainingFeatures[0][0].size();
118
120 const unsigned int num_layers = m_nneuron.size()+2;
121 const float desired_error = 0.0003;
122 const unsigned int iterations_between_reports = (m_verbose) ? m_maxit+1:0;
123 if(m_verbose>1){
124 cout << "creating artificial neural network with " << m_nneuron.size() << " hidden layer, having " << endl;
125 for(int ilayer=0;ilayer<m_nneuron.size();++ilayer)
126 cout << m_nneuron[ilayer] << " ";
127 cout << "neurons" << endl;
128 }
129 switch(num_layers){
130 case(3):{
131 unsigned int layers[3];
132 layers[0]=nFeatures;
133 layers[1]=m_nneuron[0];
134 layers[2]=nclass;
135 net.create_sparse_array(m_connection,num_layers,layers);
136 break;
137 }
138 case(4):{
139 unsigned int layers[4];
140 layers[0]=nFeatures;
141 layers[1]=m_nneuron[0];
142 layers[2]=m_nneuron[1];
143 layers[3]=nclass;
144 net.create_sparse_array(m_connection,num_layers,layers);
145 break;
146 }
147 default:
148 cerr << "Only 1 or 2 hidden layers are supported!" << endl;
149 exit(1);
150 break;
151 }
152
153 net.set_learning_rate(m_learning);
154
155 net.set_activation_function_hidden(FANN::SIGMOID_SYMMETRIC_STEPWISE);
156 net.set_activation_function_output(FANN::SIGMOID_SYMMETRIC_STEPWISE);
157
158 vector<unsigned short> referenceVector;
159 vector<unsigned short> outputVector;
160 float rmse=0;
161 vector<Vector2d<float> > tmpFeatures(nclass);
162 for(int iclass=0;iclass<nclass;++iclass){
163 tmpFeatures[iclass].resize(trainingFeatures[iclass].size(),nFeatures);
164 for(unsigned int isample=0;isample<m_nctraining[iclass];++isample){
165 for(int ifeature=0;ifeature<nFeatures;++ifeature){
166 tmpFeatures[iclass][isample][ifeature]=trainingFeatures[iclass][isample][ifeature];
167 }
168 }
169 }
170 m_cm.clearResults();
171 if(m_cv>0){
172 rmse=net.cross_validation(tmpFeatures,
173 ntraining,
174 m_cv,
175 m_maxit,
176 desired_error,
177 referenceVector,
178 outputVector,
179 m_verbose);
180 for(int isample=0;isample<referenceVector.size();++isample){
181 string refClassName=m_nameVector[referenceVector[isample]];
182 string className=m_nameVector[outputVector[isample]];
183 if(m_classValueMap.size())
184 m_cm.incrementResult(type2string<short>(m_classValueMap[refClassName]),type2string<short>(m_classValueMap[className]),1.0);
185 else
186 m_cm.incrementResult(m_cm.getClass(referenceVector[isample]),m_cm.getClass(outputVector[isample]),1.0);
187 }
188 }
189 else{
190 assert(m_cv>0);
191 bool initWeights=true;
192 net.train_on_data(tmpFeatures,ntraining,initWeights, m_maxit,
193 iterations_between_reports, desired_error);
194 vector<Vector2d<float> > testFeatures(nclass);
195 vector<float> result(nclass);
196 int maxClass=-1;
197 for(int iclass=0;iclass<nclass;++iclass){
198 testFeatures.resize(m_nctest[iclass],nFeatures);
199 for(unsigned int isample=0;isample<m_nctraining[iclass];++isample){
200 for(int ifeature=0;ifeature<nFeatures;++ifeature){
201 testFeatures[iclass][isample][ifeature]=trainingFeatures[iclass][m_nctraining[iclass]+isample][ifeature];
202 }
203 result=net.run(testFeatures[iclass][isample]);
204 string refClassName=m_nameVector[iclass];
205 float maxP=-1;
206 for(int ic=0;ic<nclass;++ic){
207 float pv=(result[ic]+1.0)/2.0;
208 if(pv>maxP){
209 maxP=pv;
210 maxClass=ic;
211 }
212 }
213 string className=m_nameVector[maxClass];
214 if(m_classValueMap.size())
215 m_cm.incrementResult(type2string<short>(m_classValueMap[refClassName]),type2string<short>(m_classValueMap[className]),1.0);
216 else
217 m_cm.incrementResult(m_cm.getClass(referenceVector[isample]),m_cm.getClass(outputVector[isample]),1.0);
218 }
219 }
220 }
221 assert(m_cm.nReference());
222 return(m_cm.kappa());
223}