如何提高自编码器的准确性?

dav*_*vid 2 python keras tensorflow

我有一个自动编码器,我使用不同的解决方案检查了模型的准确性,例如更改 conv 层的数量并增加它们,添加或删除批量标准化,更改激活函数,但所有这些的准确性是相似的,但没有有任何奇怪的改进。我很困惑,因为我认为这些不同解决方案的准确度应该不同,但它是 0.8156。你能帮我解决什么问题吗?我也用 10000 个 epoch 训练它,但是 50 个 epoch 的输出是一样的!我的代码是错误的还是不能变得更好?! 精度图

我也不确定学习率衰减是否有效?!我也把我的代码放在这里:

from keras.layers import Input, Concatenate, GaussianNoise,Dropout,BatchNormalization
from keras.layers import Conv2D
from keras.models import Model
from keras.datasets import mnist,cifar10
from keras.callbacks import TensorBoard
from keras import backend as K
from keras import layers
import matplotlib.pyplot as plt
import tensorflow as tf
import keras as Kr
from keras.callbacks import ReduceLROnPlateau
from keras.callbacks import EarlyStopping
import numpy as np
import pylab as pl
import matplotlib.cm as cm
import keract
from matplotlib import pyplot
from keras import optimizers
from keras import regularizers
from tensorflow.python.keras.layers import Lambda;

image = Input((28, 28, 1))
conv1 = Conv2D(16, (3, 3), activation='elu', padding='same', name='convl1e')(image)
conv2 = Conv2D(32, (3, 3), activation='elu', padding='same', name='convl2e')(conv1)
conv3 = Conv2D(16, (3, 3), activation='elu', padding='same', name='convl3e')(conv2)
#conv3 = Conv2D(8, (3, 3), activation='relu', padding='same', name='convl3e', kernel_initializer='Orthogonal',bias_initializer='glorot_uniform')(conv2)
BN=BatchNormalization()(conv3)
#DrO1=Dropout(0.25,name='Dro1')(conv3)
DrO1=Dropout(0.25,name='Dro1')(BN)
encoded =  Conv2D(1, (3, 3), activation='elu', padding='same',name='encoded_I')(DrO1)



#-----------------------decoder------------------------------------------------
#------------------------------------------------------------------------------
deconv1 = Conv2D(16, (3, 3), activation='elu', padding='same', name='convl1d')(encoded)
deconv2 = Conv2D(32, (3, 3), activation='elu', padding='same', name='convl2d')(deconv1)
deconv3 = Conv2D(16, (3, 3), activation='elu',padding='same', name='convl3d')(deconv2)
BNd=BatchNormalization()(deconv3)
DrO2=Dropout(0.25,name='DrO2')(BNd)
#DrO2=Dropout(0.5,name='DrO2')(deconv3)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same', name='decoder_output')(DrO2) 
#model=Model(inputs=[image,wtm],outputs=decoded)

#--------------------------------adding noise----------------------------------
#decoded_noise = GaussianNoise(0.5)(decoded)


watermark_extraction=Model(inputs=image,outputs=decoded)

watermark_extraction.summary()
#----------------------training the model--------------------------------------
#------------------------------------------------------------------------------
#----------------------Data preparation----------------------------------------

(x_train, _), (x_test, _) = mnist.load_data()
x_validation=x_train[1:10000,:,:]
x_train=x_train[10001:60000,:,:]
#(x_train, _), (x_test, _) = cifar10.load_data()
#x_validation=x_train[1:10000,:,:]
#x_train=x_train[10001:60000,:,:]
#
x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_validation = x_validation.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))  # adapt this if using `channels_first` image data format
x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))  # adapt this if using `channels_first` image data format
x_validation = np.reshape(x_validation, (len(x_validation), 28, 28, 1))

#---------------------compile and train the model------------------------------
# is accuracy sensible metric for this model?
learning_rate = 0.1
decay_rate = learning_rate / 50
opt = optimizers.SGD(lr=learning_rate, momentum=0.9, decay=decay_rate, nesterov=False)

watermark_extraction.compile(optimizer=opt, loss=['mse'], metrics=['accuracy'])
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=20)
#rlrp = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, min_delta=1E-7, verbose=1)
history=watermark_extraction.fit(x_train, x_train,
          epochs=50,
          batch_size=32, 
          validation_data=(x_validation, x_validation),
          callbacks=[TensorBoard(log_dir='E:/output of tensorboard', histogram_freq=0, write_graph=False),es])
