첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

▶ NeuralNetwork.py

import numpy
import scipy.special

##################################################
# 신경망 클래스
##################################################
class NeuralNetwork:

    ##################################################
    # 생성자
    # inputNodeCount  : 입력 노드 수
    # hiddenNodeCount : 은닉 노드 수
    # outputNodeCount : 출력 노드 수
    # learningRate    : 학습률
    ##################################################
    def __init__(self, inputNodeCount, hiddenNodeCount, outputNodeCount, learningRate):

        self.inputNodeCount  = inputNodeCount
        self.hiddenNodeCount = hiddenNodeCount
        self.outputNodeCount = outputNodeCount

        self.inputHiddenWeightArray  = numpy.random.normal(0.0, pow(self.inputNodeCount , -0.5), \
                                           (self.hiddenNodeCount, self.inputNodeCount ))
        self.hiddenOutputWeightArray = numpy.random.normal(0.0, pow(self.hiddenNodeCount, -0.5), \
                                           (self.outputNodeCount, self.hiddenNodeCount))

        self.learningRate = learningRate

        self.activationFunction = lambda x: scipy.special.expit(x)

        pass

    ##################################################
    # 학습하기
    # sourceInputValueArray  : 소스 입력 값 리스트
    # sourceTargetValueArray : 소스 목표 값 리스트
    ##################################################
    def train(self, sourceInputValueArray, sourceTargetValueArray):

        inputValueArray  = numpy.array(sourceInputValueArray , ndmin = 2).T
        targetValueArray = numpy.array(sourceTargetValueArray, ndmin = 2).T

        # 은닉 계층으로 들어오는 신호를 계산한다.
        hiddenNodeInputValueArray = numpy.dot(self.inputHiddenWeightArray, inputValueArray)

        # 은닉 계층에서 나가는 신호를 계산한다.
        hiddenNodeOutputValueArray = self.activationFunction(hiddenNodeInputValueArray)

        # 출력 계층으로 들어오는 신호를 계산한다.
        outputNodeInputValueArray = numpy.dot(self.hiddenOutputWeightArray, hiddenNodeOutputValueArray)

        # 출력 계층에서 나가는 신호를 계산한다.
        outputNodeOutputValueArray = self.activationFunction(outputNodeInputValueArray)

        # 출력 계층의 오차를 계산한다. (실제 값 - 계산 값)
        outputNodeErrorArray = targetValueArray - outputNodeOutputValueArray

        # 은닉 계층의 오차는 가중치에 의해 나뉜 출력 계층의 오차들을 재조합해 계산한다.
        hiddenNodeErrorArray = numpy.dot(self.hiddenOutputWeightArray.T, outputNodeErrorArray)

        # 은닉 계층과 출력 계층 간의 가중치 오차를 업데이트 한다.
        self.hiddenOutputWeightArray += self.learningRate * \
            numpy.dot((outputNodeErrorArray * outputNodeOutputValueArray * (1.0 - outputNodeOutputValueArray)), \
                numpy.transpose(hiddenNodeOutputValueArray))

        # 입력 계층과 은닉 계층 간의 가중치 오차를 업데이트 한다.
        self.inputHiddenWeightArray += self.learningRate * \
            numpy.dot((hiddenNodeErrorArray * hiddenNodeOutputValueArray * (1.0 - hiddenNodeOutputValueArray)), \
                numpy.transpose(inputValueArray))

        pass

    ##################################################
    # 질의하기
    # sourceInputValueArray : 소스 입력 값 리스트
    ##################################################
    def query(self, sourceInputValueArray):

        inputValueArray = numpy.array(sourceInputValueArray, ndmin = 2).T

        # 은닉 계층으로 들어오는 신호를 계산한다.
        hiddenNodeInputValueArray = numpy.dot(self.inputHiddenWeightArray, inputValueArray)

        # 은닉 계층에서 나가는 신호를 계산한다.
        hiddenNodeOutputValueArray = self.activationFunction(hiddenNodeInputValueArray)

        # 출력 계층으로 들어오는 신호를 계산한다.
        outputNodeInputValueArray = numpy.dot(self.hiddenOutputWeightArray, hiddenNodeOutputValueArray)

        # 출력 계층에서 나가는 신호를 계산한다.
        outputNodeOutputValueArray = self.activationFunction(outputNodeInputValueArray)

        return outputNodeOutputValueArray

        pass

