반응형



안녕하세요~


오늘은 신경망의 기본! 퍼셉트론에 대해 알아보겠습니다~


퍼셉트론이란? 다수의 신호를 입력받아 하나의 신호를 출력하는 알고리즘입니다.



1943년 미국 신경외과 의사인 워렌 멕컬록에 의해서 발단이되었고


1957년 프랑크 로젠 블라트가 퍼셉트론 알고리즘을 고안했습니다.


사람의 뇌의 동작을 전기 스위치의 on / off 로 흉내낼 수 있다는 이론을 증명하였습니다.


간단히 말하면, 인간의 신경 세포 하나를 흉내낸 것으로

기본 가정은 아래와 같습니다.




1. 자극(simulus)   2. 역치(threshold)  3. 반응(response)



" 특정 자극이 있다면 그 자극이 어느 역치(theta: 임계값) 이상이어야지만 세포가 반응한다. "




입력신호의 연결강도가 가중치(Weight)인데,


입력신호가 뉴런에 보내질 때는 각각의 고유한 가중치가 곱해집니다.



퍼셉트론은 n 개의 이진수가 하나의 뉴런을 통과해서


가중치의 합이 0보다 크면 활성화되는 가장 간단한 신경망입니다.



문제1. 위의 식을 파이썬 Numpy 패키지로 구현하시오.



가정: theta = 0 ; x1 = 0; x2 = 1; w1 = 0.5; w2 = 0.5





퍼셉트론으로 단순한 논리 회로 4가지를 구현해보도록 하겠습니다.



1. AND 게이트




def AND(x1, x2): x = np.array([x1,x2]) w = np.array([0.5,0.5]) theta = 0.7 if np.sum(w*x) <= theta: return 0 else: return 1



inputData = np.array([[0,0],[1,0],[0,1],[1,1]])

for x in inputData: print(x[0],", ",x[1]," ==> ",AND(x[0],x[1]), sep = '')



2. OR 게이트




def OR(x1,x2): x = np.array([x1,x2]) w = np.array([?,?]) # 채워넣으세요~ theta = ? # 채워넣으세요~ if np.sum(w*x) <= theta: return 0 else: return 1


inputData = np.array([[0,0],[1,0],[0,1],[1,1]]) for x in inputData: print(x[0],", ",x[1]," ==> ",OR(x[0],x[1]), sep = '')





3. NAND 게이트




def NAND(x1,x2): x = np.array([x1,x2]) w = np.array([?,?]) # 채워넣으세요~ theta = ? # 채워넣으세요~ if np.sum(w*x) <= theta: return 0 else: return 1

inputData = np.array([[0,0],[1,0],[0,1],[1,1]]) for x in inputData: print(x[0],", ",x[1]," ==> ",NAND(x[0],x[1]), sep = '')





4. XOR 게이트




XOR 게이트를 퍼셉트론으로 해결해보세요!


결과는 다음 포스팅에서!





오늘은 여기까지~


다음 포스팅은

활성함수로 돌아오겠습니다!

반응형
반응형

 

 

이제 마지막 관문 파이썬으로 딥러닝하기!입니다.

 

 

우선, 딥러닝이란 무엇일까요?

 

 

딥러닝이란,

 

간단히 말하자면, 머신러닝의 신경망 알고리즘보다 더 deep하고 더 wide한 신경망으로

 

보다 느리지만 보다 정확한 결과를 얻을 수 있는 알고리즘입니다!

 

 

 

머신러닝이 궁금하신분은 아래의 링크를 타고 가시면 됩니다!

 

R로 머신러닝하기에서 머신러닝이란?

 

 

 

본격적인 딥러닝에 앞서,

딥러닝을 하기위해 필요한 numpy, matplotlib 패키지에 대해 알아보겠습니다.

 

 

[numpy 패키지란?]

 

1. 숫자배열 연산을 위한 라이브러리입니다.

 

2. numpy array는 파이썬 리스트보다 속도가 빠르며 리스트간 연산에 편의성을 제공합니다.

 

3. sorting이나 indexing, intersection을 찾는 경우에도 속도가 빠릅니다.

 

4. 평균, 중앙값, 최빈값, 사분위수, 분산, 표준편차를 찾는 경우에도

리스트보다 훨씬 코드가 간단하고 속도가 빠릅니다.

 

 

문제1. 아래의 행렬을 numpy로 만드시오

 

1 2

3 4

 

더보기

import numpy as np

 

print(np.array([[1,2],[3,4]]))

 

 

 

문제2. 아래의 행렬연산을 numpy로 수행하시오.

 

