'tensorflow'에 해당하는 글 5건

원-핫 인코딩은 문자를 숫자로 바꾸는 기법 중 가장 기본적인 방법으로, 서로 다른 단어들의 집합(vocabulary)을 벡터의 차원으로 만들어 인덱스를 부여하고, 표현하고 싶은 단어의 인덱스에 1, 나머지는 0을 부여하는 벡터 표현 방식이다. 


원-핫 인코딩 순서

  1. 문서나 문장에서 중복 단어 제거.
  2. 각 단어에 고유 인덱스 부여.(정수 인코딩)
  3. 표현할 단어에 인덱스 1 부여, 나머지 0 부여.


from konlpy.tag import Okt
 
okt = Okt()
token = okt.morphs("이것이 원 핫 인코딩이다")
 
word2index = {}
for voca in token:
    if voca not in word2index.keys():
        word2index[voca] = len(word2index)
print(word2index)  
# {'이': 0, '것': 1, '원': 2, '핫': 3, '인코딩': 4, '이다': 5}
 
def onehot_encoding(word, dic):
    onehot_vector = [0* (len(dic))
    index = dic[word]
    onehot_vector[index] = 1
    return onehot_vector
 
print(onehot_encoding("인코딩", word2index)) 
# 원-핫 인코딩 [0, 0, 0, 0, 1, 0]
cs



Keras 원-핫 인코딩


from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.utils import to_categorical
 
text = "나랑 점심 먹으러 갈래 점심 메뉴는 햄버거 갈래 갈래 햄버거 최고야"
 
= Tokenizer()
t.fit_on_texts([text])
print(t.word_index)
# {'갈래': 1, '점심': 2, '햄버거': 3, '나랑': 4, '먹으러': 5, '메뉴는': 6, '최고야': 7}
 
sub_text = "점심 먹으러 갈래 메뉴는 햄버거 최고야"
encoded = t.texts_to_sequences([sub_text])[0]
print(encoded)
# [2, 5, 1, 6, 3, 7]
 
one_hot = to_categorical(encoded)
print(one_hot)
 
'''
[[0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1.]]
'''
cs


원-핫 인코딩은 저장 공간 측면에서 비효율적이며 단어간 유사도를 표현할 수 없는 한계가 있지만, 다음 기법들로 다차원 공간에 유사도를 표현할 수 있다.

  • 카운트 기반의 벡터화 방법 : LSA, HAL
  • 예측 기반의 벡터화 방법 : NNLM, RNNLM, Word2Vec, FastText
  • 카운트와 예측 기반의 벡터화 방법 : GloVe




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

전처리와 정수 인코딩으로 각 문장들을 수치화 한 후에 각 문장들을 하나의 행렬로 보고 가장 긴 문장의 길이로 모든 문장들의 길이를 맞춰주는 것을 패딩(Padding) 이라 한다. 빠른 병렬 연산을 위해 필요한 기능이며, 보통 숫자 0으로 채워넣는 제로 패딩(zero padding) 을 사용한다. 패딩 길이를 지정해서 긴 문장을 자를 수도 있다.


Numpy 패딩


import numpy as np
 
encoded = [[15], [185], [135], [92], [2432], [32], [146], [146], [142], [773210111], [112313]]
 
max_len = max(len(item) for item in encoded)  # 정수 인코딩 된 각 문장의 가장 많은 요소 개수
 
for item in encoded:
    while len(item) < max_len:
        item.append(0)  # 제로 패딩
 
print(np.array(encoded))
 
 
''' 출력
[[ 1  5  0  0  0  0  0]
 [ 1  8  5  0  0  0  0]
 [ 1  3  5  0  0  0  0]
 [ 9  2  0  0  0  0  0]
 [ 2  4  3  2  0  0  0]
 [ 3  2  0  0  0  0  0]
 [ 1  4  6  0  0  0  0]
 [ 1  4  6  0  0  0  0]
 [ 1  4  2  0  0  0  0]
 [ 7  7  3  2 10  1 11]
 [ 1 12  3 13  0  0  0]]
'''
cs



Keras 패딩


from tensorflow.keras.preprocessing.sequence import pad_sequences
 
encoded = [[15], [185], [135], [92], [2432], [32], [146], [146], [142], [773210111], [112313]]
 
print(pad_sequences(encoded, padding='post', maxlen=7, value=0))
cs


pad_sequences 한 줄로 위와 동일한 결과를 출력한다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

토큰화, 정제 및 정규화 등의 전처리 작업을 마친 후에, 컴퓨터가 데이터 처리를 더 빠르게 하도록 텍스트를 수치화 하는 것을 정수 인코딩(Integer Encoding) 이라 한다.


결론 : keras 의 Tokenizer 를 사용하면 쉽게 해결



정수 인코딩 과정

  1. 문장 토큰화, 정제 및 일반화, 단어 토큰화.
  2. 빈도수를 기록하여 빈도수가 높은 순서대로 정렬 
  3. 자연어 처리에서 빈도수가 낮은 단어는 의미를 가지지 않을 가능성이 높으므로 제외
  4. 빈도수 순서로 정렬된 단어에 순차적으로 인덱스 부여
  5. 각 단어를 부여된 인덱스로 맵핑.


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from nltk.tokenize import sent_tokenize
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
 
text = "A barber is a person. a barber is good person. a barber is huge person. he Knew A Secret! The Secret He Kept is huge secret. Huge secret. His barber kept his word. a barber kept his word. His barber kept his secret. But keeping and keeping such a huge secret to himself was driving the barber crazy. the barber went up a huge mountain."
text = sent_tokenize(text)  # 문장 토큰화
 
vocab = {}
sentences = []
stop_words = set(stopwords.words('english'))
 
for i in text:
    sentence = word_tokenize(i)  # 단어 토큰화
    result = []
 
    for word in sentence:
        word = word.lower()  # 단어 중복제거를 위해 소문자화
        if word not in stop_words:
            if len(word) > 2:  # 3자 이상의 단어만 수집
                result.append(word)
                if word not in vocab:  # 단어 중복 제거
                    vocab[word] = 0
                vocab[word] += 1  # 빈도수 계산
 
    sentences.append(result)  # 문장별 정제된 단어 리스트
 
vocab_sorted = sorted(vocab.items(), key=lambda x: x[1], reverse=True)  # 빈도수 높은 순으로 단어 정렬
word_to_index = {}
= 0
for (word, frequency) in vocab_sorted:
    if frequency > 1:  # 빈도수 높은 순으로 정렬된 단어에 1부터 인덱스 부여
        i = i + 1
        word_to_index[word] = i
 
vocab_size = 5
words_frequency = [w for w, c in word_to_index.items() if c >= vocab_size + 1]
for w in words_frequency:  # 빈도수 상위 5개를 제외한 단어 제거
    del word_to_index[w]
 
word_to_index['OOV'= len(word_to_index) + 1  # OOV(Out-Of-Vocabulary) : 단어 집합에 없는 단어
encoded = []
for s in sentences:
    temp = []
    for w in s:
        try:
            temp.append(word_to_index[w])  # 단어를 인덱스로 치환
        except:
            temp.append(word_to_index['OOV'])
    encoded.append(temp)
 
print(word_to_index)
print(sentences)
print(encoded)
 

''' 출력 
{'barber'1'secret'2'huge'3'kept'4'person'5'OOV'6}
[['barber''person'], ['barber''good''person'], ['barber''huge''person'], ['knew''secret'], ['secret''kept''huge''secret'], ['huge''secret'], ['barber''kept''word'], ['barber''kept''word'], ['barber''kept''secret'], ['keeping''keeping''huge''secret''driving''barber''crazy'], ['barber''went''huge''mountain']]
[[15], [165], [135], [62], [2432], [32], [146], [146], [142], [6632616], [1636]]
'''
cs


뭔가 상당히 복잡해 보이는데 25줄까지는 전처리, 그 뒤로는 빈도수 계산하고 인덱스 부여한 뒤 단어 위치에 인덱스로 치환하는 과정이다.



27~38줄의 과정에 collection.Counter 를 사용할 수도 있다.


from collections import Counter
words = sum(sentences, [])  # 리스트 요소들을 하나의 리스트로 합치기
vocab = Counter(words)  # 중복 요소 제거 및 빈도수 계산하여 정렬
vocab = vocab.most_common(vocab_size)  # 빈도수 상위 개수만큼 추출
cs


마찬가지로 nltk.FreqDist 도 사용할 수 있다.


from nltk import FreqDist
import numpy as np
words = np.hstack(sentences)  # 리스트 요소들을 하나의 리스트로 합치기
vocab = FreqDist(words)   # 중복 요소 제거 및 빈도수 계산하여 정렬
cs


이 모든 것들을 한번에 해결하는 keras...


from tensorflow.keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer(6)  # 빈도수 상위 5개
tokenizer.fit_on_texts(sentences)  # 빈도수를 기준으로 단어 집합 생성
encode = tokenizer.texts_to_sequences(sentences)  # 정수 인코딩
cs


생성된 tokenizer 로 인덱스 부여 확인(word_index), 빈도수 확인(word_counts) 도 가능하다. 기본적으로 OOV 는 제거되므로 OOV 를 보존하려면 Tokenizer 에 oov_token 인자를 사용한다. 이 경우 OOV 의 default 인덱스 값은 1이며, 나머지 상위 5개 단어의 인덱스는 2부터 시작된다.


tokenizer = Tokenizer(num_words = vocab_size + 2, oov_token = 'OOV')
cs




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,



W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudart64_101.dll'; dlerror: cudart64_101.dll not found

I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.


PyCharm 에서 tensorflow 실행시 CUDA 10.1 이 설치되어 있지 않다는 경고(Warning).


CUDA 는 NVIDIA 의 CUDA 코어가 장착된 GPU 에서 병렬 처리를 가능하게 하는 GPGPU 기술이다. TensorFlow 2.0 부터는 CPU 버전과 GPU 버전이 통합되어, CUDA 를 지원하는 NVIDIA 그래픽카드가 있고 해당 CUDA 드라이버가 설치되어 있다면 자동으로 GPU 를 인식한다. 만약 NVIDIA 그래픽카드나 CUDA 가 설치되어 있지 않다면 PyCharm 에서는 위와 같이 경고를 발생하고 CPU 모드로 실행될 것이다.


CUDA 를 지원하는 NVIDIA 그래픽카드가 있다면 드라이버를 설치하여 GPU 가속을 사용할 수 있다. cudart64_101.dll 이 없다하니 10.1 버전을 설치하면 된다. 64는 비트 101은 버전을 뜻한다. 그 전에 본인의 CPU 가 CUDA 10.1 버전을 사용할 수 있는지를 먼저 체크해야 한다.


>>> import tensorflow as tf
>>> tf.config.list_physical_devices('GPU')
 
...
pciBusID: 0000:01:00.0 name: GeForce GTX 1050 computeCapability: 6.1
...
W tensorflow/stream_executor/platform/default/dso_loader.cc:59] Could not load dynamic library 'cudnn64_7.dll'; dlerror: cudnn64_7.dll not found
...
cs


또는 위키 사이트(https://en.wikipedia.org/wiki/CUDA) 본인 CPU 를 검색하여 compute capability 버전을 확인하면 대부분이 3.0~7.5 사이에 있으며, 이 버전들은 CUDA 10.1 을 사용하는데 문제가 없다.


 CUDA SDK 10.0 – 10.2 support for compute capability 3.0 – 7.5 




CUDA® Toolkit 설치 - https://developer.nvidia.com/cuda-toolkit-archive


설치 후에 PyCharm 을 재시작하면, 경고가 사라지고 아래와 같은 GPU 사용 로그를 볼 수 있다.


I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cudart64_101.dll


하지만 여기서 끝이 아니다.

심층 신경망을 위한 cuDNN(Cuda Deep Neural Network) 라이브러리의  cuDNN64_7.dll  파일이 없으면 TensorFlow 가 로드되지 않는다.




cuDNN 설치https://developer.nvidia.com/cudnn


cuDNN 은 NVIDIA 의 회원이어야 다운로드가 가능하다. 귀찮지만 가입을 하고 본인에 맞는 버전의 cuDNN SDK 를 다운로드한다. 마찬가지로 현재 최신버전인 cuDNN v8.0.5 for CUDA 10.1 를 사용할 수도 있지만 메시지에서 요구하는 cuDNN7 의 최신버전(cuDNN v7.6.5 for CUDA 10.1)을 다운받는다. 그리고 다운받은 디렉토리 안의 세가지 파일을

  • bin/cudnn64_7.dll, 
  • include/cudnn.h, 
  • lib/x64/cudnn.lib

CUDA 툴킷이 설치된 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1 안의 각각의 디렉토리에 복사하면 추가로 Path 설정을 할 필요가 없다.


* 설치 확인


>>> import tensorflow as tf
>>> tf.config.list_physical_devices('GPU')
 
I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library nvcuda.dll I tensorflow/core/common_runtime/gpu/gpu_device.cc:1716] Found device 0 with properties: pciBusID: 0000:01:00.0 name: GeForce GTX 1050 computeCapability: 6.1 coreClock: 1.493GHz coreCount: 5 deviceMemorySize: 2.00GiB deviceMemoryBandwidth: 104.43GiB/s I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cudart64_101.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cublas64_10.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cufft64_10.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library curand64_10.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cusolver64_10.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cusparse64_10.dll I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library cudnn64_7.dll I tensorflow/core/common_runtime/gpu/gpu_device.cc:1858] Adding visible gpu devices: 0
cs


