RNN을 사용하여 기본 수학 방정식 풀기 [코딩 예제 포함]
게시 됨: 2020-12-07삶이 RNN을 준다면 계산기를 만들어라
순환 신경망은 노드 간의 연결이 순차 방향 그래프를 형성하는 고전적인 인공 신경망 중 하나입니다. RNN은 가변 길이 시퀀스를 처리하기 위한 내부 상태 메모리로 인해 음성 인식, 필기 인식 등과 같은 애플리케이션으로 유명합니다.
RNN은 두 가지 유형으로 더 분류됩니다. 첫 번째는 신경망이 방향성 비순환 그래프 형태인 유한 임펄스로, 여기서 한 노드는 네트워크에서 가시적인 주기 없이 앞서 있는 하나 이상의 노드와 연결될 수 있습니다. 또 다른 하나는 신경망이 피드포워드 신경망으로 풀릴 수 없는 방향성 순환 그래프 형태인 무한 임펄스입니다.
목차
우리는 무엇을 할 것인가?
산술 표현식의 출력을 예측하는 모델을 작성해 보겠습니다. 예를 들어, 내가 '11+88'을 입력하면 모델은 시퀀스의 다음 단어를 '99'로 예측해야 합니다. RNN은 순차적 데이터를 다루기 때문에 입력과 출력은 일련의 문자입니다.
이제 모델의 아키텍처를 설계하는 것은 데이터 세트 수집과 비교할 때 간단한 작업처럼 보입니다. 데이터 굶주림 AI 모델은 수용 가능한 정확도를 위해 상당한 양의 데이터가 필요하기 때문에 데이터를 생성하거나 데이터 세트를 수집하는 것은 힘든 작업입니다.
따라서 이 모델은 6가지 기본 단계로 구현할 수 있습니다.

