[딥러닝] 신경망 구현 코드
2020. 3. 26. 09:42ㆍ노트/Python : 프로그래밍
신경망 구현
- 초기화 ( 입력, 은닉, 출력 노드의 수 )
- 학습 (가중치 업데이트)
- 질의 (입력 -> 연산 -> 출력 노드에 전달)
트레이닝, 테스트 데이터
라이브러리 호출
import scipy
from scipy import integrate # scipy.special 속성 오류해결
import numpy as np
신경망 클래스 생성
class neuralNetwork:
#신경망 초기화 기능
def __init__(self,input_nodes, hidden_nodes, output_nodes, learning_rate): #첫번째 인수는 무조건 self
self.inodes=input_nodes
self.hnodes=hidden_nodes
self.onodes=output_nodes
self.lr=learning_rate
#가중치는 행렬로 표현
#입력/은닉 가중치 행렬 형식:
#(은닉노드 * 입력노드)
self.wih=np.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes))
#은닉/출력 가중치 행렬 형식:
#(출력노드 * 은닉노드)
self.who=np.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
#활성화 함수 초기화
self.activation_function=lambda x:scipy.special.expit(x) #sigmoid 함수
pass
#신경망 학습 기능 (2단계)
#1단계(forward propagation): 입력 데이터에 대해 계산을 하는 단계 (query와 비슷)
#2단계(backward propagation): 예측값과 실제값의 차이계산->에러에 대해서 가중치 업데이트
def train(self, inputs_list, targets_list):
#입력리스트를 2차원 행렬로 변환
inputs=np.array(inputs_list, ndmin=2).T
targets=np.array(targets_list, ndmin=2).T
#은닉계층으로 들어오는 신호를 계산
hidden_inputs=np.dot(self.wih,inputs)
#은닉계층에서 나가는 신호 계산
hidden_outputs=self.activation_function(hidden_inputs)
#출력계층으로 들어오는 신호를 계산
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs) # sigmoid
#오차= 실제값 - 예측값
output_errors=targets-final_outputs
#은닉 계층 노드에 대한 역전파된 오차
#은닉 계층에서 오차는 가중치에 의해 나뉜 출력 계층의 오차들을 재조합하여 계산
hidden_errors=np.dot(self.who.T, output_errors)
#은닉 계층과 출력 계층 간의 가중치 업데이트 (who)
self.who+=self.lr * np.dot((output_errors * final_outputs * (1.0 - final_outputs) ) ,
np.transpose(hidden_outputs))
self.wih+=self.lr * np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs) ) ,
np.transpose(inputs))
pass
#신경망 질의 기능
def query(self, inputs_list):
#입력리스트를 2차원 행렬로 변환
inputs=np.array(inputs_list, ndmin=2).T
#은닉계층으로 들어오는 신호를 계산
hidden_inputs=np.dot(self.wih,inputs)
#은닉계층에서 나가는 신호 계산
hidden_outputs=self.activation_function(hidden_inputs)
#출력계층으로 들어오는 신호를 계산
final_inputs=np.dot(self.who,hidden_outputs)
final_outputs=self.activation_function(final_inputs)
return final_outputs
* 함수 내 지역변수를 전역변수로 지정
input_nodes, hidden_nodes, output_nodes 는 지역변수라서 train 이나 query 함수에서 사용이 불가함.
그래서 self.inodes, self.hnodes .... 로 값을 전달하여 class 내에서 해당 변수값을 사용할 수 있도록 지정.
Training
#입력, 은닉, 출력 노드의 수
input_nodes=784
hidden_nodes=100
output_nodes=10 #(0~9)
#학습률 0.3
learning_rate=0.3
#신경망 객체생성
n=neuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
#mnist 트레이닝 데이터 불러오기
training_data_file=open("mnist_train_100.csv","r")
training_data_list=training_data_file.readlines() #한 줄씩 읽어라
training_data_file.close()
epochs=100
for e in range(epochs):
for record in training_data_list:
all_values=record.split(",")
inputs=(np.asfarray(all_values[1:])/255*0.99)+0.01 #0.01~1.0 으로 rescaling
#결과값 생성
targets=np.zeros(output_nodes)+0.01
targets[int(all_values[0])]=0.99 # 정답이 들어가있음
n.train(inputs,targets)
Test
test_data_file=open("mnist_test_10.csv","r")
test_data_list=test_data_file.readlines()
test_data_file.close()
test_data_list[0]
all_values=test_data_list[0].split(",")
all_values[0] # 첫번째 테스트 데이터 정답 : 7
image_array=np.asfarray(all_values[1:]).reshape((28,28))
plt.imshow(image_array, cmap="Greys")
outputs=n.query(np.asfarray(all_values[1:])/255*0.99+0.01)
label=np.argmax(outputs)
print(label, ": my network's answer")
scorecard=[]
for record in test_data_list:
all_values=record.split(",")
#정답
correct_label=int(all_values[0])
print(correct_label, ":correct_label")
outputs=n.query(np.asfarray(all_values[1:])/255*0.99+0.01)
label=np.argmax(outputs)
print(label, ": my network's answer")
if (label==correct_label):
scorecard.append(1)
else:
scorecard.append(0)
scorecard_array=np.asarray(scorecard)
print(scorecard_array.sum()/scorecard_array.size)
'노트 > Python : 프로그래밍' 카테고리의 다른 글
[파이썬기초] 데이터 정보 확인 및 참조 (0) | 2020.03.31 |
---|---|
[Kaggle] TED-Talk 토픽모델링 (Topic modeling) (0) | 2020.03.28 |
[파이썬] 두 점사이의 거리 구하기 코드 (0) | 2020.03.28 |
[파이썬기초] pandas 데이터 읽기 (0) | 2020.03.24 |
[파이썬기초] 주피터 노트북 테마 및 디자인 변경 (0) | 2020.03.23 |