reniew's blog
cs and deep learning

CS20(TensorFlow) Lecture Note (8): CNN(Style transfer), TFRecord

|

스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.

CS20: TensorFlow for Deep Learning Research


Post list

8. CNN(Style transfer), TFRecord

이번 lecture에서는 TFRecord와 Style transfer에 대해서 알아보도록 한다. TFRecord란 텐서플로우 데이터 포맷이다. tensorflow에서 추천하는 포맷인 만큼 이번 장에서 알아보자.

TFRecord

TFRecord는 TensorFlow 데이터 포맷으로, 바이너리 형식으로 저장된다. 따라서 dick cache를 효율적으로 사용하고, 사용 시 속도가 빠르다. 그리고 바이너리 형식이라 다른 형식의 데이터들도 같이 다룰 수 있다.(image 와 label을 같이 넣을 수 있다)

image와 label을 TFRecord 파일로 저장하는 방법에 대해서 알아보자.

먼저 TFRecord 파일을 작성할 writer를 만든다.

writer = tf.python_io.TFRecrodWriter(out_file)

그리고 image의 shape과 value(binary)를 가져온다.

shape, binary_image = get_image_binary(image_file)

다음으로 tf.train.Features 객체를 만든다.

features = tf.train.Features(feature = {'label': _int64_feature(label),
                                        'shape': _bytes_feature(shape),
                                        'image': _bytes_feature(binary_image)})

위에서 정의한 feature들을 포함하는 sample을 만든다.

sample = tf.train.Example(features = features)

마지막으로 sample을 TFRecord파일로 작성한후 writer를 close한다.

writer.write(sample.SerializeToString())
writer.close()

TFRecord파일로 저장하는 방법이 끝났다. 위의 저장하는 과정을 보면 각각 int와 byte값으로 형식이 다르더라도 같이 저장할 수 있다는 장점이 있다.

위에서 사용한 각 다른 데이터 형식을 하나의 byte string으로 만드는 함수인 _int64_feature_bytes_feature는 다음과 같이 정의된다.

def _int64_feature(value):
    return tf.train.Feature(int64_list = tf.train.Int64List(value=[value]))
def _bytes_feature(value):
    return tf.train.Feature(bytes_list = tf.train.Bytes64List(value=[value]))

이제 저장한 TFRecord 파일을 사용하는 방법에 대해서 알아보자. tf.data를 이용해서 불러올 수 있다.

dataset = tf.data.TFRecordDataset(tfrecord_files)

위와 같이 불러올 수 있다. 하지만 저장할 때를 생각해보자. 각각 다른 데이터 형식을 하나의 데이터로 저장했었다. 따라서 불러온 후 다시 다른 데이터 형식은 나눠줘야 한다. 따라서 파싱하는 함수인 _parse_function_을 정의한후 이용하면 된다.

def _parse_function(tfrecord_serialized):
    features={'label': tf.FixedLenFeature([], tf.int64),
              'shape': tf.FixedLenFeature([], tf.string),
              'image': tf.FixedLenFeature([], tf.string)}

그리고 정의한 함수를 데이터의 mapping 함수로 적용하면 된다.

dataset = dataset.map(_parse_function)

TFRecord를 이용해서 데이터를 저장하고 불러오는 방법에 대해서 알아봤다. 전체 코드는 github를 참고하자.

Style transfer

Style transfer란 두개의 이미지를 사용해서 하나의 이미지에 다른 하나의 이미지의 style을 적용시키는 모델이다. 아래 그림은 Deadpool 그림이다.

dea

그리고 아래는 Picasso의 Guernica라는 그림이다.

guer

이 두 이미지를 가지고 style transfer 모델에 적용시키면, Picasso의 Guernica그림의 style을 Deadpool 그림에 적용시킬 수 있다. 즉 아래의 그림처럼 된다.

e,c

이 모델에서는 중요한 두가지 loss가 정의된다. 여기서 내용 이미지는 위의 예시로 보면 Deadpool 이미지가 되고 스타일 이미지는 피카소의 이미지가 된다.

  • Content loss

내용 이미지의 내용과 생성된 이미지의 내용간의 content loss를 측정

  • Style loss

스타일 이미지의 스타일과 생성된 이미지의 스타일간의 style loss를 측정

그리고 이 모델의 Optimizer는 두개의 loss를 같이 최소화 하도록 한다.

그리고 구현 과정에 대해서 설명하면 다음과 같다.

  • 가중치 대신 input값을 학습한다.
  • 같은 변수를 공유해서 사용한다.
  • Pre-trained 된 가중치를 사용했다.(VGG-19)

Comments