- 데이터 생성
- 모델 구축
- 데이터 벡터화 및 역벡터화
- 데이터세트 만들기
- 모델 훈련
- 모델 테스트
모델 구현에 대해 알아보기 전에 필요한 모든 라이브러리를 가져오겠습니다.
| numpy 를 np 로 가져오기 텐서플로 를 tf 로 가져오기 tensorflow.keras.models 에서 가져오기 순차 tensorflow.keras.layers 에서 Dense, Dropout, SimpleRNN, RepeatVector, TimeDistributed 가져 오기 tensorflow.keras.callbacks 에서 EarlyStopping, LambdaCallback 가져오기 termcolor 에서 가져 오기 |
1. 데이터 생성
기본 산술 방정식을 작성하는 데 필요한 모든 문자를 포함하는 문자열을 정의해 보겠습니다. 따라서 문자열은 0-9의 모든 문자와 /, *, +, -, .(십진수)와 같은 모든 산술 연산자로 구성됩니다.
수치 데이터를 모델에 직접 공급할 수 없으며 데이터를 텐서 형태로 전달해야 합니다. 데이터의 문자열을 원-핫 인코딩된 벡터로 변환하면 최적화된 모델 성능을 얻을 수 있습니다. 원-핫 인코딩된 벡터는 우리의 char 스트링의 길이와 같은 길이를 갖는 배열이며, 각 원-핫 벡터는 각 스트링에 존재하는 각각의 문자 인덱스에서만 1을 가집니다.
예를 들어, 문자열이 '0123456789'이고 '12'와 같은 문자열을 인코딩하려는 경우 원-핫 벡터는 [ [0,1,0,0,0,0,0,0 ,0,0], [0,0,1,0,0,0,0,0,0,0]]. 그렇게 하려면 하나의 인덱스를 키로 사용하고 문자를 값으로 사용하고 다른 하나를 그 반대로 사용하는 두 개의 사전을 만들어야 합니다.
| char_string = ' 0123456789/*+-. ' num_chars = len (문자열) character_to_index = dict ((c, i) for i, c in enumerate (char_string)) index_to_character = dict ((i, c) for i, c in enumerate (char_string)) |
이제 해당 방정식의 결과와 함께 임의의 산술 방정식을 반환하는 함수를 작성해 보겠습니다.
| def 나눗셈 (n, d): d != 0 이면 n / d 를 반환 하고 그렇지 않으면 0 def 데이터젠 (): random1 = np.random.randint(낮음 = 0 , 높음 = 100 ) random2 = np.random.randint(낮음 = 0 , 높음 = 100 ) 연산 = np.random.randint(낮음 = 0 , 높음 = 4 ) 연산 == 1 인 경우 : 산술 = str (무작위1) + ' + ' + str (무작위2) res = str (random1 + random2) 엘리프 연산 == 1 : 산술 = str (random1) + ' – ' + str (random2) res = str (random1 – random2) 엘리프 연산 == 2 : 산술 = str (random1) + ' * ' + str (random2) res = str (random1 * random2) 다른 : 산술 = str (random1) + ' / ' + str (random2) res = str ( round (division(random1, random2), 2 )) 산술 반환 , res |
더 읽어보기: 흥미로운 신경망 프로젝트 아이디어
2. 모델 구축
모델에는 인코더와 디코더가 있습니다. 인코더는 입력 형태가 (None,num_chars)이고 128개의 은닉 유닛이 있는 단순한 RNN 모델입니다. 우리가 은닉 유닛을 32,64,128 등으로 선택하는 이유는 은닉 유닛을 거듭제곱한 CPU 또는 GPU의 성능이 더 우수하기 때문입니다. 2.
인코더는 완전히 연결된 네트워크가 될 것이며 이들의 출력은 네트워크로 피드백될 것입니다. 이것이 RNN이 작동하는 방식입니다. RNN 레이어는 기본적으로 'tanh' 활성화를 사용하며 인코더에 가장 적합하기 때문에 변경하지 않을 것입니다. 이 레이어의 출력은 단일 벡터가 되며 전체 출력의 단일 벡터를 얻기 위해 필요한 횟수만큼 RepeatVector() 레이어를 매개변수로 사용합니다.
이제 출력 벡터는 주어진 입력의 본질을 갖게 되며 이 벡터는 디코더에 공급됩니다.
디코더는 단순한 RNN 레이어로 구성되며, 예측 시퀀스를 반환하기 위해 RNN 레이어가 필요하므로 'return_sequences'를 True로 플래그 지정해야 하므로 출력 시퀀스를 생성합니다. 'return_sequences'를 True로 지정하면 RNN 계층은 각 시간 단계(다대다 RNN)에 대해 예측된 시퀀스를 반환합니다.
이 RNN 레이어의 출력은 'num_chars'개의 은닉 유닛이 있는 Dense 레이어에 공급되며 각 문자의 확률이 필요하기 때문에 softmax 활성화를 사용합니다. Dense 계층을 배포하기 전에 각 시간 단계의 출력에 대해 Dense 계층을 배포해야 하므로 이 계층을 TimeDistributed 계층으로 연결해야 합니다.
| hidden_units = 128 max_time_steps = 5 #출력을 5자로 하드코딩하고 있습니다. def 모델 (): 모델 = 순차() model.add(SimpleRNN(hidden_units, input_shape = ( None , num_chars))) model.add(RepeatVector(max_time_steps)) model.add(SimpleRNN(hidden_units, return_sequences = True )) model.add(TimeDistributed(Dense(num_chars, 활성화 = ' softmax ' ))) 반환 모델 모델 = 모델() model.summary() model.compile(loss = ' categorical_crossentropy ' , 옵티마이저 = ' adam ' , 메트릭 = [ ' 정확도 ' ]) |

