【问题标题】:Loss and accuracy don't change during the training phase损失和准确性在训练阶段不会改变
【发布时间】:2018-09-23 04:38:57
【问题描述】:

我建立了一个模型来对灰度图像进行着色,在训练阶段,我向网络提供了 100 张森林的 RGB 图像,然后我将图像转换为 LAB 颜色空间以将训练集拆分为 L 和 AB, 基于训练好的 AB 数据,模型将在测试阶段为灰度输入图像预测这两个通道。 现在我遇到了一个问题,我用不同的架构训练模型,而不是用 10 幅图像,损失降低到 0.0035 并且效果很好,为此,我想增加数据集的大小以获得更好的结果,但是作为交换,损失和准确率保持不变,模型输出一团糟, 我的代码如下,我希望任何人都可以指导我做错了什么,是因为优化器吗?损失函数?批量大小?或者其他我不知道的事情, 提前谢谢你。

# Import images
MODEL_NAME = 'forest'

X = []
Y = []
for filename in os.listdir('forest/'):
    if (filename != '.DS_Store'):
        image = img_to_array(load_img("/Users/moos/Desktop/Project-Master/forest/" + filename))
        image = np.array(image, dtype=float)
        imL = rgb2lab(1.0 / 255 * image)[:, :,0]
        X.append(imL)
        imAB = rgb2lab(1.0 / 255 * image)[:, :,1:]
        imAB = imAB/128
        Y.append(imAB)

X = np.array(X)
Y = np.array(Y)

X = X.reshape(1, 256 , np.size(X)/256, 1)
Y = Y.reshape(1, 256, np.size(Y)/256/2, 2)

# Building the neural network
model = Sequential()
model.add(InputLayer(input_shape=(256, np.size(X)/256, 1)))
model.add(Conv2D(8, (3, 3), activation='relu', padding='same', strides=2))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', strides=2))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same', strides=1))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same', strides=1))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', strides=1))
model.add(UpSampling2D((2, 2)))
model.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(8, (3, 3), activation='relu', padding='same'))
model.add(UpSampling2D((2, 2)))
model.add(Conv2D(2, (3, 3), activation='relu', padding='same'))
model.add(Conv2D(2, (3, 3), activation='tanh', padding='same'))
model.add(UpSampling2D((2, 2)))

# Finish model
model.compile(optimizer='rmsprop',loss='mse', metrics=['acc'])

#Train the neural network
model.fit(x=X, y=Y, batch_size=100, epochs=1000)
print(model.evaluate(X, Y, batch_size=100))

输出

Epoch 1/1000 1/1 [==============================] - 7s 7s/step - loss: 0.0214 - 累积:0.4987 纪元 2/1000 1/1 [===============================] - 7s 7s/step - loss: 0.0214 - acc : 0.4987 纪元 3/1000 1/1 [===============================] - 9s 9s/step - loss: 0.0214 - acc : 0.4987 纪元 4/1000 1/1 [===============================] - 8s 8s/step - loss: 0.0214 - acc : 0.4987 。 . . .

