如何提高自动编码器的精度?

时间:2019-02-12 04:56:54

标签: python tensorflow keras

我有一个自动编码器,我用不同的解决方案来检查模型的准确性,例如更改conv层的数量并增加它们,添加或删除“批处理归一化”,更改激活函数,但是所有这些模型的准确性都是相似的,并且它没有任何奇怪的改进。我很困惑,因为我认为这些不同解决方案的准确性应该有所不同,但是为0.8156。您能帮我什么问题吗?我也用10000个时间段训练它,但是50个时间段的输出是相同的!我的代码是错误的还是不能变得更好? the accuracy graph

我还不确定学习率是否会下降?! 我也将代码放在这里:

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

1 个答案:

答案 0 :(得分:1)

由于您说过您是一个初学者,所以我将尝试从头开始构建代码,并尝试在代码中尽可能多地附上说明。

第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])

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

第3部分现在,棺材中最大的钉子已经到来,您已经实现了一个dropout层,首先您应该从不在卷积层中实现dropout。 This Link explains why and It discusses various ideas that I think if you are a beginner you should check out.现在,让我们看看为什么使用Dropout的方式真的很糟糕。正如已经说明的那样,最适合您的模型的是过滤器中学习值1的所有参数。现在发生的是,您已迫使其中一些过滤器关闭,除了关闭某些过滤器外,无所作为在这篇文章中,所有要做的就是降低下一层的图像强度。(因为CNN滤镜在所有输入通道上取平均值)

DrO2=Dropout(0.25,name='DrO2')(BNd)

第4部分,这只是一些建议,不会引起任何问题 BNd=BatchNormalization()(deconv3)

在这里,您试图对批处理中的数据进行规范化,在大多数情况下,数据规范化非常重要,因为您可能知道它不会让一个功能决定模型,而每个功能在模型中都有同等的发言权,但是在图像数据中,每个点已经在0到255之间缩放,因此使用归一化在0到1之间缩放不会增加任何值,只会给模型增加不必要的计算。

我建议您先进行部分理解,如果有不清楚的地方,请在下面发表评论,尽量不要对使用CNN的自动编码器有所了解(它们始终没有任何实际的应用程序),而应该使用它来理解各种复杂性之所以选择ConvNets(CNN),是因为我选择写这样的答案来解释您的网络的某些部分,而不是代码,是因为您要查找的代码只是Google搜索而已,如果您对此答案很感兴趣并想知道CNN的工作原理,请查看https://www.youtube.com/watch?v=ArPaAX_PhIs&list=PLkDaE6sCZn6Gl29AoE31iwdVwSG-KnDzF,如果您对此疑问有任何疑问,甚至对下面的视频评论有任何疑问。