tensorflow - 高损失的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很低。
解决方案
您的代码几乎没有问题。我将尝试在下面详细说明所有这些。
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,并将其放在密集层之后或之间。
推荐阅读
- c# - 将存档文件中的 Stream 转换为 Byte[]
- python - 从 selenium 中,如何通过 id 查找值?
- android - 我必须安装 Android SDK 才能开发 Android 应用程序吗?
- node.js - 使用贝宝安全付款
- java - Java 命名文件
- xml - 为路径组合变量
- ios - 有没有办法在 Windows 上构建 IOS 应用程序?
- wpf - WPF 覆盖 TabControl 的选项卡内容对齐方式
- android - 为什么这段代码只在 9.0 Pie 上崩溃?
- wordpress - 我可以在 wordpress 的自定义链接菜单上添加 onClick() 事件吗?