레이블이 Deep Learning인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Deep Learning인 게시물을 표시합니다. 모든 게시물 표시

2019년 1월 13일 일요일

Machine Learning 에서 NaN 처리

Machine Learning 에서 NaN 처리

굉장히 고민이 되는 주제입니다.

https://stats.stackexchange.com/questions/258610/machine-learning-dealing-with-nan-values

위 답변의 결론은 NaN 값이 생성 하게 되는 방법을 (해당 항목이 왜 NaN이 된것인지)이해하고 각 기능의 예상되는 동작이 무엇인지 가정해서 진행해야 합니다. 어떤때는 0으로 치환되기도 하지만 어떤 경우에는 다른값 의미가 되어야 합니다. 그것은 해당 항목에 따라 면밀히 살펴보고 진행하여야 합니다.

어떤 값으로 변경해야 할지 모르기 때문에 다른 값으로 변경하는 예제를 만들어 두었습니다.

1. NaN 값을 -999 값으로 변경하기 pytorch tensor

import pandas as pd

dataset = pd.read_csv("train.tsv", delimiter='\t', header=0)
print(dataset.info(verbose=True))

import torch
one_hot_encoded = pd.get_dummies(dataset) 
torch_tensor = torch.from_numpy(one_hot_encoded.values)
print(torch_tensor)

torch_tensor[torch_tensor != torch_tensor] = -999
print(torch_tensor)

NaN텐서의 값을 변경하는 코드
torch_tensor[torch_tensor != torch_tensor] = -999

입력 데이터
0 1 지역 3 4
NaN 0.3160718715457761 광주 0.618074061962662 부산
0.4779143261004096 0.7640950473377978 인천 0.7554662967547567 인천
0.46356805076582885 0.5837447431729355 대전 0.793675978965779 광주
0.5695109222857196 0.05089301078346342 인천 0.9556152127770076 부산
0.04493729261707624 0.14316706161067427 경기 0.3853064558624778 울산
0.4211392967613088 0.4223696769241083 울산 0.5668579921124862 광주
0.6968309725237914 0.9771633054896907 서울 0.8357267917293922 경기
0.11353740126056755 0.7601654905557846 대전 0.743158407293178 부산
0.22370034270270966 0.3115915771469119 대전 0.11848968372403645 부산
0.137646137601257 0.600286886461799 광주 0.7007352606121582 강원
0.031428666050948184 0.39108944068098905 대전 0.8733145643417124 강원
0.9964849451141898 0.1515641318053479 인천 0.5335673749065628 인천
0.22542471556473298 0.8561772376533481 서울 0.9362096685200896 울산
0.4686621433360696 0.17537990374522128 대구 0.3499523151304561 울산
0.046060811241397714 0.8299155100569963 경기 0.21535901604117658 경기
0.1899909553960777 0.21936448957471155 인천 0.6575452140509177 경기
0.41758513381425333 0.42277109702047366 서울 0.8529515809615816 부산
0.3197992908993763 NaN 강원 0.4037015504523124 대구
0.0562629654450455 0.551939153390536 인천 0.9260164254116474 세종
0.587953265713976 0.6413981811587487 대구 0.023584307830762707 대전

결과
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 5 columns):
0     19 non-null float64
1     19 non-null float64
지역    20 non-null object
3     20 non-null float64
4     20 non-null object
dtypes: float64(3), object(2)
memory usage: 880.0+ bytes
None
tensor([[    nan,  0.3161,  0.6181,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.4779,  0.7641,  0.7555,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000],
        [ 0.4636,  0.5837,  0.7937,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.5695,  0.0509,  0.9556,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0449,  0.1432,  0.3853,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.4211,  0.4224,  0.5669,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.6968,  0.9772,  0.8357,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1135,  0.7602,  0.7432,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.2237,  0.3116,  0.1185,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1376,  0.6003,  0.7007,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0314,  0.3911,  0.8733,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.9965,  0.1516,  0.5336,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000],
        [ 0.2254,  0.8562,  0.9362,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.4687,  0.1754,  0.3500,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000],
        [ 0.0461,  0.8299,  0.2154,  0.0000,  1.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.1900,  0.2194,  0.6575,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  1.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.4176,  0.4228,  0.8530,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000],
        [ 0.3198,     nan,  0.4037,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          1.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000],
        [ 0.0563,  0.5519,  0.9260,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  0.0000,  0.0000,  1.0000,  0.0000,  0.0000],
        [ 0.5880,  0.6414,  0.0236,  0.0000,  0.0000,  0.0000,  1.0000,
          0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
          0.0000,  1.0000,  0.0000,  0.0000,  0.0000,  0.0000]], dtype=torch.float64)
tensor([[-999.0000,    0.3161,    0.6181,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.4779,    0.7641,    0.7555,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000],
        [   0.4636,    0.5837,    0.7937,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.5695,    0.0509,    0.9556,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0449,    0.1432,    0.3853,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.4211,    0.4224,    0.5669,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    1.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.6968,    0.9772,    0.8357,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1135,    0.7602,    0.7432,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.2237,    0.3116,    0.1185,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1376,    0.6003,    0.7007,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0314,    0.3911,    0.8733,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.9965,    0.1516,    0.5336,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    1.0000],
        [   0.2254,    0.8562,    0.9362,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.4687,    0.1754,    0.3500,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000],
        [   0.0461,    0.8299,    0.2154,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.1900,    0.2194,    0.6575,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.4176,    0.4228,    0.8530,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000],
        [   0.3198, -999.0000,    0.4037,    1.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    1.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000],
        [   0.0563,    0.5519,    0.9260,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    1.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    0.0000,    0.0000,    1.0000,
            0.0000,    0.0000],
        [   0.5880,    0.6414,    0.0236,    0.0000,    0.0000,    0.0000,
            1.0000,    0.0000,    0.0000,    0.0000,    0.0000,    0.0000,
            0.0000,    0.0000,    0.0000,    1.0000,    0.0000,    0.0000,
            0.0000,    0.0000]], dtype=torch.float64)