모델의 아키텍처는 위와 같습니다.
필독: 신경망 튜토리얼
3. 데이터 벡터화 및 역벡터화
데이터를 벡터화 및 역벡터화하는 함수를 정의해 보겠습니다.
다음은 산술식과 결과를 함께 벡터화하는 함수입니다.
| def 벡터화 (산술, 해상도): x = np.zeros((max_time_steps, num_chars)) y = np.zeros((max_time_steps, num_chars)) ![]() x_remaining = max_time_steps – len (산술) y_remaining = max_time_steps – len (res) 열거 (산술) 에서 i, c 에 대해 : x[x_remaining + i, character_to_index[c]] = 1 범위 (x_remaining) 에 있는 i 의 경우: x[i, character_to_index[ ' 0 ' ]] = 1 열거 (res) 에서 i, c 에 대해 : y[y_remaining + i, character_to_index[c]] = 1 범위 내 i 의 경우 (y_remaining): y[i, character_to_index[ ' 0 ' ]] = 1 반환 x, y |
마찬가지로 여기에 문자열을 역 벡터화하는 함수가 있습니다. 우리가 받는 출력은 확률의 벡터이므로 가장 높은 확률을 가진 문자를 선택하기 위해 np.argmax()를 사용할 것입니다. 이제 index_to_character 사전을 사용하여 해당 인덱스의 문자를 역추적합니다.
| def devectorize (입력): res = [index_to_character[np.argmax(vec)] for i, vec in enumerate ( 입력 )] ' ' .join(res) 반환 |
이제 'devectorize' 기능에 대한 제약 조건은 후행 문자를 0으로 채울 것이라는 것입니다. 예를 들어, 입력 벡터가 ('1-20', '-19')이면 역 벡터화된 출력은 ('01-20', '00-19')입니다. 우리는 이러한 추가 패딩된 0을 처리해야 합니다. 문자열을 제거하는 함수를 작성해 보겠습니다.
| def 스트리핑 (입력): 플래그 = 거짓 출력 = ' ' c 의 경우 입력 : 플래그 및 c == ' 0 ' 이 아닌 경우 : 계속하다 c == ' + ' 또는 c == ' – ' 또는 c == ' * ' 또는 c == ' / ' 또는 c == '인 경우 . ' : 플래그 = 거짓 다른 : 플래그 = 참 출력 += c 반환 출력 |
4. 데이터 세트 만들기
이제 데이터 생성을 위한 함수 정의가 완료되었으므로 해당 함수를 사용하여 이러한 (산술 표현식, 결과) 쌍이 많은 데이터 세트를 만들어 보겠습니다.
| def create_dataset (num_equations): x_train = np.zeros((num_equations, max_time_steps, num_chars)) y_train = np.zeros((num_equations, max_time_steps, num_chars)) 범위 (num_equations) 의 i 에 대해 : e, l = 데이터젠() x, y = 벡터화(e, l) x_train[i] = x y_train[i] = y x_train, y_train 반환 |
5. 모델 훈련
데이터 기아 모델을 훈련시키기에 적당한 50,000개 샘플의 데이터 세트를 생성해 보겠습니다. 이 데이터의 25%를 검증에 사용할 것입니다. 또한 정확도가 8 Epoch 동안 변경되지 않은 경우 지능형 훈련 중단에 대한 콜백을 생성해 보겠습니다. 이는 인내 매개변수를 8로 설정하여 달성할 수 있습니다.

| x_train, y_train = create_dataset( 50000 ) simple_logger = LambdaCallback( on_epoch_end = 람다 전자, l: 인쇄 ( ' {:.2f} ' .format(l[ ' val_accuracy ' ]), end = ' _ ' ) ) Early_stopping = EarlyStopping(모니터 = ' val_loss ' , 인내 = 8 ) model.fit(x_train, y_train, epochs = 100 , validation_split = 0.25 , verbose = 0 , 콜백 = [simple_logger, early_stopping]) |
6. 모델 테스트
이제 크기가 30인 데이터 세트를 만들어 모델을 테스트해 보겠습니다.
| x_test, y_test = create_dataset(num_equations = 20 ) preds = model.predict(x_test) full_seq_acc = 0 i의 경우 pred 열거 형 ( preds): pred_str = 스트리핑(devectorize(pred)) y_test_str = 스트리핑(devectorize(y_test[i])) x_test_str = 스트리핑(devectorize(x_test[i])) col = ' 녹색 ' pred_str == y_test_str 이면 ' 빨간색 ' _ full_seq_acc += 1 / len (preds) * int (pred_str == y_test_str) outstring = ' 입력: {}, 출력: {}, 예측: {} ' .format(x_test_str, y_test_str, pred_str) 인쇄 (색상(아웃스트링, 열)) print ( ' \n 전체 시퀀스 정확도: {:.3f} % ' .format( 100 * full_seq_acc)) |
출력은 다음과 같을 것입니다

