원래는 파이토치만 하는 데, 오토인코더는 하도 케라스 버젼이 많아서 그냥 케라스로 짜봤다.
논문 제목 : Improving Unsupervised Defect Segmentation by Applying Structural Similarity To Autoencoders
논문 주소 : https://arxiv.org/pdf/1807.02011.pdf
다른 사람의 구현 버젼 :
처음에는 그냥 가져다가 쓰려고 했는 데, 논문 내용과 맞지가 않아서 그냥 직접 구현하였다.
맞지 않은 이유는, 논문에서는 LeakyRelu를 사용했다고 하는 데, github에 구현된 것은 Relu를 사용하였고, 심지어 Upsampling을 사용하지 않았는 데도, 사용하여서 어거지로 feature map을 만든 것을 확인할 수 있었다. 나 말고도 역시 다른 사람들도 의아해한다는 것을 Issue를 클릭하면 확인 가능... 그리고 Latent Space를 논문에서는 100 또는 500으로 하였는 데, 1로 구현한 것도 차이점이다. 그냥 쉽게 말하면 논문에서 말한대로 구현 안했는 데 해놨다고 하는 사람인 것 같다...
def Convolutional_encoder(width=128,height=128):
input_shape = (width, height, 1)
model = Sequential([
# encoding
Conv2D(32, (4, 4), padding='same', strides=2, input_shape=input_shape),
LeakyReLU(alpha=0.2),
Conv2D(32, (4, 4) ,padding='same', strides=2),
LeakyReLU(alpha=0.2),
Conv2D(32, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Conv2D(64, (4, 4), padding='same', strides=2),
LeakyReLU(alpha=0.2),
Conv2D(64, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Conv2D(128, (4, 4), padding='same', strides=2),
LeakyReLU(alpha=0.2),
Conv2D(64, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Conv2D(32, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Conv2D(100, (8, 8), padding='valid', strides=1), # encoded 100 or 500
Sigmoid()
# 저자들은 Texture에는 100으로 하였다고 하고, Object 같은 경우네는 500으로 했다고 하니 선택하면 된다.
# encoder와 decoder의 마지막은 리키렐루가 아닌 선형 활성화 함수를 사용하였다고 한다.
# decoding
Deconv2D(32, (8, 8), padding='valid', strides=1),
LeakyReLU(alpha=0.2),
Deconv2D(64, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Deconv2D(128, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Deconv2D(64, (4, 4), padding='same', strides=2),
LeakyReLU(alpha=0.2),
Deconv2D(64, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Deconv2D(32, (4, 4), padding='same', strides=2),
LeakyReLU(alpha=0.2),
Deconv2D(32, (3, 3), padding='same', strides=1),
LeakyReLU(alpha=0.2),
Deconv2D(32, (4, 4), padding='same', strides=2),
LeakyReLU(alpha=0.2),
Deconv2D(1, (4, 4), padding='same', strides=2), # decoded
Sigmoid()
])
return model
논문에서는 Encoder 구조만 올려놓고 반대로 뒤집어서 Decoder를 구현했다고 하여서 Decoder 부분은 내가 직접 확인하면서 할 수 밖에 없었다.
(혹시 틀린 게 있다면 알려주세요...)
추가적으로 알려주자면, Epoch은 200 , Optimizer = Adam, lr = 0.0002, weight decay = 0.0001 이다.
손실함수로는 다양한 것을 사용하였는 데, L2 와 SSIM을 사용했다.
'논문 구현' 카테고리의 다른 글
ENAS 코드 받아와서 구현해보기 (0) | 2019.01.23 |
---|