【问题讨论】:

    标签: tensorflow deep-learning keras loss-function


    【解决方案1】:

    首先,我简化了图像加载代码,并且分别对所有通道(L、A、B)进行了归一化(减去均值,除以标准差),还重命名了变量,这通常很有帮助。 (5 minute free Coursera video about normalizing inputs (will bug you to subscribe but just click that away.).) 所以加载部分现在看起来像这样:

    # Import images
    MODEL_NAME = 'forest'
    
    imgLABs = []
    for filename in os.listdir('./forest/'):
        if (filename != '.DS_Store'):
            image = img_to_array( load_img("./forest/" + filename) )
            imgLABs.append( rgb2lab( image / 255.0 ) )
    
    imgLABs_arr = np.array( imgLABs )
    
    L, A, B = imgLABs_arr[ :, :, :, 0 : 1 ], imgLABs_arr[ :, :, :, 1 : 2 ], imgLABs_arr[ :, :, :, 2 : 3 ]
    
    L_mean, L_std = np.mean( L ), np.std( L )
    A_mean, A_std = np.mean( A ), np.std( A )
    B_mean, B_std = np.mean( B ), np.std( B )
    L, A, B = ( L - L_mean ) / L_std, ( A - A_mean ) / A_std, ( B - B_mean ) / B_std
    AB = np.concatenate( ( A, B ), axis = 3)
    

    还改变了模型,增加了更多的特征深度和一些最大池层(不要忘记将它们包含在导入中,未显示)。请注意,最后几层的激活函数设置为 None 以允许负值,因为我们期望得到标准化结果:

    # Building the neural network
    model = Sequential()
    model.add(InputLayer( input_shape = L.shape[ 1: ] ) )
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2,
                     kernel_initializer='truncated_normal'))
    model.add(MaxPooling2D( (3, 3), strides = 1, padding='same' ) )
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same',
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2,
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1,
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=2,
                     kernel_initializer='truncated_normal'))
    model.add(MaxPooling2D( (3, 3), strides = 1, padding='same' ) )
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1,
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1,
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1,
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(64, (3, 3), activation='relu', padding='same', strides=1,
                     kernel_initializer='truncated_normal'))
    model.add(UpSampling2D((2, 2)))
    model.add(Conv2D(32, (3, 3), activation='relu', padding='same',
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(32, (3, 3), activation='relu', padding='same',
                     kernel_initializer='truncated_normal'))
    model.add(UpSampling2D((2, 2)))
    model.add(Conv2D(32, (3, 3), activation=None, padding='same',
                     kernel_initializer='truncated_normal'))
    model.add(Conv2D(2, (3, 3), activation=None, padding='same',
                     kernel_initializer='truncated_normal'))
    model.add(UpSampling2D((2, 2)))
    
    # Finish model
    optimizer = optimizers.RMSprop( lr = 0.0005, decay = 1e-5 )
    model.compile( optimizer=optimizer, loss='mse', metrics=['acc'] )
    
    #Train the neural network
    model.fit( x=L, y=AB, batch_size=1, epochs=1800 )
    model.save("forest-model-v2.h5")
    

    注意 0.0005 的学习率,我已经尝试了一些值,这看起来最好。然后学习率衰减可以在训练后期提供帮助,随着我们的进行降低学习率。此外,我已将 batch_size 更改为 1 - 这是非常特定于此网络,通常不推荐使用。但是在这里你主要有直接卷积,所以在每个样本之后更新内核是有意义的,因为每个样本本身都会影响每个像素的权重。但是如果你改变架构,那么这可能不再有意义,你应该改变批量大小。我还将 epoch 增加到 1,800,因为它在我的机器上运行得相当快,而且我有时间运行它。但它达到了大约 1,000 的最大值。

    综上所述,这是训练的输出(仅第一行和最后几行):

    纪元 1/1800
    100/100 [===============================] - 6s 63ms/步 - 损失:1.0554 - acc: 0.5217
    纪元 2/1800
    100/100 [===============================] - 1s 13ms/步 - 损失:1.1097 - acc: 0.5703
    ...
    1000/1800 纪元
    100/100 [===============================] - 1s 13ms/step - 损失:0.0533 - acc: 0.9338
    ...
    1800/1800 纪元
    100/100 [===============================] - 1s 13ms/step - loss: 0.0404 - acc: 0.9422

    为了打印重新着色的图像,我使用了以下代码,请注意 5 只是我从 100 中挑选的图像的任意索引;我们还需要添加 L、A 和 B 的均值和标准差(当您想将这六个数字用于实际重新着色时,您必须将这六个数字视为网络的一部分 - 您需要使用 L_std 预处理输入, L_mean,然后用A、B均值和std-s对输出进行后处理):

    predicted = model.predict( x = L[ 5 : 6 ], batch_size = 1, verbose = 1 )
    plt.imshow( lab2rgb( np.concatenate(
        ( ( L[ 5 ] * L_std ) + L_mean,
         ( predicted[ 0, :, :, 0 : 1 ] * A_std ) + A_mean,
         ( predicted[ 0, :, :, 1 : 2 ] * B_std ) + B_mean),
        axis = 2 ) ) )
    
    img_pred = lab2rgb( np.concatenate(
        ( ( L[ 5 ] * L_std ) + L_mean,
         ( predicted[ 0, :, :, 0 : 1 ] * A_std ) + A_mean,
         ( predicted[ 0, :, :, 1 : 2 ] * B_std ) + B_mean),
        axis = 2 ) ) 
    img_orig = lab2rgb( np.concatenate(
        ( ( L[ 5 ] * L_std ) + L_mean,
          ( A[ 5 ] * A_std ) + A_mean,
          ( B[ 5 ] * B_std ) + B_mean ),
        axis = 2 ) ) 
    diff = img_orig - img_pred
    plt.imshow( diff * 10 )
    

    所有图像都是(原始;灰度网络输入;网络输出(颜色恢复);原始和恢复之间的差异):

    相当整洁! :) 主要是关于山上的一些细节,只是丢失了。由于它只有 100 个训练图像,但它可能会严重过度拟合。不过,我希望这能给您一个好的开始!

    【讨论】:

    • 谢谢你提到上面的错误,我打错了,但我再次运行它仍然得到相同的输出。
    • 在我的答案中添加了更多候选错误
    • 去掉 9 号指令似乎可以减少损失,但我还是保持原样,但是,它的减少速度非常缓慢。
    • 他们有什么建议可以提高损失减少率吗?
    • 我已将其更改为 '0.005' 和 '0.01' 并以更高的值返回恒定值。会不会是网络架构导致了这些输出?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多