참고로 NaN 인식하는 스트링 값은 nan,NaN,NA 3가지 이며 text에 해당 string이 있을때 숫자로 인식(numpy.nan)하게 됩니다.

2. pandas fillna 이용

>>> df = pd.DataFrame([[np.nan, 2, np.nan, 0],
...                    [3, 4, np.nan, 1],
...                    [np.nan, np.nan, np.nan, 5],
...                    [np.nan, 3, np.nan, 4]],
...                    columns=list('ABCD'))
>>> df
     A    B   C  D
0  NaN  2.0 NaN  0
1  3.0  4.0 NaN  1
2  NaN  NaN NaN  5
3  NaN  3.0 NaN  4
>>> df.fillna(0)
    A   B   C   D
0   0.0 2.0 0.0 0
1   3.0 4.0 0.0 1
2   0.0 0.0 0.0 5
3   0.0 3.0 0.0 4

3. 범주형 데이터 NaN 처리 방법

범주형이란 선택 사항이 유한한 집합에 속한 하나 이상의 이산 항목을 표현하는 입력 특성을 가리킵니다, 범주형 데이터에는 논리적 순서가 없을 수도 있습니다. 예를 들면, 범주형에는 성별, 지역, 결제 방법이 있습니다. 서울=1, 광주=2, 인천=3 으로 표현되더라도 해당 항목은 범주형에 해당됩니다. 인천(3)-광주(2)=서울(1)의 의미를 지니지 않기 때문입니다. 그러면 이러한 범주형 데이터는 Machine Learning에서 어떻게 해야할까요?
아래 좋은 자료가 있습니다.
https://blog.myyellowroad.com/using-categorical-data-in-machine-learning-with-python-from-dummy-variables-to-deep-category-66041f734512
https://blog.myyellowroad.com/using-categorical-data-in-machine-learning-with-python-from-dummy-variables-to-deep-category-42fd0a43b009

카테고리 데이터가 많지 않다면 one hot encoding 을 사용하는 방법입니다. 즉 인천에 차원 하나를 할당하고 서울에도 차원 하나를 할당 하는 방식입니다. pandas에 get_dummies 함수를 이용하면 쉽게 변환이 가능합니다.

입력 데이터
0 1 지역 3 4
NaN 0.3160718715457761 광주 0.618074061962662 부산
0.4779143261004096 0.7640950473377978 인천 0.7554662967547567 인천
0.46356805076582885 0.5837447431729355 대전 0.793675978965779 광주
0.5695109222857196 0.05089301078346342 인천 0.9556152127770076 부산
0.04493729261707624 0.14316706161067427 경기 0.3853064558624778 울산
0.4211392967613088 0.4223696769241083 울산 0.5668579921124862 광주
0.6968309725237914 0.9771633054896907 서울 0.8357267917293922 경기
0.11353740126056755 0.7601654905557846 대전 0.743158407293178 부산
0.22370034270270966 0.3115915771469119 대전 0.11848968372403645 부산
0.137646137601257 0.600286886461799 광주 0.7007352606121582 강원
0.031428666050948184 0.39108944068098905 대전 0.8733145643417124 강원
0.9964849451141898 0.1515641318053479 인천 0.5335673749065628 인천
0.22542471556473298 0.8561772376533481 서울 0.9362096685200896 울산
0.4686621433360696 0.17537990374522128 대구 0.3499523151304561 울산
0.046060811241397714 0.8299155100569963 경기 0.21535901604117658 경기
0.1899909553960777 0.21936448957471155 인천 0.6575452140509177 NaN
0.41758513381425333 0.42277109702047366 서울 0.8529515809615816 부산
0.3197992908993763 NaN 강원 0.4037015504523124 대구
0.0562629654450455 0.551939153390536 인천 0.9260164254116474 세종
0.587953265713976 0.6413981811587487 대구 0.023584307830762707 대전

코드에 dummy_na=True 옵션을 넣으면 다음 코드에 의해서  pd.get_dummies(dataset,dummy_na=True),  4_nan와 같이 마지막 항목에 nan 처리를 위한 차원이 늘어나게 됩니다.
import pandas as pd

dataset = pd.read_csv("train.tsv", delimiter='\t', header=0)
print(dataset.info(verbose=True))
print(dataset)

import torch
one_hot_encoded = pd.get_dummies(dataset,dummy_na=True) 
print(one_hot_encoded)
print(one_hot_encoded.info(verbose=True))

결과
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 5 columns):
0     19 non-null float64
1     19 non-null float64
지역    20 non-null object
3     20 non-null float64
4     19 non-null object
dtypes: float64(3), object(2)
memory usage: 880.0+ bytes
None
           0         1  지역         3    4
0        NaN  0.316072  광주  0.618074   부산
1   0.477914  0.764095  인천  0.755466   인천
2   0.463568  0.583745  대전  0.793676   광주
3   0.569511  0.050893  인천  0.955615   부산
4   0.044937  0.143167  경기  0.385306   울산
5   0.421139  0.422370  울산  0.566858   광주
6   0.696831  0.977163  서울  0.835727   경기
7   0.113537  0.760165  대전  0.743158   부산
8   0.223700  0.311592  대전  0.118490   부산
9   0.137646  0.600287  광주  0.700735   강원
10  0.031429  0.391089  대전  0.873315   강원
11  0.996485  0.151564  인천  0.533567   인천
12  0.225425  0.856177  서울  0.936210   울산
13  0.468662  0.175380  대구  0.349952   울산
14  0.046061  0.829916  경기  0.215359   경기
15  0.189991  0.219364  인천  0.657545  NaN
16  0.417585  0.422771  서울  0.852952   부산
17  0.319799       NaN  강원  0.403702   대구
18  0.056263  0.551939  인천  0.926016   세종
19  0.587953  0.641398  대구  0.023584   대전
           0         1         3  지역_강원  지역_경기  지역_광주  지역_대구  지역_대전  지역_서울  지역_울산  ...    4_강원  4_경기  4_광주  4_대구  4_대전  4_부산  4_세종  4_울산  4_인천  4_nan