CUDA 관련 자세한 사항은 텐스플로우 사이트의 [GPU 지원] 항목을 참조.

https://www.tensorflow.org/install/gpu





WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

PyCharm + Anaconda + Tensorflow 에 처음 손대면서 생긴일.

  • PyCharm 은 사이트에서 받아서 설치하고,
  • Anaconda 도 사이트에서 받아 설치하고,
  • Tensorflow 는 pip 로 설치하고...


하지만 PyCharm 에서 별 설정없이  import tensorflow  를 날렸다가는,


ImportError: DLL load failed while importing _pywrap_tensorflow_internal: 지정된 모듈을 찾을 수 없습니다.

...or...

ModuleNotFoundError: No module named 'tensorflow'


식의 에러메시지를 만나게 된다.


설치가 되어 있음에도 모듈을 찾을 수 없다는 것은 해당 IDE 에서 tensorflow 를 사용할 수 있도록 설정 등이 제대로 되어 있지 않음을 뜻하는거 같은데...


만약 Anaconda 설치 전에 python 을 별도로 설치했거나, PyCharm 설치 후에 새 프로젝트 생성하면서 default 로 대충 넘기다 보면 나도 모르게 가상환경으로 인터프리터가 생성 되던지.. 해서 일단 인터프리터는 두 이상이 되어 있을 수 있다. 그리고 현재 인터프리터에서 tensorflow 를 사용할 수 있도록 준비가 되어 있는지를 확인해야 한다.


