목록개발 및 공부 (189)
NeuroWhAI의 잡블로그
Rust. Change mutable reference to immutable. &mut T 형식으로 받았는데 원하는 메소드가 &T에만 구현된 경우가 있었습니다.(C++ 사용자는 뭔소리야 싶겠지만 Rust는 타입이 사용된 상태?마다 다르게 메소드를 구현할 수 있습니다.)아래는 그 오류를 재연한 예제입니다. https://ideone.com/YeENwm trait FooPow { fn pow(&self) -> i32; } struct Foo(i32); impl i32 { self.0 * self.0 } } /*impl i32 { self.0 * self.0 } }*/ fn test1(x: &Foo) { println!("{}", x.pow()); } fn test2(x: &mut Foo) { println..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 매개변수라 함은 학습시 손실을 줄이기 위해 조절하는 변수들을 말합니다. 가중치나 편향 등을 매개변수라고 할 수 있습니다. 이때까지는 매개변수를 단순히 학습률과 기울기의 곱으로 빼서 갱신했지만 그것보다 더 잘할 수 있는 방법이 많습니다. 참고로 이때까지 사용한 방법은 SGD(확률적 경사 하강법)로 볼 수 있습니다. 아래 코드는 5장에서 구현했던 신경망을 살짝 수정해서 여러 매개변수 갱신법을 사용해 MNIST 학습을 진행하는 예제입니다. 코드: use std::collections::HashMap; use rulinalg::matrix::{Matrix, BaseMatrix, BaseMatrixMut}; use common::utils; ..
드디어 다 읽었습니다! 제가 원래 책을 많이 게으르게느리게 읽는 편인데 이건 2개월만에 다 읽었습니다!저는 사정상 파이썬이 아니라 오직 표준 라이브러리만 이용한 C++로 진행했는데 고된 시간이었지만 작동할때의 뿌듯함은 더 컸습니다 ㅎㅎ 정말 재밌었습니다! 재미도 있고 이해도 잘 됩니다. 밑바닥이라고 하니 거부감이 드실지도 모르지만 이미 텐서플로 같은 고수준 라이브러리로 딥러닝을 좀 공부해보신 분들이라도 재밌게 보실 수 있을겁니다. 왜냐면 제가 그렇거든요! 이 책은 특히 신경망이 어떻게 데이터로부터 학습하는지를 제대로 이해할 수 있게됩니다. 행렬에 익숙하지 않은 분들은 CNN에서 이해가 좀 어려우실 수 있지만 책에서 예제 코드도 제공해주니 찬찬히 살펴보시면 됩니다. 또 마지막엔 딥러닝의 최근 동향(DQN,..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 5장의 마지막입니다. ReLU, Affine 등의 레이어를 잘 구현해서 쌓아올리기만 하면 학습이 가능한 신경망을 만들 수 있습니다.이게 가능한 이유는 체인룰 덕분이고 이전 글에서 계산 그래프를 통해 설명되었습니다. forward, backward 메소드에 주목하셔야 하는데 forward는 흔히 아시는 순전파에 역전파에 사용할 값을 기억해두는 역할도 합니다. backward가 역전파이고 뒷 계층의 기울기(dout)를 받아 현재 계층의 기울기를 구하여 저장한 뒤 앞 계층으로 넘겨줍니다. 아래 코드는 Affine - ReLU - Affine - Softmax 순서로 계층을 쌓아 만든 신경망으로 MNIST를 학습하는 예제입니다. 이전에 수치..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 5장에서는 계산 그래프라는 방법을 통해 순전파, 역전파를 가르쳐줍니다. 연쇄 법칙(Chain rule) 덕분에 각 층의 자체(?) 기울기를 곱하면서 역전파하면 각 층의 최종 기울기를 얻을 수 있습니다. 아래 코드는 간단하게 덧셈, 곱셈 레이어를 만들고 이를 사용하여 사과, 오렌지의 가격을 순전파로 계산한 다음 역전파로 각 요소가 최종 가격에 끼치는 기울기를 계산하는 예제입니다. 코드: pub struct MulLayer { x: f32, y: f32, } impl MulLayer { pub fn new() -> Self { MulLayer { x: 0.0, y: 0.0 } } pub fn forward(&mut self, x: f32..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 이번에는 이때까지 구현한 기능을 조합하여 2층 신경망을 만들어봅니다. 다만 수치 미분을 사용했기에 매우 느려 학습이 잘 되는지는 확인하지 못했으니 대충 흐름만 보시면 되겠습니다. 코드에서 MNIST 데이터셋과 관련된 부분은 포함하지 않았으니 관심있으신 분은 GitHub에서 보시면 되겠습니다.또한 속도를 높히기 위하여 데이터셋의 일부만 학습에 사용하였고테스트를 위해 사용했던 해석적 미분을 이용한 부분은 주석 처리 해두었습니다. 코드: use std::f32; use rulinalg::matrix::{Matrix, BaseMatrix, BaseMatrixMut}; use rand; use ch03::activation; use commo..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 이전에 신경망의 학습은 손실 함수의 값을 최소화하는 방향으로 파라미터를 조정한다고 했습니다. 그럼 파라미터를 어떻게 조절해야 손실이 줄어드는지 알 수 있을까요? 저는 미적분을 제대로 배우지 않았지만 미분은 값의 변화와 관련이 있다는건 압니다. 그러니까 L = f(x)이고 x가 d만큼 변했을때 L은 d의 몇 배만큼 변하는지가 미분이라고 대충 알고 있습니다. 여기서 L을 손실, f를 손실 함수 + 신경망, x를 파라미터라고 하면 대충 윤곽이 보이죠. 우리는 f 함수를 미분하여 기울기를 구해 x를 올바른 방향으로 조절할 수 있습니다. 그런데 저 같은 수포자에게 함수를 미분하라는건 힘든 일입니다. 그러나 수치 미분이란 방법을 쓰면 해석적 미..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 손실 함수는 신경망의 학습 정도를 수치화하는데 사용되는 함수입니다. 손실 함수의 값을 최소화하는 방향으로 신경망의 파라미터들을 조정하는게 학습입니다. 여러 종류가 있는데 보통은 어떤 문제를 푸느냐에 따라 다른 함수를 사용하는 것 같습니다. 아래 코드는 대표적인 손실 함수인 MSE와 Cross entropy를 구현하고 손실값을 계산해보는 예제입니다. 코드: use rulinalg::matrix::{Matrix, BaseMatrix, BaseMatrixMut}; pub fn mean_squared_error(y: &Matrix, t: &Matrix) -> f32 { let mut err = y - t; err = err.apply(&|v..
※ 실제로 동작하는 전체 소스코드는 GitHub에서 보실 수 있습니다. 활성화 함수는 뉴런에서 입력을 받아 합산한 값을 출력으로 내보낼때 거치는 함수입니다. 어떤 활성화 함수를 사용하느냐도 학습에 중요한 요소로 작용합니다. 책에서는 계단 함수, 시그모이드, ReLU(렐루?)를 소개하고 있습니다. 코드: use rulinalg::matrix::{Matrix, BaseMatrixMut}; pub fn step_function(x: Matrix) -> Matrix { x.apply(&|value| if value > 0.0 { 1.0 } else { 0.0 }) } pub fn sigmoid(x: Matrix) -> Matrix { x.apply(&|value| 1.0 / (1.0 + (-value).exp(..
1장은 건너뛰고 책에서 미리 준비된 코드를 사용해서 진행하는 실습도 건너뛰었습니다. 남은건 퍼셉트론 뿐... 예제는 퍼셉트론으로 AND, OR, NAND 그리고 이를 조합하여 XOR 게이트를 구현한 코드입니다. 코드: use rulinalg::matrix::BaseMatrix; pub fn and_gate(x1: f32, x2: f32) -> f32 { let x = matrix![x1, x2]; let w = matrix![0.5, 0.5]; let b = -0.7; let out = x.elemul(&w).sum() + b; if out > 0.0 { 1.0 } else { 0.0 } } pub fn or_gate(x1: f32, x2: f32) -> f32 { let x = matrix![x1, x..