0        NaN  0.316072  0.618074      0      0      1      0      0      0      0  ...       0     0     0     0     0     1     0     0     0      0
1   0.477914  0.764095  0.755466      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     1      0
2   0.463568  0.583745  0.793676      0      0      0      0      1      0      0  ...       0     0     1     0     0     0     0     0     0      0
3   0.569511  0.050893  0.955615      0      0      0      0      0      0      0  ...       0     0     0     0     0     1     0     0     0      0
4   0.044937  0.143167  0.385306      0      1      0      0      0      0      0  ...       0     0     0     0     0     0     0     1     0      0
5   0.421139  0.422370  0.566858      0      0      0      0      0      0      1  ...       0     0     1     0     0     0     0     0     0      0
6   0.696831  0.977163  0.835727      0      0      0      0      0      1      0  ...       0     1     0     0     0     0     0     0     0      0
7   0.113537  0.760165  0.743158      0      0      0      0      1      0      0  ...       0     0     0     0     0     1     0     0     0      0
8   0.223700  0.311592  0.118490      0      0      0      0      1      0      0  ...       0     0     0     0     0     1     0     0     0      0
9   0.137646  0.600287  0.700735      0      0      1      0      0      0      0  ...       1     0     0     0     0     0     0     0     0      0
10  0.031429  0.391089  0.873315      0      0      0      0      1      0      0  ...       1     0     0     0     0     0     0     0     0      0
11  0.996485  0.151564  0.533567      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     1      0
12  0.225425  0.856177  0.936210      0      0      0      0      0      1      0  ...       0     0     0     0     0     0     0     1     0      0
13  0.468662  0.175380  0.349952      0      0      0      1      0      0      0  ...       0     0     0     0     0     0     0     1     0      0
14  0.046061  0.829916  0.215359      0      1      0      0      0      0      0  ...       0     1     0     0     0     0     0     0     0      0
15  0.189991  0.219364  0.657545      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     0     0     0      1
16  0.417585  0.422771  0.852952      0      0      0      0      0      1      0  ...       0     0     0     0     0     1     0     0     0      0
17  0.319799       NaN  0.403702      1      0      0      0      0      0      0  ...       0     0     0     1     0     0     0     0     0      0
18  0.056263  0.551939  0.926016      0      0      0      0      0      0      0  ...       0     0     0     0     0     0     1     0     0      0
19  0.587953  0.641398  0.023584      0      0      0      1      0      0      0  ...       0     0     0     0     1     0     0     0     0      0

[20 rows x 22 columns]
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 22 columns):
0         19 non-null float64
1         19 non-null float64
3         20 non-null float64
지역_강원     20 non-null uint8
지역_경기     20 non-null uint8
지역_광주     20 non-null uint8
지역_대구     20 non-null uint8
지역_대전     20 non-null uint8
지역_서울     20 non-null uint8
지역_울산     20 non-null uint8
지역_인천     20 non-null uint8
지역_nan    20 non-null uint8
4_강원      20 non-null uint8
4_경기      20 non-null uint8
4_광주      20 non-null uint8
4_대구      20 non-null uint8
4_대전      20 non-null uint8
4_부산      20 non-null uint8
4_세종      20 non-null uint8
4_울산      20 non-null uint8
4_인천      20 non-null uint8
4_nan     20 non-null uint8
dtypes: float64(3), uint8(19)
memory usage: 940.0 bytes
None



2018년 12월 16일 일요일

PyTorch Example XOR using pandas DataFrame(pandas DataFrame 를 이용한 XOR PyTorch 예제)

pandas DataFrame 를 이용한 XOR PyTorch 예제

아래 예제는 csv 파일을 읽고 pytorch로 learning 후 결과를 출력하는 예제입니다.

일반적인 DataSet은 3가지가 주어집니다.

Training set은 Train하기 위한 데이터입니다.
Validation dataset은 검증하기 위한 데이터고요, 그리고 Test dataset는 최종 예측이나 값을 테스트 하기 위한 데이터입니다.

3가지 데이터가 파일로 주어질때 처리하는 방법에 대해 예제로 작성하였습니다. 3가지 데이터이지만 실제는 2가지로 주어지는 경우가 많습니다. 아래 참고
train.csv 파일은 xor의 입력은 2개이지만 출력은 일반적으로 1개입니다. 좀 더 범용적인 예제를 만들기위해서 y1,y2를 넣었으며, y2는 y1의 negative 값으로 넣었습니다. 만약 출력이 하나만 필요하다고 생각한다면 하나는 삭제하면 됩니다.
train.csv
x1,x2,y1,y2
0,0,0,1
0,1,1,0
1,0,1,0
1,1,0,1
0,1,1,0
1,1,0,1
1,0,1,0
1,1,0,1
0,1,1,0
1,1,0,1
1,0,1,0
1,1,0,1
0,1,1,0
1,1,0,1
0,1,1,0
1,1,0,1
1,0,1,0
1,1,0,1
1,1,0,1
0,1,1,0
1,1,0,1
1,0,1,0
1,1,0,1
0,1,1,0
1,1,0,1

test.csv
x1,x2
0,1
0,0
1,0
1,1
0,1
0,0
1,0
1,1
0,1
0,0
1,0
1,1

