003-01.手書き文字-日本語-keras-基準モデルの構築

サイトの紹介と使い方動画


created: 2021/09/26 modified: 2021/10/25

概要

  1. 学習条件を考えると、次の3つが必要になると思います。
    1. 画像の状態(モード、サイズ)
    2. レイヤの選択(種類、数、順番)
    3. レイヤのパラメータ
  2. 上記の3つの組み合わせの全てを検証することは、困難であると思います。
  3. さらに、出力(精度としての結果)は確率的に求められることを加味すれば、作業量は爆発的に増加します。
  4. 求めたい作業の結果は、モデルになります。
  5. そして、最適な結果は上述の条件の組み合わせから求められるべきです。
    (前述のように作業量が膨大なのですべての組み合わせを確かめることはできませんが)
  6. 注意点として、AとB、BとCに関係がないからといって、AとBとCの組み合わせに関係がないとは限らないということです。

モデルの構築手順

  1. ある程度、固定していい条件を決定します。
  2. 単純なものから条件と条件の関係を検証します。
  3. 暫定的なモデルを構築します。
  4. 暫定的なモデルは必要に応じて改善させていきます。

モデル構築時の評価基準

  1. 誤差関数(損失関数)(loss,val_loss)と精度(ACC)の変化量を観察します。

画像の状態とモデルの構築手順(実作業)

画像の状態

モード

  1. 撮影時の画像を処理して、2値化画像にしました。
  2. その画像をRGBモードで保存しています。
  3. 何故かは分かりませんが、プログラム処理時にRGBモードをグレースケールなどに変換すると精度が目に見えて落ちてしまうので、RGBモードのまま処理しています。
  4. 結論として、画像モードはRGBで処理します。

解像度

  1. 撮影時の1文字の解像度は、約240x240~300x300pixelです。
  2. ディスク容量や処理速度を考慮して、1文字を80x80pixelに落として保存しています。
    尚、80x80の数字的根拠はありません。これくらいかなという感じです。
  3. とりあえず、20x20、40x40、60x60、80x80にresizeして、レイヤ(Conv2D)との関係を検証したいと思います。

モデルの構築(Sequentialのみ)

初期モデルの試行

  1. 数字0-9を使用しました。
  2. 学習画像数50,テスト画像数10です。
  3. loss='categorical_crossentropy'
  4. optimizer='adam'
  5. metrics=['acc']
  6. batch_size=10
  7. epochs=30
