1919import edu .hitsz .c102c .util .Util .Operator ;
2020
2121public class CNN {
22- private static final double ALPHA = 0.01 ;
23- protected static final double LAMBDA = 0.005 ;
22+ private static final double ALPHA = 1 ;
23+ protected static final double LAMBDA = 0 ;
2424 // 网络的各层
2525 private List <Layer > layers ;
2626 // 层数
@@ -99,7 +99,7 @@ public void train(Dataset trainset, int repeat) {
9999 for (int t = 0 ; t < repeat ; t ++) {
100100 int epochsNum = 1 + trainset .size () / batchSize ;// 多抽取一次,即向上取整
101101 for (int i = 0 ; i < epochsNum ; i ++) {
102- int [] randPerm = Util .randomPerm (trainset .size (), batchSize );
102+ int [] randPerm = Util .randomPerm (trainset .size (), batchSize );
103103 Layer .prepareForNewBatch ();
104104 for (int index : randPerm ) {
105105 train (trainset .getRecord (index ));
@@ -140,14 +140,20 @@ private double test(Dataset trainset) {
140140 double [][] outmap = outputLayer .getMap (m );
141141 out [m ] = outmap [0 ][0 ];
142142 }
143+ // if (record.getLable().intValue() ==
144+ // Util.getMaxIndex(out))
145+ // right++;
143146 if (isSame (out , target )) {
144147 right ++;
145- // if (right % 1000 == 0)
146- // Log.i("out:" + Arrays.toString(out) + " \n target:"
147- // + Arrays.toString(target));
148+ // if (right % 1000 == 0)
149+ // Log.i("out:" + Arrays.toString(out)
150+ // + " \n target:"
151+ // + Arrays.toString(target));
148152 }
149- Log .i ("out:" + Arrays .toString (out ) + " \n target:"
150- + Arrays .toString (target ));
153+
154+ if (count ++ % 1000 == 0 )
155+ Log .i ("out:" + Arrays .toString (out ) + " \n target:"
156+ + Arrays .toString (target ));
151157 }
152158 return 1.0 * right / trainset .size ();
153159 }
@@ -261,28 +267,33 @@ private void updateBias(Layer layer, Layer lastLayer) {
261267 private void updateKernels (Layer layer , Layer lastLayer ) {
262268 int mapNum = layer .getOutMapNum ();
263269 int lastMapNum = lastLayer .getOutMapNum ();
270+ // double[][][][] errors = layer.getErrors();
271+ // double[][][][] lastMaps =
272+ // lastLayer.getMaps();
264273 for (int j = 0 ; j < mapNum ; j ++) {
265274 for (int i = 0 ; i < lastMapNum ; i ++) {
266- double [][] kernel = layer . getKernel ( i , j );
267- double [][] deltaKernel = null ;
275+ // double[][] deltaKernel = Util
276+ // .convnValid(lastMaps, i, errors, j) ;
268277 // 对batch的每个记录delta求和
278+ double [][] deltaKernel = null ;
269279 for (int r = 0 ; r < batchSize ; r ++) {
270280 double [][] error = layer .getError (r , j );
271281 if (deltaKernel == null )
272- deltaKernel = Util .convnValid (
273- Util . rot180 ( lastLayer . getMap ( r , i )), error );
282+ deltaKernel = Util .convnValid (lastLayer . getMap ( r , i ),
283+ error );
274284 else {// 累积求和
275- deltaKernel = Util .matrixOp (Util . convnValid (
276- Util .rot180 (lastLayer .getMap (r , i ) ), error ),
285+ deltaKernel = Util .matrixOp (
286+ Util .convnValid (lastLayer .getMap (r , i ), error ),
277287 deltaKernel , null , null , Util .plus );
278288 }
279289 }
280290
281291 // 除以batchSize
282292 deltaKernel = Util .matrixOp (deltaKernel , divide_batchSize );
283293 // 更新卷积核
294+ double [][] kernel = layer .getKernel (i , j );
284295 deltaKernel = Util .matrixOp (kernel , deltaKernel ,
285- multiply_lambda , multiply_alpha , Util .minus );
296+ multiply_lambda , multiply_alpha , Util .plus );
286297 layer .setKernel (i , j , deltaKernel );
287298 }
288299 }
@@ -344,37 +355,18 @@ private void setConvErrors(final Layer layer, final Layer nextLayer) {
344355 // 卷积层的下一层为采样层,即两层的map个数相同,且一个map只与令一层的一个map连接,
345356 // 因此只需将下一层的残差kronecker扩展再用点积即可
346357 int mapNum = layer .getOutMapNum ();
347- int cpuNum = ConcurenceRunner .cpuNum ;
348- cpuNum = cpuNum < mapNum ? cpuNum : 1 ;// 比cpu的个数小一个时,只用一个线程
349- final CountDownLatch gate = new CountDownLatch (cpuNum );
350- int fregLength = (mapNum + cpuNum - 1 ) / cpuNum ;
351- for (int cpu = 0 ; cpu < cpuNum ; cpu ++) {
352- int start = cpu * fregLength ;
353- int tmp = (cpu + 1 ) * fregLength ;
354- int end = tmp <= mapNum ? tmp : mapNum ;
355- Task task = new Task (start , end ) {
356-
357- @ Override
358- public void process (int start , int end ) {
359- for (int m = start ; m < end ; m ++) {
360- Size scale = nextLayer .getScaleSize ();
361- double [][] nextError = nextLayer .getError (m );
362- double [][] map = layer .getMap (m );
363- // 矩阵相乘,但对第二个矩阵的每个元素value进行1-value操作
364- double [][] outMatrix = Util .matrixOp (map ,
365- Util .cloneMatrix (map ), null , Util .one_value ,
366- Util .multiply );
367- outMatrix = Util .matrixOp (outMatrix ,
368- Util .kronecker (nextError , scale ), null , null ,
369- Util .multiply );
370- layer .setError (m , outMatrix );
371- }
372- gate .countDown ();
373- }
374- };
375- runner .run (task );
358+ for (int m = 0 ; m < mapNum ; m ++) {
359+ Size scale = nextLayer .getScaleSize ();
360+ double [][] nextError = nextLayer .getError (m );
361+ double [][] map = layer .getMap (m );
362+ // 矩阵相乘,但对第二个矩阵的每个元素value进行1-value操作
363+ double [][] outMatrix = Util .matrixOp (map , Util .cloneMatrix (map ),
364+ null , Util .one_value , Util .multiply );
365+ outMatrix = Util
366+ .matrixOp (outMatrix , Util .kronecker (nextError , scale ),
367+ null , null , Util .multiply );
368+ layer .setError (m , outMatrix );
376369 }
377- await (gate );
378370
379371 }
380372
@@ -384,15 +376,32 @@ public void process(int start, int end) {
384376 * @param record
385377 */
386378 private void setOutLayerErrors (Record record ) {
379+
387380 Layer outputLayer = layers .get (layerNum - 1 );
388381 int mapNum = outputLayer .getOutMapNum ();
389- double [] target = record .getDoubleEncodeTarget (mapNum );
390- for (int m = 0 ; m < mapNum ; m ++) {
391- double [][] outmap = outputLayer .getMap (m );
392- double output = outmap [0 ][0 ];
393- double errors = output * (1 - output ) * (target [m ] - output );
394- outputLayer .setError (m , 0 , 0 , errors );
395- }
382+ double [] target =
383+ record .getDoubleEncodeTarget (mapNum );
384+ for (int m = 0 ; m < mapNum ; m ++) {
385+ double [][] outmap = outputLayer .getMap (m );
386+ double output = outmap [0 ][0 ];
387+ double errors = output * (1 - output ) *
388+ (target [m ] - output );
389+ outputLayer .setError (m , 0 , 0 , errors );
390+ }
391+
392+ // double[] errors = new double[mapNum];
393+ // double[] outmaps = new double[mapNum];
394+ // for (int m = 0; m < mapNum; m++) {
395+ // double[][] outmap = outputLayer.getMap(m);
396+ // outmaps[m] = outmap[0][0];
397+ //
398+ // }
399+ //
400+ // errors[record.getLable().intValue()] = 1;
401+ // for (int m = 0; m < mapNum; m++) {
402+ // outputLayer.setError(m, 0, 0, outmaps[m] * (1 - outmaps[m])
403+ // * (errors[m] - outmaps[m]));
404+ // }
396405 }
397406
398407 /**
@@ -433,32 +442,12 @@ private void setInLayerOutput(Record record) {
433442 final double [] attr = record .getAttrs ();
434443 if (attr .length != mapSize .x * mapSize .y )
435444 throw new RuntimeException ("数据记录的大小与定义的map大小不一致!" );
436- int cpuNum = ConcurenceRunner .cpuNum ;
437- cpuNum = cpuNum < mapSize .y ? cpuNum : 1 ;// 比cpu的个数小一个时,只用一个线程
438- final CountDownLatch gate = new CountDownLatch (cpuNum );
439- int fregLength = (mapSize .y + cpuNum - 1 ) / cpuNum ;
440- for (int cpu = 0 ; cpu < cpuNum ; cpu ++) {
441- int start = cpu * fregLength ;
442- int tmp = (cpu + 1 ) * fregLength ;
443- int end = tmp <= mapSize .y ? tmp : mapSize .y ;
444- Task task = new Task (start , end ) {
445-
446- @ Override
447- public void process (int start , int end ) {
448-
449- for (int i = 0 ; i < mapSize .x ; i ++) {
450- for (int j = start ; j < end ; j ++) {
451- // 将记录属性的一维向量弄成二维矩阵
452- double value = attr [mapSize .x * i + j ];
453- inputLayer .setMapValue (0 , i , j , value );
454- }
455- }
456- gate .countDown ();
457- }
458- };
459- runner .run (task );
445+ for (int i = 0 ; i < mapSize .x ; i ++) {
446+ for (int j = 0 ; j < mapSize .y ; j ++) {
447+ // 将记录属性的一维向量弄成二维矩阵
448+ inputLayer .setMapValue (0 , i , j , attr [mapSize .x * i + j ]);
449+ }
460450 }
461- await (gate );
462451 }
463452
464453 /*
@@ -467,49 +456,30 @@ public void process(int start, int end) {
467456 private void setConvOutput (final Layer layer , final Layer lastLayer ) {
468457 int mapNum = layer .getOutMapNum ();
469458 final int lastMapNum = lastLayer .getOutMapNum ();
470- int cpuNum = ConcurenceRunner .cpuNum ;
471- cpuNum = cpuNum < mapNum ? cpuNum : 1 ;// 比cpu的个数小一个时,只用一个线程
472- final CountDownLatch gate = new CountDownLatch (cpuNum );
473- int fregLength = (mapNum + cpuNum - 1 ) / cpuNum ;
474- for (int cpu = 0 ; cpu < cpuNum ; cpu ++) {
475- int start = cpu * fregLength ;
476- int tmp = (cpu + 1 ) * fregLength ;
477- int end = tmp <= mapNum ? tmp : mapNum ;
478- Task task = new Task (start , end ) {
459+ for (int j = 0 ; j < mapNum ; j ++) {
460+ double [][] sum = null ;// 对每一个输入map的卷积进行求和
461+ for (int i = 0 ; i < lastMapNum ; i ++) {
462+ double [][] lastMap = lastLayer .getMap (i );
463+ double [][] kernel = layer .getKernel (i , j );
464+ if (sum == null )
465+ sum = Util .convnValid (lastMap , kernel );
466+ else
467+ sum = Util .matrixOp (Util .convnValid (lastMap , kernel ), sum ,
468+ null , null , Util .plus );
469+ }
470+ final double bias = layer .getBias (j );
471+ sum = Util .matrixOp (sum , new Operator () {
479472
480473 @ Override
481- public void process (int start , int end ) {
482- for (int j = start ; j < end ; j ++) {
483- double [][] sum = null ;// 对每一个输入map的卷积进行求和
484- for (int i = 0 ; i < lastMapNum ; i ++) {
485- double [][] lastMap = lastLayer .getMap (i );
486- double [][] kernel = layer .getKernel (i , j );
487- if (sum == null )
488- sum = Util .convnValid (lastMap , kernel );
489- else
490- sum = Util .matrixOp (
491- Util .convnValid (lastMap , kernel ), sum ,
492- null , null , Util .plus );
493- }
494- final double bias = layer .getBias (j );
495- sum = Util .matrixOp (sum , new Operator () {
496-
497- @ Override
498- public double process (double value ) {
499- return Util .sigmod (value + bias );
500- }
501-
502- });
503- if (sum [0 ][0 ] > 1 )
504- Log .i (sum [0 ][0 ] + "" );
505- layer .setMapValue (j , sum );
506- }
507- gate .countDown ();
474+ public double process (double value ) {
475+ return Util .sigmod (value + bias );
508476 }
509- };
510- runner .run (task );
477+
478+ });
479+ if (sum [0 ][0 ] > 1 )
480+ Log .i (sum [0 ][0 ] + "" );
481+ layer .setMapValue (j , sum );
511482 }
512- await (gate );
513483
514484 }
515485
@@ -521,32 +491,13 @@ public double process(double value) {
521491 */
522492 private void setSampOutput (final Layer layer , final Layer lastLayer ) {
523493 int lastMapNum = lastLayer .getOutMapNum ();
524- int cpuNum = ConcurenceRunner .cpuNum ;
525- cpuNum = cpuNum < lastMapNum ? cpuNum : 1 ;// 比cpu的个数小一个时,只用一个线程
526- final CountDownLatch gate = new CountDownLatch (cpuNum );
527- int fregLength = (lastMapNum + cpuNum - 1 ) / cpuNum ;
528- for (int cpu = 0 ; cpu < cpuNum ; cpu ++) {
529- int start = cpu * fregLength ;
530- int tmp = (cpu + 1 ) * fregLength ;
531- int end = tmp <= lastMapNum ? tmp : lastMapNum ;
532- Task task = new Task (start , end ) {
533-
534- @ Override
535- public void process (int start , int end ) {
536- for (int i = start ; i < end ; i ++) {
537- double [][] lastMap = lastLayer .getMap (i );
538- Size scaleSize = layer .getScaleSize ();
539- // 按scaleSize区域进行均值处理
540- double [][] sampMatrix = Util .scaleMatrix (lastMap ,
541- scaleSize );
542- layer .setMapValue (i , sampMatrix );
543- }
544- gate .countDown ();
545- }
546- };
547- runner .run (task );
494+ for (int i = 0 ; i < lastMapNum ; i ++) {
495+ double [][] lastMap = lastLayer .getMap (i );
496+ Size scaleSize = layer .getScaleSize ();
497+ // 按scaleSize区域进行均值处理
498+ double [][] sampMatrix = Util .scaleMatrix (lastMap , scaleSize );
499+ layer .setMapValue (i , sampMatrix );
548500 }
549- await (gate );
550501 }
551502
552503 /**
0 commit comments