watermark_extraction.summary()
#--------------------visuallize the output layers------------------------------
#_, train_acc = watermark_extraction.evaluate(x_train, x_train)
#_, test_acc = watermark_extraction.evaluate([x_test[5000:5001],wt_expand], [x_test[5000:5001],wt_expand])
#print('Train: %.3f, Test: %.3f' % (train_acc, test_acc))
## plot loss learning curves
pyplot.subplot(211)
pyplot.title('MSE Loss', pad=-40)
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='validation')
pyplot.legend()

pyplot.subplot(212)
pyplot.title('Accuracy', pad=-40)
pyplot.plot(history.history['acc'], label='train')
pyplot.plot(history.history['val_acc'], label='test')
pyplot.legend()
pyplot.show
Run Code Online (Sandbox Code Playgroud)

ana*_*ngh 7

既然你说你是一个初学者,我将尝试从下往上构建,并尽可能地用这种解释来约束你的代码。

第 1 部分自动编码器由两部分(编码器和解码器)组成。自编码器减少了存储信息所需的变量数量,而解码器尝试从压缩形式中取回这些信息。(请注意,由于其不确定性和数据相关性,在实际数据压缩任务中不使用自动编码器)。

现在在你的代码中你保持padding不变。

conv1 = Conv2D(16, (3, 3), activation='elu', padding='same', name='convl1e')(image)

这基本上消除了自动编码器的压缩和扩展功能,即在每个步骤中,您都使用相同数量的变量来表示信息。

第 2 部分现在继续训练算法

history=watermark_extraction.fit(x_train, x_train,
          epochs=50,
          batch_size=32, 
          validation_data=(x_validation, x_validation),
          callbacks=[TensorBoard(log_dir='E:/PhD/thesis/deepwatermark/journal code/autoencoder_watermark/11-2-2019/output of tensorboard', histogram_freq=0, write_graph=False),es])
Run Code Online (Sandbox Code Playgroud)

从这个表达式/语句/代码行我得出的结论是,您想要生成与您在代码中放置的相同的图像,现在由于图像存储在相同数量的变量中,您的模型只需要传递相同的图像到每个步骤而不更改图像中的任何内容,这会激励您的模型将每个过滤器参数优化为 1。

第 3 部分现在是棺材中最大的钉子,你已经实现了一个 dropout 层,首先你应该永远不要在卷积层中实现 dropout。此链接解释了原因并讨论了我认为如果您是初学者应该查看的各种想法。现在让我们看看为什么你使用 Dropout 的方式真的很糟糕。如前所述,最适合您的模型的是过滤器中学习值 1 的所有参数。现在这里发生的情况是您已强制关闭其中一些过滤器,这除了关闭所讨论的某些过滤器之外什么也不做在文章中,所有这些都是降低下一层图像的强度。(因为 CNN 过滤器对所有输入通道取平均值)

DrO2=Dropout(0.25,name='DrO2')(BNd)
Run Code Online (Sandbox Code Playgroud)

第 4 部分这只是一点建议,不会成为任何问题的根源 BNd=BatchNormalization()(deconv3)

在这里,您已经尝试对批量数据进行标准化,在大多数情况下,数据标准化非常重要,因为您可能知道它不会让一个特征决定模型,每个特征在模型中都得到同等的发言权,但在图像数据中每个点都已经在 0 到 255 之间进行了缩放,因此使用归一化将其缩放到 0 到 1 之间不会增加任何值,只会为模型增加不必要的计算。

我建议您逐部分理解,如果有不清楚的地方,请在下面评论,尽量不要使用 CNN(它们没有任何实际应用)来说明自动编码器,而是使用它来理解 ConvNets 的各种复杂性( CNN),我之所以选择写这样的答案来解释您的网络的一部分而不是代码是因为您正在寻找的代码只是谷歌搜索,如果您对这个答案感兴趣并且想要确切了解 CNN 的工作方式,请查看https://www.youtube.com/watch?v=ArPaAX_PhIs&list=PLkDaE6sCZn6Gl29AoE31iwdVwSG-KnDzF,如果您对此答案有任何疑问,甚至对下面的视频评论有任何疑问。