Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby의 신경망:그리 무섭지 않은 소개

이 포스트에서는 신경망의 기초와 Ruby를 활용하여 신경망을 구현하는 방법에 대해 알아보겠습니다! 인공 지능과 딥 러닝에 관심이 있지만 시작하는 방법이 확실하지 않은 경우 이 게시물이 적합합니다! 핵심 개념을 강조하기 위해 간단한 예를 살펴보겠습니다. Ruby를 사용하여 다층 신경망을 작성할 가능성은 거의 없지만 단순성과 가독성을 위해 진행 상황을 이해하는 좋은 방법입니다. 먼저 한 발 물러나서 어떻게 여기까지 왔는지 살펴보겠습니다.

Ruby의 신경망:그리 무섭지 않은 소개 영화 Ex Machnia의 스틸컷. 사진 크레딧

엑스마키나는 2014년 개봉한 영화다. 구글에서 제목을 찾아보면 영화의 장르가 '드라마/판타지'로 분류돼 있다. 그리고 처음 이 영화를 보았을 때, 그것은 공상 과학 소설처럼 보였습니다.

하지만 훨씬 더 오래?

구글에서 일하는 저명한 미래학자 레이 커즈와일에게 묻는다면, 2029년은 인공지능이 유효한 튜링 테스트(인간이 기계/컴퓨터와 다른 인간을 구별할 수 있는지 알아보는 실험)를 통과하는 해가 될 것입니다. ) 그는 또한 특이점(컴퓨터가 인간의 지능을 능가할 때)이 2045년까지 나타날 것이라고 예측합니다.

무엇이 커즈와일을 그렇게 자신감 있게 만드는가?

딥 러닝의 등장

간단히 말해서 딥 러닝은 신경망을 활용하여 대량의 데이터에서 통찰력을 추출하는 기계 학습의 하위 집합입니다. 딥 러닝의 실제 응용 프로그램에는 다음이 포함됩니다. - 자율 주행 자동차 - 암 감지 - Siri 및 Alexa와 같은 가상 비서 - 지진과 같은 기상 이변 예측

하지만 "신경망"이란 무엇입니까?

신경망은 전기 및 화학 신호를 통해 정보를 처리하고 전달하는 뇌 세포인 뉴런에서 이름을 얻습니다. 재미있는 사실:인간의 뇌는 800억 개 이상의 뉴런으로 구성되어 있습니다!

컴퓨팅에서 신경망은 다음과 같습니다.

Ruby의 신경망:그리 무섭지 않은 소개 신경망 다이어그램의 예. 사진 크레딧

보시다시피, 세 부분이 있습니다:1) 입력 계층 -- 초기 데이터 2) 은닉 계층 -- 신경망은 1개(또는 그 이상) 은닉 계층을 가질 수 있습니다. 여기에서 모든 계산이 완료됩니다! 3) 출력 레이어 -- 최종 결과/예측

빠른 역사 수업

신경망은 새로운 것이 아닙니다. 사실, 최초의 훈련 가능한 신경망(퍼셉트론)은 1950년대 코넬 대학에서 개발되었습니다. 그러나 원래 모델이 하나의 은닉층으로만 구성되었기 때문에 신경망의 적용 가능성을 둘러싸고 많은 비관론이 있었습니다. 1969년에 출판된 한 책에 따르면 Perceptron을 상당히 단순한 계산에 활용하는 것은 비실용적입니다.

신경망의 부활은 컴퓨터 게임에 기인할 수 있으며, 이제 아키텍처는 신경망과 매우 유사한 고성능 그래픽 처리 장치(GPU)를 필요로 합니다. 차이점은 숨겨진 레이어의 수입니다. 오늘날 훈련된 신경망은 1개 대신 10개, 15개 또는 50개 이상의 레이어를 사용하고 있습니다!

예시 시간!

이것이 어떻게 작동하는지 이해하기 위해 예를 살펴보겠습니다. ruby-fann을 설치해야 합니다. 보석. 터미널을 열고 작업 디렉토리로 이동하십시오. 그런 다음 다음을 실행하십시오.

gem install ruby-fann

새 Ruby 파일을 만듭니다(내 이름은 neural-net.rb ).