위와 같이 일반적으로 train.csv , test.csv 2가지 파일만 존재합니다. 해당 파일의 가장 큰 차이점은 y값 즉, 최종 target값을 모르기 때문에 해당값을 예측하는것이 Deep learning의 목표(goal)가 됩니다.
두개의 dataset이 주어질때 validation dataset이 필요하게 됩니다. 그것은 training set에서 일부를 validation dataset으로 사용하게 됩니다.
아래 소스에서 아래 부분입니다.
train_df : training set
val_df :validation dataset
train_df = input_df[0:int(input_row_size/2)]
val_df = input_df[int(input_row_size/2):input_row_size]

XOR 소스
import pandas as pd
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable

input_df = pd.read_csv("train.csv", header=0)

input_row_size, input_column_size = input_df.shape

# 입력의 일부를 validation 용으로 나눈다.
train_df = input_df[0:int(input_row_size/2)]
val_df = input_df[int(input_row_size/2):input_row_size]

train_X = train_df.drop(['y1', 'y2'], axis=1)
train_Y = train_df[['y1', 'y2']]

val_X = val_df.drop(['y1', 'y2'], axis=1)
val_Y = val_df[['y1', 'y2']]

train_inputs = (torch.from_numpy(train_X.values))
train_inputs = train_inputs.float()
train_targets = (torch.from_numpy(train_Y.values))
train_targets = train_targets.float()

val_inputs = (torch.from_numpy(val_X.values))
val_inputs = val_inputs.float()
val_targets = (torch.from_numpy(val_Y.values))
val_targets = val_targets.float()

EPOCHS_TO_TRAIN = 10000

use_cuda = torch.cuda.is_available()

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(2, 3, True)
        self.fc2 = nn.Linear(3, 2, True)

    def forward(self, x):
        x = F.sigmoid(self.fc1(x))
        x = self.fc2(x)
        x = F.sigmoid(x)
        return x
  
    def name(self):
        return "Net"
  
model = Net()
if use_cuda:
    model = model.cuda()

criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

print("Training loop:")
for epoch in range(0, EPOCHS_TO_TRAIN):
 for phase in ['train','valid']:
  running_loss = 0.0
  if phase == 'train':
   model.train(True)
   for input, target in zip(train_inputs, train_targets):
    if use_cuda:
     input, target = input.cuda(), target.cuda()
    optimizer.zero_grad()   # zero the gradient buffers
    input = Variable(input)
    target = Variable(target)
    output = model(input)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()    # Does the update
    if use_cuda:
     running_loss += loss.data.cpu().numpy()
    else:
     running_loss += loss.data.numpy()
   if epoch % 1000 == 0:
    print("train:",epoch, running_loss)
  else:
   model.train(False)
   for input, target in zip(val_inputs, val_targets):
    if use_cuda:
     input, target = input.cuda(), target.cuda()
    input = Variable(input)
    target = Variable(target)
    output = model(input)
    loss = criterion(output, target)
    if use_cuda:
     running_loss += loss.data.cpu().numpy()
    else:
     running_loss += loss.data.numpy()
   if epoch % 1000 == 0:
    print("validation:",epoch, running_loss)

# test
test_df = pd.read_csv("test.csv", header=0)
test_inputs = (torch.from_numpy(test_df.values))
test_inputs = test_inputs.float()

print("Final results:")
for input in test_inputs:
 input = Variable(input)
 output = model(input)
 print("Input:",input,",output:",output)
 
#torch.save(model.state_dict(), model.name())

결과
Training loop:
train: 0 8.562797486782074
validation: 0 9.413674592971802
train: 1000 7.372614145278931
validation: 1000 7.221763789653778
train: 2000 4.808089405298233
validation: 2000 3.305788993835449
train: 3000 3.6996061131358147
validation: 3000 1.8894704058766365
train: 4000 3.199199952185154
validation: 4000 1.4243120700120926
train: 5000 2.6419421173632145
validation: 5000 1.1351843103766441
train: 6000 1.8101112879812717
validation: 6000 0.8552077151834965
train: 7000 1.100499752908945
validation: 7000 0.6019697394222021
train: 8000 0.7131331823766232
validation: 8000 0.4354256521910429
train: 9000 0.5095871035009623
validation: 9000 0.33376642130315304
Final results:
Input: tensor([ 0.,  1.]) ,output: tensor([ 0.9737,  0.0267])
Input: tensor([ 0.,  0.]) ,output: tensor([ 0.1409,  0.8564])
Input: tensor([ 1.,  0.]) ,output: tensor([ 0.9735,  0.0268])
Input: tensor([ 1.,  1.]) ,output: tensor([ 0.0151,  0.9848])
Input: tensor([ 0.,  1.]) ,output: tensor([ 0.9737,  0.0267])
Input: tensor([ 0.,  0.]) ,output: tensor([ 0.1409,  0.8564])
Input: tensor([ 1.,  0.]) ,output: tensor([ 0.9735,  0.0268])
Input: tensor([ 1.,  1.]) ,output: tensor([ 0.0151,  0.9848])
Input: tensor([ 0.,  1.]) ,output: tensor([ 0.9737,  0.0267])
Input: tensor([ 0.,  0.]) ,output: tensor([ 0.1409,  0.8564])
Input: tensor([ 1.,  0.]) ,output: tensor([ 0.9735,  0.0268])
Input: tensor([ 1.,  1.]) ,output: tensor([ 0.0151,  0.9848])


출력이 0~1 사이의 값을 나타내므로 loss function은 BCELoss 함수를 사용하였습니다.

필요에 따라 Net의 Model과 EPOCH값을 적절히 조절하면 다른곳에서도 사용하기 좋은 예제가 될것입니다.

Batch 처리 부분은 빠져있습니다. 한번에 다루기 어려운 많은 메모리 사용을 위해서는 batch 처리가 필요합니다. CUDA가 없는 환경이라 CUDA 병렬처리 부분 구현이 미흡합니다.



