亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Keras 模型未能減少損失

Keras 模型未能減少損失

Go
慕萊塢森 2022-06-14 17:43:39
我提出了一個tf.keras模型無法從非常簡單的數據中學習的示例。我正在使用tensorflow-gpu==2.0.0和keras==2.3.0Python 3.7。在文章的最后,我給出了 Python 代碼來重現我觀察到的問題。數據樣本是形狀為 (6, 16, 16, 16, 3) 的 Numpy 數組。為了使事情變得非常簡單,我只考慮充滿 1 和 0 的數組。帶有 1 的數組被賦予標簽 1,帶有 0 的數組被賦予標簽 0。我可以使用以下n_samples = 240代碼生成一些樣本(在下面,):def generate_fake_data():    for j in range(1, 240 + 1):        if j < 120:            yield np.ones((6, 16, 16, 16, 3)), np.array([0., 1.])        else:            yield np.zeros((6, 16, 16, 16, 3)), np.array([1., 0.])為了在模型中輸入這些數據,我使用下面的代碼tf.keras創建了一個實例。tf.data.Dataset這將基本上創建洗牌批次的BATCH_SIZE = 12樣本。def make_tfdataset(for_training=True):    dataset = tf.data.Dataset.from_generator(generator=lambda: generate_fake_data(),                                             output_types=(tf.float32,                                                           tf.float32),                                             output_shapes=(tf.TensorShape([6, 16, 16, 16, 3]),                                                            tf.TensorShape([2])))    dataset = dataset.repeat()    if for_training:        dataset = dataset.shuffle(buffer_size=1000)    dataset = dataset.batch(BATCH_SIZE)    dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)    return dataset問題!在 500 個 epoch 中,模型損失保持在 0.69 左右,并且從未低于 0.69。如果我將學習率設置為1e-2而不是1e-3. 數據非常簡單(只有 0 和 1)。天真地,我希望該模型具有比僅 0.6 更好的精度。事實上,我希望它能夠迅速達到 100% 的準確率。我做錯了什么?
查看完整描述

2 回答

?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

您的代碼有一個關鍵問題:維度洗牌。您永遠不應該觸及的一個維度是批處理維度- 因為根據定義,它包含數據的獨立樣本。在您的第一次重塑中,您將特征尺寸與批量尺寸混合:

Tensor("input_1:0", shape=(12, 6, 16, 16, 16, 3), dtype=float32)
Tensor("lambda/Reshape:0", shape=(72, 16, 16, 16, 3), dtype=float32)

這就像喂食 72 個獨立的形狀樣本(16,16,16,3)。其他層也有類似的問題。



解決方案


  • 與其重塑每一步(你應該使用它Reshape),不如塑造你現有的 Conv 和池化層,讓一切都直接進行。

  • 除了輸入和輸出層,最好給每一層命名簡短而簡單 - 不會失去清晰度,因為每一行都由層名稱明確定義

  • GlobalAveragePooling旨在成為最后一層,因為它會折疊特征尺寸- 在您的情況下,如下所示(12,16,16,16,3) --> (12,3):之后的轉換幾乎沒有用

  • 根據上述,我替換Conv1DConv3D

  • 除非您使用可變批量大小,否則請始終使用batch_shape=vs. shape=,因為您可以全面檢查圖層尺寸(非常有幫助)

  • 您的真實值batch_size是 6,從您的評論回復中推斷出來

  • kernel_size=1并且(尤其是)filters=1是一個非常弱的卷積,我相應地替換了它 - 如果你愿意,你可以恢復

  • 如果您的預期應用程序中只有 2 個類,我建議您Dense(1, 'sigmoid')使用binary_crossentropy損失

最后一點:除了維度改組建議之外,您可以將上述所有內容都扔掉,仍然可以獲得完美的訓練集性能;這是問題的根源。

def create_model(batch_size, input_shape):


    ipt = Input(batch_shape=(batch_size, *input_shape))

    x   = Conv3D(filters=64, kernel_size=8, strides=(2, 2, 2),

                             activation='relu', padding='same')(ipt)

    x   = Conv3D(filters=8,  kernel_size=4, strides=(2, 2, 2),

                             activation='relu', padding='same')(x)

    x   = GlobalAveragePooling3D()(x)

    out = Dense(units=2, activation='softmax')(x)


    return Model(inputs=ipt, outputs=out)

BATCH_SIZE = 6

INPUT_SHAPE = (16, 16, 16, 3)

BATCH_SHAPE = (BATCH_SIZE, *INPUT_SHAPE)


def generate_fake_data():

    for j in range(1, 240 + 1):

        if j < 120:

            yield np.ones(INPUT_SHAPE), np.array([0., 1.])

        else:

            yield np.zeros(INPUT_SHAPE), np.array([1., 0.])



def make_tfdataset(for_training=True):

    dataset = tf.data.Dataset.from_generator(generator=lambda: generate_fake_data(),

                                 output_types=(tf.float32,

                                               tf.float32),

                                 output_shapes=(tf.TensorShape(INPUT_SHAPE),

                                                tf.TensorShape([2])))

    dataset = dataset.repeat()

    if for_training:

        dataset = dataset.shuffle(buffer_size=1000)

    dataset = dataset.batch(BATCH_SIZE)

    dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

    return dataset

結果:


Epoch 28/500

40/40 [==============================] - 0s 3ms/step - loss: 0.0808 - acc: 1.0000


查看完整回答
反對 回復 2022-06-14
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

由于您的標簽可以是 0 或 1,我建議將激活函數更改為softmax,將輸出神經元的數量更改為 2?,F在,最后一層(輸出)將如下所示:

out = Dense(units=2, activation='softmax')(reshaped_conv_features)

我之前也遇到過同樣的問題,并發現由于 1 或 0 的概率是相關的,從某種意義上說,它不是一個多標簽分類問題,Softmax 是一個更好的選擇。Sigmoid 分配概率而不考慮其他可能的輸出標簽。


查看完整回答
反對 回復 2022-06-14
  • 2 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號