首页 > 解决方案 > 高损失的keras模型

问题描述

我已经创建了一个Nvidia自动驾驶汽车的Keras模型。 https://arxiv.org/pdf/1604.07316.pdf 但是有一个问题,损失非常高,精度为0。

这是我使用的 45000 张图像的图像数据集。

我裁剪图像的大小。

def LoadTrain(batch_size):
global train_batch_pointer
x_out=[]
y_out=[]
for i in range(0, batch_size):
    Image.open(train_xs[(train_batch_pointer + i) % num_train_images])
    # reading width, height
    width, height = im.size
    left, top, right, bottom = 150,height/2, width, height
    im_new = im.crop((left, top, right, bottom))
    img_arr = np.array(im_new)
    x_out.append(img_arr)
    y_out.append([(train_batch_pointer + i) % num_train_images])
return x_out, y_out

X_train, y_train = LoadTrain(len(train_xs))
X_test, y_test = LoadTrain(len(val_xs))


X_train_new = asarray(X_train, dtype=np.float32)
X_test_new = asarray(X_test, dtype=np.float32)
y_train_new = asarray(y_train, dtype=np.float32)
y_test_new = asarray(y_test, dtype=np.float32)

模型

def keras_model(input_data):
model = Sequential()
model.add(Lambda(lambda x: x/255., input_shape=input_data))
model.add(BatchNormalization())
model.add(Conv2D(24, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(36, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(48, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(64,(3,3), activation='relu', strides=(1, 1)))
model.add(Conv2D(64,(3,3), activation='relu', strides=(1, 1)))

model.add(Flatten())
model.add(Dropout(0.3))
model.add(Dense(1164, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='relu'))
return model

模型调用

model = keras_model(X_train_new[0].shape)
keras.utils.plot_model(model, 'generator.png', show_shapes=True)


Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lambda (Lambda)              (None, 128, 305, 3)       0         
_________________________________________________________________
batch_normalization (BatchNo (None, 128, 305, 3)       12        
_________________________________________________________________
conv2d (Conv2D)              (None, 62, 151, 24)       1824      
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 29, 74, 36)        21636     
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 13, 35, 48)        43248     
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 11, 33, 64)        27712     
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 9, 31, 64)         36928     
_________________________________________________________________
flatten (Flatten)            (None, 17856)             0         
_________________________________________________________________
dropout (Dropout)            (None, 17856)             0         
_________________________________________________________________
dense (Dense)                (None, 1164)              20785548  
_________________________________________________________________
dense_1 (Dense)              (None, 100)               116500    
_________________________________________________________________
dense_2 (Dense)              (None, 50)                5050      
_________________________________________________________________
dense_3 (Dense)              (None, 10)                510       
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 11        
=================================================================
Total params: 21,038,979
Trainable params: 21,038,973
Non-trainable params: 6
_________________________________________________________________
None

在此处输入图像描述

编译

adam = Adam(learning_rate=0.0001)
model.compile(optimizer=adam, loss='mean_squared_error', metrics=['Accuracy'])

合身

model.fit(X_train_new, y_train_new, epochs=10, batch_size=64, verbose=1, validation_data=. 
(X_test_new, y_test_new), callbacks = callback) 

输出

Epoch 1/30

568/568 [===============================] 3762s 7s/步 - 损耗:195265259.8383 - 精度:0.0000e+00 - val_loss:148408736.0000 - val_accuracy:0.0000e+00

Epoch 2/30

568/568 [===============================] - 2313s 4s/步 - 损耗:111066534.5659 - 精度:0.0000e+ 00 - val_loss:197166144.0000 - val_accuracy:0.0000e+00

不知道为什么损失这么大。

解决方案 PIL有一个问题,为什么loss很高。我用cv2调整图片大小,loss很低。

标签: tensorflowkerasdeep-learningconv-neural-network

解决方案


您的代码几乎没有问题。我将尝试在下面详细说明所有这些。

TLDR;删除最后一个relu,添加 maxpooling2d 并使用 1164 减少密集层的神经元,因为它花费了模型中所有训练权重的 99.16%,这是一个主要瓶颈。