2018년 12월 2일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (16)


LSTM networks (2/2)


LSTM에 있어서 가장 중요한것은 앞의 다이어그램에서 셀을 가로 지르는 수평선으로 표시된 모든 반복을 통해 통과하는 셀(cell) 상태(state) 입니다. LSTM 내부의 다중 네트워크는 셀 상태를 통해 이동하는 정보를 제어합니다. LSTM(작은 네트워크는 앞에 그림에서 σ로 표시되었습니다.)에서 첫번째 스텝은 어떤 정보가 셀 상태에서 벗어날것인지를 결정하는 것입니다. 이 네트워크를 forget gate 라고 불립니다. 그리고 활성 함수로서 sigmoid를 가집니다. 그런데 이 활성 함수는 셀 상태에서 각각의 원소에 대해 0과 1사이의 값을 출력합니다. 네트워크는(PyTorch layer) 다음 공식을 이용해서 표현됩니다.
네트웍으로 부터의 값들은 셀 상태에서 보유 할 값과 버려야 할 값을 결정합니다. 다음 단계는 셀 상태에 어떤 정보를 추가할지 결정하는 것입니다. 여기에는 두 부분이 있습니다. 입력 게이트 (input gate) 라 불리는 시그모이드 (sigmoid) 레이어는 업데이트 될 값을 결정합니다. 셀 상태에 추가 할 새 값을 만드는 tanh 레이어가 있습니다. 수학적 표현은 아래와 같습니다.

다음 스텝에서 우리는 입력 gate와 tanh에 의해서 생성된 두개의 값들을 결합 합니다. 지금 우리는 forget gate 와 다음 공식에 표현된 it 와 Ct의 프로덕트 합계 사이의 엘리먼트 단위의 곱셈을 함으로서 셀 상태를 업데이트 할 수 있습니다.
 
마침내 우리는 셀 상태의 필터링 된 버전이 될 출력을 결정해야합니다. LSTM의 이용가능한 다른 버전이 있습니다. 그들중 대부분은 비슷한 원리로 동작합니다. 개발자 혹은 데이터 과학자로서, 우리는 LSTM 안쪽이 어떻게 동작하는지 거의 걱정할 필요가 없습니다. 당신이 그것에 관해 좀 더 배우길 원한다면 다음 블로그 링크를 방문하세요.
http://colah.github.io/posts/2015-08-Understanding-LSTMs
https://brohrer.github.io/how_rnns_lstm_work.html
우리가 LSTM을 이해 했으므로, 의미 분류기를 만드는데 사용할 수 있는 PyTorch 네트워크를 구현해 봅시다.
다음 단계를 따라서 분류기를 생성할것 입니다.
1. Preparing the data ( 데이터 준비 )
2. Creating the batches ( 일괄 생성 )
3. Creating the network ( 네트워크 생성 )
4. Training the model ( 모델 훈련 )











2018년 11월 25일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (15)

LSTM networks (1/2)


LSTM은 long-term(장 기간) 의존도를 학습 할 수 있는 RNN의 특별한 종류입니다.  1977년에 소개 되었고 최근에 인기를 얻게 되었습니다. LSTM은 매우 다양한 문제에 대해 대단히 잘 작동하며 널리 사용됩니다.
LSTM은 긴 시간의 정보를 기억하는 디자인을 가지는 long-term(장 기간) 의존도 문제를 회피 하기 위해서 디자인 되었습니다. RNN에서 그들이 순서의 각각의 요소들 전체를 그들 스스로 어떻게 반복하는지 우리는 보았습니다. 표준 RNN에서 그 반복 모듈은 하나의 linear layer (선형 layer) 와 같은 간단한 구조를 가질 것입니다.
다음 그림은 어떻게 단순 RNN이 그 자신을 반복하는지 보여줍니다.

LSTM안에는 간단한 선형 layer를 사용하는 대신에 우리는 독립적인 일을 하는 LSTM 내부에 작은 네트워크를 가지고 있습니다. 다음 그림임이 LSTM안에 무엇이 일어나는 보여 줍니다.

진행 다이어 그램 두번째 박스에 있는 작은 사각형들 각각은 PyTorch layer를 표현합니다. 원들은 원소 행렬이나 벡터 덧셈을 표현합니다. 합쳐진 선들은 두벡터가 연결되어지는것을 표현합니다. 좋은 부분은 우리가 손으로 이것 전체를 구현 하는것을 필요로 하지 않습니다. 대부분의 최근 딥러닝 프레임워크들은 LSTM 내부에서 일어나는 일을 처리할 추상화을 제공합니다. PyTorch 는 nn.LSTM 레이어 안에 모든 기능의 추상화를 제공 합니다.









2018년 11월 18일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (14)

LSTM

RNN은 언어 번역, 문장 분류, 많은 순차적인 프로그램등과 같은 실제 세계 어플리케이션을 만드는데 꽤 대중적입니다. 그러나 실제에 있어서 우리가 앞에서 보았던 RNN의 바닐라 버전(기본적인 버전)은 매우 드물게 사용됩니다. RNN의 바닐라 버전은 큰 순차데이터를 다룰때 사라지는 기울기, 기울기 폭발과 같은 문제점들을 가지고 있습니다. 대부분의 실제 프로그램에서는 RNN은 변형, LSTM 또는 GRU가 사용됩니다. 이것은 기본적인 RNN의 한계를 해결합니다. 또한 순차적인 데이터를 더잘 다룰 수 있는 능력을 가지고 있습니다. 여기에서는 LSTM안에서 어떤 일이 일어나는지 이해하는 것을 시도 할 것입니다. 그리고 IMDB데이터 셋을 이용하여 텍스트 분류 문제를 해결하기위한 LSTM에 기초한 network을 만들것입니다.