다음으로 Kaggle의 "학생 알코올 소비량" 데이터세트를 활용합니다. 여기에서 다운로드할 수 있습니다. Google 스프레드시트(또는 선택한 편집기)에서 "student-mat.csv" 파일을 엽니다. 다음을 제외한 모든 열을 삭제합니다. - Dalc(1이 매우 낮고 5가 매우 높은 근무일 알코올 소비량) - Walc (주말 알코올 도수는 1이 매우 낮고 5가 매우 높음) - G3(최종 등급 0~20)

ruby-fann gem이 작동하려면 최종 등급 열을 바이너리(0 또는 1)로 변경해야 합니다. 이 예에서는 10보다 작거나 같은 모든 것이 "0"이고 10보다 크면 "1"이라고 가정합니다. 사용 중인 프로그램에 따라 셀에 수식을 작성하여 셀 값에 따라 값을 1 또는 0으로 자동 변경할 수 있어야 합니다. Google 스프레드시트에서는 다음과 같이 표시됩니다.

=IF(C3 >= 10, 1, 0)

이 데이터를 .CSV 파일로 저장합니다(저는 students.csv ) Ruby 파일과 동일한 디렉토리에 있습니다.

신경망에는 다음과 같은 레이어가 있습니다. - 입력 레이어:2개의 노드(주중 알코올 섭취 및 주말 알코올 섭취) - 숨겨진 레이어:6개의 숨겨진 노드(이는 시작하기에 다소 임의적이며 나중에 테스트할 때 수정할 수 있음) 출력 레이어:노드 1개(0 또는 1)

먼저 ruby-fann이 필요합니다. gem 및 내장 csv 도서관. 다음을 Ruby 프로그램의 첫 번째 줄에 추가하십시오.

require 'ruby-fann' require 'csv'

다음으로 CSV 파일의 데이터를 배열로 로드해야 합니다.

# Create two empty arrays. One will hold our independent varaibles (x_data), and the other will hold our dependent variable (y_data).
x_data = []
y_data = []

# Iterate through our CSV data and add elements to applicable arrays. 
# Note that if we don't add the .to_f and .to_i, our arrays would have strings, and the ruby-fann library would not be happy.
CSV.foreach("students.csv", headers: false) do |row|
  x_data.push([row[0].to_f, row[1].to_f])
  y_data.push(row[2].to_i)
end

다음으로 데이터를 훈련 데이터와 테스트 데이터로 나누어야 합니다. 데이터의 20%가 테스트에 사용되고 80%가 교육에 사용되는 80/20 분할은 매우 일반적입니다. 여기서 "훈련"은 모델이 이 데이터를 기반으로 학습한 다음 "테스트" 데이터를 사용하여 모델이 결과를 얼마나 잘 예측하는지 확인하는 것을 의미합니다.

# Divide data into a training set and test set.
testing_percentage = 20.0

# Take the number of total elements and multiply by the test percentage.
testing_size = x_data.size * (testing_percentage/100.to_f)

# Start at the beginning and end at the testing_size - 1 since arrays are 0-indexed. 
x_test_data = x_data[0 .. (testing_size-1)]
y_test_data = y_data[0 .. (testing_size-1)]

# Pick up where we left off until the end of the dataset. 
x_train_data = x_data[testing_size .. x_data.size] 
y_train_data = y_data[testing_size .. y_data.size] 

시원한! 데이터를 사용할 준비가 되었습니다. 다음은 마법입니다!

# Set up the training data model.
train = RubyFann::TrainData.new(:inputs=> x_train_data, :desired_outputs=>y_train_data)

RubyFann::TrainData 개체를 사용하고 x_train_data, 이는 근무일 및 주말 알코올 소비량과 y_train_data, 최종 코스 성적에 따라 0 또는 1입니다.

이제 앞에서 논의한 숨겨진 뉴런의 수로 실제 신경망 모델을 설정해 보겠습니다.

# Set up the model and train using training data.
model = RubyFann::Standard.new(
              num_inputs: 2,
              hidden_neurons: [6],
              num_outputs: 1 );

좋아, 훈련할 시간이야!

model.train_on_data(train, 1000, 10, 0.01)