注意:正如您所评论的,我使用的输入形状是 (160,305,3) -

1.输出激活不正确

由于您正在处理具有任意输出的单输出回归问题,因此您不想使用 arelu而是希望在最后一层没有任何激活。Arelu只会返回大于 0 的连续任意值,而不是任意输出范围。

检查此表以获得关于在输出激活时如何处理不同问题类型的良好参考。

在此处输入图像描述

2. Metric 定义不正确

如果你在做一个回归问题,那么你就不会使用准确度作为衡量标准,因为那是为了计算分类的准确度。相反,您将使用mse它自己或mean absolute error代替此类问题。


旁注:如果您正在处理分类问题,您会使用accuracy而不是Accuracy.

TENSORFLOW2 没有抛出错误而只输出 0.00 精度的原因是我之前在 StackOverflow 上识别、跟踪和解决的 TENSORFLOW 2 错误

检查此 SO 帖子:神经网络精度始终为 0

我在 tensorflow2 源代码中详细跟踪了该错误,并提出了一个错误报告并提出了一个拉取请求来修复它,我正在等待回复。如果有兴趣,请检查我对为什么会发生这种情况的解释。


修复了这些问题的更新代码应类似于以下内容 -

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Lambda, BatchNormalization, Conv2D, Flatten, Dropout
from tensorflow.keras.optimizers import Adam

input_dim = (160,305,3)

model = Sequential()
model.add(Lambda(lambda x: x/255., input_shape=input_dim))
model.add(BatchNormalization())
model.add(Conv2D(24, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(36, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(48, (5,5), activation='relu', strides=(2, 2)))
model.add(Conv2D(64,(3,3), activation='relu', strides=(1, 1)))
model.add(Conv2D(64,(3,3), activation='relu', strides=(1, 1)))

model.add(Flatten())
model.add(Dropout(0.3))
model.add(Dense(1164, activation='relu'))
model.add(Dense(100, activation='relu'))
model.add(Dense(50, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1))

adam = Adam(learning_rate=0.0001)
model.compile(optimizer=adam, loss='mse')

model.summary()
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lambda_6 (Lambda)            (None, 160, 305, 3)       0         
_________________________________________________________________
batch_normalization_6 (Batch (None, 160, 305, 3)       12        
_________________________________________________________________
conv2d_30 (Conv2D)           (None, 78, 151, 24)       1824      
_________________________________________________________________
conv2d_31 (Conv2D)           (None, 37, 74, 36)        21636     
_________________________________________________________________
conv2d_32 (Conv2D)           (None, 17, 35, 48)        43248     
_________________________________________________________________
conv2d_33 (Conv2D)           (None, 15, 33, 64)        27712     
_________________________________________________________________
conv2d_34 (Conv2D)           (None, 13, 31, 64)        36928     
_________________________________________________________________
flatten_6 (Flatten)          (None, 25792)             0         
_________________________________________________________________
dropout_6 (Dropout)          (None, 25792)             0         
_________________________________________________________________
dense_30 (Dense)             (None, 1164)              30023052  
_________________________________________________________________
dense_31 (Dense)             (None, 100)               116500    
_________________________________________________________________
dense_32 (Dense)             (None, 50)                5050      
_________________________________________________________________
dense_33 (Dense)             (None, 10)                510       
_________________________________________________________________
dense_34 (Dense)             (None, 1)                 11        
=================================================================
Total params: 30,276,483
Trainable params: 30,276,477
Non-trainable params: 6
_________________________________________________________________

3. 其他补充

我建议您尝试更多更改 -

  • 在展平层之后你有一个很大的瓶颈。这一层占(30,023,052 / 30,276,477)模型中所有训练参数的 99.16%。你可能想减少它。您最好的选择是在每个 conv2d 层之后添加您错过的 maxpooling2d 层。您也可以减少该层的密集神经元(1164 是非常多的神经元,尤其是当您突然下降到 100 时)。
  • 有了这么多 Dense 层,您可以减少神经元的数量或减少最初的层数,以查看模型的性能。我建议将 dropout 增加到 0.5,并将其放在密集层之后或之间。

推荐阅读