난 현재 인터프리터에서 pip 로 tensorflow 설치 및 확인하였고, PyCharm 탐색기의 External Libraries, ~/anaconda3/Lib/site-packages 에서도 확인했는데 tensorflow 패키지는 확실히 있다. PyCharm 문법에서도 오류 없이 타이핑된다. 하지만 해당 파일을 실행시키면 ImportError...


더 알 수 없는 것은 PC 두 대에 동일하게 설치했는데 한 대는 이상이 없고 한 대만 ImportError 가 발생한다. 같은 2.3.1 버전인데... 인터넷 검색 결과 ImportError 에 관련된 비슷비슷한 에러가 상당히 많다. 그나마 가능성이 있을 것 같은 두 가지 원인을 찾아냈다.



두 PC 모두 하드웨어 사양은 동일했는데, 에러없이 정상적으로 구동된 PC 는 위 드라이버가 모두 설치되어 있었다. (내 손으로 깔은 기억은 없음...)


  • Microsoft Visual C++ 2017 Redistributable(x64)
  • NVIDIA CUDA Visual Studio Integration 10.0
  • NVIDIA Nsight Visual Studio Edition 6.0


에러난 PC에 하나하나 깔아보려고 했는데  vc_redist 2015-2019  를 설치하자마자 ImportError 문제가 해결이 됐다...; 참고로 Visual C++ 재배포 가능 패키지란, Visual C++ 이 설치되어 있지 않은 컴퓨터에 Visual C++ 라이브러리의 런타임 구성 요소를 설치하여 Visual C++ 로 개발된 응용 프로그램을 실행하게 해주는 패키지이다.


일단 되서 다행인데 vc_redist 2015 가 이미 깔려 있었는데 안됐던것도 억울하고,

에러도 _pywrap_tensorflow_internal 라고 나와 있으면 내가 어찌 아냐? 그것도 억울하고,

그렇게 중요한 파일이면 vc_redist 파일을 필수로 설치하게 하던지... 무식이 가장 억울하다... 






WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,