回答編集履歴

4

誤字の修正

2017/06/28 06:44

投稿

退会済みユーザー
test CHANGED
@@ -548,7 +548,7 @@
548
548
 
549
549
 
550
550
 
551
- 前回のコードの変更点は第一に、入力する値を小さくしています(0.01倍)
551
+ 前回のコードの変更点は第一に、入力する値を小さくしています(0.01倍)
552
552
 
553
553
  シグモイド関数に値を通しても、数値大小が変わる事はありません
554
554
 

3

実験の追記

2017/06/28 06:44

投稿

退会済みユーザー
test CHANGED
@@ -292,30 +292,328 @@
292
292
 
293
293
 
294
294
 
295
- その他、重みをランダムに変える。loss関数の修正を行っています。
296
-
297
- だ正解率は上がりせん
298
-
299
-
300
-
301
- ここからはあくまでも直感の話になりますが、恐らくこの問題に適応しようとした時、パラメーターが均一に勾配下降していき、その結果正答率が50%に収束していくのでは、と考えます。
302
-
303
-
304
-
305
- 二番目と四番目の値が同じ数字である時は、
306
-
307
- 出力層の一番目を大きくするようにパラメーターが変動します。
308
-
309
- (二番目の値は小さくしようとする)
310
-
311
-
312
-
313
- それに対して、二番目と四番目が違う数字である時は、出力層の二番目が大きくなるようにパメーターを変動させます。(一番目の値は小さくしようとする。)
314
-
315
-
316
-
317
- そうすると訓練データをランダムに与え続けと、互いが反発しあって、結果的に、出力層の一番目と二播目の両方の値が均一になる調整が行われて、この問題に対応出来なくなっているんじゃないかなあと
318
-
319
-
320
-
321
- つまり問題設定そのものが正解率があがらない原因かなと考えます
295
+ 追記
296
+
297
+ ちょっとし実験をしてみした
298
+
299
+
300
+
301
+ ```python
302
+
303
+ import tensorflow as tf
304
+
305
+ import numpy as np
306
+
307
+ from dataset.mnist import load_mnist
308
+
309
+
310
+
311
+ 訓練データ = []
312
+
313
+ 正解ベル = []
314
+
315
+
316
+
317
+ """任意の比率で訓練データを作成す
318
+
319
+ 引数で100の内、正解ラベル[1,0]の訓練データを何個作るかを決める"""
320
+
321
+
322
+
323
+ def 訓練_正解データ(value):
324
+
325
+ 訓練データ = []
326
+
327
+ 正解ラベル = []
328
+
329
+ for i in range(value):
330
+
331
+ x = np.random.randint(1, 3) * 0.01
332
+
333
+ 入力値 = [
334
+
335
+ np.random.randint(18, 81) * 0.01,
336
+
337
+ x,
338
+
339
+ np.random.randint(18, 81) * 0.01,
340
+
341
+ x,
342
+
343
+ ]
344
+
345
+
346
+
347
+ 正解値 = [1, 0]
348
+
349
+
350
+
351
+ 訓練データ.append(入力値)
352
+
353
+ 正解ラベル.append(正解値)
354
+
355
+ #ここから残りの2割の訓練データを埋める
356
+
357
+ if i == value - 1:
358
+
359
+ while len(訓練データ) < 100:
360
+
361
+ x = np.random.randint(1, 3) * 0.01
362
+
363
+ y = np.random.randint(1, 3) * 0.01
364
+
365
+
366
+
367
+ if x == y:
368
+
369
+ continue
370
+
371
+
372
+
373
+ 入力値 = [
374
+
375
+ np.random.randint(18, 81) * 0.01,
376
+
377
+ x,
378
+
379
+ np.random.randint(18, 81) * 0.01,
380
+
381
+ y,
382
+
383
+ ]
384
+
385
+
386
+
387
+ 正解値 = [0, 1]
388
+
389
+ 訓練データ.append(入力値)
390
+
391
+ 正解ラベル.append(正解値)
392
+
393
+
394
+
395
+ """念の為シャッフルする"""
396
+
397
+ シード値 = np.random.randint(0,1000)
398
+
399
+
400
+
401
+ np.random.seed(シード値)
402
+
403
+ np.random.shuffle(訓練データ)
404
+
405
+
406
+
407
+ np.random.seed(シード値)
408
+
409
+ np.random.shuffle(正解ラベル)
410
+
411
+
412
+
413
+ return [訓練データ, 正解ラベル]
414
+
415
+
416
+
417
+ print(訓練_正解データ(100))
418
+
419
+
420
+
421
+ """パラメーターの作成をする"""
422
+
423
+ 入力数 = 4
424
+
425
+ 中間数 = 100
426
+
427
+ 出力数 = 2
428
+
429
+
430
+
431
+ 入力ホルダ = tf.placeholder(tf.float32, [None, 入力数])
432
+
433
+ 正解ホルダ = tf.placeholder(tf.float32, [None, 出力数])
434
+
435
+ キープ率 = tf.placeholder(tf.float32)
436
+
437
+
438
+
439
+ 重み1 = tf.Variable(tf.truncated_normal([入力数, 中間数],
440
+
441
+ stddev=tf.sqrt(2.0 /入力数)))
442
+
443
+ バイアス1 = tf.Variable(tf.truncated_normal([中間数],
444
+
445
+ stddev=0.1))
446
+
447
+
448
+
449
+ 重み2 = tf.Variable(tf.truncated_normal([中間数, 出力数],
450
+
451
+ stddev=tf.sqrt(2.0 / 中間数)))
452
+
453
+ バイアス2 = tf.Variable(tf.truncated_normal([出力数],
454
+
455
+ stddev=0.1))
456
+
457
+
458
+
459
+ """伝達処理をする"""
460
+
461
+ 一層目 = tf.matmul(入力ホルダ, 重み1) + バイアス1
462
+
463
+ 活性化1 = tf.nn.relu(一層目)
464
+
465
+ ドロップアウト1 = tf.nn.dropout(活性化1, キープ率)
466
+
467
+ 二層目 = tf.matmul(ドロップアウト1, 重み2) + バイアス2
468
+
469
+ 出力層 = tf.nn.sigmoid(二層目)
470
+
471
+
472
+
473
+ """欠損関数を作成する。
474
+
475
+ 欠損値がnanにならないようにtf.clip_by_valueで対策する"""
476
+
477
+ 欠損値バッチ = -tf.reduce_sum(正解ホルダ * tf.log(tf.clip_by_value(
478
+
479
+ 出力層, 1e-10, 1.0),
480
+
481
+ ),axis=1)
482
+
483
+ 交差エントロピー = tf.reduce_mean(欠損値バッチ)
484
+
485
+
486
+
487
+ """正解率の作成"""
488
+
489
+ 真理値判定 = tf.equal(tf.argmax(出力層, 1), tf.argmax(正解ホルダ, 1))
490
+
491
+ 正解率 = tf.reduce_mean(tf.cast(真理値判定, tf.float32))
492
+
493
+
494
+
495
+ """確率的勾配下降の作成"""
496
+
497
+ 勾配下降 = tf.train.GradientDescentOptimizer(0.01).minimize(交差エントロピー)
498
+
499
+
500
+
501
+ with tf.Session() as セッション:
502
+
503
+ セッション.run(tf.global_variables_initializer())
504
+
505
+
506
+
507
+ for i in range(10000):
508
+
509
+ #学習させる比率を決める
510
+
511
+ n, m = 訓練_正解データ(30)
512
+
513
+ セッション.run(勾配下降, feed_dict={
514
+
515
+ 入力ホルダ:n,正解ホルダ:m,キープ率:1.0})
516
+
517
+
518
+
519
+ if i % 100 == 0:
520
+
521
+ #テストデータの比率を決める
522
+
523
+ testn, testm = 訓練_正解データ(90)
524
+
525
+ out, sigmoid = セッション.run([二層目, 出力層], feed_dict={
526
+
527
+ 入力ホルダ:n,正解ホルダ:m,
528
+
529
+ キープ率:1.0})
530
+
531
+
532
+
533
+ print(out)
534
+
535
+ print(sigmoid)
536
+
537
+ テスト = セッション.run(正解率, feed_dict={
538
+
539
+ 入力ホルダ:testn,正解ホルダ:testm,
540
+
541
+ キープ率:1.0})
542
+
543
+
544
+
545
+ print(テスト)
546
+
547
+ ```
548
+
549
+
550
+
551
+ 前回のコードの変更点は第一に、入力する値を小さくしています(0.01倍)
552
+
553
+ シグモイド関数に値を通しても、数値大小が変わる事はありません
554
+
555
+ しかし一定の数値を超えると、数値の大小に限らず1を返すようです。
556
+
557
+ 当然そうなれば正常な判断が出来ません
558
+
559
+ 試しに0.01倍を外してみるとわかると思います
560
+
561
+ 画像を学習させる時も、普通は、その配列の中で最も大きい値で割る、平均の値で全ての配列を割るなどして値を小さくしますので、今回もそれに乗っ取ります
562
+
563
+
564
+
565
+ 過学習対策のドロップアウト層も組み込んでいます。
566
+
567
+ 一言で言えば、訓練データをニューラルネットに丸暗記をさせてはいけないのですが、一定確率でランダムなユニットを除去する事で、1ループだけ学習を停滞させ、丸暗記を防いでいます
568
+
569
+ ただし今回の場合は、特に効果は見られなかったので、キープ率は1.0のそのままにしてあります
570
+
571
+
572
+
573
+ そして実験用に、正解ラベルが[1,0]か[0,1]かを任意の比率で生成できる関数を作ってみました
574
+
575
+ 自分の推測では、[1,0]が正解ラベルの時は出力層の一層目の値が大きくなるように変動し、
576
+
577
+ [0,1]が正解ラベルの時は出力層の二層目の値が大きくなるように変動するというものでした
578
+
579
+ 比率を決める事で、本当にそうなるのかを確かめてみます
580
+
581
+
582
+
583
+ ではまず、上に張り付けたコードを実行してみてください。
584
+
585
+ このコードでは訓練データを3:7([1,0] ,[0,1])の比率で与えてみます
586
+
587
+ コードで言うとn, m = 訓練_正解データ(30)
588
+
589
+
590
+
591
+ テストデータは9:1の割合で与えます
592
+
593
+ testn, testm = 訓練_正解データ(90)
594
+
595
+
596
+
597
+ 今回の場合ですと、自分の推測通りであれば、訓練データに[0,1]のデータを多く与えているわけですから二層目の値が大きくなるように学習をします
598
+
599
+ その結果テストデータで与える[1,0]が正解ラベルのデータに関しては全て不正解になるはずです
600
+
601
+ つまり9:1の割合でテストデータを与えると正解率は1割と推測できます
602
+
603
+
604
+
605
+ 実際に実行してみると正解率が0.1になるのがわかると思います。
606
+
607
+
608
+
609
+ その他与える比率を変えてみてください
610
+
611
+ 比率が傾いた方に出力層が大きくなり、そうでない方のテストデータは全て不正解になるはずです
612
+
613
+ また訓練、テストともに5:5で与えると多少のばらつきはあるものの50%に収束していきます
614
+
615
+
616
+
617
+ この実装が間違っていない限りは、真理値判定でも出来ない限りは、これに対応できる関数を作るのは難しく
618
+
619
+ 、収束していった結果がこの正解率なのが伺えると思います

2

実験の追記

2017/06/28 06:40

投稿

退会済みユーザー
test CHANGED
File without changes

1

実験結果の追記

2017/06/28 06:38

投稿

退会済みユーザー
test CHANGED
File without changes