“大家好
我目前正在研究一个关键点检测网络,目标是预测每个关键点的正确x和y值。我遇到了预测值的问题。我已经成功地规范化了数据,确保关键点的值落在0到1的范围内。为了验证我提供给模型的数据是否正确(包括验证、训练和测试集),我使用了函数sk.show_keypoint,它们正是我所期望的。
然而,我遇到了一个问题,网络预测的值超出了预期范围。例如,我得到的预测是
[[ 1.5571796 -1.5212063 -1.5553608 1.5570908 -1.5887384 1.5819738 1.5625474 -1.5526751 -1.5711758 1.5739774 1.5815413 1.5541165 -1.5574389 -1.8088359 -1.5553869 1.5725775 1.5559578 -1.5867838 1.5536412 1.61665 -1.5670778 -1.5944076 1.5860206 1.5846121 -1.5490519 1.5757351 -1.5185088 -1.5199621]]
字符串
,它们不在预期的0到1范围内。
我已经尝试了不同的学习率(LR),我目前使用的值是:
- 初始LR(lr_i)= 0.88
- 最终LR(lr_f)= 0.01
- 衰减因子(decay_f)= 39
尽管调整了LR,但问题仍然存在。我正在寻求您的帮助,了解为什么会发生这种情况,以及我如何解决它。
下面是我的代码片段以供参考:
from keras.applications import ResNet50
from tensorflow.data import TFRecordDataset
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, BatchNormalization
from tensorflow.keras.optimizers import Adam, schedules
from tensorflow.keras.callbacks import EarlyStopping , LearningRateScheduler
import glob
import math
import matplotlib.pyplot as plt
import os
import lib.deserialize_example_cnn as des
import lib.show_keypoints as sk
def main(lr_i,lr_f,decay_f,bst):
# parameters
fs= " lr_i:"+str(lr_i)+" lr_f:"+str(lr_f)+" decay_f:"+str(decay_f)+" bst:"+str(bst)
print(fs)
shape_image = 500
input_shape = (shape_image,shape_image,1)
num_classes = 28
files_out_names = "early_stopping_shuffle_low_low_lr"
dir_in = "C:/risorse/PDL/dataset_mini/"
model_path = "C:/risorse/PDL/"
num_epochs = 5
batch_size_training = bst
initial_learning_rate = lr_i
decay_step = num_epochs*batch_size_training*decay_f
end_learning_rate = lr_f
dir_in_training = dir_in + "training/"
dir_in_validation = dir_in + "validation/"
dir_in_testing = dir_in + "testing/"
# loading training dataset
#print("dir_in_training:"+dir_in_training)
filenames_train = glob.glob(dir_in_training + "*.tfrecord")
ds_bytes = TFRecordDataset(filenames_train)
dataset_training = ds_bytes.map(des.deserialize_example)
dataset_training = dataset_training.shuffle(5340, reshuffle_each_iteration=True) #5340 is the seed
# Visualizing training images
xi = 0
for image, label in dataset_training:
#print(label)
if sk.prob(1):
draw_label = sk.inversion(label)
sk.show_keypoints(image,draw_label,"cnn"+ str(xi)) #this is the function I've used to check the keypoint are correct
xi += 1
# loading validating dataset
filename_validate = glob.glob(dir_in_validation + "*.tfrecord")
ds_bytes = TFRecordDataset(filename_validate)
dataset_validation = ds_bytes.map(des.deserialize_example)
# batching data
dataset_training = dataset_training.batch(batch_size_training)
dataset_validation = dataset_validation.batch(1)
# Model definition
model = Sequential()
resnet_model = ResNet50(include_top=False, weights=None, input_shape=input_shape)
model.add(resnet_model)
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(num_classes))
lr = schedules.PolynomialDecay(
initial_learning_rate,
decay_step,
end_learning_rate
)
callback = EarlyStopping(monitor='val_loss',mode="min",patience=2,restore_best_weights=True)
lr_callback = LearningRateScheduler(verbose=1)
optimizer = Adam(learning_rate=lr)
# Compiling model
#model.compile(loss='mse',optimizer=Adam(learning_rate = initial_learning_rate))
model.compile(loss='mse',optimizer=optimizer)
# Fit model
print(fs)
history = model.fit(dataset_training, epochs=num_epochs, batch_size=batch_size_training,callbacks=[lr_callback , callback],validation_data = dataset_validation,use_multiprocessing=True)
model.save(model_path + "model_" + files_out_names + ".h5",save_format='h5')
# plot graph
x = []
y = []
for i in range(len(history.history['loss'])):
x.append(i)
y.append(history.history['loss'][i])
# loading test dataset
filename_test = glob.glob(dir_in_testing + "*.tfrecord")
ds_bytes = TFRecordDataset(filename_test)
dataset_test = ds_bytes.map(des.deserialize_example)
# batch dataset
dataset_test = dataset_test.batch(1)
# Evaluate model on test dataset
print("Evaluate on Test Dataset")
eval_loss = model.evaluate(dataset_test)
print("Evaluation loss:", eval_loss)
return eval_loss
型
我认为修改LR可以解决这个问题,但我得到的val_loss和test_loss的最佳值是4.26。我训练了5个epoch:
Epoch 1/5
700/700 [==============================] - 54s 69ms/step - loss: 298610458624.0000 - val_loss: 4.2689
Epoch 2/5
700/700 [==============================] - 48s 68ms/step - loss: 4.1115 - val_loss: 4.2684
Epoch 3/5
700/700 [==============================] - 49s 68ms/step - loss: 4.1110 - val_loss: 4.2678
Epoch 4/5
700/700 [==============================] - 49s 69ms/step - loss: 4.1102 - val_loss: 4.2667
Epoch 5/5
700/700 [==============================] - 49s 68ms/step - loss: 4.1089 - val_loss: 4.2652
型
1条答案
按热度按时间zfycwa2u1#
你有一个分类问题,所以donoforaiur建议
categorical crossentropy
作为损失函数是正确的。此外,您的最后一层没有激活功能:
字符串
您可以使用
softmax
激活函数在[0,1]中获得分类预测,如下所示:型
如果目标数据不是one-hot编码的,而是标签编码的,则可以使用
sparse_categorical_crossentropy
作为损失函数。如果你不想在最后一层使用softmax激活函数,你可以不激活它,在model.compile()中使用
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True)
。编辑:如果没有分类问题,并且您需要输出范围为(0,1),请使用
sigmoid
激活函数。请注意,0和1永远不会到达这里。这样做也不是很常见,通常你只是让网络弄清楚它,然后进行线性激活,就像你的例子一样。一般来说,如果没有激活函数,网络的输出范围就不受限制。使用正确的激活函数,可以限制输出值的范围。对于回归,你通常不希望这样做,但你可以尝试看看
sigmoid
是否适合你。也可能是一个问题,你试图让网络预测14个变量,其中14个是成对连接的(x和y坐标)。这可不少您可以尝试减少网络必须预测的点的数量。