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)
:之后的轉換幾乎沒有用根據上述,我替換
Conv1D
為Conv3D
除非您使用可變批量大小,否則請始終使用
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

TA貢獻1852條經驗 獲得超1個贊
由于您的標簽可以是 0 或 1,我建議將激活函數更改為softmax
,將輸出神經元的數量更改為 2?,F在,最后一層(輸出)將如下所示:
out = Dense(units=2, activation='softmax')(reshaped_conv_features)
我之前也遇到過同樣的問題,并發現由于 1 或 0 的概率是相關的,從某種意義上說,它不是一個多標簽分類問題,Softmax 是一個更好的選擇。Sigmoid 分配概率而不考慮其他可能的輸出標簽。
- 2 回答
- 0 關注
- 160 瀏覽
添加回答
舉報