docs: @Override
  	public Linear train(InstanceSet trainset, InstanceSet devset) {
  		int numSamples = trainset.size();
  		System.out.println("Instance Number: "+numSamples);
  		float[] hisErrRate = new float[historyNum];
  
  		long beginTime, endTime;
  		long beginTimeIter, endTimeIter;
  		int iter = 0;
  		int frac = numSamples / 10;
  
  		//平均化感知器需要减去的权重
  		float[] extraweight = null;
  		extraweight = new float[weights.length];
  			
  		
  		beginTime = System.currentTimeMillis();
  		
  		
  		//遍历的总样本数
  		int k=0;
  
  		while (iter++ < iternum) {
  			if (!simpleOutput) {
  				System.out.print("iter "+iter+":  ");
  			}
  			
  			float err = 0;
  			float errtot = 0;
  			int cnt = 0;
  			int cnttot = 0;
  			int progress = frac;			
  
  			if (shuffle)
  				trainset.shuffle(random);
  			
  			beginTimeIter = System.currentTimeMillis();
  			for (int ii = 0; ii < numSamples; ii++) {
  				
  				k++;
  				Instance inst = trainset.getInstance(ii);
  				Predict pred = (Predict) inferencer.getBest(inst,2);				
  				
  				float l = loss.calc(pred.getLabel(0), inst.getTarget());
  				if (l > 0) {
  					err += l;
  					errtot++;
  					update.update(inst, weights, k, extraweight, pred.getLabel(0), c);
  					
  				}else{
  					if (pred.size() > 1)
  						update.update(inst, weights, k, extraweight, pred.getLabel(1), c);
  				}
  				cnt += inst.length();
  				cnttot++;				
  
  				if (!simpleOutput && progress != 0 && ii % progress == 0) {
  					System.out.print('.');
  					progress += frac;
  				}				
  				
  			}//end for
  
  			float curErrRate = err / cnt;
  
  			endTimeIter = System.currentTimeMillis();
  
  			if (!simpleOutput) {
  				System.out.println("  time: " + (endTimeIter - beginTimeIter)
  						/ 1000.0 + "s");
  				System.out.print("Train:");
  				System.out.print("  Tag acc: ");
  			}
  			System.out.print(1 - curErrRate);
  			if (!simpleOutput) {
  				System.out.print("  Sentence acc: ");
  				System.out.print(1 - errtot / cnttot);
  				System.out.println();
  			}
  
  			System.out.print("Weight Numbers: "
  					+ MyArrays.countNoneZero(weights));
  			if (innerOptimized) {
  				int[] idx = MyArrays.getTop(weights.clone(), threshold, false);
  				MyArrays.set(weights, idx, 0.0f);
  				System.out.print("	After Optimized: "
  						+ MyArrays.countNoneZero(weights));
  			}
  			System.out.println();
  
  			if (devset != null) {
  				evaluate(devset);
  			}
  			System.out.println();			
  
  			if (interim) {
  				Linear p = new Linear(inferencer, af);
  				try {
  					p.saveTo("tmp.model");
  				} catch (IOException e) {
  					System.err.println("write model error!");
  				}
  			}
  			hisErrRate[iter%historyNum] = curErrRate;
  			if(MyArrays.viarance(hisErrRate) < eps){
  				System.out.println("convergence!");
  				break;	
  			}
  			
  		}// end while 外循环
  		
  		//平均化参数
  		for (int i = 0; i < weights.length; i++) {
  			weights[i] -= extraweight[i]/k;
  		}
  		
  		System.out.print("Non-Zero Weight Numbers: " + MyArrays.countNoneZero(weights));
  		if (finalOptimized) {
  			int[] idx = MyArrays.getTop(weights.clone(), threshold, false);
  			MyArrays.set(weights, idx, 0.0f);
  			System.out.print("	After Optimized: "
  					+ MyArrays.countNoneZero(weights));
  		}
  		System.out.println();
  
  		endTime = System.currentTimeMillis();
  		System.out.println("time escape:" + (endTime - beginTime) / 1000.0
  				+ "s");
  		System.out.println();
  		Linear p = new Linear(inferencer,af);
  		return p;
  	}