##################################################
# 신경망 객체를 생성한다.
##################################################
print("신경망 객체를 생성한다.")

inputNodeCount  = 784
hiddenNodeCount = 100
outputNodeCount = 10

learningRate = 0.1

neuralNetwork = NeuralNetwork(inputNodeCount, hiddenNodeCount, outputNodeCount, learningRate)

##################################################
# MNIST 학습 데이터를 로드한다.
##################################################
print("MNIST 학습 데이터를 로드한다.")

trainingDataFile = open("c:\\mnist_train.csv", 'r')

trainingDataList = trainingDataFile.readlines()

trainingDataFile.close()

print("학습 데이터 : %s건" % len(trainingDataList))

##################################################
# MNIST 학습 데이터를 사용해 신경망을 학습시킨다.
##################################################
print("MNIST 학습 데이터를 사용해 신경망을 학습시킨다.")

epochCount = 5

for epoch in range(epochCount):

    print("학습 주기 = ", epoch)

    for trainingData in trainingDataList:

        trainigDataArray = trainingData.split(',')

        # 학습에 사용되는 MNIST 숫자 이미지는 28×28 픽셀 = 784개 데이터를 갖으며 훈련 데이터 배열에서 두번째 컬럼 이후 부터 저장된다.
        testInputValueArray = (numpy.asfarray(trainigDataArray[1:]) / 255.0 * 0.99) + 0.01

        trainingTargetValueArray = numpy.zeros(outputNodeCount) + 0.01

        trainingTargetValueArray[int(trainigDataArray[0])] = 0.99

        neuralNetwork.train(testInputValueArray, trainingTargetValueArray)

        pass

    pass

print("학습 완료")

##################################################
# MNIST 테스트 데이터를 로드한다.
##################################################
print("MNIST 테스트 데이터를 로드한다.")

testDataFile = open("c:\\mnist_test.csv", 'r')

testDataList = testDataFile.readlines()

testDataFile.close()

print("테스트 데이터 : %s건" % len(testDataList))

##################################################
# MNIST 테스트 데이터를 사용해 신경망을 테스트한다.
##################################################
print("MNIST 테스트 데이터를 사용해 신경망을 테스트한다.")

scoreCardList = []

for testData in testDataList:

    testDataArray = testData.split(',')

    correctLabel = int(testDataArray[0])

    testInputValueArray = (numpy.asfarray(testDataArray[1:]) / 255.0 * 0.99) + 0.01

    testOutputValueArray = neuralNetwork.query(testInputValueArray)

    answerLabel = numpy.argmax(testOutputValueArray)

    if(answerLabel == correctLabel):

        scoreCardList.append(1)

        pass

    else:

        scoreCardList.append(0)

        pass

    pass

scoreCardArray = numpy.asarray(scoreCardList)

print("정확도 = ", scoreCardArray.sum() / scoreCardArray.size)

##################################################
# MNIST 테스트 데이터 1건을 사용해 신경망을 테스트한다.
# ※ 아나콘다에서 실행한다.
##################################################

import matplotlib
%matplotlib inline

testDataArray = testDataList[200].split(',')

print("테스트 데이터 정답 : ", testDataArray[0])

testInputValueArray = (numpy.asfarray(testDataArray[1:]) / 255.0 * 0.99) + 0.01

testOutputValueArray = neuralNetwork.query(testInputValueArray)

print("테스트 결과 값 : ", numpy.argmax(testOutputValueArray))
print()
print(testOutputValueArray)

testDataImageArray = numpy.asfarray(testDataArray[1:]).reshape((28,28))

matplotlib.pyplot.imshow(testDataImageArray, cmap='Greys', interpolation='None')
728x90
반응형
그리드형(광고전용)
Posted by icodebroker
TAG , ,

댓글을 달아 주세요