chihiro1364
@chihiro1364

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Denseのユニット数の指定基準が解らないので教えて頂けませんか?

解決したいこと

kerasを使う為にレイヤー作成が必要になりますが、その時にDense関数を使っています。
入力層作成時の第一引数のユニット数は入力する値に何か基準はあるのか知りたいです。

発生している問題・エラー

from tensorflow import keras
from tensorflow.keras.layers import Dense

seq = Sequential()
seq.add(Dense("この部分です。", activation="relu, input_shape(4, )))
0

1Answer

入力層作成時の第一引数のユニット数は

とおっしゃっていますが,コードの次の行がわからないのでなんとも言えないので仮定の上で話します.中間層なしであればそこは出力の次元数にするべきですし,中間層としたい場合は下記のようにパラメータを調整する必要があります.

中間層としたい場合で話を進めると,こちらの記事で得た内容と私の経験則で回答いたします.ユニット数は,データの性質次第というのが一般的な答えです.

なので,データの性質を,主成分分析をはじめとする次元削減を用いて調査しつつ,ユニット数を決めるのが一般的な流れになっていると思います.その手間を省いて決めたい場合であれば,入力の$4$つのパラメータの組み合わせを全パターン網羅できる数を試すのが初手だと思います.すなわち,

$$
_4C_1+_4C_2+_4C_3+_4C_4 = 4 + 6 + 4 + 1 = 15
$$

ぐらい1から始めるのが良さそうです.全ての組み合わせをそれぞれのノードが学習してくれればそれでよく,過学習しているのであれば数を減らせば良いのではないでしょうか.基本的には試行錯誤です.必要に応じて増やすことになるかもしれません.したがって,データの性質次第ということになります.

ちなみに中間層の数は特徴空間における飛び地の数に比例させる必要があることも加えておきます.

中間層なしで実装したい場合

2値分類をしたくて1つの出力でよければ,下記コードで実装できます.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model

model = Sequential()
model.add(Dense(1, activation = "sigmoid", input_shape = (4,)))

plot_model(model, to_file = "model.png", show_shapes = True)

状態としては次の図のようになります2

スクリーンショット 2022-04-02 20.08.27.png

出力されるmodel.pngは

model.png

ですね.

中間層ありで実装したい場合

中間層1層で2値分類をしたい場合は

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model

model = Sequential()
model.add(Dense(15, activation = "relu", input_shape = (4,)))
model.add(Dense(1, activation = "sigmoid"))

plot_model(model, to_file = "model.png", show_shapes = True)

状態としては次のようになります2

スクリーンショット 2022-04-02 20.07.13.png

出力されるmodel.pngは

model.png

ですね.場合によってはめちゃくちゃ過学習しそうです.
自分語りになってしまって申し訳ないのですが,個人的には名前を付けやすいことから次の書き方を好んで使います.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.utils import plot_model

model = Sequential()
model.add(Input(shape = (4,), name = "InputLayer"))
model.add(Dense(15, activation = "relu", name = "HiddenLayer"))
model.add(Dense(1, activation = "sigmoid", name = "OutputLayer"))

plot_model(model, to_file = "model.png", show_shapes = True)

model.pngにおいて名前がちゃんと付いてくれて,

model.png

このようになってくれます.先は勝手にdense_inputとかdense_1とかいう名前を割り振ってくれていましたが,今後の可視性を考えた上での記述になります.

  1. 入力数$N$に対して$2^N-1$と同一です.$N$個の中から$1$個だけ選ぶパターン,$2$個だけ選ぶパターン,...,$N-1$個だけ選ぶパターン,$N$個だけ選ぶパターンを合計すると$2^N-1$になります.選ぶと選ばないの$2$択を$N$回やる中で,全て選ばないパターンを除くからです.

  2. Biasのユニットも含めたので,入力層と中間層でそれぞれ1次元ずつ増えているように見えます.描画にNN-SVGを使いました 2

1Like

Comments

  1. @chihiro1364

    Questioner

    ごめんなさい。
    多分私が、どのレイヤが入力層、中間層になるのか解ってないみたいなのでそれについて質問させて下さい。
    中間層無しで実装したい場合に該当するんですが、
    書いて頂いた
    model = Sequential()
    model.add(Dense(1, activation = "sigmoid", input_shape = (4,)))
    の部分ですが、作成したレイヤは入力層ですか?出力層ですか?

    作成したレイヤが入力層な場合、第一引数の1の部分がなぜ1になるのかが解らないのです。

    もしくは、出力層だとした場合の第一引数は出力数(ラベル数)を指定しているのでしょうか?
  2. その1行で入力層と出力層の両方を実現しています.後に続く画像を見て欲しいのですが,InputLayerとしてdense_input,Dense(出力層)としてdenseが構成されています.

    > 出力層だとした場合の第一引数は出力数(ラベル数)を指定しているのでしょうか?

    おっしゃる通りです(正しくは出力数というかユニット数ですが,ユニットの数だけ出力があるので値としては同一です).2値分類である場合は1で十分です.多値分類である場合は,その種類数に応じた値(ラベル数)を入れて活性化関数をsoftmaxにしてください.

    こういった議論でこのinput_shapeを使った記述が紛らわしいのもあって,私はちゃんとレイヤInputをmodelにaddする形で記述したいのというのもありますので,上では
    model.add(Input(shape = (4,), name = "InputLayer"))
    model.add(Dense(15, activation = "relu", name = "HiddenLayer"))
    model.add(Dense(1, activation = "sigmoid", name = "OutputLayer"))
    と書きました.中間層なしのやつに反映させると
    model.add(Input(shape = (4,), name = "InputLayer"))
    model.add(Dense(1, activation = "sigmoid", name = "OutputLayer"))
    がわかりやすいですね.ちゃんとkeras.layerからimportしてきたInputレイヤを使用しているので,記述としても正しく感じます.
    Denseにinput_shapeを指定できることで,Input()の項を書かなくて済むのは魅力的ですが,紛らわしいことこの上ないです.
  3. @chihiro1364

    Questioner

    理解できました。
    ありがとうございます。

Your answer might help someone💌