티스토리 뷰

728x90

개발자로 살아간다면 소프트웨어 품질이라는 말을 한 번 쯤은 들어봤을 것이다.

 

소프트웨어 품질을 결정하는 특징 중에는 Maintainability가 있다.

말 그대로 코드의 유지보수성이다.

 

Code Maintainability를 구글링 했을 때, 여러 업계 종사자들이 정의를 내리거나 설명하는 글들을 찾을 수 있었다.

이 중 나는 "code that is easy to modify or extend"라고 깔끔하게 정의한게 제일 공감되었다.

 

딥 러닝 프로젝트나 연구들 중에서 어떻게 하면 코드의 Maintainability를 유지하고,

코드의 품질을 높일 수 있을지 공부해보았던 것들을 정리해본다.

 

이 중 첫 번째는 YAML 사용하기다.

 


YAML은 JSON과 같이 데이터 직렬화에 사용되는 포맷으로써, *.yaml의 확장자를 가진다.

 

  • YAML 예시(아래에서 사용할 sigmoid.yaml)
hyper_parameters:
  batch_size : 32
  epochs : 5
  learning_rate : 0.01

network_parameters:
  activation : 'sigmoid'

data_scale_factor : 2

dataset_root : '../../00_data'

 

YAML은 딥 러닝 프로젝트에서 하이퍼 파라미터 등의 변수를 관리하는데에 사용할 수 있다.

그래서 서비스 등으로 배포한 후 유지보수 측면에서라기 보다는

적은 코드 수정으로 다양한 실험을 해볼 수 있다는 점이 더 매력적으로 느껴졌다.

 

YAML을 사용하였을 때, 내가 생각하는 장점을 정리하면 다음과 같다.

    1) argument로 코드 실행하는 것 대비, cli 명령어가 간단해 진다.

        ㆍargument 사용시

python main.py --batch_size 32 --epochs 5 --learning_rate 0.01 --activation ‘sigmoid’ --data_scale_factor 2 --dataset_root ../../00_data

 

        ㆍYAML 사용시

python main.py --config sigmoid.yaml

 

    2) 변수 추가시 코드 수정을 할 수 있다.

        ㆍargument 사용시

…

parser.add_argument(‘--loss_weight’, type=float)

…

loss = loss * parser.loss_weight

        ㆍYAML 사용시

loss = loss * config[‘loss_weight’]

 

의외에도 모델 학습시 configure를 저장할 때에도 유용하고,

나중에 소개할 Python DecoratorCatalog Pattern과도 궁합이 좋은 것 같다.

 

이제 간단한 MNIST 예제에, YAML 사용 예제를 끼얹어 보았다.

 

main 코드의 변경없이 sigmoid.yamlrelu.yaml을 이용하여,

activation이 sigmoid인 모델relu인 모델을 실험해보는 코드이다.

 

relu.yaml은 sigmoid.yaml에서 learning_rate와 activation만 'relu'로 변경한 YAML이다.

relu.yaml
hyper_parameters:
  batch_size : 32
  epochs : 5
  learning_rate : 0.001

network_parameters:
  activation : 'relu'

data_scale_factor : 2

dataset_root : '../../00_data'

 


python에서 YAML을 로드하기 위한 라이브러리가 있다.

pip등을 이용하여 pyyaml을 설치하자.

설치가 완료되면, 아래와 같이 로드가 가능하며, dict 타입으로 로드 된다.

import yaml

with open(‘sigmoid.yaml’) as f:
	config = yaml.safe_load(f)

 

tensorflow 공식 튜토리얼 코드를 기반으로 실험 코드를 구현해보았다.

데이터 크기가 작기 때문에 GPU가 없어도 실험이 가능하며, pytorch 코드도 구현해 보았다.

 

굵직한 것 몇 가지만 본 글에서 소개하고, 

전체 코드는 https://github.com/tjd229/CodeMaintainability-For-Deep-Learning에서 확인할 수 있다.

 

  • tensorflow
코드

간단한 모델 분류기를 다음과 같이 구현하였다.

class MyModel(Model):
    def __init__(self, activation='sigmoid'):
        super(MyModel, self).__init__()
        self.flatten = Flatten()
        self.d0 = Dense(256, activation=activation)
        self.d1 = Dense(128, activation=activation)
        self.d2 = Dense(10)

    def call(self, x):
        x = self.flatten(x)
        x = self.d0(x)
        x = self.d1(x)
        return self.d2(x)

dataset, model, loss, optimizer instance를 정의

train_ds, test_ds = mk_dataset(config)

model = MyNetwork.MyModel(activation=config['network_parameters']['activation'])

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
 
metric helper instance 정의
 
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
test_loss = tf.keras.metrics.Mean(name='test_loss')
test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')

 

  • pytorch
코드

간단한 모델 분류기를 다음과 같이 구현하였다.

class MyModel(nn.Module):
    def __init__(self, activation='sigmoid'):
        super(MyModel, self).__init__()
        self.flatten = nn.Flatten()
        self.d0 = nn.Linear(28*28,256)
        self.d1 = nn.Linear(256,128)
        self.d2 = nn.Linear(128,10)

        if activation =='sigmoid':
            self.act = nn.Sigmoid()
        elif activation =='relu':
            self.act = nn.ReLU()
        else:
            self.act = nn.Identity()

    def forward(self, x):
        x = self.flatten(x)
        x = self.act(self.d0(x))
        x = self.act(self.d1(x))
        return self.d2(x)

dataset, model, loss, optimizer instance를 정의

train_ds, test_ds = mk_dataset(config)

model = MyNetwork.MyModel(activation=config['network_parameters']['activation'])model.to(device)
#
loss_object = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
 

 

 

모델 등을 정의하고 아래와 같은 파이프라인으로 실험 코드를 돌려보았다.

pytorch와 tensorflow 코드 모두 정상 작동하였다.

 

Pseudo code

 

실행은 어떠한 코드 변경도 없이 아래와 같이 실행할 수 있다.

  • sigmoid model
python main.py --config ./configs/sigmoid.yaml
  • relu model
python main.py --config ./configs/relu.yaml

 

실행 결과 예시

 


참조

728x90
댓글
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함