1 3 7              0 0 5

  + 

1 0 0              7 5 0

 

 

더보기

import numpy as np

 

a = np.array([[1,3,7],[1,0,0]])

b = np.array([[0,0,5],[7,5,0]])

 

print(a+b)

 

 

 

만약, 위의 문제와 달리,

행렬의 shape(차원, 원소개수)가 다르면 어떻게 연산을 해야할까요?

 

 

numpy 패키지에는 broadcasting라는 특징이 있습니다.

 

The term broadcasting describes how numpy treats arrays with different shapes during arithmetic operations.

Subject to certain constraints, the smaller array is “broadcast” across the larger array so that they have compatible shapes.

 

출처ㅣ SciPy.org

 

broadcasting이란 산술 연산시 다른 shape의 배열을 처리하는 방법으로

 

특정 제약 조건에 따라, 작은 배열을 큰 배열 와 서로 호환되도록

아래와 같이 작은 배열이 큰 배열에 크기를 맞추는 것을 브로드캐스트라고 합니다.

 

 

 

[broadcasting]

 

 

문제3. 위의 braodcasting 그림을 파이썬으로 구현하시오

 

더보기

import numpy as np

 

a = np.array([[1,2],[3,4]])

 

print(a * 10)

 

 

 

문제4. 아래의 배열의 원소들의 평균값을 구하시오

 

import numpy as np

 

a = np.array([1,2,4,5,5,7,10,13,18,21])

 

더보기

print(np.mean(a))

 

※ 참고:

 

중앙값: np.median(a)

 

최대값: np.max(a)

 

최소값: np.min(a)

 

표준편차: np.std(a)

 

분산: np.var(a)

 

 

문제5. 아래의 행렬식을 numpy로 구현하고 아래의 요소에서 15 이상인것만 출력하시오

 

51 55

14 19

0    4

 

더보기

a = np.array([[51,55],[14,19],[0,4]])

 

print(a[a>=15])

 

 

 

[ matplotlib 패키지란? ]

 

딥러닝 실험에서는 그래프 그리기와 데이터 시각화가 중요합니다.

 

matplolib은 파이썬으로 그래프를 그릴 때 유용한 라이브러리 입니다.

 

 

"백문이 불여일타"

 

우선 그래프를 그려볼까요?

 

import numpy as np

import matplotlib.pyplot as plt

 

a = np.array([1,2,4,5,5,7,10,13,18,21])

 

plt.plot(a)

plt.show()

 

다음으로

 

제목, x 라벨, y 라벨을 추가해볼까요?

 

단, matplotlib 라이브러리의 경우 한글 폰트를 지원하지 않습니다.

 

한글 폰트를 넣어주어야합니다.

 

import numpy as np

import matplotlib.pyplot as plt

from matplotlib import font_manager, rc    # 한글 폰트 설정font_name = font_manager.FontProperties(fname="C:/Windows/Fonts/H2PORM.TTF").get_name()rc('font', family=font_name)
x = np.array([0,1,2,3,4,5,6,7,8,9])

y = np.array([1,2,4,5,5,7,10,13,18,21])

 

plt.plot(x,y)

 