정확도가 약간 떨어지는 것을 볼 수 있습니다. 어쨌든 은닉 유닛의 수, 검증 분할, 에포크 수 등과 같은 몇 가지 하이퍼파라미터를 조정하여 정확도를 최적화할 수 있습니다.
결론
우리는 RNN의 기본 워크플로를 이해했으며, RNN이 순차 데이터에 가장 적합하다는 것을 이해하고, 무작위 산술 방정식의 데이터 세트를 생성하고, 기본 산술 표현식의 출력을 예측하기 위한 순차 모델을 개발하고, 다음 데이터 세트로 해당 모델을 훈련했습니다. 우리는 모델이 전에 본 적이 없는 작은 데이터 세트로 모델을 만들고 마침내 테스트했습니다.
RNN, 머신 러닝에 대해 자세히 알아보려면 IIIT-B & upGrad의 기계 학습 및 AI PG 디플로마를 확인하세요. 이 디플로마는 일하는 전문가를 위해 설계되었으며 450시간 이상의 엄격한 교육, 30개 이상의 사례 연구 및 과제를 제공합니다. IIIT-B 동문 자격, 5개 이상의 실용적인 실습 캡스톤 프로젝트 및 최고의 기업과의 취업 지원.
머신 러닝에서 다양한 유형의 신경망은 무엇입니까?
기계 학습에서 인공 신경망은 기본적으로 인간의 두뇌를 닮도록 설계된 계산 모델입니다. 기계 학습이 달성해야 하는 수학적 계산을 기반으로 사용하는 다양한 종류의 인공 신경망이 있습니다. 이러한 신경망은 다양한 방식으로 데이터에서 학습하는 다양한 기계 학습 기술의 하위 집합입니다. 가장 널리 사용되는 신경망 유형은 순환 신경망 - 장기 단기 기억, 피드포워드 신경망 - 인공 뉴런, 방사형 기저 기능 신경망, 코호넨 자기 조직화 신경망, 컨볼루션 신경망 및 모듈식 신경망입니다. 다른 사람들 사이에서.
순환 신경망의 장점은 무엇입니까?
순환 신경망은 딥 러닝 및 머신 러닝에서 가장 일반적으로 사용되는 인공 신경망 중 하나입니다. 이러한 유형의 신경망 모델에서는 이전 단계에서 얻은 결과가 다음 단계의 입력으로 제공됩니다. 순환 신경망은 다음과 같은 몇 가지 장점이 있습니다. 이전 입력을 포함하여 시간이 지남에 따라 모든 정보를 유지할 수 있어 시계열 예측에 이상적입니다. 이 유형은 장단기 기억의 가장 좋은 예입니다. 또한 순환 신경망은 컨볼루션 레이어를 사용하여 건설적인 픽셀 이웃을 제공합니다.
실제 응용 프로그램에서 신경망은 어떻게 사용됩니까?
인공 신경망은 머신 러닝과 인공 지능의 초 전문 분야인 딥 러닝의 필수적인 부분입니다. 신경망은 다양한 주요 목표를 달성하기 위해 다양한 산업에서 사용됩니다. 인공 신경망의 가장 흥미로운 실제 응용 분야로는 주식 시장 예측, 안면 인식, 항공우주 산업의 고성능 자동 조종 및 결함 진단, 국방 부문의 무장 공격 및 물체 위치 분석, 이미지 처리, 의료 분야의 약물 발견 및 질병 감지, 서명 검증, 필기 분석, 일기 예보 및 소셜 미디어 동향 예측 등.

