请注意,我是TensorFlow的新手,对机器学习也是一般了解。
我有一个神经网络在训练一组不平衡的数据,因此我需要不同的样本权重。
我的模型是这么构建的:
def loss(a1, a2): customloss = keras.backend.mean(keras.backend.square((a1 - a2))) return customlossdef build_model(): model = keras.Sequential() model.add(keras.layers.Dense(101, activation=keras.activations.linear, input_shape=(101,))) model.add(keras.layers.Dense(101, activation=keras.activations.linear)) model.add(keras.layers.Dense(101)) optimizer = keras.optimizers.RMSprop(0.00001) model.compile(loss=loss, optimizer=optimizer, metrics=['mae', 'accuracy']) return model
我这样训练它:
EPOCHS=400early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)model = build_model()history = model.fit(x, y, epochs=EPOCHS, validation_split=0.2, verbose=1, sample_weight=weights, callbacks=[early_stop])
其中weights
是一个形状为(9171,)
的数组,而x
和y
的形状各为(9171,101)
。
如果我移除sample_weight
参数,网络可以运行。但是在使用它时,我得到了以下错误消息:
Epoch 1/400Traceback (most recent call last): File "nnotest.py", line 153, in <module> history = model.fit(x, y, epochs=EPOCHS, validation_split=0.2, verbose=1, sample_weight=weights, callbacks=[early_stop]) File "/home/star2/hgc4/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 780, in fit steps_name='steps_per_epoch') File "/home/star2/hgc4/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py", line 363, in model_iteration batch_outs = f(ins_batch) File "/home/star2/hgc4/.local/lib/python3.6/site-packages/tensorflow/python/keras/backend.py", line 3292, in __call__ run_metadata=self.run_metadata) File "/home/star2/hgc4/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1458, in __call__ run_metadata_ptr)tensorflow.python.framework.errors_impl.InvalidArgumentError: Can not squeeze dim[0], expected a dimension of 1, got 32 [[{{node loss_1/dense_8_loss/weighted_loss/Squeeze}}]]
我对为什么会这样有些想法。我明白它可能试图将我的1D数组解析成默认的批量大小32,但我无法理解为什么。从阅读文档来看,似乎可以添加一个1D数组来构成从权重到训练数据的1D映射,所以这应该是容易的?我错过了什么?
回答:
因为你的损失函数没有考虑到样本。你得到的是一个全局均值。
如果您想要的是均方误差,请使用loss='mse'
进行编译。
如果是其他情况,不要压缩批次维度(axis=0):
def loss(true, pred): return keras.backend.mean(keras.backend.square(true-pred), axis=-1)