[deep learning 학습 노트] Yusugomori의 SDA 코드를 주석하여 - 준비 작업

3433 단어
1. SDA 기본 원리
사실은 앞의 몇 편의 블로그를 이어받아 Yusugomori의 deep learning 코드를 계속 주석하고 SDA에 주석을 달았습니다. 그리고 기본 원리를 말씀드리겠습니다.
SDA는 Stack denosing autoencoders의 약자입니다.표준 DA(denosing autoencoders)에 비해 주요 차이점은 다음과 같다.은밀층인 Stack의 의미가 많아졌다.2. 맨 윗층은 LR(logestic regresssion)이고 softmax로 각 카테고리의 확률을 계산한다.두 은밀층 사이는 표준DA의 훈련 알고리즘으로 훈련한다.마지막 층은 LR 알고리즘으로 훈련한다.이때 억제된 레이어도 RBM으로 대체할 수 있습니다.RBM의 기본 원리는 DA와 다르지만 작용은 똑같으며 모두 입력 층의 표현 방식이다.
2. hidden layer
Hidden layer와 DA는 코드에서 모두 SDA의 구성 요소로 네트워크 구조에서 Hidden layer와 DA는 같은 네트워크 구조를 공유한다.그런데 왜 두 가지를 성명했을까요?SDA에서 Sample의 과정(확률을 계산한 후 현재 확률에 따라 베누리 실험을 진행하여 0-1 출력을 얻는다)을 사용해야 하기 때문에 이것은 DA의 코드에 없다(RBM의 코드에 있다).사실 Sample 함수를 단독으로 쓰면hidden layer 클래스를 만들 필요가 없습니다.그러나 유수고모리의 원본 코드에는 DNN도 있다. 이렇게 쓰면 DNN의 실현을 편리하게 할 수 있을 것이다.
3. HiddenLayer.h
헤더 파일은 다음과 같습니다.
class HiddenLayer 
{
public:
  	int N;			// the number of training samples
  	int n_in;		// the node number of input layer
  	int n_out;		// the node number of output layer
  	double **W;		// the network weights
  	double *b;		// the bias 
  	
  	// allocate memory and initialize the parameters
  	HiddenLayer (
	  	int, 		// N
	  	int, 		// n_in
	  	int, 		// n_out
	  	double**, 	// W
	  	double*		// b
		  );
  	~HiddenLayer();
  	// calculate the value of a certain node in hidden layer
  	double output (
	  	int*, 		// input value vector
	  	double*, 	// the network weight of the node in hidden layer
	  	double		// the bias of the node in hidden layer
		  );
	// sample the 0-1 state of hidden layer given the input
  	void sample_h_given_v (
	  	int*, 		// input value vector
	  	int*		// the output 0-1 state of hidden layesr
		  );
};

4. HiddenLayer의 실현은 Sda에 있다.cpp에서 구현되는 코드 세그먼트는 다음과 같습니다.
// HiddenLayer
HiddenLayer::HiddenLayer (
		int size, 			// N
		int in, 			// n_in
		int out, 			// n_out
		double **w, 		// W
		double *bp			// b
			) 
{
  	N = size;
  	n_in = in;
  	n_out = out;

  	if(w == NULL) 
  	{
  		// allocate memory for W
    	W = new double*[n_out];
    	for(int i=0; i<n_out; i++) 
			W[i] = new double[n_in];
		// the initial value
    	double a = 1.0 / n_in;
    	for(int i=0; i<n_out; i++) 
		{
      		for(int j=0; j<n_in; j++) 
 			{
        		W[i][j] = uniform(-a, a);
      		}
    	}
  	} 
  	else 
	{
    	W = w;
  	}

  	if(bp == NULL) 
  	{
    	b = new double[n_out];
    	memset (b, 0, sizeof(int));	// I add this to initialize b
  	} 
  	else 
  	{
    	b = bp;
  	}
}

HiddenLayer::~HiddenLayer() 
{
	// clear W and b
  	for(int i=0; i<n_out; i++) 
	  	delete W[i];
  	delete[] W;
  	delete[] b;
}

double HiddenLayer::output (
		int *input, 
		double *w, 
		double b
			) 
{
	// iterate all the input nodes and calcualte the output of the hidden node
  	double linear_output = 0.0;
  	for(int j=0; j<n_in; j++) 
  	{
    	linear_output += w[j] * input[j];
  	}
  	linear_output += b;
  	return sigmoid(linear_output);
}

void HiddenLayer::sample_h_given_v (
		int *input, 
		int *sample
			) 
{
  	for(int i=0; i<n_out; i++) 
  	{
  		// get the result of binomial test
    	sample[i] = binomial(1, output(input, W[i], b[i]));
  	}
}

5. SDA에는 LR, DA 등이 사용된다.
그들의 헤더 파일 주석은 나의 이전의 블로그를 참고하여 실현 코드를 모두 Sda에 두었다.cpp에서 및 이전 dA.cpp、LR.cpp 대비, 차별 없이 간단한copy &paste입니다.이 코드들의 주석은 여기에도 상세하게 쓰지 않으니 필요한 것은 제 앞에 있는'[deep learning 학습 노트] 주석 유수고모리의 xxx 코드'시리즈의 박문을 참고하세요.

좋은 웹페이지 즐겨찾기