plt.title('으니's 소득증가추이')

plt.xlabel('년')

plt.ylabel('연평균 소득(단위:천만)')

plt.show()

 

 

하나의 화면에 여러개의 그래프를 중첩해서 그리고 싶을 때는 어떻게 할까요?

 

import matplotlib.pyplot as plt

from matplotlib import font_manager, rcimport pandas as pd

 

chi = pd.read_csv("창업건수.csv", engine='python')

pae = pd.read_csv("폐업건수.csv", engine='python')

chi = chi.T

 

y = chi.loc['치킨집']

x = chi.iloc[0]

 

pae['년도'] = pae['Unnamed: 0']

px = pae['년도']

py = pae['치킨집']

 

plt.figure(figsize=(6,4))

# 하나의 화면에 여러개의 그래프를 중첩해서 그릴 때

 

plt.plot(x,y)

plt.plot(px,py, color = "Hotpink")

 

plt.xlabel('년도')

plt.ylabel('치킨집 창업 건수')

plt.title('"치킨집 년도별 현황"')

 

plt.show()

 
 

참고 데이터:


창업건수.csv
다운로드
폐업건수.csv
다운로드

 


 

오늘은 여기까지~

 

다음은

 

퍼셉트론으로 돌아올게요~

 

 

반응형
반응형

 

안녕하세요

오늘은 Gradient Descent 와 SGD(Stochastic Gradient Descent)에 대해 알아보도록 하겠습니다.


 

Gradient Descent (경사하강법)이란?

 

손실(cost) 를 줄이는 알고리즘 입니다.

간단히 말하자면, 미분 값(기울기)이 최소가 되는 점을 찾아 알맞은 weight(가중치 매개변수)를 찾아 냅니다.

 

< 손실 함수(Cost Function) >

 

 

 : step size(기계학습에서 learning rate라고도 함)

 

 

  : 기울기를 의미한다.

 

 

 

 

 


 

1. 경사 하강법의 첫 번째 단계는 w1에 대한 시작점을 선택하는 것입니다.
 linear regression의 경우 위의 그림과 같이 매끈한 모양으로 시작점은 별로 중요하지 않습니다.
많은 알고리즘 에서는 w1을 0으로 설정하거나 임의의 값을 선택합니다.
위의 그림에서는 0보다 조금 큰 시작점을 지정했습니다.

 

(단, cost 함수가 위와 같지 않다면 시작값을 찾는 것이 매우 중요합니다.)

 

 

 

 

 

 

2. 시작점에서 손실 곡선의 기울기(Gradient)를 계산합니다.
여기서 기울기는 편미분의 벡터로, 어느 방향이 더 정확한지 혹은 더 부정확한지를 알려줍니다.

 

위의 그림에서 나온 것과 같이 단일 가중치에 대한 손실의 기울기는 미분 값과 같습니다.

 

 

 

손실함수 곡선의 다음 지점을 결정하기 위해
경사하강법(Gradient Descent) 알고리즘은 

단일 가중의 일부를 시작점에 더합니다.

 

( 어느 방향(+, -)으로 이동해야하는지를 결정함 )

 

 

 

기울기의 보폭(Learning rate)을 통해 손실 곡선의 다음 지점으로 이동합니다.

 




3. 경사하강법은 위의 과정을 반복해 최소값에 점점 접근합니다.

 

 

 

 

SGD (Stochastic Gradient Descent)이란?

 

 

배치 크기가 1인 경사하강법 알고리즘 입니다.

 

즉, 확률적 경사하강법은 데이터 세트에서 무작위로 균일하게 선택한 하나의 예를 의존하여

각 단계의 예측 경사를 계산합니다.

 

 

< 최소값을 찾는 과정 >

https://engmrk.com/mini-batch-gd/
그림 출처: https://engmrk.com/mini-batch-gd/

 

배치란?

경사하강법에서 배치는 단일 반복에서 기울기를 계산하는 데 사용하는 예(data)의 총 개수입니다

Gradient Descent 에서의 배치는 전체 데이터 셋라고 가정합니다.

 

하지만규모의 작업에서는 데이터 셋에 수십억, 수천억 개의 예가 포함되는 경우가 많습니다.

또한 대규모의 데이터 셋에는 엄청나게 많은 특성이 포함되어 있습니다.

 

따라서 배치가 거대해질 수 있습니다.

배치가 너무 커지면 단일 반복으로도 계산하는 데 오랜 시간이 걸릴 수 있습니다.

 

 

 

 

 

따라서 무작위로 샘플링된 예가 포함된 대량의 데이터 셋에는 중복 데이터가 포함되어 있을 수 있습니다

 

실제로 배치 크기가 커지면 중복의 가능성도 그만큼 높아집니다.

 

 

 " 만약에 훨씬 적은 계산으로 적절한 기울기를 얻을 수 있다면 어떨까요? "

 

 

데이터 세트에서 예(data)를 무작위로 선택하면 (노이즈는 있겠지만) 훨씬 적은 데이터 세트로 중요한 평균값을 추정할 수 있습니다

 

확률적 경사하강법(SGD)은 이 아이디어를 더욱 확장한 것으로서, 반복당 하나의 예(배치 크기 1)만을 사용합니다

 

 

'확률적(Stochastic)'이라는 용어는 각 배치를 포함하는 하나의 예가 무작위로 선택된다는 것을 의미합니다.

 

 

 

 

<단점>

반복이 충분하면 SGD가 효과는 있지만 노이즈가 매우 심합니다.

 

확률적 경사하강법의 여러 변형 함수의 최저점에 가까운 점을 찾을 가능성이 높지만 항상 보장되지는 않습니다.

(최저점을 찾지는 못할 수 있음)

 

 

 

<단점 극복하기>

 

미니 배치 확률적 경사하강법(미니 배치 SGD)은 전체 배치 반복과 SGD 의 절충안입니다.

 

미니 배치는 일반적으로 무작위로 선택한 10개에서 1,000개 사이의 예로 구성됩니다.

미니 배치 SGD SGD의 노이즈를 줄이면서도 전체 배치보다는 더 효율적입니다.

 

 

 


 

 

참고: 구글 머신러닝 단기 집중과정

 

 

 

간단한 설명을 위해 단일 특성에 대한 경사하강법에 중점을 두었습니다.

 

경사하강법은 여러 개의 특성을 갖는 특성 세트에도 사용 가능합니다.

 

반응형
반응형

안녕하세요~


매일매일 딥러닝 으니입니다!


오늘은 Python 첫번째 편!


BeutifulSoup, scrapy, urllib 등을 이용한 다양한 웹 크롤링 방법 중 BeautifulSoup을 이용하여 웹 크롤러를 만들어 보겠습니다!





크롤러란?


크롤링(crawling) 혹은 스크레이핑(scraping)은 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 행위이다. 크롤링하는 소프트웨어는 크롤러(crawler)라고 부른다.   출처: 나무위키



1. NaverAPI를 이용한 웹 크롤


NaverDeveloper: https://developers.naver.com



[ step1. 어플리케이션 등록하기! ]


※ naver id로 등록하실 수 있습니다.




[ step2. id & key 확인하기 ]


※ 위에서 생성한 내 어플리케이션에서 확인하실 수 있습니다.



[ step3. 웹 크롤러 만들기 ]

# naver_search_api import os import sys import urllib.request import json client_id = "YOUR_CLIENT_ID" client_secret = "YOUR_CLIENT_SECRET" encText = urllib.parse.quote(input('검색할 단어 : ')) start = "&start=" + input('검색 시작 위치 : ') display = "&display=" + input('출력건수 : ') category = input('news or cafearticle : ')

# xml 결과

# url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText

# json 결과

# url = "https://openapi.naver.com/v1/search/" + category + "?query=" + encText


# option 추가 가능

url = "https://openapi.naver.com/v1/search/"+category+"?query="+encText+start+display request = urllib.request.Request(url) request.add_header("X-Naver-Client-Id",client_id) request.add_header("X-Naver-Client-Secret",client_secret) response = urllib.request.urlopen(request) rescode = response.getcode() response_body = response.read().decode('utf-8') json_data = json.loads(response_body) items = json_data["items"]

# rescode 200은 상태를 정상을 의미한다. if(rescode==200):

# 결과 파일로 저장하기 file = open("naver_"+category+".txt","w",encoding='utf-8') for item in items: file.write('제목: ' + item["title"] + '\n') file.write('요약내용 : ' + item["description"] + '\n') file.write('\n') file.close() else: print("Error Code:" + rescode)




2. 웹 크롤 중 발생하는 한글 인코딩 문제 해결하기


import requests from bs4 import BeautifulSoup


page = requests.get(url) # print(page.encoding)

# page.encoding = 'utf-8'


if(page.status_code==200):

soup_sub = BeautifulSoup(page_sub.content, 'html.parser',from_encoding='ANSI')


처음 인코딩 에러가 났을 때 utf-8 로 인코딩을 다시해봤지만 문제가 해결되지 않았습니다.


그때 이 문제를 해결하는 방법은 ANSI 로 인코딩하는 것입니다.




여기서 잠깐!

[ utf-8과 ANSI 인코딩의 차이? ]


ANSI와 UTF-8은 널리 사용되는 두 개의 문자 인코딩 방식압나다.



ANSI


ANSI 표준에서 모두는 128문자 이하로 했습니다. 


128문자 이하는 ASCII와 거의 같았지만, 지역에 따라 128 자 이상에서 문자를 처리 할 수있는 여러 가지 방법이있습니다.

이러한 서로 다른 시스템을 코드페이지라고 하며 한국의 경우 CP949 입니다.

(참고: 리눅스에서는 cp949로 해야 인코딩이 되었습니다.)


출처: 

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)



UTF-8


UTF-8 인코딩은 유니코드 한 문자를 나타내기 위해 1바이트에서 4바이트까지를 사용합니다.


7비트 ASCII 문자와 혼동되지 않게 하기 위하여 모든 바이트들의 최상위 비트는 1입니다. 

따라서 첫 128 문자는 1바이트로 표시되고, 그 다음 1920 문자는 2바이트로 표시되며, 나머지 문자들 중 BMP 안에 들어 있는 것은 3바이트, 아닌 것은 4바이트로 표시됩니다.


출처: 위키백과 UTF-8




오늘은 여기까지!!

반응형

+ Recent posts