if (i.checkForStringAttributes()) { throw new UnsupportedAttributeTypeException("Cannot handle string attributes!"); }  if (i.numInstances() == 0) { throw new IllegalArgumentException("No training instances."); }
getCapabilities().testWithFail(i);   i = new Instances(i); i.deleteWithMissingClass();
  public void buildClassifier(Instances i) throws Exception {    if (i.checkForStringAttributes()) {      throw new UnsupportedAttributeTypeException("Cannot handle string attributes!");    }    if (i.numInstances() == 0) {      throw new IllegalArgumentException("No training instances.");    }    m_epoch = 0;    m_error = 0;    m_instances = null;    m_currentInstance = null;    m_controlPanel = null;    m_nodePanel = null;            m_outputs = new NeuralEnd[0];    m_inputs = new NeuralEnd[0];    m_numAttributes = 0;    m_numClasses = 0;    m_neuralNodes = new NeuralConnection[0];        m_selected = new FastVector(4);    m_graphers = new FastVector(2);    m_nextId = 0;    m_stopIt = true;    m_stopped = true;    m_accepted = false;        m_instances = new Instances(i);    m_instances.deleteWithMissingClass();    if (m_instances.numInstances() == 0) {      m_instances = null;      throw new IllegalArgumentException("All class values missing.");    }    m_random = new Random(m_randomSeed);    m_instances.randomize(m_random);    if (m_useNomToBin) {      m_nominalToBinaryFilter = new NominalToBinary();      m_nominalToBinaryFilter.setInputFormat(m_instances);      m_instances = Filter.useFilter(m_instances,				     m_nominalToBinaryFilter);    }    m_numAttributes = m_instances.numAttributes() - 1;    m_numClasses = m_instances.numClasses();         setClassType(m_instances);           //this sets up the validation set.    Instances valSet = null;    //numinval is needed later    int numInVal = (int)(m_valSize / 100.0 * m_instances.numInstances());    if (m_valSize > 0) {      if (numInVal == 0) {	numInVal = 1;      }      valSet = new Instances(m_instances, 0, numInVal);    }    ///////////    setupInputs();          setupOutputs();        if (m_autoBuild) {      setupHiddenLayer();    }        /////////////////////////////    //this sets up the gui for usage    if (m_gui) {      m_win = new JFrame();            m_win.addWindowListener(new WindowAdapter() {	  public void windowClosing(WindowEvent e) {	    boolean k = m_stopIt;	    m_stopIt = true;	    int well =JOptionPane.showConfirmDialog(m_win, 						    "Are You Sure...\n"						    + "Click Yes To Accept"						    + " The Neural Network" 						    + "\n Click No To Return",						    "Accept Neural Network", 						    JOptionPane.YES_NO_OPTION);	    	    if (well == 0) {	      m_win.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);	      m_accepted = true;	      blocker(false);	    }	    else {	      m_win.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);	    }	    m_stopIt = k;	  }	});            m_win.getContentPane().setLayout(new BorderLayout());      m_win.setTitle("Neural Network");      m_nodePanel = new NodePanel();      JScrollPane sp = new JScrollPane(m_nodePanel,				       JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 				       JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);      m_controlPanel = new ControlPanel();                 m_win.getContentPane().add(sp, BorderLayout.CENTER);      m_win.getContentPane().add(m_controlPanel, BorderLayout.SOUTH);      m_win.setSize(640, 480);      m_win.setVisible(true);    }       //This sets up the initial state of the gui    if (m_gui) {      blocker(true);      m_controlPanel.m_changeEpochs.setEnabled(false);      m_controlPanel.m_changeLearning.setEnabled(false);      m_controlPanel.m_changeMomentum.setEnabled(false);    }         //For silly situations in which the network gets accepted before training    //commenses    if (m_numeric) {      setEndsToLinear();    }    if (m_accepted) {      m_win.dispose();      m_controlPanel = null;      m_nodePanel = null;      m_instances = new Instances(m_instances, 0);      return;    }    //connections done.    double right = 0;    double driftOff = 0;    double lastRight = Double.POSITIVE_INFINITY;    double tempRate;    double totalWeight = 0;    double totalValWeight = 0;    double origRate = m_learningRate; //only used for when reset        //ensure that at least 1 instance is trained through.    if (numInVal == m_instances.numInstances()) {      numInVal--;    }    if (numInVal < 0) {      numInVal = 0;    }    for (int noa = numInVal; noa < m_instances.numInstances(); noa++) {      if (!m_instances.instance(noa).classIsMissing()) {	totalWeight += m_instances.instance(noa).weight();      }    }    if (m_valSize != 0) {      for (int noa = 0; noa < valSet.numInstances(); noa++) {	if (!valSet.instance(noa).classIsMissing()) {	  totalValWeight += valSet.instance(noa).weight();	}      }    }    m_stopped = false;         for (int noa = 1; noa < m_numEpochs + 1; noa++) {      right = 0;      for (int nob = numInVal; nob < m_instances.numInstances(); nob++) {	m_currentInstance = m_instances.instance(nob);		if (!m_currentInstance.classIsMissing()) {	   	  //this is where the network updating (and training occurs, for the	  //training set	  resetNetwork();	  calculateOutputs();	  tempRate = m_learningRate * m_currentInstance.weight();  	  if (m_decay) {	    tempRate /= noa;	  }	  right += (calculateErrors() / m_instances.numClasses()) *	    m_currentInstance.weight();	  updateNetworkWeights(tempRate, m_momentum);	  	}	      }      right /= totalWeight;      if (Double.isInfinite(right) || Double.isNaN(right)) {	if (!m_reset) {	  m_instances = null;	  throw new Exception("Network cannot train. Try restarting with a" +			      " smaller learning rate.");	}	else {	  //reset the network	  m_learningRate /= 2;	  buildClassifier(i);	  m_learningRate = origRate;	  m_instances = new Instances(m_instances, 0);	  	  return;	}      }      ////////////////////////do validation testing if applicable      if (m_valSize != 0) {	right = 0;	for (int nob = 0; nob < valSet.numInstances(); nob++) {	  m_currentInstance = valSet.instance(nob);	  if (!m_currentInstance.classIsMissing()) {	    //this is where the network updating occurs, for the validation set	    resetNetwork();	    calculateOutputs();	    right += (calculateErrors() / valSet.numClasses()) 	      * m_currentInstance.weight();	    //note 'right' could be calculated here just using	    //the calculate output values. This would be faster.	    //be less modular	  }	  	}		if (right < lastRight) {	  driftOff = 0;	}	else {	  driftOff++;	}	lastRight = right;	if (driftOff > m_driftThreshold || noa + 1 >= m_numEpochs) {	  m_accepted = true;	}	right /= totalValWeight;      }      m_epoch = noa;      m_error = right;      //shows what the neuralnet is upto if a gui exists.       updateDisplay();      //This junction controls what state the gui is in at the end of each      //epoch, Such as if it is paused, if it is resumable etc...      if (m_gui) {	while ((m_stopIt || (m_epoch >= m_numEpochs && m_valSize == 0)) && 		!m_accepted) {	  m_stopIt = true;	  m_stopped = true;	  if (m_epoch >= m_numEpochs && m_valSize == 0) {	    	    m_controlPanel.m_startStop.setEnabled(false);	  }	  else {	    m_controlPanel.m_startStop.setEnabled(true);	  }	  m_controlPanel.m_startStop.setText("Start");	  m_controlPanel.m_startStop.setActionCommand("Start");	  m_controlPanel.m_changeEpochs.setEnabled(true);	  m_controlPanel.m_changeLearning.setEnabled(true);	  m_controlPanel.m_changeMomentum.setEnabled(true);	  	  blocker(true);	  if (m_numeric) {	    setEndsToLinear();	  }	}	m_controlPanel.m_changeEpochs.setEnabled(false);	m_controlPanel.m_changeLearning.setEnabled(false);	m_controlPanel.m_changeMomentum.setEnabled(false);		m_stopped = false;	//if the network has been accepted stop the training loop	if (m_accepted) {	  m_win.dispose();	  m_controlPanel = null;	  m_nodePanel = null;	  m_instances = new Instances(m_instances, 0);	  return;	}      }      if (m_accepted) {	m_instances = new Instances(m_instances, 0);	return;      }    }    if (m_gui) {      m_win.dispose();      m_controlPanel = null;      m_nodePanel = null;    }    m_instances = new Instances(m_instances, 0);    }