Long-term dependency

이론에 있어서 RNN은 다음에 무슨일이 발생하는지에 대한 컨텍스트의 빌드를 위해서 과거 데이터로 부터 필요한 모든 의존도를 학습해야 합니다. 예를 들자면, 우리는 "the clouds are in the sky" 문장에서 마지막 단어를 예측하는 중입니다. RNN은 정보 (clouds)가 단지 몇 마디 뒤이기 때문에 그것을 예측할 수 있습니다. 의존도가 필요하고 그것이 가깝지 않은 다른 긴 문장을 봅시다. 그리고 우리는 그것이 마지막 단어에서 예측하기를 원합니다. 그 문장은 다음과 같습니다. "I am born in Chennai a city in Tamilnadu. Did schooling in different states of India and I speak..." RNN의 바닐라 버전(기본적인 버전)에서는 그것을 순차적 앞선 부분에서 일어난 컨텍스트를 기억하기 위해서 어렵게 찾습니다. LSTM과 다른 RNN의 변형은 얼마나 많은지 또는 어떤 데이터가 기억될 수 있는지 나중에 결정하는 LSTM 내부에 다른 신경망을 더 함으로서 이 문제를 해결합니다.



2018년 11월 11일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (13)


Understanding how RNN works with an example(2/2)

앞에서는 RNN 을 blackbox로 보고 외부적인 내용을 코드로 구현해 보았습니다. 여기에서는 RNN 내부 클래스를 보도록 하겠습니다.

import torch.nn as nn
from torch.autograd import Variable