試行①
def build_model01( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( xxx,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 4行目のConv2Dレイヤは、固定して使うことにします。
    Conv2Dレイヤの第2引数の3以降も固定します。
    Conv2Dレイヤの第1引数の特徴量(畳み込み)のパターン数は、画像の解像度と組み合わせて評価します。
    1. 画像サイズ集合S={20x20,40x40,60x60,80x80}
    2. パターン数集合P={16,32,64,128,256,512}
    3. SxPで4x6=24通りのテストを行います。
20x20
16-loss: 0.0231 - acc: 1.0000 - val_loss: 2.8162 - val_acc: 0.5300
32-loss: 0.0116 - acc: 1.0000 - val_loss: 3.1625 - val_acc: 0.5700
64-loss: 0.0051 - acc: 1.0000 - val_loss: 3.1904 - val_acc: 0.5300
128-loss: 0.0024 - acc: 1.0000 - val_loss: 3.2259 - val_acc: 0.5800
256-loss: 0.0012 - acc: 1.0000 - val_loss: 3.1922 - val_acc: 0.5900
512-loss: 7.4320e-04 - acc: 1.0000 - val_loss: 3.4959 - val_acc: 0.6000

40x40
16-loss: 0.0019 - acc: 1.0000 - val_loss: 2.7489 - val_acc: 0.5000
32-loss: 9.9235e-04 - acc: 1.0000 - val_loss: 2.7926 - val_acc: 0.4900
64-loss: 5.4808e-04 - acc: 1.0000 - val_loss: 3.0685 - val_acc: 0.5000
128-loss: 3.2879e-04 - acc: 1.0000 - val_loss: 3.0904 - val_acc: 0.5000
256-loss: 2.0196e-04 - acc: 1.0000 - val_loss: 3.5503 - val_acc: 0.5000
512-loss: 1.1816e-04 - acc: 1.0000 - val_loss: 3.8917 - val_acc: 0.4600

60x60
16-loss: 0.0011 - acc: 1.0000 - val_loss: 2.4300 - val_acc: 0.5300
32-loss: 5.5330e-04 - acc: 1.0000 - val_loss: 2.4037 - val_acc: 0.5400
64-loss: 3.3811e-04 - acc: 1.0000 - val_loss: 2.6807 - val_acc: 0.5200
128-loss: 1.8429e-04 - acc: 1.0000 - val_loss: 2.9407 - val_acc: 0.5000
256-loss: 1.1751e-04 - acc: 1.0000 - val_loss: 3.0973 - val_acc: 0.5000
512-loss: 7.5716e-05 - acc: 1.0000 - val_loss: 3.6374 - val_acc: 0.5200

80x80
16-loss: 0.0038 - acc: 1.0000 - val_loss: 3.1719 - val_acc: 0.4900
32-loss: 0.0021 - acc: 1.0000 - val_loss: 3.1665 - val_acc: 0.5000
64-loss: 0.0012 - acc: 1.0000 - val_loss: 3.1783 - val_acc: 0.4900
128-loss: 6.5036e-04 - acc: 1.0000 - val_loss: 3.0763 - val_acc: 0.4900
256-処理時間がかかり過ぎる。
512-処理時間がかかり過ぎる。

評価:特徴量(畳み込み)のパターン数と画像の解像度の間には強い相関関係はなさそうです。
但し、パターン数と解像度が大きくなると、指数的に処理時間が増えるようです。
試行②
def build_model01( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-end' ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 7行目にDense( 16, activation='relu',name='Dense-end' )を加えます。
20x20
16-loss: 0.0163 - acc: 1.0000 - val_loss: 3.0281 - val_acc: 0.4900
32-loss: 0.0151 - acc: 1.0000 - val_loss: 2.8420 - val_acc: 0.5400
64-loss: 0.0158 - acc: 0.9960 - val_loss: 3.6926 - val_acc: 0.4600
128-loss: 0.0401 - acc: 0.9920 - val_loss: 5.0744 - val_acc: 0.4700
256-loss: 0.0012 - acc: 1.0000 - val_loss: 3.4752 - val_acc: 0.4900
512-loss: 8.5943e-04 - acc: 1.0000 - val_loss: 4.7095 - val_acc: 0.4800

40x40
16-loss: 0.0013 - acc: 1.0000 - val_loss: 2.7115 - val_acc: 0.4800
32-loss: 5.8173e-04 - acc: 1.0000 - val_loss: 3.4370 - val_acc: 0.4800
64-loss: 4.1582e-04 - acc: 1.0000 - val_loss: 2.8206 - val_acc: 0.4900
128-loss: 3.5607e-04 - acc: 1.0000 - val_loss: 3.6865 - val_acc: 0.4800
256-loss: 2.2318e-04 - acc: 1.0000 - val_loss: 3.7739 - val_acc: 0.4800
512-loss: 1.4646e-04 - acc: 1.0000 - val_loss: 4.5355 - val_acc: 0.4200

60x60
16-loss: 6.1864e-04 - acc: 1.0000 - val_loss: 2.3410 - val_acc: 0.5500
32-loss: 4.3831e-04 - acc: 1.0000 - val_loss: 3.5345 - val_acc: 0.4800
64-loss: 3.5698e-04 - acc: 1.0000 - val_loss: 3.6581 - val_acc: 0.5200
128-loss: 2.1713e-04 - acc: 1.0000 - val_loss: 4.5516 - val_acc: 0.5400

評価:この組み合わせはNG。
試行③
def build_model01( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-end' ),
         Dropout( 0.1 ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 7行目にDense( 16, activation='relu',name='Dense-end' )
  2. 8行目にDropout( 0.1 )を加えます。
20x20
16-loss: 0.2858 - acc: 0.9100 - val_loss: 2.4456 - val_acc: 0.4600
32-loss: 0.0807 - acc: 0.9780 - val_loss: 3.0949 - val_acc: 0.5300
64-loss: 0.1265 - acc: 0.9540 - val_loss: 2.7467 - val_acc: 0.5500
128-loss: 0.0756 - acc: 0.9720 - val_loss: 3.1328 - val_acc: 0.5200
256-loss: 0.1183 - acc: 0.9560 - val_loss: 3.4163 - val_acc: 0.3900
512-loss: 0.2486 - acc: 0.9180 - val_loss: 5.1486 - val_acc: 0.4100

40x40
16-loss: 0.0537 - acc: 0.9860 - val_loss: 3.7503 - val_acc: 0.4500
32-loss: 0.0413 - acc: 0.9840 - val_loss: 4.2370 - val_acc: 0.4300
64-loss: 0.0792 - acc: 0.9700 - val_loss: 3.8316 - val_acc: 0.4200
128-loss: 0.0405 - acc: 0.9860 - val_loss: 4.5714 - val_acc: 0.4500
256-loss: 0.1013 - acc: 0.9620 - val_loss: 5.0884 - val_acc: 0.4400
512-loss: 0.1650 - acc: 0.9360 - val_loss: 5.5033 - val_acc: 0.4000

60x60
16-loss: 0.0444 - acc: 0.9900 - val_loss: 3.7554 - val_acc: 0.4500
32-loss: 0.0284 - acc: 0.9920 - val_loss: 4.5296 - val_acc: 0.4200
64-loss: 0.0751 - acc: 0.9740 - val_loss: 4.4131 - val_acc: 0.4100
128-loss: 0.0522 - acc: 0.9760 - val_loss: 4.8729 - val_acc: 0.4400

評価:この組み合わせはNG。
試行④
def build_model04( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
20x20
16-loss: 0.0041 - acc: 1.0000 - val_loss: 3.6393 - val_acc: 0.5900
32-loss: 0.0014 - acc: 1.0000 - val_loss: 3.3409 - val_acc: 0.6300
64-loss: 5.2244e-04 - acc: 1.0000 - val_loss: 3.4144 - val_acc: 0.6600
128-loss: 1.9421e-04 - acc: 1.0000 - val_loss: 3.0970 - val_acc: 0.6700
256-loss: 9.3203e-05 - acc: 1.0000 - val_loss: 2.9370 - val_acc: 0.6700
512-処理時間がかかり過ぎる。

40x40
16-loss: 4.2111e-04 - acc: 1.0000 - val_loss: 4.2901 - val_acc: 0.5400
32-loss: 1.7837e-04 - acc: 1.0000 - val_loss: 4.8021 - val_acc: 0.5600
64-loss: 4.1101e-05 - acc: 1.0000 - val_loss: 4.7767 - val_acc: 0.5400
128-loss: 3.8737e-05 - acc: 1.0000 - val_loss: 5.1597 - val_acc: 0.5200
256-処理時間がかかり過ぎる。
512-処理時間がかかり過ぎる。

60x60
16-loss: 2.0950e-04 - acc: 1.0000 - val_loss: 4.5182 - val_acc: 0.5700
32-loss: 8.8693e-05 - acc: 1.0000 - val_loss: 4.5054 - val_acc: 0.5900
64-loss: 4.6610e-05 - acc: 1.0000 - val_loss: 4.4632 - val_acc: 0.5600
128-loss: 1.9395e-05 - acc: 1.0000 - val_loss: 4.4419 - val_acc: 0.5700
256-処理時間がかかり過ぎる。
512-処理時間がかかり過ぎる。

評価:この組み合わせは少し有望かもしれませんが、処理時間がかかります。
試行⑤

def build_model05( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 6行目にMaxPooling2D( pool_size=(2, 2) )を加えました。
20x20
16-loss: 0.1065 - acc: 0.9960 - val_loss: 1.9509 - val_acc: 0.6100
32-loss: 0.0467 - acc: 1.0000 - val_loss: 2.3128 - val_acc: 0.5800
64-loss: 0.0235 - acc: 1.0000 - val_loss: 2.5293 - val_acc: 0.5900
128-loss: 0.0101 - acc: 1.0000 - val_loss: 2.6790 - val_acc: 0.6100
256-loss: 0.0047 - acc: 1.0000 - val_loss: 3.0364 - val_acc: 0.6000
512-loss: 0.0025 - acc: 1.0000 - val_loss: 3.1608 - val_acc: 0.6200

40x40
16-loss: 0.0083 - acc: 1.0000 - val_loss: 2.3046 - val_acc: 0.6200
32-loss: 0.0039 - acc: 1.0000 - val_loss: 2.2699 - val_acc: 0.6000
64-loss: 0.0020 - acc: 1.0000 - val_loss: 2.6134 - val_acc: 0.6000
128-loss: 0.0012 - acc: 1.0000 - val_loss: 2.6701 - val_acc: 0.6400
256-loss: 6.7203e-04 - acc: 1.0000 - val_loss: 2.8046 - val_acc: 0.6400
512-loss: 4.0774e-04 - acc: 1.0000 - val_loss: 3.3307 - val_acc: 0.6000

60x60
16-loss: 0.0038 - acc: 1.0000 - val_loss: 2.7338 - val_acc: 0.5800
32-loss: 0.0019 - acc: 1.0000 - val_loss: 2.9205 - val_acc: 0.5600
64-loss: 0.0010 - acc: 1.0000 - val_loss: 3.1599 - val_acc: 0.5600
128-処理時間がかかり過ぎる。
256-処理時間がかかり過ぎる。
512-処理時間がかかり過ぎる。

評価:MaxPooling2Dの組み込みは必須だと思われるので、精度がやや上がって少し安心しました。
◎試行⑥
  1. 試行したい組み合わせが増えていくので、画像サイズを暫定的に決めたいと思います。
  2. 試行①~⑤までで、画像サイズの決定因子が見つけられなかったので、次の2つの条件から決めたいと思います。
    1. サイズが小さい方が処理時間が短くて済みます。
    2. 漢字を処理するとき、どのくらいのサイズが必要か?
  3. 常用漢字29画、常用漢字外36画を想定した時、最低限を考えると活字体だと40x40、手書きだと60x60が必要だと思われますので、画像サイズは60x60pixelにしたいと思います。
def build_model06( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 6行目にConv2D( 16,3,activation='relu',name='Conv-2' )を加えました。
Conv-1 Conv-2
16-16>loss: 9.2406e-04 - acc: 1.0000 - val_loss: 4.5054 - val_acc: 0.6600
16-32>loss: 5.6926e-04 - acc: 1.0000 - val_loss: 4.1209 - val_acc: 0.6600
16-64>loss: 2.8045e-04 - acc: 1.0000 - val_loss: 3.7156 - val_acc: 0.7100
16-128>loss: 2.1953e-04 - acc: 1.0000 - val_loss: 3.6557 - val_acc: 0.7300
32-16>loss: 6.0040e-04 - acc: 1.0000 - val_loss: 4.0961 - val_acc: 0.6900
32-32>loss: 3.6516e-04 - acc: 1.0000 - val_loss: 3.8639 - val_acc: 0.6700
32-64>loss: 2.1345e-04 - acc: 1.0000 - val_loss: 3.7682 - val_acc: 0.7100
32-128>loss: 1.2075e-04 - acc: 1.0000 - val_loss: 3.4090 - val_acc: 0.7200
64-16>loss: 3.6875e-04 - acc: 1.0000 - val_loss: 3.5434 - val_acc: 0.7100
64-32>loss: 2.4558e-04 - acc: 1.0000 - val_loss: 4.1160 - val_acc: 0.7000
64-64>loss: 1.4243e-04 - acc: 1.0000 - val_loss: 3.4409 - val_acc: 0.7100
64-128>loss: 8.3642e-05 - acc: 1.0000 - val_loss: 3.3412 - val_acc: 0.7200
128-16>loss: 2.2914e-04 - acc: 1.0000 - val_loss: 3.6571 - val_acc: 0.7300
128-32>loss: 4.6949e-05 - acc: 1.0000 - val_loss: 3.4905 - val_acc: 0.7200
128-64>loss: 1.0044e-04 - acc: 1.0000 - val_loss: 3.4555 - val_acc: 0.7200
128-128>loss: 4.7357e-05 - acc: 1.0000 - val_loss: 2.9780 - val_acc: 0.7300

評価:この組み合わせは、かなり有望だと思われます。
試行⑦
def build_model07( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Dense( 16, activation='relu',name='Dense-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 6行目にDense( 16, activation='relu',name='Dense-1' )を加えました。
Conv-1 Dense-1
16-16>loss: 0.0010 - acc: 1.0000 - val_loss: 4.3769 - val_acc: 0.5600
16-32>loss: 7.0621e-04 - acc: 1.0000 - val_loss: 4.0234 - val_acc: 0.6100
16-64>loss: 3.8324e-04 - acc: 1.0000 - val_loss: 4.1565 - val_acc: 0.6000
16-128>loss: 9.6042e-05 - acc: 1.0000 - val_loss: 4.3745 - val_acc: 0.5900
32-16>loss: 7.7071e-04 - acc: 1.0000 - val_loss: 4.4662 - val_acc: 0.5500
32-32>loss: 4.3177e-04 - acc: 1.0000 - val_loss: 4.6119 - val_acc: 0.5300
32-64>loss: 2.8450e-04 - acc: 1.0000 - val_loss: 4.3589 - val_acc: 0.5700
32-128>loss: 2.1713e-04 - acc: 1.0000 - val_loss: 4.3174 - val_acc: 0.5900
64-16>loss: 5.4342e-04 - acc: 1.0000 - val_loss: 4.6699 - val_acc: 0.5900
64-32>loss: 3.1740e-04 - acc: 1.0000 - val_loss: 4.6166 - val_acc: 0.5700
64-64>loss: 2.0981e-04 - acc: 1.0000 - val_loss: 5.0301 - val_acc: 0.5700
64-128>loss: 1.0235e-04 - acc: 1.0000 - val_loss: 4.6548 - val_acc: 0.5300
128-16>loss: 3.9207e-04 - acc: 1.0000 - val_loss: 5.0715 - val_acc: 0.5700
128-32>loss: 2.7883e-04 - acc: 1.0000 - val_loss: 5.1655 - val_acc: 0.5500
128-64>loss: 1.4588e-04 - acc: 1.0000 - val_loss: 5.1592 - val_acc: 0.5500
128-128>loss: 9.1117e-05 - acc: 1.0000 - val_loss: 4.9934 - val_acc: 0.5700

評価:この組み合わせはNG。
試行⑧
def build_model08( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),
         Dense( 16, activation='relu',name='Dense-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 6行目にConv2D( 128,3,activation='relu',name='Conv-2' )を加えました。
  2. 7行目にDense( 16, activation='relu',name='Dense-1' )を加えました。
Conv-1 Conv-2 Dence-1
128-16-16>loss: 1.5736e-04 - acc: 1.0000 - val_loss: 3.9181 - val_acc: 0.7300
128-16-32>loss: 1.3667e-04 - acc: 1.0000 - val_loss: 3.7000 - val_acc: 0.7000
128-16-64>loss: 3.1002e-05 - acc: 1.0000 - val_loss: 4.0656 - val_acc: 0.7000
128-16-128>loss: 6.4537e-05 - acc: 1.0000 - val_loss: 3.5717 - val_acc: 0.7200

評価:この組み合わせはNG。
試行⑨
def build_model09( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-2' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 6行目にDropout( 0.1 )を加えました。
Conv-1(128) Conv-2(128)
Dropout()は確率要因が多いので1パラメータで3回試行しました。
0.1-loss: 5.6572e-05 - acc: 1.0000 - val_loss: 3.0021 - val_acc: 0.7300
   -loss: 6.4414e-05 - acc: 1.0000 - val_loss: 3.2341 - val_acc: 0.7300
   -loss: 5.3637e-05 - acc: 1.0000 - val_loss: 3.2736 - val_acc: 0.7300
0.2-loss: 4.7608e-05 - acc: 1.0000 - val_loss: 3.3339 - val_acc: 0.7300
   -loss: 6.9741e-05 - acc: 1.0000 - val_loss: 3.3472 - val_acc: 0.7300
   -loss: 7.4597e-05 - acc: 1.0000 - val_loss: 3.4485 - val_acc: 0.7500
0.3-loss: 5.4596e-05 - acc: 1.0000 - val_loss: 3.3064 - val_acc: 0.7300
   -loss: 3.2513e-05 - acc: 1.0000 - val_loss: 3.0908 - val_acc: 0.7100
   -loss: 3.2513e-05 - acc: 1.0000 - val_loss: 3.0908 - val_acc: 0.7100
0.4-loss: 7.0417e-05 - acc: 1.0000 - val_loss: 3.0805 - val_acc: 0.7300
   -loss: 8.0341e-05 - acc: 1.0000 - val_loss: 3.1521 - val_acc: 0.7400
   -loss: 9.0273e-05 - acc: 1.0000 - val_loss: 3.1139 - val_acc: 0.7100
0.5-loss: 1.3764e-04 - acc: 1.0000 - val_loss: 2.9503 - val_acc: 0.7700
   -loss: 1.1432e-04 - acc: 1.0000 - val_loss: 3.3115 - val_acc: 0.7500
   -loss: 9.3553e-05 - acc: 1.0000 - val_loss: 3.0958 - val_acc: 0.7200

評価:大きな変化はありませんでした。Dropout()は過学習予防に有効なようなので採用したいと思います。尚、パラメータは中間の0.3を使いたいと思います。
試行⑩
def build_model10( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,4,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 4行目の特徴量抽出パターンを3x3から4x4に変更しました。
Conv-1(128)
Conv-2(16)-loss: 0.0109 - acc: 0.9980 - val_loss: 3.9553 - val_acc: 0.6900
Conv-2(32)-loss: 2.5828e-04 - acc: 1.0000 - val_loss: 3.4635 - val_acc: 0.7400
Conv-2(64)-loss: 1.3790e-04 - acc: 1.0000 - val_loss: 2.9480 - val_acc: 0.7500
Conv-2(128)-loss: 1.0117e-04 - acc: 1.0000 - val_loss: 2.9424 - val_acc: 0.7500

batch_size=5,epochs=20で試行してみます。

Conv-2(16)-loss: 0.0233 - acc: 0.9960 - val_loss: 2.1307 - val_acc: 0.7800
Conv-2(32)-loss: 2.6650e-04 - acc: 1.0000 - val_loss: 2.7348 - val_acc: 0.7200
Conv-2(64)-loss: 0.1862 - acc: 0.9560 - val_loss: 1.7397 - val_acc: 0.6900
Conv-2(128)-loss: 9.5785e-05 - acc: 1.0000 - val_loss: 2.7712 - val_acc: 0.7700

評価:安定してval_lossの低下が見られました。batch_size=5,epochs=20を採用したいと思います。
試行⑪
def build_model11( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-22' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

    history = model.fit(x_train,y_train, batch_size=5, epochs=20, validation_data=(x_test, y_test),verbose=1 )
  1. 次のレイヤーを1セットとして2セット行います。
    1. Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' )
    2. MaxPooling2D( pool_size=(2, 2) )
    3. Conv2D( 128,3,activation='relu',name='Conv-12' )
    4. Dropout( 0.3 )
  2. model.fit(x_train,y_train, batch_size=5, epochs=20,で行います。
Conv-11(128) Conv-12(128)
Conv-21(16) Conv-22(16)-loss: 0.0104 - acc: 0.9960 - val_loss: 1.3858 - val_acc: 0.8300
Conv-21(32) Conv-22(32)-loss: 0.0269 - acc: 0.9900 - val_loss: 1.4335 - val_acc: 0.8100
Conv-21(64) Conv-22(64)-loss: 0.1213 - acc: 0.9680 - val_loss: 0.3700 - val_acc: 0.9000
Conv-21(128) Conv-22(128)-loss: 0.0149 - acc: 0.9940 - val_loss: 0.9840 - val_acc: 0.8600

確認のためパラメータ64を3回試行します。
Conv-21(64) Conv-22(64)-loss: 0.0025 - acc: 0.9980 - val_loss: 0.7749 - val_acc: 0.8800
Conv-21(64) Conv-22(64)-loss: 3.9076e-04 - acc: 1.0000 - val_loss: 1.0852 - val_acc: 0.8900
Conv-21(64) Conv-22(64)-loss: 0.0018 - acc: 1.0000 - val_loss: 0.8826 - val_acc: 0.8900

評価:パラメータ64を採用します。理由はval_lossが1以下になったからです。loss,acc,val_accは目安として見ています。重要なのはval_lossだと思っています。
試行⑫
def build_model12( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.3 ),

         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-22' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 3セットで試行します。
Conv-10(128) Conv-20(64)
Conv-30(16)-loss: 0.0660 - acc: 0.9740 - val_loss: 0.2862 - val_acc: 0.9300
Conv-30(32)-loss: 0.1001 - acc: 0.9660 - val_loss: 0.2771 - val_acc: 0.9400
Conv-30(64)-loss: 0.0148 - acc: 0.9960 - val_loss: 0.2910 - val_acc: 0.9400
Conv-30(128)-loss: 0.0104 - acc: 0.9940 - val_loss: 0.4436 - val_acc: 0.9600

評価:自分の勘で選択していきます。loss,acc,val_loss,val_accのバランスがいい。
パラメータは32を採用したい。
試行⑬
def build_model13( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.2 ),

         Conv2D( 32,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 32,3,activation='relu',name='Conv-32' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. Dropoutのパラメータを1セット目(0.3)、2セット目(0.2)、3セット目(0.1)として試行したい。
3回試行
loss: 0.0051 - acc: 1.0000 - val_loss: 0.1904 - val_acc: 0.9400
loss: 0.0439 - acc: 0.9840 - val_loss: 0.5150 - val_acc: 0.8900
loss: 0.0369 - acc: 0.9920 - val_loss: 0.2264 - val_acc: 0.9600

評価:モデルの構築の時、数回の試行で最も適したものを選ぶので、この試行に若干のばらつきはありますが、採用したいと思います。
試行⑭
def build_model14( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.2 ),

         Conv2D( 32,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 32,3,activation='relu',name='Conv-32' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-41' ),
         Dropout( 0.1 ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model
  1. 20行目にDense( 16, activation='relu',name='Dense-41' )を加えました。
  2. 21行目にDropout( 0.1 )を加えました。
3回試行
loss: 0.1375 - acc: 0.9620 - val_loss: 0.3693 - val_acc: 0.8900
loss: 0.2593 - acc: 0.9340 - val_loss: 0.5519 - val_acc: 0.8800
loss: 0.1166 - acc: 0.9540 - val_loss: 0.5515 - val_acc: 0.8900

評価:不採用。

レイヤの考察

  1. Conv2D:特徴量抽出(畳み込み)
  2. MaxPooling2D:各画像位置の最大値を特徴量として配列を畳む。
  3. Dense:全結合。試行では効果が見られませんでした。よって、不採用。
  4. Dropout:過学習予防
  5. Flatten:1次元化。Dense(softmax)のために必須。
  6. Dense(softmax):分類問題に適合する活性化関数
活性化関数
  1. relu:途中の隠れレイヤで使う
  2. softmax:出力レイヤで使う

コンパイル(compile)

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
  1. loss(損失関数):categorical_crossentropy
  2. optimizer(最適化アルゴリズム):adam
  3. metrics(評価関数):acc

学習(訓練)(fit)

    history = model.fit(x_train,y_train, batch_size=25, epochs=10, verbose=1 )
  1. x_train
    1. (size,row,col,chanel)
    2. sizeは画像数です。
    3. row,colは画像のサイズです。col,rowかもしれません。
    4. chanelは、RGBの時3です。
  2. y_train
    1. 教師データです。
    2. 正解値の設定が必要です。
  3. batch_size
    1. いくつの値がいいのかは一概にいえないようです。
    2. batch_size=s、sは小さいほどメモリの消費が少なくてすみます。
    3. sが大きいほど、一度に処理する量が増えるので処理速度が上がります。
    4. batch_size=5~30とepochs=30~100の組み合わせで評価の観察をします。
  4. epochs
    1. epochs=n、nは学習の繰り返し回数です。
    2. nを大きくすれば、損失値が減って、精度が上がります。
    3. ただし、nを大きくすれば、処理時間がかかります。
    4. 実行課程ログを見ながら、nの調整が必要です。
  5. verbose
    1. verbose=1にすると、実行課程ログを表示してくれます。

損失値 (evaluate)

  1. 準備中

基準モデルの構築(決定)version 1.0

試行用ソース

#試行用ソース

import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from tensorflow.keras.layers import Activation,Dropout,Flatten,Dense
from tensorflow.keras.utils import to_categorical

import c001_env as env

def build_model01( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model02( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-end' ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model03( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-end' ),
         Dropout( 0.1 ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model04( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model05( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 16,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model06( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-2' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model07( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Dense( 128, activation='relu',name='Dense-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model08( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 16,3,activation='relu',name='Conv-2' ),
         Dense( 32, activation='relu',name='Dense-1' ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model09( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-2' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model10( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,4,input_shape=x_train.shape[1:],activation='relu',name='Conv-1' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-2' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model11( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model12( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.3 ),

         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-32' ),
         Dropout( 0.3 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model13( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.2 ),

         Conv2D( 32,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 32,3,activation='relu',name='Conv-32' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model14( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.2 ),

         Conv2D( 32,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 32,3,activation='relu',name='Conv-32' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( 16, activation='relu',name='Dense-41' ),
         Dropout( 0.1 ),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def build_model99( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 512,3,input_shape=x_train.shape[1:],padding='same',activation='relu',name='Conv-1' ),#ok
         MaxPooling2D( pool_size=(2, 2) ),		#ok
         Dense( 32, activation='relu',name='Dense-1' ),	#ok
         Dropout( 0.5 ),				#ok

         Conv2D( 64,3,activation='relu',name='Conv-2' ),#ok
         MaxPooling2D( pool_size=(2, 2) ),		#ok
         Dense( 192, activation='relu',name='Dense-2' ),#150~256
         Dropout( 0.2 ),				#0.15~0.25

         Conv2D( 40,3,activation='relu',name='Conv-3' ),#32~48
         MaxPooling2D( pool_size=(2, 2) ),		#ok
#         Dense( 4, activation='relu',name='Dense-3' ),	#ok
         Dropout( 0.2 ),				#ok

         Flatten(),
         Dense( 16, activation='relu',name='Dense-4' ),	#ok
         Dropout( 0.1 ),				#~0.2
         Dense( nb_classes, activation='softmax',name='Dense-5' )
        ] )

    return model

def main():
    x_train = np.load( env.npy_x_train,allow_pickle=True)
    y_train = np.load( env.npy_y_train,allow_pickle=True)
    x_train = x_train.astype( 'float32' ) /255
    y_train = to_categorical( y_train,env.nb_classes )

    x_test,y_test = env.load_img( env.test_dir,env.groups,env.file_type,env.img_size,env.img_mode )
    x_test = x_test.astype( 'float32' ) /255
    y_test = to_categorical( y_test,env.nb_classes )

    if( env.m_type=="T1" ):
        model = build_model01( x_train,env.nb_classes )
    elif( env.m_type=="T2" ):
        model = build_model02( x_train,env.nb_classes )
    elif( env.m_type=="T3" ):
        model = build_model03( x_train,env.nb_classes )
    elif( env.m_type=="T4" ):
        model = build_model04( x_train,env.nb_classes )
    elif( env.m_type=="T5" ):
        model = build_model05( x_train,env.nb_classes )
    elif( env.m_type=="T6" ):
        model = build_model06( x_train,env.nb_classes )
    elif( env.m_type=="T7" ):
        model = build_model07( x_train,env.nb_classes )
    elif( env.m_type=="T8" ):
        model = build_model08( x_train,env.nb_classes )
    elif( env.m_type=="T9" ):
        model = build_model09( x_train,env.nb_classes )
    elif( env.m_type=="T10" ):
        model = build_model10( x_train,env.nb_classes )
    elif( env.m_type=="T11" ):
        model = build_model11( x_train,env.nb_classes )
    elif( env.m_type=="T12" ):
        model = build_model12( x_train,env.nb_classes )
    elif( env.m_type=="T13" ):
        model = build_model13( x_train,env.nb_classes )
    elif( env.m_type=="T14" ):
        model = build_model14( x_train,env.nb_classes )
    else:
        return

    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
    model.summary()

    if( env.e_type=="summary" ):
        return

    if( env.m_type=="T1" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T2" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T3" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T4" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T5" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T6" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T7" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T8" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    elif( env.m_type=="T9" ):
        history = model.fit(x_train,y_train, batch_size=10, epochs=30, validation_data=(x_test, y_test),verbose=1 )
    else:
        history = model.fit(x_train,y_train, batch_size=5, epochs=20, validation_data=(x_test, y_test),verbose=1 )

    json_string = model.to_json()
    open( env.fs_json,'w').write(json_string )
    model.save_weights( env.fs_hdf5 )

    print( 'success' )

main()

基準モデルのソース

#基準モデルのソース

import numpy as np

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D,MaxPooling2D
from tensorflow.keras.layers import Activation,Dropout,Flatten,Dense
from tensorflow.keras.utils import to_categorical

import c001_env as env

def build_model( x_train,nb_classes ):
    model = Sequential(
        [ 
         Conv2D( 128,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-11' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 128,3,activation='relu',name='Conv-12' ),
         Dropout( 0.3 ),

         Conv2D( 64,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-21' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 64,3,activation='relu',name='Conv-22' ),
         Dropout( 0.2 ),

         Conv2D( 32,3,input_shape=x_train.shape[1:],activation='relu',name='Conv-31' ),
         MaxPooling2D( pool_size=(2, 2) ),
         Conv2D( 32,3,activation='relu',name='Conv-32' ),
         Dropout( 0.1 ),

         Flatten(),
         Dense( nb_classes, activation='softmax',name='Dense-class' )
        ] )

    return model

def main():
    x_train = np.load( env.npy_x_train,allow_pickle=True)
    y_train = np.load( env.npy_y_train,allow_pickle=True)
    x_train = x_train.astype( 'float32' ) /255
    y_train = to_categorical( y_train,env.nb_classes )

    x_test,y_test = env.load_img( env.test_dir,env.groups,env.file_type,env.img_size,env.img_mode )
    x_test = x_test.astype( 'float32' ) /255
    y_test = to_categorical( y_test,env.nb_classes )

    model = build_model( x_train,env.nb_classes )
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
    history = model.fit(x_train,y_train, batch_size=5, epochs=20, validation_data=(x_test, y_test),verbose=1 )

    json_string = model.to_json()
    open( env.fs_json,'w').write(json_string )
    model.save_weights( env.fs_hdf5 )

    print( 'success' )

main()

全体像

レイヤの種別

  1. まず、できるだけ、全レイヤを洗い出します。
  2. そこから、使う使わないを判断します。

Coreレイヤ

  1. Dense---通常の全結合CNNレイヤ(試用)
  2. Activation---出力に活性化関数を適用(試用)
  3. Dropout---過学習防止(試用)
  4. Flatten---入力を平坦化(試用)
  5. Input---(保留)
  6. Reshape---(保留)
  7. Permute---(保留)
  8. RepeatVector---(保留)
  9. Lambda---(保留)
  10. ActivityRegularization---(保留)
  11. Masking---(保留)

Convolutional(畳み込み)レイヤ

  1. Conv1D---1次元の畳み込みレイヤ(時間的な畳み込みなど)(保留)
  2. Conv2D---2次元の畳み込みレイヤ(イメージの空間的畳み込みなど)(試用)
  3. SeparableConv2D---(保留)
  4. Conv2DTranspose---(保留)
  5. Conv3D---3次元の畳み込みレイヤ(保留)
  6. Cropping1D---(保留)
  7. Cropping2D---2次元の入力を切り落とします。(試用)
  8. Cropping3D---(保留)
  9. UpSampling1D---(保留)
  10. ZeroPadding1D---(保留)
  11. ZeroPadding2D---(試用)
  12. ZeroPadding3D---(保留)

Poolingレイヤ

  1. MaxPooling1D---(保留)
  2. MaxPooling2D---(試用)
  3. MaxPooling3D---(保留)
  4. AveragePooling1D---(保留)
  5. AveragePooling2D---(試用)
  6. AveragePooling3D---(保留)
  7. GlobalMaxPoolind1D---(保留)
  8. GlobalMaxPooling2D---(試用)
  9. GlobalMaxPooling3D---(保留)
  10. GlobalAveragePooling1D---(保留)
  11. GlobalAveragePooling2D---(試用)
  12. GlobalAveragePooling3D---(保留)

Mergeレイヤ

  1. (保留)

活性化関数の種別

  1. softmax---0~1の値をとります。出力値の総計が1になるので、個々の値は確率とみなすことができます。
    そのため、分類問題に適しています。
  2. Raises---保留
  3. elu---負の値を許すので、分類問題に適さないと思います。
  4. selu---負の値を許すので、分類問題に適さないと思います。
  5. softplus---負の値を許すので、分類問題に適さないと思います。
  6. softsign---負の値を許すので、分類問題に適さないと思います。
  7. relu---負の値をすべてゼロにします。分類問題に使えるかもしれません。
  8. tanh---負の値を許すので、分類問題に適さないと思います。
  9. sigmoid---負の値を許すので、分類問題に適さないと思います。
  10. hard_sigmoid---負の値を許すので、分類問題に適さないと思います。
  11. linear---負の値を許すので、分類問題に適さないと思います。

コンパイル(compile)

  1. loss:損失関数
    1. categorical_crossentropy
    2. sparse_categorical_crossentropy
  2. optimizer:最適化アルゴリズム
    1. adam
    2. admax
    3. nadam
    4. adadelta
    5. RMSprop
    6. Adagrad
    7. Ftrl
    8. SGD
  3. metrics:評価関数
    1. acc
    2. binary_accuracy
    3. categorical_accuracy
    4. sparse_categorical_accuracy
    5. top_k_categorical_accuracy
    6. mae

前の記事:002-01.手書き文字-日本語-画像の準備作業
次の記事:011-01.手書き文字-日本語-プログラムの管理リスト

お問合せ・御要望

  • お問合せ
  • トップへ戻る
    タイトルとURLをコピーしました