自动编码的二进制激活函数

2024-04-19 08:17:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个自动编码器,有两个输出(解码,pred,w),一个输出是重建的输入图像,另一个是重建的二进制图像。我在最后一层使用了sigmoid激活函数,但输出是浮点数,我需要网络标签每个像素为0或1。我把我的代码附在这里。你能告诉我怎么解决这个问题吗? 谢谢。在

from keras.layers import Input, Concatenate, GaussianNoise,Dropout
from keras.layers import Conv2D
from keras.models import Model
from keras.datasets import mnist
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
import numpy as np
import pylab as pl
import matplotlib.cm as cm
import keract
from tensorflow.python.keras.layers import Lambda;

#-----------------building w train---------------------------------------------
w_main = np.random.randint(2,size=(1,4,4,1))
w_main=w_main.astype(np.float32)
w_expand=np.zeros((1,28,28,1),dtype='float32')
w_expand[:,0:4,0:4]=w_main
w_expand.reshape(1,28,28,1)
w_expand=np.repeat(w_expand,49999,0)

#-----------------building w validation---------------------------------------------
w_valid = np.random.randint(2,size=(1,4,4,1))
w_valid=w_valid.astype(np.float32)
wv_expand=np.zeros((1,28,28,1),dtype='float32')
wv_expand[:,0:4,0:4]=w_valid
wv_expand.reshape(1,28,28,1)
wv_expand=np.repeat(wv_expand,9999,0)

#-----------------building w test---------------------------------------------
w_test = np.random.randint(2,size=(1,4,4,1))
w_test=w_test.astype(np.float32)
wt_expand=np.zeros((1,28,28,1),dtype='float32')
wt_expand[:,0:4,0:4]=w_test
wt_expand.reshape(1,28,28,1)
#wt_expand=np.repeat(wt_expand,10000,0)

#-----------------------encoder------------------------------------------------
#------------------------------------------------------------------------------
wtm=Input((28,28,1))
image = Input((28, 28, 1))
conv1 = Conv2D(16, (3, 3), activation='relu', padding='same', name='convl1e')(image)
conv2 = Conv2D(32, (3, 3), activation='relu', padding='same', name='convl2e')(conv1)
conv3 = Conv2D(8, (3, 3), activation='relu', padding='same', name='convl3e')(conv2)
DrO1=Dropout(0.25)(conv3)
encoded =  Conv2D(1, (3, 3), activation='relu', padding='same',name='reconstructed_I')(DrO1)


#-----------------------adding w---------------------------------------
#add_const = Kr.layers.Lambda(lambda x: x + Kr.backend.constant(w_expand))
#encoded_merged=Kr.layers.Add()([encoded,wtm])

add_const = Kr.layers.Lambda(lambda x: x + wtm)
encoded_merged = add_const(encoded)
encoder=Model(inputs=image, outputs= encoded_merged)
encoder.summary()

#-----------------------decoder------------------------------------------------
#------------------------------------------------------------------------------

#encoded_merged = Input((28, 28, 2))
deconv1 = Conv2D(16, (3, 3), activation='relu', padding='same', name='convl1d')(encoded_merged)
deconv2 = Conv2D(32, (3, 3), activation='relu', padding='same', name='convl2d')(deconv1)
deconv3 = Conv2D(8, (3, 3), activation='relu',padding='same', name='convl3d')(deconv2)
DrO2=Dropout(0.25)(deconv3)
decoded = Conv2D(1, (3, 3), activation='relu', padding='same', name='decoder_output')(DrO2) 

#decoder=Model(inputs=encoded_merged, outputs=decoded)
#decoder.summary()
model=Model(inputs=image,outputs=decoded)
#----------------------w extraction------------------------------------
convw1 = Conv2D(16, (3,3), activation='relu', padding='same', name='conl1w')(decoded)
convw2 = Conv2D(32, (3, 3), activation='relu', padding='same', name='convl2w')(convw1)
convw3 = Conv2D(8, (3, 3), activation='relu', padding='same', name='conl3w')(convw2)
DrO3=Dropout(0.25)(convw3)
pred_w = Conv2D(1, (1, 1), activation='sigmoid', padding='same', name='reconstructed_W')(DrO3)  
# reconsider activation (is W positive?)
# should be filter=1 to match W
w_extraction=Model(inputs=[image,wtm],outputs=[decoded,pred_w])


#----------------------training the model--------------------------------------
#------------------------------------------------------------------------------
#----------------------Data preparesion----------------------------------------

(x_train, _), (x_test, _) = mnist.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?
w_extraction.compile(optimizer='adadelta', loss={'decoder_output':'mse','reconstructed_W':'mse'}, metrics=['mae'])
w_extraction.fit([x_train,w_expand], [x_train,w_expand],
          epochs=100,
          batch_size=128, 
          validation_data=([x_validation,wv_expand], [x_validation,wv_expand]),
          callbacks=[TensorBoard(log_dir='E:/tmp/AutewithW200', histogram_freq=0, write_graph=False)])
model.summary()

Tags: nametestimportnptrainactivationkerasvalidation
2条回答

如果您需要在模型中使用它,可以使用K.round()来自keras.backend。注意这是不可微的,也不能很好地用于培训。在

如果只需要结果,可以简单地定义一个阈值(通常为0.5),然后:

binary_reslts = results > threshold

向模型中添加指标

您可以通过添加围绕数据的度量来查看结果。 标准度量可以是"accuracy"或{}。您可以定义自己的指标,例如:

^{pr2}$

度量被添加到compile

model.compile(optimizer=..., loss=..., metrics = [diceMetric, 'categorical_accuracy'])

指标并不影响训练,它们只是让你知道发生了什么的反馈。在

为什么您需要网络精确地输出0或1?您可以将网络的输出解释为概率度量,即输入像素对应于类0或1的可能性。 因此,在训练过程中,模型试图逼近未知的概率分布。在

当涉及到预测时,可以使用像.5这样的阈值,也可以使用像otsu阈值这样的值。然后您将获得一个二进制输出。不幸的是,阈值会造成一些间隙或缩小一些预测形状的面积。在

注: 通常情况下,你需要在自动编码器中上下采样,否则模型会发现identity函数是最优的。在

相关问题 更多 >