class RNN(nn.module):
 def __init__(self, input_size, hidden_size, output_size):
  super(RNN, self).__init__()
  self.hidden_size = hidden_size
  self.i2h = nn.Linear(input_size+hidden_size, hidden_size)
  self.i2o = nn.Linear(input_size+hidden_size, output_size)
  self.softmax = nn.LogSoftmax(dim=1)
  
 def forward(self, input, hidden):
  combined = torch.cat((input, hidden), 1)
  hidden = self.i2h(combined)
  output = self.i2o(combined)
  output = self.softmax(output)
  return output, hidden
 
 def initHidden(self):
  return Variable(torch.zeros(1, self.hidden_size)

앞의 코드에서 RNN이라는 단어를 제외하면 PyTorch는 많은 역전파의 복잡합을 숨기기 때문에 다른 모든 것은 이전 장에서 사용했던 것과 매우 유사하게 보입니다. init 함수와 forward 함수를 살펴보도록 하겠습니다.
init 함수는 출력 계산을 위한 하나와 state와 hidden vector를 계산하기 위한
 2개의 Liner layer를 초기화 합니다. forward 함수는 input vector와 hidden vector (combine)결합하고 출력 vector와 hidden state를 생성하는 두개의 linear layer에 통과 시킵니다. 출력 layer에 대해서는 log_softmax함수를 적용합니다.
torch.cat()은 두개의 텐서를 이어 붙이는 메소드입니다.
initHidden함수는 최초 RNN이 호출을 위해 state가 없을때 hidden vector를 생성하는것을 돕습니다. 지금까지 코드를 그림으로 그려보면 아래와 같습니다.


위 그림은 어떻게 RNN이 동작하는지 보여줍니다.
RNN에 관한 내용은 아래 블로그를 참고하세요.
http://karpathy.github.io/2015/05/21/rnn-effectiveness/
http://colah.github.io/posts/2015-08-Understanding-LSTMs/
다음에는 LSTM이라고 불리우는 RNN 변형에 대해서 배울것입니다.





2018년 11월 7일 수요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (12)


Understanding how RNN works with an example(1/2)

RNN 내부에서 어떤 일이 발생하는지 탐험 해봅시다.
RNN모델의 입력으로 Thor 리뷰를 생각해봅시다. 예제 텍스트는 "the action scenes were top notch in this movie..." 입니다. 첫번째 단어인 the 부터 통과해서 시작합니다. RNN 모델은 State Vector, Output Vector를 생성합니다.  State vector는 그것이 다음 단어 진행시 모델로 통과 되어 새로운 state vector를 생성 시킵니다. 우리는 단지 마지막 순서 동안 생성된 모델의 Output을 고려합니다. 다음 그림이 요약된 내용입니다.


아래 코드는 위의 이미지 내용을 코드로 구현한 내용의 일부입니다. RNN을 블랙박스를 보고 작성한 간단한 코드입니다.

rnn = RNN(input_size, hidden_size, output_size)
for i in range(len(Thor_review)):
    output, hidden = rnn(thor_review[i], hidden)

위 코드에서 hidden 변수는 state vector를 표현하고 때때로 hidden state로 불립니다. 다음은 RNN 구현 코드를 살펴보고 RNN내부에 어떤 일이 발생하는지 알아보도록 하겠습니다.


2018년 10월 28일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (11)


Recursive neural networks

RNNs(재귀 신경망)은 분류, 순차적 데이터 레이블 지정, 다음 단어를 예측하는 swiftkey 키보드 응용 프로그램과 같은 일련의 텍스트 생성과 같은 응용 프로그램을 사용할 수있게 해주는 가장 강력한 모델 중 하나입니다.
feedforward NN(neural network) 와 같은 모델 구조의 대부분은 순차적 데이터 처리의 이점을 가지고 있지 않습니다. feedforward NN(neural network)은 단지 모든 특징들이 한번에 보여지고 출력에 매핑되도록 디자인 되었습니다. 순서가 있는 텍스트 예를 봅시다. "I had cleaned my car" 와 "I had my car cleaned" 같은 단어를 가지는 두개의 문장입니다. 그러나 우리가 단어의 순서를 고려할때 그 의미는 다릅니다.
인간은 왼쪽에서 오른쪽으로 단어를 읽고 텍스트가 나타내는 모든 다른 단어를 이해하는 강력한 모델을 구축함으로써 텍스트 데이터를 이해하게 됩니다. RNN은 한 번에 한 단어씩 텍스트로 보면서 약간 유사하게 작동합니다. RNN은 그것 안에 특별한 layer를 가진 NN입니다. 한번에 처리하는 대신에 데이터를 반복 합니다. RNN은 순차적인 데이터를 처리 할 수 있기 때문에 다른길이의 벡터들을 사용 할 수 있습니다. 그리고 다른 길이의 출력을 생성 할 수 있습니다. 다른 표현들 중 일부는 다음 이미지로 제공됩니다.

위 이미지는 유명한 RNN 블로그중 하나로 부터 온 이미지 입니다. http://karpathy.github.io/2015/05/21/rnn-effectiveness/ Python을 이용하여 처음부터 RNN을 어떻게 만드는지에 관한 내용입니다.


책 내용을 간단하게 적어봤는데 이번에는 PyTorch에 관한 내용은 없고 RNN에 관한 내용 밖에 없습니다. 개인적으로는 모두를 위한 딥러닝 강의 중 RNN 부분을 보시는게 이해가 빠를것 같습니다.
https://hunkim.github.io/ml/

Recurrent Neural Network 강의 슬라이드  실습 슬라이드 






2018년 10월 21일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (10)


Freeze the embedding layer weights


PyTorch에 embedding layer의 가중치를 변하지 않도록 하는것은 두단계 과정이 있습니다.
1. requires_grad 속성을 False로 설정합니다. 이것은 PyTorch는 이 가중치를 위한 기울기가 필요하지 않다는것을 지시합니다.
2. embedding layer 인자들의 optimizer로의 통과를 제거합니다. 모든 인자들은 기울기를 가지는 것이 예상되기 때문에, 이것을 하지 않으면 optimizer는 에러를 발생 시킵니다. 
다음 코드는 얼마나 쉽게 embedding layer 가중치값을 얼리는지 보여줍니다. 그리고 optimizer가 인자들을 사용하지 않도록 알려줍니다.

model.embedding.weight.requires_grad = False

optimizer = optim.Adam([ param for param in model.parameters() if param.requires_grad == True],lr=0.001)

우리는 일반적으로 모든 모델 인자를 optimizer로 통과 시켰습니다. 그러나 이전 코드에서 requires_grad 가 True인 인자들을 통과 시켰습니다.
우리는이 정확한 코드를 사용하여 모델을 훈련시킬 수 있으며 비슷한 정확도를 달성해야합니다. 이러한 모든 모델 구조는 텍스트의 순차적인 특성을 이용하지 못합니다.
다음에는 두가지 대중화된 기법인 순차적인 데이터의 이점이 있는 RNN 과 Conv1D 를 알아보겠습니다.

자체 테스트

아래 예제는 앞에서 사용했었던 예제입니다. Freeze 만을 위한 테스트 코드입니다. 다른 부분은 참고 할만한 코드는 아닙니다. 앞장에서도 설명했지만 freeze외에 vector도 로딩해야하지만 그부분은 이번장의 내용이 아니라서 생략하였습니다.
여기에서는 위 1번 항목인 model.embedding.weight.requires_grad = False 이 코드만 추가시켜 보았습니다.
from torchtext.data import Field, Iterator, TabularDataset, BucketIterator
import torch.nn as nn
import torch.optim as optim
import torch
import torch.nn.functional as F

is_cuda = False

if torch.cuda.is_available():
    is_cuda=True

TEXT = Field(sequential=True,
             use_vocab=True,
             lower=True, 
             batch_first=True,fix_length=20)  
LABEL = Field(sequential=False,
              use_vocab=False,
              batch_first=True)

train_data = TabularDataset(path='./data7.tsv', skip_header=True, format='tsv', fields=[('text', TEXT), ('label', LABEL)])

TEXT.build_vocab(train_data, min_freq = 1)

print('Total vocabulary: {}'.format(len(TEXT.vocab)))
print('Token for "<unk>": {}'.format(TEXT.vocab.stoi['<unk>']))
print('Token for "<pad>": {}'.format(TEXT.vocab.stoi['<pad>']))
print('stoi {}'.format(len(TEXT.vocab.stoi)))

print(train_data.text)
print(train_data.label)

class EmbNet(nn.Module):
    def __init__(self,emb_size,hidden_size1,hidden_size2=200):
        super().__init__()
        self.embedding = nn.Embedding(emb_size,hidden_size1)
        self.fc = nn.Linear(hidden_size2,3)
    def vectors(self, inputs):
        print( self.embedding(inputs) )
        return;
    def forward(self,x):
        embeds = self.embedding(x).view(x.size(0),-1)
        out = self.fc(embeds)
        return F.log_softmax(out,dim=-1)
print(len(TEXT.vocab.stoi))

model = EmbNet(len(TEXT.vocab.stoi),10) #emb_size, hidden_size1

# add
model.embedding.weight.requires_grad = False

optimizer = optim.Adam(model.parameters(),lr=0.001)

train_iter = BucketIterator(train_data, batch_size=4, device=-1,shuffle=True)
train_iter.repeat = False

losses = []
loss_function = torch.nn.NLLLoss()

def fit(epoch,model,data_loader,phase='training',volatile=False):
    if phase == 'training':
        model.train()
    if phase == 'validation':
        model.eval()
        volatile=True
    running_loss = 0.0
    running_correct = 0.0
    for batch_idx , batch in enumerate(data_loader):
        text , target = batch.text , batch.label
        if is_cuda:
            text,target = text.cuda(),target.cuda()
        
        if phase == 'training':
            optimizer.zero_grad()

        print("text",text)
        output = model(text)
        loss = F.nll_loss(output,target)
        
        running_loss += F.nll_loss(output,target,size_average=False).data[0]
        preds = output.data.max(dim=1,keepdim=True)[1]
        running_correct += preds.eq(target.data.view_as(preds)).cpu().sum()
        if phase == 'training':
            loss.backward()
            optimizer.step()
    
    loss = running_loss/len(data_loader.dataset)
    accuracy = 100.0 * running_correct/len(data_loader.dataset)
    
    print(f"{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)} {accuracy}")
    return loss,accuracy

train_losses , train_accuracy = [],[]
val_losses , val_accuracy = [],[]

for epoch in range(1,10):
    epoch_loss, epoch_accuracy = fit(epoch,model,train_iter,phase='training')
    #val_epoch_loss , val_epoch_accuracy = fit(epoch,model,test_iter,phase='validation')
    train_losses.append(epoch_loss)
    train_accuracy.append(epoch_accuracy)
    #val_losses.append(val_epoch_loss)
    #val_accuracy.append(val_epoch_accuracy)

print (model.embedding.weight.data)

실행 결과
gradients가 없다고 에러 발생합니다.
Traceback (most recent call last):
  File "test6-2.py", line 51, in <module>
    optimizer = optim.Adam(model.parameters(),lr=0.001)
  File "E:\ProgramData\Anaconda3\lib\site-packages\torch\optim\adam.py", line 41, in __init__
    super(Adam, self).__init__(params, defaults)
  File "E:\ProgramData\Anaconda3\lib\site-packages\torch\optim\optimizer.py", line 43, in __init__
    self.add_param_group(param_group)
  File "E:\ProgramData\Anaconda3\lib\site-packages\torch\optim\optimizer.py", line 193, in add_param_group
    raise ValueError("optimizing a parameter that doesn't require gradients")
ValueError: optimizing a parameter that doesn't require gradients

2번 항목을 추가 해보겠습니다.
optimizer = optim.Adam([ param for param in model.parameters() if param.requires_grad == True],lr=0.001) 이 코드는 model.parameters() 인자들 중에 requires_grad == True 조건이 있는 값만 인자로 넘기게 됩니다.
에러는 발생하지 않습니다.
from torchtext.data import Field, Iterator, TabularDataset, BucketIterator
import torch.nn as nn
import torch.optim as optim
import torch
import torch.nn.functional as F

is_cuda = False

if torch.cuda.is_available():
    is_cuda=True

TEXT = Field(sequential=True,
             use_vocab=True,
             lower=True, 
             batch_first=True,fix_length=20)  
LABEL = Field(sequential=False,
              use_vocab=False,
              batch_first=True)

train_data = TabularDataset(path='./data7.tsv', skip_header=True, format='tsv', fields=[('text', TEXT), ('label', LABEL)])

TEXT.build_vocab(train_data, min_freq = 1)

print('Total vocabulary: {}'.format(len(TEXT.vocab)))
print('Token for "<unk>": {}'.format(TEXT.vocab.stoi['<unk>']))
print('Token for "<pad>": {}'.format(TEXT.vocab.stoi['<pad>']))
print('stoi {}'.format(len(TEXT.vocab.stoi)))

print(train_data.text)
print(train_data.label)

class EmbNet(nn.Module):
    def __init__(self,emb_size,hidden_size1,hidden_size2=200):
        super().__init__()
        self.embedding = nn.Embedding(emb_size,hidden_size1)
        self.fc = nn.Linear(hidden_size2,3)
    def vectors(self, inputs):
        print( self.embedding(inputs) )
        return;
    def forward(self,x):
        embeds = self.embedding(x).view(x.size(0),-1)
        out = self.fc(embeds)
        return F.log_softmax(out,dim=-1)
print(len(TEXT.vocab.stoi))

model = EmbNet(len(TEXT.vocab.stoi),10) #emb_size, hidden_size1

# add
model.embedding.weight.requires_grad = False

#optimizer = optim.Adam(model.parameters(),lr=0.001)
optimizer = optim.Adam([ param for param in model.parameters() if param.requires_grad == True],lr=0.001)

train_iter = BucketIterator(train_data, batch_size=4, device=-1,shuffle=True)
train_iter.repeat = False

losses = []
loss_function = torch.nn.NLLLoss()

def fit(epoch,model,data_loader,phase='training',volatile=False):
    if phase == 'training':
        model.train()
    if phase == 'validation':
        model.eval()
        volatile=True
    running_loss = 0.0
    running_correct = 0.0
    for batch_idx , batch in enumerate(data_loader):
        text , target = batch.text , batch.label
        if is_cuda:
            text,target = text.cuda(),target.cuda()
        
        if phase == 'training':
            optimizer.zero_grad()

        print("text",text)
        output = model(text)
        loss = F.nll_loss(output,target)
        
        running_loss += F.nll_loss(output,target,size_average=False).data[0]
        preds = output.data.max(dim=1,keepdim=True)[1]
        running_correct += preds.eq(target.data.view_as(preds)).cpu().sum()
        if phase == 'training':
            loss.backward()
            optimizer.step()
    
    loss = running_loss/len(data_loader.dataset)
    accuracy = 100.0 * running_correct/len(data_loader.dataset)
    
    print(f"{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)} {accuracy}")
    return loss,accuracy

train_losses , train_accuracy = [],[]
val_losses , val_accuracy = [],[]

for epoch in range(1,10):
    epoch_loss, epoch_accuracy = fit(epoch,model,train_iter,phase='training')
    #val_epoch_loss , val_epoch_accuracy = fit(epoch,model,test_iter,phase='validation')
    train_losses.append(epoch_loss)
    train_accuracy.append(epoch_accuracy)
    #val_losses.append(val_epoch_loss)
    #val_accuracy.append(val_epoch_accuracy)

print (model.embedding.weight.data)