質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

kerasのbatch_sizeについて(分からない)

解決済

回答 1

投稿

  • 評価
  • クリップ 2
  • VIEW 4,931

n0pj

score 12

前提・実現したいこと

kerasのfit関数の引数batch_sizeについてです。
半年ほどニューラルネットワークを勉強しているんですが、つまずきました。
batch_sizeについてですが、以下の事が解だと思っています。

1, バッチ分データを分割して学習(batch_size=2, data_set=400の場合、400/2回学習)、割り切れなかったりした場合は切り捨て?して計算してくれる(はず)
2, batch_size=1であれば確率的になる。
3, 指定しない場合はDefault=32となる(Noneでも)。
4, batch_sizeは2^nで決めると良い。(ケースバイケース)

これらのことから、あまり深く決める必要はないと感じました。
が、しかし、

発生している問題・エラーメッセージ

batch_size=8の場合です。
なぜでしょうか。
これはどの部分を指しているのでしょうか。

Incompatible shapes: [8] vs. [8,64,64]


また、batch_size=64にした場合、こうなります。
よく分かりません。

Incompatible shapes: [24] vs. [24,64,64]


合わすことができれば、こういう風に計算できると思うんですが…

x = np.ones(64)
y = np.ones((64, 64, 64))
dot = np.dot(x, y)

該当のソースコード

長いので、関連がありそうな部分だけを載せます。
trainは664、validateは166
Convが1層しかない簡単なネットワークです。

h = 64
w = 64
d = 3
入出力は、
Input
in  :(None, 64, 64, 3)
out:(None, 64, 64, 3)
Conv2D
in  :(None, 64, 64, 3)
out:(None, 64, 64, 64)
Dense
in  :(None, 64, 64, 64)
out:(None, 64, 64, 64)
Dense
in  :(None, 64, 64, 64)
out:(None, 64, 64, 3)

class teratail(object):
    def __init__(self, h, w, d, label):
        self.inputs = Input(shape=(h, w, d), name="inputs")
        self.x = Conv2D(64, 3, padding="same", activation="relu")(self.inputs)
        self.x = Dense(64, activation="relu")(self.x)
        self.outputs = Dense(label, activation="softmax")(self.x)

    def create_model(self):
        self.model = Model(self.inputs, self.outputs, name="network")

    def model_compile(self):
        loss_object = tf.losses.CategoricalCrossentropy()
        optimizer = tf.optimizers.Adam(lr=1e-4)

        self.model.compile(loss=loss_object,
                           optimizer=optimizer,
                           metrics=["accuracy"])

    def model_fit(self, x_train, y_train, epochs=10):

        _return = self.model.fit(x_train, y_train,
                                 batch_size=8,
                                 epochs=epochs,
                                 validation_split=0.2,
                                 )
        self.model.summary()


お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

1, バッチ分データを分割して学習(batch_size=2, data_set=400の場合、400/2回学習)、割り切れなかったりした場合は切り捨て?して計算してくれる(はず)

400 / 2 = 200 回重みの更新されるので、その認識であっています。
端数となるサンプルを切り捨てるかどうかはライブラリの実装に依ります。

2, batch_size=1であれば確率的になる。

バッチサイズ1の場合 確率的勾配法 になりますが、バッチサイズ < サンプル数であれば、サンプル全部の勾配をサンプルの一部の勾配で近似しているわけなので、確率的といえます。

3, 指定しない場合はDefault=32となる(Noneでも)。

その認識であっています。公式ドキュメント記載の通り。

batch_size: 整数またはNone.設定したサンプル数ごとに勾配の更新を行います. 指定しなければデフォルトで32になります.

Sequentialモデル - Keras Documentation

4, batch_sizeは2^nで決めると良い。(ケースバイケース)

2の累乗がよいという特段の理由はありません。
プログラマにとって、2の累乗はキリのいい数なので、32や64といった値がよく使われているだけです。

  • バッチサイズを小さくする:
    局所解に嵌りずらくなる。
    GPU を使用する場合、計算効率が悪くなる。

  • バッチサイズを大きくする:
    局所解に嵌りやすくなる。
    GPU を使用する場合、一度に計算できたほうが計算効率がよい。
    あまり大きい値にしすぎると、GPU のメモリに乗り切らない場合もある。

どのくらいの値がよいかというのはハイパーパラメータなので、ケースバイケースです。

エラーについて

Incompatible shapes: [8] vs. [8,64,64]

そのエラーはモデル作成時または fit() 関数による学習時のどちらのタイミングででましたか?
後者の場合、モデルは (None, 64, 64, 3) の入力を期待しているので、
fit 関数に与えるデータ x_train の形状は (サンプル数, 64, 64, 3) の numpy 配列、y_train は (サンプル数, クラス数) の numpy 配列の必要があります。
x_train.shape, y_train.shape を print してみてそのようになっているか確認してみてください。

追記

よく見たら、Conv2D -> Dense の間に Flatten する層が抜けていますね。
エラーはそれが原因です。

動作確認したコード

from tensorflow.keras.layers import Input, Conv2D, Dense, Flatten
from tensorflow.keras.models import Model

inputs = Input(shape=(64, 64, 3))
x1 = Conv2D(64, 3, padding="same", activation="relu")(inputs)
x2 = Flatten()(x1)
x3 = Dense(64, activation="relu")(x2)
outputs = Dense(8, activation="softmax")(x3)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss="categorical_crossentropy", optimizer="Adam", metrics=["accuracy"])
model.summary()

x_train = np.random.randn(1000, 64, 64, 3)
y_train = np.random.randn(1000, 8)

model.fit(x_train, y_train, batch_size=8, epochs=100, validation_split=0.2)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/28 12:14

    importしていたのにすっかり忘れていました。ありがとうございます。
    Flattenを用いない方法もあった気がするんですが、ご存知でないでしょうか?
    全貌が明らかでないので不確かですが、こちらのブログ主さんはできているようです。
    何か条件があるのであれば教えていただきたいです。
    http://liaoyuan.hatenablog.jp/entry/2018/02/24/124442

    キャンセル

  • 2019/05/28 12:31 編集

    上記ブログのコードを拝見しましたが Flatten() してから全結合層に渡しています。

    > Flattenを用いない方法もあった気がするんですが、ご存知でないでしょうか?

    Global Average Pooling でも Flatten と同じことができます。
    https://qiita.com/Phoeboooo/items/f188eb2426afc8757272

    > 何か条件があるのであれば教えていただきたいです。

    条件等ではなく、(BatchSize, H, W, C) の配列をそのまま出力数Nの全結合層に渡すと、ブロードキャストで計算され、(BatchSize, H, W, N) の配列が最終的なモデルの出力となるので、そのあとの損失関数の計算で形状の不一致が起こります。
    なので、全結合層にわたす前には必ず Flatten してください。

    キャンセル

  • 2019/05/28 19:05

    なるほど…なるほど…
    詳しくありがとうございます。
    また新しいことを学べました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る