2017-08-31 3 views
1

J'essaie de mettre en œuvre ce document dans Keras: https://arxiv.org/pdf/1603.09056.pdf qui utilise Conv-Deconv avec des connexions de saut pour créer un réseau de débruitage d'image. Mon réseau fonctionne plutôt bien si je fais des liaisons de saut symétriques entre les couches Conv-Deconv correspondantes mais si j'ajoute une connexion entre l'entrée et la sortie (comme dans le papier), mon réseau est impossible à former. Est-ce moi qui ne comprends pas le papier?La perte n'évolue pas lors de l'utilisation des connexions de saut

« Cependant, notre réseau apprend la corruption additif de l'entrée car il y a une connexion de saut entre l'entrée et la sortie du réseau »

Voici le réseau décrit dans le document:

enter image description here

Et voici mon réseau:

input_img = Input(shape=(None,None,3)) 

############################ 
####### CONVOLUTIONS ####### 
############################ 

c1 = Convolution2D(64, (3, 3))(input_img) 
a1 = Activation('relu')(c1) 

c2 = Convolution2D(64, (3, 3))(a1) 
a2 = Activation('relu')(c2) 

c3 = Convolution2D(64, (3, 3))(a2) 
a3 = Activation('relu')(c3) 

c4 = Convolution2D(64, (3, 3))(a3) 
a4 = Activation('relu')(c4) 

c5 = Convolution2D(64, (3, 3))(a4) 
a5 = Activation('relu')(c5) 

############################ 
###### DECONVOLUTIONS ###### 
############################ 

d1 = Conv2DTranspose(64, (3, 3))(a5) 
a6 = Activation('relu')(d1) 

m1 = add([a4, a6]) 
a7 = Activation('relu')(m1) 

d2 = Conv2DTranspose(64, (3, 3))(a7) 
a8 = Activation('relu')(d2) 

m2 = add([a3, a8]) 
a9 = Activation('relu')(m2) 

d3 = Conv2DTranspose(64, (3, 3))(a9) 
a10 = Activation('relu')(d3) 

m3 = add([a2, a10]) 
a11 = Activation('relu')(m3) 

d4 = Conv2DTranspose(64, (3, 3))(a11) 
a12 = Activation('relu')(d4) 

m4 = add([a1, a12]) 
a13 = Activation('relu')(m4) 

d5 = Conv2DTranspose(3, (3, 3))(a13) 
a14 = Activation('relu')(d5) 

m5 = add([input_img, a14]) # Everything goes well without this line 
out = Activation('relu')(m5) 

model = Model(input_img, out) 
model.compile(optimizer='adam', loss='mse') 

Si je le former, voici ce que je reçois:

Epoch 1/10 
31250/31257 [============================>.] - ETA: 0s - loss: 0.0015 
Current PSNR: 28.1152534485 

31257/31257 [==============================] - 89s - loss: 0.0015 - val_loss: 0.0015 
Epoch 2/10 
31250/31257 [============================>.] - ETA: 0s - loss: 0.0015 
Current PSNR: 28.1152534485 

31257/31257 [==============================] - 89s - loss: 0.0015 - val_loss: 0.0015 
Epoch 3/10 
31250/31257 [============================>.] - ETA: 0s - loss: 0.0015 
Current PSNR: 28.1152534485 

31257/31257 [==============================] - 89s - loss: 0.0015 - val_loss: 0.0015 
Epoch 4/10 
31250/31257 [============================>.] - ETA: 0s - loss: 0.0015 
Current PSNR: 28.1152534485 

31257/31257 [==============================] - 89s - loss: 0.0015 - val_loss: 0.0015 
Epoch 5/10 
31250/31257 [============================>.] - ETA: 0s - loss: 0.0015 
Current PSNR: 28.1152534485 

Quel est le problème avec mon réseau?

+0

Mais votre perte est assez faible. Pourquoi prétends-tu que ce n'est pas en train d'apprendre? –

+0

Parce que la perte n'évolue pas? Est-il pas censé être progressivement réduite au minimum? –

Répondre

0

L'activation 'relu'ne renvoie jamais une valeur négative.

Puisque vous ajoutez l'entrée à la sortie (a14) et vous devez « débruitage » (enlever bruit), il est certainement prévu que la sortie (a14) contient à la fois positives et négatives des valeurs. (Vous voulez assombrir les taches claires et éclaircir les taches sombres).

À cause de cela, l'activation a14 ne peut pas être 'relu'. Ce doit être quelque chose à la fois positif et négatif, et capable d'atteindre la portée du bruit. Probablement un 'tanh' ou une activation personnalisée. Si votre entrée va de 0 à 1, un 'tanh' serait probablement la meilleure option.

(Je ne sais pas sur les couches précédentes, peut-être certains d'entre eux en utilisant 'tanh' rendrait le processus plus facile)


Parfois, ces réseaux longue convolutifs ne se coincent, je suis ici la formation d'un U-net et il a fallu du temps pour le faire converger. Quand il est bloqué, il est parfois préférable de construire le modèle à nouveau (nouveau initalizations de poids) et essayer plus.

Voir détails ici: How to build a multi-class convolutional neural network with Keras