tensorflow 학습 튜 토리 얼 의 텍스트 분류 에 대한 상세 한 분석

머리말
요 며칠 동안 caffe 2 가 발표 되 었 습 니 다.모 바 일 을 지원 합 니 다.저 는 싱글 칩 과 같은 사물 인터넷 PC 방 이 핸드폰 이 아 닌 것 으로 이해 합 니 다.아이 폰 7 이 CNN 을 뛰 는 것 을 생각해 보 세 요.화면 이 너무 아름 답 습 니 다~
구덩이 에 막 들 어 갔 고 심지어 구덩이 에 들 어가 지 않 은 사람 으로서 텐 소 플 로 우 를 솔직히 연구 해 보 자.비록 카페 가 잘 되 지 는 않 았 지만.tensorflow 의 특징 은 소개 하지 않 겠 습 니 다.
  • 파 이 썬 을 바탕 으로 빨리 쓰 고 읽 을 수 있 습 니 다.
  • CPU 와 GPU 를 지원 해 다 중 GPU 시스템 에서 의 작 동이 더욱 원활 하 다.
  • 코드 컴 파일 효율 이 비교적 높다.
  • 지역사회 의 발전 이 매우 빠 르 고 활발 하 다.
  • 네트워크 토폴로지 구조 와 성능 을 나타 내 는 시각 화 도 를 생 성 할 수 있다.
  • tensorflow(tf)연산 절차:
    tensorflow 의 운행 절 차 는 주로 2 단계 로 구조 모델 과 훈련 이다.
    구조 모델 단계 에서 우 리 는 그림(Graph)을 구축 하여 우리 의 모델 을 묘사 해 야 한다.tensoflow 의 강력 한 점도 여기에 있다.tensorboard 를 지원 한다.

    이런 그림 은 약간 흐름 도 같 고 구 글 의 tensoflow 놀이 터 도 추천 합 니 다.재 미 있 습 니 다.
    그리고 훈련 단계 에 이 르 러 구조 모델 단계 에 서 는 계산 을 하지 않 고tensoflow.Session.run()때 만 계산 을 시작한다.
    텍스트 분류
    먼저 코드 를 제시 한 후에 우 리 는 하나하나 설명 하고 있다.
    
    # -*- coding: utf-8 -*-
    
    import pandas as pd
    import numpy as np
    import tensorflow as tf
    from collections import Counter
    from sklearn.datasets import fetch_20newsgroups
    
    def get_word_2_index(vocab):
     word2index = {}
     for i,word in enumerate(vocab):
     word2index[word] = i
     return word2index
    
    
    def get_batch(df,i,batch_size):
     batches = []
     results = []
     texts = df.data[i*batch_size : i*batch_size+batch_size]
     categories = df.target[i*batch_size : i*batch_size+batch_size]
     for text in texts:
     layer = np.zeros(total_words,dtype=float)
     for word in text.split(' '):
      layer[word2index[word.lower()]] += 1
     batches.append(layer)
     
     for category in categories:
     y = np.zeros((3),dtype=float)
     if category == 0:
      y[0] = 1.
     elif category == 1:
      y[1] = 1.
     else:
      y[2] = 1.
     results.append(y)
     return np.array(batches),np.array(results)
    
    def multilayer_perceptron(input_tensor, weights, biases):
     #hidden RELU    
     layer_1_multiplication = tf.matmul(input_tensor, weights['h1'])
     layer_1_addition = tf.add(layer_1_multiplication, biases['b1'])
     layer_1 = tf.nn.relu(layer_1_addition)
     
     layer_2_multiplication = tf.matmul(layer_1, weights['h2'])
     layer_2_addition = tf.add(layer_2_multiplication, biases['b2'])
     layer_2 = tf.nn.relu(layer_2_addition)
     
     # Output layer 
     out_layer_multiplication = tf.matmul(layer_2, weights['out'])
     out_layer_addition = out_layer_multiplication + biases['out']
     return out_layer_addition
    
    #main
    # sklearn.datas    
    cate = ["comp.graphics","sci.space","rec.sport.baseball"]
    newsgroups_train = fetch_20newsgroups(subset='train', categories=cate)
    newsgroups_test = fetch_20newsgroups(subset='test', categories=cate)
    
    #            
    vocab = Counter()
    for text in newsgroups_train.data:
     for word in text.split(' '):
     vocab[word.lower()]+=1
     
    for text in newsgroups_test.data:
     for word in text.split(' '):
     vocab[word.lower()]+=1
    
    total_words = len(vocab)
    word2index = get_word_2_index(vocab)
    
    n_hidden_1 = 100 #   hidden      
    n_hidden_2 = 100 #   hidden      
    n_input = total_words 
    n_classes = 3  # graphics, sci.space and baseball 3            
    #  
    input_tensor = tf.placeholder(tf.float32,[None, n_input],name="input")
    output_tensor = tf.placeholder(tf.float32,[None, n_classes],name="output") 
    #            
    weights = {
     'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
     'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
     'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))
    }
    biases = {
     'b1': tf.Variable(tf.random_normal([n_hidden_1])),
     'b2': tf.Variable(tf.random_normal([n_hidden_2])),
     'out': tf.Variable(tf.random_normal([n_classes]))
    }
    
    #   
    prediction = multilayer_perceptron(input_tensor, weights, biases)
    
    #    loss and optimizer   softmax  
    # reduce_mean      
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
    
    #       
    init = tf.global_variables_initializer()
    
    #   graph
    with tf.Session() as sess:
     sess.run(init)
     training_epochs = 100
     display_step = 5
     batch_size = 1000
     # Training
     for epoch in range(training_epochs):
     avg_cost = 0.
     total_batch = int(len(newsgroups_train.data) / batch_size)
     for i in range(total_batch):
      batch_x,batch_y = get_batch(newsgroups_train,i,batch_size)
      c,_ = sess.run([loss,optimizer], feed_dict={input_tensor: batch_x,output_tensor:batch_y})
      #       
      avg_cost += c / total_batch
     #  5 epoch    loss
     if epoch % display_step == 0:
      print("Epoch:", '%d' % (epoch+1), "loss=", "{:.6f}".format(avg_cost))
     print("Finished!")
    
     # Test model
     correct_prediction = tf.equal(tf.argmax(prediction, 1), tf.argmax(output_tensor, 1))
     #      
     accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
     total_test_data = len(newsgroups_test.target)
     batch_x_test,batch_y_test = get_batch(newsgroups_test,0,total_test_data)
     print("Accuracy:", accuracy.eval({input_tensor: batch_x_test, output_tensor: batch_y_test}))
    코드 해석
    여기 서 우 리 는 모델 을 저장 하 는 작업 을 하지 않 았 다.코드 절차 에 따라 저 는 각종 함수 와 선택 을 설명 하 겠 습 니 다.사실은 전체 코드 는github기 존의 것 이 고 저도 공부 합 니 다.
    데 이 터 를 가 져 옵 니 다.저 희 는 sklearn.datas 에서 데 이 터 를 가 져 옵 니 다.여기 에는 20 가지 뉴스 텍스트 가 있 습 니 다.저 희 는 모든 단어 에 따라 분류 합 니 다.
    
    #            
    vocab = Counter()
    for text in newsgroups_train.data:
     for word in text.split(' '):
     vocab[word.lower()]+=1
     
    for text in newsgroups_test.data:
     for word in text.split(' '):
     vocab[word.lower()]+=1
    
    total_words = len(vocab)
    word2index = get_word_2_index(vocab)
    각 index 에 따라 one 로 전환hot 형 인 코딩,One-hot 인 코딩 은 유효한 인 코딩 이 라 고도 부 릅 니 다.주로 N 비트 상태 레지스터 를 사용 하여 N 개의 상 태 를 인 코딩 합 니 다.모든 상 태 는 그의 독립 된 레지스터 위치 이 고 임의의 경우 에 한 명 만 유효 합 니 다.
    
    def get_batch(df,i,batch_size):
     batches = []
     results = []
     texts = df.data[i*batch_size : i*batch_size+batch_size]
     categories = df.target[i*batch_size : i*batch_size+batch_size]
     for text in texts:
     layer = np.zeros(total_words,dtype=float)
     for word in text.split(' '):
      layer[word2index[word.lower()]] += 1
     batches.append(layer)
     
     for category in categories:
     y = np.zeros((3),dtype=float)
     if category == 0:
      y[0] = 1.
     elif category == 1:
      y[1] = 1.
     else:
      y[2] = 1.
     results.append(y)
     return np.array(batches),np.array(results)
    이 코드 에 서 는 사용자 정의 data 의 데이터 범위,즉 몇 개의 데이터 에 따라 훈련 하고 일괄 처리 합 니 다.테스트 모델 을 테스트 할 때,우 리 는 더욱 큰 일괄 처리 로 사전 을 제공 할 것 이다.이것 이 바로 가 변 적 인 일괄 처리 차원 을 정의 해 야 하 는 이유 이다.
    구조 신경 망
    신경 망 은 계산 모형 이다.이 시스템 들 은 명확 한 프로 그래 밍 이 아니 라 자율 학습 과 훈련 을 받는다.아래 그림 은 전통 적 인 3 층 신경 망 이다.

    이 신경 망 에서 우리 의 hidden 층 은 2 층 으로 확대 되 었 는데 이 두 층 은 똑 같은 일 을 했 습 니 다.다만 hidden 1 층 의 수출 은 hidden 2 의 입력 입 니 다.
    
    weights = {
     'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])),
     'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
     'out': tf.Variable(tf.random_normal([n_hidden_2, n_classes]))
    }
    biases = {
     'b1': tf.Variable(tf.random_normal([n_hidden_1])),
     'b2': tf.Variable(tf.random_normal([n_hidden_2])),
     'out': tf.Variable(tf.random_normal([n_classes]))
    }
    입력 층 에 서 는 첫 번 째 숨겨 진 층 에 몇 개의 노드 가 있 는 지 정의 해 야 합 니 다.이 노드 들 은 특징 이나 신경원 이 라 고도 불 린 다.위의 예 에서 우 리 는 모든 원 으로 하나의 노드 를 표시 한다.
    입력 층 의 모든 노드 는 데이터 집중 의 한 단어 에 대응 합 니 다.(나중에 우 리 는 이것 이 어떻게 실행 되 는 지 볼 수 있 습 니 다)
    각 노드(뉴 런)에 하나의 가중치 를 곱 하 다.모든 노드 는 하나의 가중치 가 있 는데 훈련 단계 에 신경 망 은 이런 수 치 를 조정 하여 정확 한 수출 을 할 수 있다.
    입력 을 가중치 에 곱 하고 값 을 편차 와 더 하면 Y=Wx+b 와 같은 linear regression 입 니 다.이 데이터 들 도 활성화 함 수 를 통 해 전달 해 야 한다.이 활성화 함 수 는 각 노드 의 최종 출력 을 정의 합 니 다.활성화 함수 가 많 습 니 다.
  • Rectified Linear Unit(RELU)-은 층 뉴 런 출력 에 사용
  • Sigmoid-은 층 신경원 출력 에 사용
  • Softmax-다 분류 신경 망 출력
  • Linear-회귀 신경 망 출력(또는 2 분류 문제)
  • 여기 서 우리 의 hidden 층 에 서 는 RELU 를 사 용 했 습 니 다.이전 에는 대부분 전통 적 인 sigmoid 계열 로 활성화 되 었 습 니 다.


    그림 을 통 해 알 수 있 듯 이 도 수 는 0 부터 빠르게 0 에 가 까 워 져'경사도 가 사라 짐'현상 을 일 으 키 기 쉬 우 며 RelU 의 도 수 는 이러한 문제 가 존재 하지 않 는 다.sigmoid 류 함수 의 주요 변 화 는 1)일방 억제 2)상대 적 으로 넓 은 흥분 경계 3)희소 활성 입 니 다.이것 은 사람의 신경 피층 의 작업 원리 와 비슷 하 다.
    왜 오프셋 상수 를 넣 어야 합 니까?
    sigmoid 를 예 로 들 면
    가중치 w 는 sigmoid 함수 로 하여 금 경사 정 도 를 조정 할 수 있 게 합 니 다.아래 그림 은 가중치 변화 시 sigmoid 함수 도형 의 변화 상황 입 니 다.

    W 가 아무리 변화 하 더 라 도 함 수 는(0,0.5)거 쳐 야 하지만 실제 상황 에서 우 리 는 x 가 0 에 가 까 울 때 함수 결 과 는 다른 값 이 어야 할 수도 있다.
    우리 가 가중치 w 와 오프셋 b 를 바 꿀 때 뉴 런 구조 에 여러 가지 수출 가능성 을 가 질 수 있다.이것 은 하나의 뉴 런 일 뿐 신경 망 에서 수천 만 개의 뉴 런 이 결합 하면 복잡 한 수출 모델 을 만 들 수 있다.
    출력 층 의 값 도 가중치 에 곱 하고 우리 도 오 차 를 더 해 야 하지만 지금 은 함수 가 다 릅 니 다.
    모든 텍스트 를 분류 로 표시 하고 싶 으 며,이 분 류 는 서로 독립 되 어 있 습 니 다.(한 텍스트 는 두 개의 분류 에 동시에 속 할 수 없습니다.)
    이 점 을 고려 하면 ReLu 활성화 함수 가 아 닌 Softmax 함 수 를 사용 할 것 입 니 다.이 함 수 는 모든 완전한 출력 을 0 과 1 사이 의 값 으로 바 꾸 고 모든 단원 의 합 이 1 인지 확인 합 니 다.
    이 신경 망 에 서 는 output 층 에 세 개의 신경 원 이 뚜렷하게 나타 나 세 가지 분 본 분류 에 대응 하고 있다.
    
    #       
    init = tf.global_variables_initializer()
    
    #   graph
    with tf.Session() as sess:
     sess.run(init)
     training_epochs = 100
     display_step = 5
     batch_size = 1000
     # Training
     for epoch in range(training_epochs):
     avg_cost = 0.
     total_batch = int(len(newsgroups_train.data) / batch_size)
     for i in range(total_batch):
      batch_x,batch_y = get_batch(newsgroups_train,i,batch_size)
      c,_ = sess.run([loss,optimizer], feed_dict={input_tensor: batch_x,output_tensor:batch_y})
      #       
      avg_cost += c / total_batch
     #  5 epoch    loss
     if epoch % display_step == 0:
      print("Epoch:", '%d' % (epoch+1), "loss=", "{:.6f}".format(avg_cost))
     print("Finished!")
    여기 인자 설정:
  • training_epochs=100\#100 회 재 귀 훈련
  • display_step=5\#print 5 회 마다 현재 loss 값
  • batch_size=1000\#훈련 데이터 의 분할
  • 네트워크 가 공부 하고 있 는 지 알 기 위해 서 는 출력 값(Z)과 기대치(expected)를 비교 해 봐 야 한다.우 리 는 이것 의 차이 점 을 어떻게 계산 해 야 합 니까?이 문 제 를 해결 할 방법 은 매우 많다.
    우 리 는 분류 임 무 를 진행 하고 있 기 때문에 손실 을 측정 하 는 가장 좋 은 방법 은 교차 엔트로피 오차 이다.
    TensorFlow 를 통 해 교차 엔트로피 오차(이것 은 softmax 활성화 함수)를 계산 하고 평균 오차 tf.nn.softmax_cross_entropy_with_logits() 를 계산 합 니 다.
    출력 오 차 를 최소 화하 기 위해 가중치 와 오차 의 최 적 치 를 사용 합 니 다.이 를 위해 서 는 경사도 하강 법 이 필요 하 다.더 구체 적 으로 는 무 작위 경사도 하강 이 필요 하 다.
    대응 코드:
    
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=output_tensor))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
    tensoflow 는 이미 이 잡다 한 알고리즘 을 함수 로 봉 했 습 니 다.우 리 는 특정한 함수 만 선택 하면 됩 니 다.tf.reduced_mean()방법 은 문법 사탕 으로 두 가지 일 을 했다.
    compute_gradients(loss,)계산
    apply_gradients(<변수 목록>)전시
    이 방법 은 새로운 값 으로 모든 tf.Variables 를 업데이트 하 였 기 때문에 변수 목록 을 전달 할 필요 가 없습니다.
    실행 계산
    Epoch: 0001 loss= 1133.908114347
    Epoch: 0006 loss= 329.093700409
    Epoch: 00011 loss= 111.876660109
    Epoch: 00016 loss= 72.552971845
    Epoch: 00021 loss= 16.673050320
    ........
    Finished!
    Accuracy: 0.81
    Accuracy:0.81 은 신뢰 도가 81%라 는 것 을 나타 낸다.우 리 는 매개 변 수 를 조정 하고 데이터 양 을 증가 시 키 며 신뢰 도 에 변화 가 생 길 수 있다.
    끝나다
    그렇지!신경 망 을 이용 하여 텍스트 를 서로 다른 분류 로 분류 하 는 모형 을 만 들 었 다.GPU 를 사용 하거나 분포 식 TF 를 사용 하면 훈련 속도 와 효율 을 높 일 수 있 습 니 다~
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기