Chainer에서 매우 간단한 선형 분리를 시도했습니다.

6524 단어 파이썬Chainer
Chainer 연습으로서 간단한 선형 분리 문제에 도전해 보았다.

환경


  • OSX 10.11
  • 파이썬 2.7.11
  • chainer 1.7.2

  • 작업



    신장(cm), 체중(kg), 가슴둘레(cm)를 입력으로써 비만 상태인지 여부를 판별하는 함수를 학습하고 싶다. 다만, 여기서 비만 상태란 BMI(체중을 신장의 제곱으로 나눈 수)가 25 이상이라고 정의한다. 따라서 비만 상태인지 여부를 판단하기 위해서는 체중과 신장 정보가 있으면 충분하며 가슴 둘레 정보는 필요하지 않습니다. 그렇다면 이번 만드는 학습기는 과연 가슴둘레 정보에 당황하지 않고 신장과 체중에만 주목하여 비만 상태인지 아닌지를 판별할 수 있을까.

    데이터



    엑셀로 더미 데이터를 만들었다. 스페이스 구분으로 신장, 체중, 가슴둘레, 비만플래그를 한 줄로 늘어놓고 있다. 신장, 체중, 가슴둘레는 각각 남성의 평균값에 적당한 분산을 갖는 정규난수를 더하여 생성하였다. 비만 플래그는 신장과 체중으로부터 산출되는 BMI가 25 이상이면 1을 세웠다. 이것을 독립적으로 1000개 만들고, 900개를 학습용, 100개를 평가용으로 나누었다.
    身長  体重  胸囲  肥満フラグ
    152.5110992 70.64096855 76.24909648 1
    176.5483602 72.54812988 79.99468908 0
    171.9815877 78.13768514 80.87788608 1
    180.013773  77.60660479 79.71464192 0
    171.9685041 81.20240554 84.93720091 1
    186.3999693 77.03393024 82.25099179 0
    175.1117213 81.23388203 86.89111757 1
    



    보시다시피 거의 선형이다.

    학습기



    Chainer의 연습이 다층 퍼셉트론을 짜 보았다. 입력 3차원, 숨겨진 소자 4차원, 출력 2차원의 3층 구조로 했다. (선형 분리 작업이므로 단층 퍼셉트론으로도 가능.) 그 외의 설정은 이하와 같이 했다.
  • 활성화 함수: ReLu
  • 최적화 알고리즘: Adam
  • 오차 함수 : 소프트 맥스 크로스 엔트로피
  • Dropout 비율: 0.5
  • 미니 배치 수: 5
  • 반복 수(epoch 수): 100
  • class MLP(Chain):
      def __init__(self):
        super(MLP, self).__init__(
          # 3-4-2次元のネットワーク
          l1=L.Linear(3, 4),
          l2=L.Linear(4, 2),
         )
      def forward(self, x, t, train):
        h1 = F.dropout(F.relu(self.l1(x)), train=train)
        y = self.l2(h1)
        return F.softmax_cross_entropy(y, t), F.accuracy(y, t)
    
    # インスタンス化
    model = MLP()
    # 最適化アルゴリズムにはAdamを採用
    optimizer = optimizers.Adam()
    optimizer.setup(model)
    
    N = 900         # 学習データ数
    N_test = 100    # 評価データ数
    n_epoch = 100  # 反復数
    batchsize = 5   # ミニバッチ
    #以下省略
    

    결과



    오차 함수와 정답률을 epoch 수로 플로팅했다.

  • 왼쪽 파란색 : 학습 데이터의 오차 함수
  • 왼쪽 녹색 : 학습 데이터의 정답률
  • 오른쪽 파랑 : 평가 데이터의 오차 함수
  • 오른쪽 녹색 : 평가 데이터의 정답률

  • 80% 미만의 성능이었다. 미묘?

    또한, 학습 후에 평가 데이터에 대해 어떤 출력이 이루어지는지를 보았다.
    身長   体重   胸囲   システムが推定した肥満フラグ   正解の肥満フラグ 
    [ 179.30055237   69.73477936   84.73832703] 0 0
    [ 176.89619446   84.05502319   85.10128021] 1 1
    [ 172.04129028   77.36618805   87.89541626] 1 1
    [ 168.48660278   73.91072845   84.5171814 ] 1 1
    [ 166.53656006   71.42696381   83.17546844] 0 1
    [ 163.44270325   77.11021423   90.57539368] 1 1
    [ 180.63993835   77.33372498   85.33548737] 0 0
    [ 165.73175049   71.87976837   80.57328033] 0 1
    

    본래는 비만인 아래에서 2번째와 4번째를 정상이라고 판단해 버렸다. 모두 체중만 보면 낮지 않다. 신장과의 관계를 파악할 수 없는 것인가.

    막히는 곳


  • overflow encountered in subtract
    softmax_cross_entropy를 사용하는 곳에서 overflow encountered in subtract 라는 오류가 나오고, 오차 함수가 nan이 되는 것이 많았다. 이 오류는 cross-entropy 오류 함수를 계산할 때 log에 0을 입력했기 때문에 발생하는 것 같습니다. 실은 처음, 활성화 함수에 선형 함수를 채용하고 있었지만, 그것이 안 되는 것 같다.
  • 국소해에 빠지다
    국소해에 빠져 학습이 진행되지 않게 되는 것이 여러 번 있었다. 미니배치수를 작게 하거나, 가중치의 초기치를 되풀이해 몇번이나 시행해, 잘 학습될 때까지 다시 했다.

  • 미래



    이 작업에서 성능 80% 미만은 낮다. 학습률, 미니 배치 사이즈, 드롭아웃율, 데이터 정규화 등 여러가지 조정하여 감각을 잡아 가고 싶다.

    좋은 웹페이지 즐겨찾기