Tensorflow 损失和准确度don';在训练阶段不要改变

Tensorflow 损失和准确度don';在训练阶段不要改变,tensorflow,deep-learning,keras,loss-function,Tensorflow,Deep Learning,Keras,Loss Function,我建立了一个模型,对灰度图像进行着色,在训练阶段,我将100张森林的RGB图像送入网络,然后将图像转换到实验室颜色空间,将训练集拆分为L和AB, 基于训练的AB数据,该模型将在测试阶段预测灰度输入图像的这两个通道。 现在我遇到了一个问题,我用不同的架构训练了一个模型,这个架构有10个图像,损失减少到0.0035,效果很好,为此,我想增加数据集的大小以获得更好的结果,但作为交换,损失和准确度保持不变,模型输出混乱, 我的代码如下,我希望任何人都能告诉我我做错了什么,是因为优化器吗?损失函数?批量大

我建立了一个模型,对灰度图像进行着色,在训练阶段,我将100张森林的RGB图像送入网络,然后将图像转换到实验室颜色空间,将训练集拆分为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))
输出 纪元1/1000 1/1[==================================================================-7s/s/步长-损耗:0.0214-附件:0.4987 Epoch 2/1000 1/1[================================================]-7s/s阶跃-损耗:0.0214-acc: 0.4987 纪元3/1000 1/1[======================================================-9s/step-损耗:0.0214-附件:0.4987 纪元4/1000 1/1[=============================================]-8s/step-损耗:0.0214-acc:
0.4987 . . . .

首先,我简化了图像加载代码,还分别对所有通道(L、A、B)进行了归一化(减去平均值,除以标准偏差),还重命名了变量,这通常会有很大帮助。()因此加载部分现在看起来如下所示:

# 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,我已经用一些值进行了实验,这看起来是最好的。然后,学习率衰减可以帮助以后的训练,随着训练的进行,学习率会降低。此外,我已将批处理大小更改为1-这是非常特定于此网络的,通常不推荐使用。但是这里大部分是直接卷积,所以在每个示例之后更新内核是有意义的,因为每个示例本身都会影响每个像素的权重。但是如果您更改了体系结构,那么这可能就没有意义了,您应该重新更改批处理大小。我还将历代数增加到1800,因为它在我的机器上运行得相当快,我有时间运行它。不过,它在1000左右达到了最大值

所有这些,下面是培训的输出(仅第一行和最后几行):

纪元1/1800
100/100[===============================================================-6s 63ms/步-损耗:1.0554-附件:0.5217
纪元2/1800
100/100[======================================================]1s 13ms/步-损耗:1.1097-acc:0.5703

纪元1000/1800
100/100[===================================================]1s 13ms/步-损耗:0.0533-附件:0.9338

纪元1800/1800
100/100[=============================================]1s 13ms/步-损耗:0.0404-附件:0.9422

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

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


非常整洁!:)主要是山上的一些细节,只是丢失了一些。由于它只有100张训练图像,所以它可能被严重地过度拟合了。不过,我希望这能给你一个好的开始

谢谢你提到上面的错误,我打错了,但是我再次运行了它,仍然得到了相同的输出。在我的回答中添加了更多的bug候选者删除9号指令似乎使损失减少了,尽管如此,我还是保持了原样,它的下降速度非常慢。他们有什么建议来提高损失下降率吗?我已经将它改为“0.005”和“0.01”,并且它以更高的值返回常量。是否是网络架构导致了这些输出?
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 )