여기에서 train 앞서 생성한 변수. 1000은 max_epochs의 수를 나타내고 10은 보고서 간의 오류 수를 나타내며 0.1은 원하는 평균 제곱 오류입니다. 한 시대는 전체 데이터 세트가 신경망을 통과하는 때입니다. 평균 제곱 오차는 최소화하려는 것입니다. 이것이 의미하는 바에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

다음으로, 모델이 테스트 데이터에 대해 예측한 것을 실제 결과와 비교하여 모델이 얼마나 잘 수행되었는지 알고 싶습니다. 다음 코드를 사용하여 이를 수행할 수 있습니다.

predicted = []

# Iterate over our x_test_data, run our model on each one, and add it to our predicted array. 
x_test_data.each do |params|
  predicted.push( model.run(params).map{ |e| e.round } )
end

# Compare the predicted results with the actual results. 
correct = predicted.collect.with_index { |e,i| (e == y_test_data[i]) ? 1 : 0 }.inject{ |sum,e| sum+e }

# Print out the accuracy rate. 
puts "Accuracy: #{((correct.to_f / testing_size) * 100).round(2)}% - test set of size #{testing_percentage}%"

프로그램을 실행하고 어떤 일이 일어나는지 봅시다!

ruby neural-net.rb

Epoch에 대한 많은 출력이 표시되어야 하지만 하단에는 다음과 같은 내용이 표시되어야 합니다.

Accuracy: 56.82% - test set of size 20.0%

으악, 별로 좋지 않아! 하지만 우리만의 데이터 포인트를 만들어내고 모델을 실행해 봅시다.

prediction = model.run( [1, 1] )
# Round the output to get the prediction.
puts "Algorithm predicted class: #{prediction.map{ |e| e.round }}"

prediction_two = model.run( [5, 4] )
# Round the output to get the prediction.
puts "Algorithm predicted class: #{prediction_two.map{ |e| e.round }}"

여기에 두 가지 예가 있습니다. 먼저 주중 및 주말 알코올 소비에 대해 1을 전달합니다. 내가 도박을 하는 사람이라면 이 학생의 최종 성적이 10점 이상(즉, 1점)을 받을 것이라고 추측할 것입니다. 두 번째 예는 알코올 소비에 대해 높은 값(5 및 4)을 전달하므로 이 학생의 최종 성적은 10 이하(즉, 0)가 될 것이라고 추측합니다. 프로그램을 다시 실행하고 어떤 일이 발생하는지 봅시다!

출력은 다음과 같아야 합니다.

Algorithm predicted class: [1]
Algorithm predicted class: [0]

우리 모델은 스펙트럼의 하단 또는 상단에 있는 숫자에 대해 예상한 대로 수행하는 것으로 보입니다. 그러나 숫자가 반대이거나(예를 들어 1과 5 또는 2와 3의 다른 조합을 자유롭게 시도할 수 있음) 중간에 있을 때 어려움을 겪습니다. Epoch 데이터에서 오류는 줄어들지만 여전히 매우 높음(중간 20%)을 볼 수 있습니다. 이것이 의미하는 바는 알코올 소비와 코스 성적 사이에 관계가 없을 수 있다는 것입니다. Kaggle의 원본 데이터 세트를 가지고 노는 것이 좋습니다. 코스 결과를 예측하는 데 사용할 수 있는 다른 독립 변수가 있습니까?

요약

이 모든 작업을 수행하기 위해 내부에서 발생하는 많은 복잡성(대부분 수학과 관련하여)이 있습니다. 궁금하고 더 자세히 알고 싶다면 FANN의 문서를 보거나 ruby-fann의 소스 코드를 보는 것이 좋습니다. 보석. 또한 Netflix에서 "AlphaGo" 다큐멘터리를 확인하는 것이 좋습니다. 이 다큐멘터리를 즐기는 데 많은 기술 지식이 필요하지 않으며 딥 러닝이 컴퓨터가 달성할 수 있는 한계를 어떻게 밀어붙이고 있는지에 대한 훌륭하고 실제적인 예를 제공합니다.

Kurzweil은 결국 그의 예측이 맞을까요? 단지 시간이 말해 줄 것이다!